Light Dark Auto

Enable mTLS for Mesh

Greymatter Version

  • v1.8.1

Enable Mesh-wide mTLS

Using the greymatter operator with GitOps makes it simple to enable TLS on an edge gateway and internal sidecars. In this scenario, the edge gateway handles TLS termination while all internal communication within the mesh between sidecars is mutual TLS (mTLS). In other words, all sidecar to sidecar connections are required to authenticate via TLS in both directions.


Edge EncryptionInternal Encryptiondefaults.edge.enable_tlsdefaults.edge.require_client_certsdefaults.core_internal_tls_certs.enabledefaults.core_internal_tls_certs.require_client_certsconfigs.spire
Plain TextPlain Textfalsefalsefalsefalsefalse
Plain TextSpirefalsefalsefalsefalsetrue
TLSPlain Texttruefalsefalsefalsefalse
mTLSPlain Texttruetruefalsefalsefalse

For TLS/mTLS you must create gm-edge-ingress-cert (see below) For Spire Internal Encryption you must have Spire deployed

Create TLS Certificates

Your enterprise operations team may issue certificates at your request but if you’d like to generate your own self-signed certificates, follow these certbot instructions.

Apply TLS Certificates to Your Mesh

Using your terminal, navigate to the directory the certificates are located in and create a Kubernetes secret referencing the certificates you created in the previous step.

kubectl create secret generic gm-edge-ingress-certs \
    --from-file=ca.crt=./ca.crt \
    --from-file=server.crt=./server.crt \
    --from-file=server.key=./server.key \
    -n greymatter

In your editor, open inputs.cue in <your-org>/greymatter-core repository. Search for enable_tls and change the value from false to true.

enable_tls: true

Once you have finished and save, commit/push your changes to <your-org>/greymatter-core repository. Your pods will be restarted by the operator once this change is detected. Because the system is eventually consistent the change may not happen immediately but it will be fast.

Retrieve your external IP from the edge LoadBalancer service with the following command:

kubectl get service -n greymatter

You should see an output like:

NAME   TYPE           CLUSTER-IP   EXTERNAL-IP     PORT(S)           AGE
edge   LoadBalancer   x.x.x.x      x.x.x.x         10808:32021/TCP   48m

Once retrieved, navigate to https://{EXTERNAL_IP}:10808 and the dashboard will load through the edge gateway over TLS.

Using different certificates for internal mTLS (Optional)

By default the GitOps Core repo will re-use the Kubernetes secret defined above, containing your edge certificates, for internal mTLS; however, different certificates for internal traffic can be accommodated.

kubectl create secret generic gm-internal-certs \
    --from-file=ca.crt=./ca.crt \
    --from-file=server.crt=./server.crt \
    --from-file=server.key=./server.key \
    -n greymatter

In your editor, open inputs.cue in <your-org>/greymatter-core repository. Search for: core_internal_tls_certs and edit the cert_secret name gm-internal-certs. Once you have completed your changes, save and push your changes to <your-org>/greymatter-core repository.

Your pods will be restarted by the operator once this change is detected. Because the system is eventually consistent the change may not happen immediately but it will be fast.

Using an existing SPIRE instance

You can leverage an existing SPIRE instance to manage Greymatter’s internal mTLS. In Kubernetes, SPIRE Registrar provides two pod identification methods, pod_label and pod_annotation. In both cases the SPIRE Registrar utilizes Kubernetes API and searches for pods with a matching label/annotation.

To configure greymatter we first need to gather information about the existing SPIRE’s configuration. Here is an example of the config file for SPIRE’s registrar:

log_level = "info"
log_path = "/dev/stdout"
addr = ""
cluster = "quickstart"
server_socket_path = "/run/spire/socket/registration.sock"
trust_domain = ""
cert_path = "/run/spire/tls/registrar.spire.svc.crt"
key_path = "/run/spire/tls/registrar.spire.svc.key"
cacert_path = "/run/spire/tls/ca.crt"
insecure_skip_client_verification	= true
pod_label = ""

In your mesh’s inputs.cue in the defaults.spire block we will want to update the trust_domain to match the registrar config’s trust_domain

spire: {
  // namespace is where SPIRE server and agents are deployed to.
  namespace: "spire"
  // trust_domain is the trust domain that must match what's configured at the server.
  trust_domain: ""
  // socket_mount_path is the mount path of the SPIRE socket for communication with an agent.
  socket_mount_path: "/run/spire/socket"
  // ca_secret_name is the name of the secret that is injected when config.deploy_spire is true.
  ca_secret_name: "server-ca"
  // host_mount_socket controls whether a host mount is used for the socket.
  // Requires hostPID permission.
  host_mount_socket: true

In the defaults.additional_labels section update external_spire_label to match the registrar config’s pod_label:

additional_labels: {
  // Labels to add to all greymatter core pods
  all_pods: [...string] | *[]
  // If integrating with an external spire that uses pod_labels for registration
  // Add the label it is looking for and this label will be added to all greymatter
  // core components
  external_spire_label: string | *""
  // Labels to add to the edge service
  edge_service: [...string] | *[]