RFC: DBaaS M1 TLS Lifecycle and Certificate Management #172
Yohansenanayake
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Context
This proposal suggests treating TLS as its own lifecycle for M1, separate from the tenant master password lifecycle.
The tenant master password lifecycle covers provisioning, BYO password, generated initial password, reveal, and reset. TLS is different: it controls PostgreSQL transport security and server identity.
The goal of this discussion is to agree on the M1 TLS API and lifecycle. Feedback is especially welcome on the open questions at the end.
Goals
For M1, TLS support could provide:
Non-Goals for M1
Suggested non-goals for M1:
Proposed API
TLS Enabled
TLS Disabled
API Fields
spec.tls.modeControls whether PostgreSQL is provisioned with TLS.
Supported M1 values:
Suggested default:
The current proposal is to enable TLS by default for M1 DBInstances and let users explicitly opt out with
tls.mode=Disabled.Possible future values:
spec.tls.certificate.durationControls the validity duration for DBaaS-managed certificates.
Example:
Suggested M1 validation:
If
tls.mode=Disabled,certificate.durationhas no effect because no certificate is issued. Whether this should be rejected at admission time or ignored is an open question below. The current leaning is to reject it so the spec does not contain inert configuration.Mutability Rules
Suggested M1 behavior:
Rationale:
Changing TLS mode after provisioning requires modifying PostgreSQL config, rewriting
pg_hba.conf, reloading/restarting PostgreSQL, updating endpoint URLs, and possibly creating/deleting cert material. The proposal is to defer that modify workflow until after M1.Secret Model
When TLS is enabled, the proposed model is for DBaaS to create durable private TLS material in the controller namespace, for example
dbaas-system.Tenant-readable connection material would live in a common connection Secret in the tenant namespace. This Secret exists for both TLS-enabled and TLS-disabled configurations, but it contains
ca.crtonly when TLS is enabled.The connection Secret is different from password reveal/reset Secrets:
Hash input:
Including the UID helps avoid collisions when a tenant deletes and recreates a DBInstance with the same name.
Recommended Secret Shapes
Private TLS Secret
Readable by the DBaaS controller only.
Public Connection Secret
Readable by users or applications that need DB connection metadata.
When TLS is enabled:
When TLS is disabled, the same Secret shape is used but
ca.crtis omitted:The public connection Secret would not include:
Reasons to provide a common connection Secret even when endpoint details are also available in status:
ca.crtin a stable Secret path avoids copying PEM blocks out of status into a separate app Secret.The connection Secret intentionally does not include the tenant master password. In BYO mode, the user owns the password Secret. In generated-password mode, the password is delivered through a temporary reveal/reset Secret and is not stored long-term by DBaaS.
If TLS is disabled, DBaaS would still create the connection Secret, but without
ca.crt. DBaaS would not create the private TLS Secret.Status Shape
TLS Enabled
Whether to expose the controller-private TLS Secret reference in status is an open question below. Tracking it improves admin visibility for debugging, audits, backup checks, and recovery; it does not grant Secret data access without RBAC. Omitting it keeps status smaller and lets the controller track the Secret internally by namespace/name/UID hash and labels.
TLS Disabled
TLS Impaired
Connection URL Behavior
When TLS is enabled:
When TLS is disabled:
Flow 1: Provision With TLS Enabled
sequenceDiagram actor User participant K8s as Kubernetes API participant DBI as DBInstance participant Ctrl as DBaaS Controller participant TLS as Private TLS Secret participant Conn as Connection Secret participant VM as PostgreSQL VM participant PG as PostgreSQL User->>K8s: Create DBInstance with tls.mode=DBaaSManaged K8s->>DBI: Store DBInstance Ctrl->>K8s: Watch DBInstance Ctrl->>Ctrl: Resolve certificate duration Ctrl->>Ctrl: Generate CA + server certificate Ctrl->>TLS: Store ca.crt, ca.key, tls.crt, tls.key in dbaas-system Ctrl->>Conn: Store connection details + public ca.crt in tenant namespace Ctrl->>VM: Bootstrap PostgreSQL with TLS material VM->>PG: Configure ssl=on and hostssl rules PG-->>Ctrl: PostgreSQL ready Ctrl->>DBI: Update status.tls and endpoint URL Ctrl-->>User: DB ready with public TLS trust material Note over Conn: Tenant mounts connection details and ca.crt. Note over TLS: Private TLS keys remain controller-private.Flow 2: Provision With TLS Disabled
sequenceDiagram actor User participant K8s as Kubernetes API participant DBI as DBInstance participant Ctrl as DBaaS Controller participant VM as PostgreSQL VM participant PG as PostgreSQL User->>K8s: Create DBInstance with tls.mode=Disabled K8s->>DBI: Store DBInstance Ctrl->>K8s: Watch DBInstance Ctrl->>Ctrl: Skip TLS material generation Ctrl->>Connection Secret: Store connection details without ca.crt Ctrl->>VM: Bootstrap PostgreSQL without TLS material VM->>PG: Configure ssl=off and host rules PG-->>Ctrl: PostgreSQL ready Ctrl->>DBI: Update status.tls.mode=Disabled and endpoint URL Ctrl-->>User: DB ready without TLSState Machine
stateDiagram-v2 [*] --> TLSModeResolved TLSModeResolved --> TLSDisabled: mode=Disabled TLSDisabled --> DBReady: PostgreSQL ssl=off TLSModeResolved --> TLSPending: mode=DBaaSManaged TLSPending --> TLSMaterialCreated: private TLS Secret created TLSMaterialCreated --> TLSConfigured: PostgreSQL ssl=on TLSConfigured --> TLSActive: endpoint published with verify-ca TLSActive --> TLSImpaired: private material missing or invalid TLSImpaired --> TLSActive: recovered safely TLSActive --> TLSDeleting: DBInstance deletion DBReady --> TLSDeleting: DBInstance deletion TLSDeleting --> [*]: DBaaS-owned connection/TLS material deletedProposed Cleanup
If TLS is enabled:
If TLS is disabled:
Open Questions
spec.tls.certificate.durationdefault to 1 year or 90 days?tls.mode=Disabled, shouldcertificate.durationbe rejected at admission time or ignored?status.tls.privateSecretRefbe exposed in tenant-facing status, or tracked only internally?Beta Was this translation helpful? Give feedback.
All reactions