<Home>
DocumentationSELF-HOSTED / DEVELOPMENT RELEASEView source ↗
GUIDE 21 / Databases

Database credentials and TLS

Understand scoped application access, verified server identity, renewal and external connection grants.

Self-hosted alpha.47 includes PostgreSQL, Redis and MongoDB. MySQL, ClickHouse, Oracle Database, Vitess, Neon and Supabase remain unavailable while native qualification is incomplete. Check the managed database guide for availability; these guides describe source behavior, not a production deployment.

Credentials and TLS have separate jobs#

An application binding stores a database reference and endpoint choice:

[services.api.bindings.DATABASE_URL]
managed_database = "DATABASE_ID"
protocol = "postgres"
endpoint = "read_write"

A reviewed connection change checks the application and database revisions, saves the binding and queues application deployment in one transaction. Runtime resolution provides the restricted application account and public trust material to the bound service. Bootstrap, monitoring and recovery accounts stay separate. Applications receive neither Kubernetes credentials nor a database CA private key.

A private address does not authenticate its server. Required TLS checks the issuer, hostname and certificate actually served; native probes also check database access and role. A configuration flag alone cannot verify that a router checks its backend identity. MySQL Router's adversarial backend-certificate test is a separate acceptance gate.

Inspect the CA certificate with hakopod database trust DATABASE_ID. Configure the driver to trust that CA and verify the database hostname. MySQL drivers differ in how they interpret URL options, and Oracle clients may need a wallet containing the CA certificate. Never copy the server wallet or turn verification off to make a connection succeed.

Renewal includes issuing/reloading server identities, overlap trust where supported, native verification and application trust rollout. An existing TLS session may outlive a certificate reload. Test new physical connections as well as running applications. Binding removal revokes network access; recovery additionally closes target ingress and revokes sessions before writing restored data.

See TLS verification, served-certificate checks, bindings and runtime binding resolution.

Check a connection without exposing its credentials#

Start with the public trust response:

hakopod database trust DATABASE_ID

Save the returned public certificate for the client. For a MySQL Router write endpoint, a native check prompts for the application password rather than placing it in the command arguments:

mysql --host=OBSERVED_HOST --port=6446 --user=app --password \
  --database=app --ssl-mode=VERIFY_IDENTITY --ssl-ca=database-ca.crt

Use the observed hostname, not a substituted IP address. The certificate must verify for the actual endpoint name. Driver-specific connection options matter; testing this command does not configure every application's MySQL library.

Review renewal and revocation separately#

A server can accept the new certificate while an application still trusts only the old issuer. Inspect server verification, public trust rollout and new application connections together. Test the transition through the old/new trust overlap, then verify that an unrelated issuer and wrong hostname are rejected.

Revoking a binding should remove access from the affected service. Restoring into a target also needs to terminate existing sessions before archive writes; removing a network grant alone does not establish that every old connection is closed. The recovery guide explains why the target stays isolated until inspection.