Skip to content

AuthGateway TLS Configuration

This guide covers how to configure TLS for AuthGateway to enable secure HTTPS connections with valid certificates.

Overview

AuthGateway uses Pomerium as a reverse proxy. For production deployments, you need to configure TLS with valid certificates so clients can connect securely.

TLS Configuration Options

Create a Kubernetes TLS secret with your certificate and key, then reference it in the AuthGateway CR.

Step 1: Create the TLS Secret

# From certificate files
kubectl create secret tls pomerium-tls \
  --cert=fullchain.crt \
  --key=server.key \
  -n <namespace>

Or if you have separate certificate and CA bundle files:

# First combine the certificate with CA chain
cat server.crt ca_bundle.crt > fullchain.crt

# Then create the secret
kubectl create secret tls pomerium-tls \
  --cert=fullchain.crt \
  --key=server.key \
  -n <namespace>

Step 2: Reference in AuthGateway CR

apiVersion: e6data.io/v1alpha1
kind: AuthGateway
metadata:
  name: query-gateway
  namespace: poc1
spec:
  domain: query.example.com
  replicas: 2

  tls:
    secretName: pomerium-tls  # Reference to the TLS secret

  services:
    - name: query-engine
      isGRPC: true           # Enables h2c://, timeout: 0s for gRPC streaming
      backend:
        serviceName: poc1-traffic-envoy
        servicePort: 8080

Option 2: Cert-Manager Integration

For automatic certificate management with Let's Encrypt or other ACME providers.

Prerequisites

  1. Install cert-manager in your cluster:

    kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
    

  2. Create a ClusterIssuer (example for Let's Encrypt):

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-prod
    spec:
      acme:
        server: https://acme-v02.api.letsencrypt.org/directory
        email: admin@example.com
        privateKeySecretRef:
          name: letsencrypt-prod
        solvers:
          - http01:
              ingress:
                class: nginx
    

Create Certificate Resource

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: pomerium-cert
  namespace: poc1
spec:
  secretName: pomerium-tls  # This secret will be auto-created
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - query.example.com
    - "*.example.com"  # Wildcard if needed

Then reference pomerium-tls in your AuthGateway CR as shown above.

gRPC Backend Configuration

When routing to gRPC backends (like TrafficInfra Envoy), enable the isGRPC flag:

services:
  - name: query-engine
    isGRPC: true           # Required for gRPC
    backend:
      serviceName: poc1-traffic-envoy
      servicePort: 8080

When isGRPC: true, the operator automatically configures: - h2c:// scheme for HTTP/2 cleartext to backend - timeout: 0s for unlimited streaming - idle_timeout: 0s for long-running streams

Note: gRPC uses HTTP/2 bidirectional streaming, which is different from WebSockets. The allowWebsockets option is NOT needed for gRPC.

Working Configuration Example

Based on tested configuration with Pomerium v0.31.3:

apiVersion: e6data.io/v1alpha1
kind: AuthGateway
metadata:
  name: query-gateway
  namespace: poc1
spec:
  domain: pom-linode.uzumaki.me
  replicas: 2

  image:
    tag: v0.31.3

  tls:
    secretName: pomerium-tls

  services:
    - name: query-engine
      subdomain: ""  # Use the base domain
      isGRPC: true
      backend:
        serviceName: poc1-traffic-envoy
        servicePort: 8080

This generates the Pomerium config:

address: :443

certificate_file: /pomerium/tls/tls.crt
certificate_key_file: /pomerium/tls/tls.key

authenticate_service_url: https://pom-linode.uzumaki.me

routes:
  - from: https://pom-linode.uzumaki.me
    to: h2c://poc1-traffic-envoy.poc1.svc.cluster.local:8080
    timeout: 0s
    idle_timeout: 0s
    allow_public_unauthenticated_access: true

Troubleshooting

Certificate Not Found

If AuthGateway shows Pending with message "Waiting for TLS secret: pomerium-tls":

# Check if secret exists
kubectl get secret pomerium-tls -n <namespace>

# Verify secret has correct keys
kubectl get secret pomerium-tls -n <namespace> -o jsonpath='{.data}' | jq 'keys'
# Should show: ["tls.crt", "tls.key"]

gRPC Stream Errors

If you see "server closed the stream without sending trailers":

  1. Verify isGRPC: true is set for the service
  2. Check Pomerium config has h2c:// in the "to" URL
  3. Check timeout: 0s and idle_timeout: 0s are set

Certificate Chain Issues

If clients fail with SSL certificate errors:

  1. Ensure you're using a full chain certificate (server cert + intermediate CAs)
  2. Verify certificate matches the domain in the AuthGateway
# Check certificate
openssl s_client -connect domain:443 -servername domain < /dev/null 2>/dev/null | \
  openssl x509 -noout -dates -subject

Status Fields

AuthGateway status includes certificate readiness:

status:
  phase: Ready
  certificateReady: true  # TLS secret found and valid
  pomeriumReady: true
  endpoint: https://pom-linode.uzumaki.me

When certificateReady: false, check the TLS secret configuration.