Skip to main content
Version: v4.10 Stable

Authenticate to an External PostgreSQL Database with Kerberos

info
This feature is available from the Platform version v4.10.0
Modify the following with your specific values to replace on the whole page and generate copyable commands:

Overview​

When you run vCluster Platform with an external database, the platform's embedded database connects to your PostgreSQL backend. Instead of a static password or a cloud IAM token, that connection can authenticate with Kerberos/GSSAPI using a mounted keytab. This suits enterprises that already operate a Kerberos realm (an MIT KDC or Active Directory) and require Kerberos for all database access.

Authentication relies on existing Helm values. A passwordless config.database.dataSource carries the client principal and points at a mounted keytab. The generic volumes, volumeMounts, and env values mount the keytab and krb5.conf. No platform-specific Kerberos fields are required.

note

This applies to the platform's external PostgreSQL backend only. Kerberos authentication for the Database Connector (the tenant cluster datastore path) is not covered here.

Prerequisites​

Before you begin, ensure you have:

  • vCluster Platform v4.10.0 or later. Earlier platform builds do not include the GSSAPI-capable database and fail to start against a Kerberos datasource.
  • An existing Kerberos environment:
    • A KDC and realm (for example EXAMPLE.COM).
    • A client principal for the platform, for example krb5-db-user@EXAMPLE.COM, that you can export to a keytab.
  • A PostgreSQL server built with GSSAPI support, reachable from the control plane cluster at a stable fully qualified domain name (FQDN), with:
    • The service principal postgres/<postgres-fqdn>@REALM present in the server's keytab and referenced by krb_server_keyfile.
    • A pg_hba.conf rule that authenticates the platform connection with gss.
    • A login role and database that the client principal maps to (see Step 2).
  • The platform already configured for an external database deployment (config.database.enabled). Follow the external database overview and the deployment walkthrough for the surrounding high-availability setup. This page covers only the Kerberos authentication wiring.

Step 1 - Create the database principal and export a keytab​

Create the client principal in your KDC and export it to a keytab file. With MIT Kerberos, use kadmin:

kadmin -q "addprinc -randkey krb5-db-user@EXAMPLE.COM"
kadmin -q "ktadd -k krb5-db-user.keytab krb5-db-user@EXAMPLE.COM"

This produces a krb5-db-user.keytab file containing credentials for the principal. Keep this file secure. Anyone holding it can authenticate as the principal.

Step 2 - Create the PostgreSQL role and database​

Create a passwordless login role whose name matches the principal's short name and a database the role can use. Because the pg_hba.conf rule below uses include_realm=0, PostgreSQL strips the @REALM suffix, so the principal krb5-db-user@EXAMPLE.COM maps to the role krb5-db-user.

CREATE ROLE "krb5-db-user" LOGIN;
CREATE DATABASE kine OWNER "krb5-db-user";

Point PostgreSQL at its service keytab in postgresql.conf:

krb_server_keyfile = '/etc/postgres-keytab/krb5.keytab'

Add a gss rule to pg_hba.conf so remote TCP connections from the platform authenticate over Kerberos. PostgreSQL uses the first matching pg_hba.conf rule, so place this rule before broader host rules that use another authentication method. Scope the address range to the platform network where possible:

host all all 0.0.0.0/0 gss include_realm=0 krb_realm=EXAMPLE.COM
info

krbsrvname in the datasource (Step 4) selects the postgres service principal, and krb_realm restricts which realm's principals the rule accepts. Keep include_realm=0 and the role name aligned, otherwise the mapped role will not match and the connection is rejected.

Step 3 - Create the keytab Secret and krb5.conf ConfigMap​

Create a Kubernetes Secret holding the client keytab and a ConfigMap holding the client krb5.conf, both in the platform namespace (vcluster-platform).

kubectl create secret generic kine-keytab \
--from-file=krb5.keytab=krb5-db-user.keytab \
--namespace vcluster-platform

Write a local krb5.conf file that points at your KDC. When your service DNS names lack matching PTR records, disable DNS canonicalization and reverse lookups so the service principal name matches the host the platform connects to:

[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = false
dns_canonicalize_hostname = false
rdns = false
[realms]
EXAMPLE.COM = {
kdc = kdc.example.com
admin_server = kdc.example.com
}

Create the ConfigMap from that file:

kubectl create configmap krb5-conf \
--from-file=krb5.conf=krb5.conf \
--namespace vcluster-platform

Step 4 - Configure the platform Helm values​

Add the Kerberos datasource and the keytab/krb5.conf mounts to your platform values file (platform-kerberos-values.yaml). The datasource carries no password. The principal lives in the user part of the connection string, krb5_keytab points at the mounted keytab, and krbsrvname selects the PostgreSQL service principal.

config:
database:
enabled: true
# Passwordless GSSAPI datasource. The principal in the user part is URL-encoded
# (@ becomes %40); krb5_keytab points at the mounted keytab.
dataSource: "postgres://krb5-db-user%40EXAMPLE.COM@postgres.example.com:5432/kine?krb5_keytab=/etc/kine-keytab/krb5.keytab&krbsrvname=postgres"
extraArgs:
- --datastore-max-open-connections=5
- --datastore-max-idle-connections=2

# KRB5_CONFIG tells the GSSAPI client where to read the realm configuration.
env:
KRB5_CONFIG: /etc/krb5.conf

# Mount the client keytab and krb5.conf into the platform pod.
volumes:
- name: kine-keytab
secret:
secretName: kine-keytab
- name: krb5-conf
configMap:
name: krb5-conf

volumeMounts:
- name: kine-keytab
mountPath: /etc/kine-keytab
readOnly: true
- name: krb5-conf
mountPath: /etc/krb5.conf
subPath: krb5.conf
readOnly: true
warning

The principal in the datasource user part must be URL-encoded. Write the @ between the principal and the realm as %40 (for example krb5-db-user%40EXAMPLE.COM). The datasource host must exactly match the host in the PostgreSQL service principal (postgres/<host>@REALM) baked into the server keytab. A mismatch makes the GSSAPI handshake fail even when every other value is correct.

note

Kerberos authenticates the database connection, but it does not replace TLS. Add the PostgreSQL TLS options your environment requires to the datasource, such as sslmode=verify-full, and configure the corresponding database CA or client certificate values as needed.

Merge these values with the rest of your external database configuration (replicaCount, ingress, and so on) from the deployment walkthrough.

Step 5 - Install and verify​

Install or upgrade the platform with the values file:

vcluster platform start \
--namespace vcluster-platform \
--values platform-kerberos-values.yaml

Wait for the deployment to become ready:

kubectl rollout status deployment/loft -n vcluster-platform

A ready replica confirms the GSSAPI handshake succeeded when the matching pg_hba.conf rule permits only gss for the platform connection. The datasource carries no password, so Kerberos is the only authentication path available.

If the deployment stays unready, check the platform pod logs:

kubectl logs -n vcluster-platform -l app=loft --tail=100

A wrong or absent principal surfaces a KDC_ERR_C_PRINCIPAL_UNKNOWN error. The KDC has no such principal, so the credential could not be acquired. Confirm that the principal in the datasource exactly matches the one exported into the mounted keytab. See Troubleshooting External Database for more Kerberos failure modes.