Rotate keys and certificates
Every credential SkelaDB uses lives in your cluster or your secret store. This
guide lists each one, where it lives and how to replace it. Generate new values
with openssl rand -hex 32 unless stated otherwise, and never paste them into
shell history (read -r -s VALUE).
Platform tokens
| Credential | Where | Used by |
|---|---|---|
| Admin API token | skela-api Secret, key token |
Operators and automation with full access |
| Proxy token | skela-api, key proxy-token |
The proxy, which can only resolve connections |
| Metrics token | skela-api, key metrics-token |
Prometheus scrapes of /metrics |
| Project tokens | skela-project-tokens Secret, one key per project |
Console regions and per-project automation |
| Proxy peer secret | skela-proxy-peer, key secret |
Proxy replicas authenticating each other |
The controller and proxy read the first three at startup. To rotate one:
kubectl -n skela patch secret skela-api --type merge -p "{\"stringData\":{\"token\":\"$NEW\"}}"
kubectl -n skela rollout restart deployment/skela-control deployment/skela-proxy
Update every client of the admin token at the same time. Rotating the proxy token or the peer secret makes logins wait for the restart to finish, so do it in a quiet period.
The controller reads project tokens on every request: replace or remove a key in
skela-project-tokens and the old token stops working at once. If the
console uses that slot, update the token in the cloud-regions Secret and restart
cloud-api and cloud-worker in skela-cloud.
License key
Install a renewed key before the old one expires (the controller exports
skela_license_expiry_timestamp):
kubectl -n skela create secret generic skela-license --from-literal=key="$SKELA_LICENSE_KEY" \
--dry-run=client -o yaml | kubectl apply -f -
kubectl -n skela rollout restart deployment/skela-control
Rerunning ./install.sh apply with SKELA_LICENSE_KEY set also updates the
Secret; restart the controller afterwards. See licensing.md.
Database passwords
- Console databases: Databases → Rotate password issues a new password for that database’s role; connected sessions keep running and new logins need the new password.
- Roles you created yourself:
ALTER ROLE ... PASSWORD ...as usual. - The branch’s internal passwords live in the branch’s Secret; the platform reinstalls them whenever the Secret changes.
Console keys and secrets
Encryption keys. SKELA_CLOUD_ENCRYPTION_KEYS lists id:base64key, newest
first, with numeric IDs from 1 to 255. To rotate:
- Escrow the new key, then prepend it:
2:<new>,1:<old>. Restartcloud-apiandcloud-worker. New values are sealed with key 2, and the worker re-seals existing values in the background, 100 per table each minute. - Wait until the API metric
skela_cloud_sealed_values_not_currentis 0. - Remove key 1 from the list and restart. Keep it in escrow as long as any backup sealed with it is retained.
Run cloud/render.sh check-keys after any change; it fails if any stored value
cannot be opened with the configured keys.
WorkOS. Rotate the API key and webhook secret in WorkOS, update
cloud-config and console-config, and restart the three workloads. Changing
SKELA_WORKOS_COOKIE_PASSWORD signs everyone out.
Metrics token (SKELA_CLOUD_METRICS_TOKEN): update the Secret and your
Prometheus configuration together.
Certificates
cert-manager renews leaf certificates before they expire. The controller, proxy,
database computes and storage services pick up renewed certificates while
running (the platform services check every five seconds), and existing
connections continue. Nothing needs to be done as long as the issuing CA stays
the same. Watch the certificate expiry alert in observability/.
Replacing the certificate authority
A new CA must be trusted everywhere before anything presents a certificate signed by it. Plan a maintenance window and keep the old CA and issuer until the end.
- Inventory every verifier: application clients, the proxy, the console’s
region CA files (
controller_ca,compute_ca), database computes and storage services. - Distribute a bundle with both the old and the new CA to every verifier (for
issuers that do not write
ca.crt, theSKELA_TLS_CA_SECRETSecret) and restart the proxy and controller, which read trust at startup. Keep the old certificates in place. - Check application logins, the console and backups.
- Point the issuer at the new CA and reissue certificates (delete the
Certificate Secrets one by one, or
cmctl renew). Repeat the checks. - When everything uses new certificates, remove the old CA from the bundles, restart the verifiers and confirm that a certificate from the old CA is refused.
Before step 5 you can roll back by restoring the old certificates. Clients that
verify the proxy (sslmode=verify-full) need the new CA before step 4.
Release signing key
SkelaDB signs releases with one key published at
https://skeladb.com/releases/cosign.pub. If we ever replace it, the new key
and its fingerprint are announced in verify.md and the release
notes; update any admission policy that pins it.