Encrypt database connection

This guide provides an example how to setup a TLS encrypted database connection. By default, database connection encryption is enabled. However there are additional steps required.

See the following manuals on how to customize connection encryption:

The built-in database provider only supports self-signed certificates. This is because Keycloak connects through the cluster-internal service and not an externally resolvable resp. verifiable hostname.

Requirements

  • commodore

  • kubectl

  • openssl

  • vault

Using self-signed certificates

  1. Prepare certificate files when using self-signed certificates

    Built-in database
    # Adjust the lifetime as necessary
    lifetime=3650
    openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -days ${lifetime} -subj '/CN=keycloak'
    External database
    # Save the cert and key in these temporary files
    editor server.key
    editor server.crt
  2. Store certificate in Vault

    instance=keycloak
    parent="clusters/kv/${TENANT_ID}/${CLUSTER_ID}"
    
    # Use the 'patch' subcommand to add to existing secret
    vault kv patch "${parent}/${instance}" server-cert=@server.crt server-cert-key=@server.key
  3. Remove temporary files

    rm server.{key,crt}

Using valid server certificates

  1. Configure TLS verification mode when using verified/signed certificates

    Verified server certificate (only external database)
    parameters:
      keycloak:
        database:
          # Verify server certificate using the built-in CA bundle.
          jdbcParams: sslmode=verify-ca&sslrootcert=/etc/ssl/certs/ca-bundle.crt
          tls:
            verification: verify

Verify that Keycloak connects securely

  1. Verify that Keycloak connects using TLS

    Built-in database
    namespace=syn-keycloak
    kubectl exec -it -n ${namespace} keycloak-postgresql-0 -c keycloak-postgresql -- sh -c \
    'PGDATABASE="$POSTGRES_DATABASE" PGUSER="$POSTGRES_USER" PGPASSWORD="$POSTGRES_PASSWORD" '\
    'psql -c "SELECT datname, usename, ssl, client_addr FROM pg_stat_ssl JOIN pg_stat_activity ON pg_stat_ssl.pid = pg_stat_activity.pid;"'
    External database
    # First, connect to your database server where `psql` is available.
    # Then connect to postgres.
    sudo -u postgres psql
    
    # List the connected users with the following query:
    SELECT datname, usename, ssl, client_addr FROM pg_stat_ssl JOIN pg_stat_activity ON pg_stat_ssl.pid = pg_stat_activity.pid;

    For each client_addr you should see a t in the ssl column.

Disable encryption

While not recommended, it’s possible to disable encryption. Set the following parameters and skip the Vault steps:

parameters:
  keycloak:
    database:
      jdbcParams: ""
      tls:
        enabled: false
    helm_values:
      extraVolumes: ""
      extraVolumeMounts: ""

Note that this will also remove the default volumeMounts added by the Chart, like "startup" and "keycloak-tls."