⚙️Configure HTTPS

External traffic

Overview

External Traffic

You have two ingresses to secure:

  • The main entrypoint nginx (for the example, we assume the address app.example.com)

  • The authentication service entrypoint curity (we assume the address auth.example.com)

This guide assumes you have a DNS entry pointing to the IP address of the Load Balancer where you're running Toucan.

This guide also assume full understanding of TLS and how to configure it.

Parameters

Here's the location of the parameters you need to configure:

yaml: values.override.yaml
global:
  hostname: 'app.example.com'

nginx:
  ingress:
    enabled: true
    selfSigned: false
    pathType: ImplementationSpecific
    path: /
    annotations: {}
    hostname: '' # optional, this will be set to `global.hostname`
    ingressClassName: 'nginx'
    # By setting tls to true, the ingress will fetch a secret named `<host>-tls`, i.e., `app.example.com-tls`
    tls: false
    extraHosts:
      []
      # - name: app.example.com
      #   path: /#
    extraPaths:
      []
      # - path: /*
      #   backend:
      #     serviceName: ssl-redirect
      #     servicePort: use-annotation
    extraTls:
      []
      # - hosts:
      #     - app.example.com
      #   secretName: app.example.com-tls
    secrets:
      []
      # - name: app.example.com-tls
      #   key: |-
      #     -----BEGIN RSA PRIVATE KEY-----
      #     ...
      #     -----END RSA PRIVATE KEY-----
      #   certificate: |-
      #     -----BEGIN CERTIFICATE-----
      #     ...
      #     -----END CERTIFICATE-----
    extraRules:
      []
      # See: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-rules

curity:
  runtime:
    ingress:
      enabled: false
      pathType: ImplementationSpecific
      hostname: auth.example.com
      ingressClassName: 'nginx'
      path: /
      annotations: {}
      tls: false
      selfSigned: false
      extraHosts: []
      extraPaths: []
      extraTls: []
      secrets: []
      extraRules: []

Using cert-manager

Configuring the Issuer

Check the official documentation: cert-manager - Issuer Configuration.

yaml: issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: example-issuer
  namespace: cert-manager
spec:
  acme:
    email: [email protected]
    server: https://acme-v02.api.letsencrypt.org/directory
    preferredChain: 'ISRG Root X1'
    privateKeySecretRef:
      name: example-issuer-account-key
    solvers:
      - dns01:
          # Use the appropriate Cloud DNS solver
          # See the list at: https://cert-manager.io/docs/configuration/acme/dns01/
          cloudDNS:
            project: $PROJECT_ID
            serviceAccountSecretRef:
              name: clouddns-dns01-solver-svc-acct
              key: key.json

Each time you deploy a new Certificate, the solver will try to create a DNS record with the name _acme-challenge.<host>.

Using the Issuer

You can set the parameters as follows:

yaml: values.override.yaml
global:
  hostname: 'app.example.com'

nginx:
  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      cert-manager.io/issuer: example-issuer
    tls: true

curity:
  runtime:
    ingress:
      enabled: true
      ingressClassName: nginx
      hostname: auth.example.com
      annotations:
        cert-manager.io/issuer: example-issuer
      tls: true

This will automatically generate a certificate and secret named app.example.com-tls, and configure the ingress to use the certificate issued by the Issuer named test-issuer.

Manually

If you have a certificate and private key ready, you can deploy it as a Secret:

yaml: tls-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: app.example.com-tls # Format must be `<hostname>-tls`
stringData:
  tls.crt: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
  tls.key: |
    -----BEGIN RSA PRIVATE KEY-----
    ...
    -----END RSA PRIVATE KEY-----
---
apiVersion: v1
kind: Secret
metadata:
  name: auth.example.com-tls # Format must be `<hostname>-tls`
stringData:
  tls.crt: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
  tls.key: |
    -----BEGIN RSA PRIVATE KEY-----
    ...
    -----END RSA PRIVATE KEY-----

And set the values:

yaml: values.override.yaml
global:
  hostname: 'app.example.com'

nginx:
  ingress:
    enabled: true
    ingressClassName: nginx
    tls: true

curity:
  runtime:
    ingress:
      enabled: true
      ingressClassName: nginx
      hostname: auth.example.com
      tls: true

We do not recommend setting the certificate and private key in the values.override.yaml file if you plan to do GitOps in the future.

Prefer using a secret manager like external-secrets or sealed-secrets.

Lastly, if you are using a private CA, you need to inject the CA's certificate to the internal services that uses auth.example.com:

yaml: /work/values.override.yaml
laputa:
  config:
    common:
      REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt

  extraVolumes:
    # You need to repeat the default values to append to a list. Helm does
    # not support merging lists.
    - name: spicedb-certs
      secret:
        secretName: '{{ template "toucan-stack.spicedb.tls.secretName" . }}'
        items:
          - key: ca.crt
            path: ca.crt
    - name: ca-bundle
      secret:
        secretName: 'auth.example.com-tls'
        items:
          - key: ca.crt
            path: ca-certificates.crt

  extraVolumeMounts:
    - name: spicedb-certs
      mountPath: /spicedb-certs
    - name: ca-bundle
      mountPath: /etc/ssl/certs

layout:
  extraEnvVars:
    - name: NODE_EXTRA_CA_CERTS
      value: /etc/ssl/certs/ca-certificates.crt

  extraVolumes:
    - name: spicedb-certs
      secret:
        secretName: '{{ template "toucan-stack.spicedb.tls.secretName" . }}'
        items:
          - key: ca.crt
            path: ca.crt
    - name: ca-bundle
      secret:
        secretName: 'auth.example.com-tls'
        items:
          - key: ca.crt
            path: ca-certificates.crt

  extraVolumeMounts:
    - name: spicedb-certs
      mountPath: /spicedb-certs
    - name: ca-bundle
      mountPath: /etc/ssl/certs

dataset:
  extraEnvVars:
    - name: SSL_CERT_FILE # For httpx
      value: /etc/ssl/certs/ca-certificates.crt
    - name: REQUESTS_CA_BUNDLE # For requests
      value: /etc/ssl/certs/ca-certificates.crt

  extraVolumes:
    - name: spicedb-certs
      secret:
        secretName: '{{ template "toucan-stack.spicedb.tls.secretName" . }}'
        items:
          - key: ca.crt
            path: ca.crt
    - name: ca-bundle
      secret:
        secretName: 'auth.example.com-tls'
        items:
          - key: ca.crt
            path: ca-certificates.crt

  extraVolumeMounts:
    - name: spicedb-certs
      mountPath: /spicedb-certs
    - name: ca-bundle
      mountPath: /etc/ssl/certs

impersonate:
  extraVolumes:
    - name: ca-bundle
      secret:
        secretName: 'auth.example.com-tls'
        items:
          - key: ca.crt
            path: ca-certificates.crt

  extraVolumeMounts:
    - name: ca-bundle
      mountPath: /etc/ssl/certs

vault:
  server:
    extraVolumes:
      - name: ca-bundle
        secret:
          secretName: 'auth.example.com-tls'
          items:
            - key: ca.crt
              path: ca-certificates.crt

    extraVolumeMounts:
      - name: ca-bundle
        mountPath: /etc/ssl/certs/

Internal traffic

Overview

Internal traffic

Parameters

By default, TLS or mTLS is enabled for all services using self-signed certificates.

This configuration is already highly secure, as the self-signed Certificate Authority (CA) remains entirely within the Kubernetes environment and is never exposed externally.

That said, you may choose to use your own Public Key Infrastructure (PKI) to facilitate more flexible and centralized trust management.

Note: At the moment of writing, we are unable to offer you a proper way to configure TLS or mTLS on the client. This feature is planned for a future release. Thank you for your patience.

Last updated

Was this helpful?