Rotate credentials
Credentials rotates differently, and some of them have a consequence worth knowing before you start.
| Credential | Rotating it interrupts | Reversible |
|---|---|---|
| Database role passwords | The services that use them, briefly | Yes |
| Object store keys | Everything that reads the object store | Yes, if you kept the old values |
| Registry pull credentials | Nothing running. New pulls only | Yes |
| Your Gen0Sec API key | Artifact delivery, briefly | Yes |
| Dashboard session signing key | Every session and every invite link | No |
If you run an external secret manager, rotation happens there and the cluster picks up the new value. This page is for installs holding plain Kubernetes secrets. See Secrets.
Database role passwords
Rotate through the Postgres operator, not by editing the secret. The operator owns these values, and an edited secret is overwritten on its next reconciliation.
After the operator has regenerated the credentials, recompose the application secrets and restart the consumers:
$KIT/scripts/make-db-secrets.sh $B/values/gen0sec-platform-values-onprem.yaml
kubectl -n gen0sec rollout restart deploy
The script preserves the dashboard's session signing key, so re-running it does not sign people out.
Object store keys
These are the ones you generated during install, and nothing regenerates them. Rotating means updating two places.
umask 077
S=$(mktemp -d)
openssl rand -hex 16 | tr -d '\n' > "$S/RUSTFS_ACCESS_KEY"
openssl rand -hex 32 | tr -d '\n' > "$S/RUSTFS_SECRET_KEY"
kubectl -n gen0sec-system delete secret gen0sec-object-store
kubectl -n gen0sec-system create secret generic gen0sec-object-store --from-file="$S"
Then restart the object store, and recompose the application secrets, because the services receive the same values under different names:
kubectl -n gen0sec-system rollout restart \
"$(kubectl -n gen0sec-system get sts,deploy -o name | grep -m1 rustfs)"
$KIT/scripts/make-db-secrets.sh $B/values/gen0sec-platform-values-onprem.yaml
kubectl -n gen0sec rollout restart deploy
Save the new files where you kept the old ones, then remove the temporary directory.
Data in the object store was written with them. A retained volume without the matching keys is data you cannot open. See Back up and restore.
Registry pull credentials
Recreate the secret in both namespaces. Running pods keep running; the new value applies to the next pull.
umask 077
AUTH=$(printf '%s:%s' "$REG_USER" "$(cat $REG_PASS_FILE)" | base64 | tr -d '\n')
printf '{"auths":{"%s":{"auth":"%s"}}}' "$REGISTRY" "$AUTH" > dockerconfig.json
unset AUTH
for ns in gen0sec-system gen0sec; do
kubectl -n $ns delete secret gen0sec-registry
kubectl -n $ns create secret generic gen0sec-registry \
--type=kubernetes.io/dockerconfigjson \
--from-file=.dockerconfigjson=dockerconfig.json
done
rm -f dockerconfig.json
Rotate before the old credential expires, not after. An expired pull secret is invisible until something reschedules.
Your Gen0Sec API key
printf '%s' '<new key issued by gen0sec>' > $RELAY_KEY_FILE
kubectl -n gen0sec delete secret gen0sec-download-proxy
kubectl -n gen0sec create secret generic gen0sec-download-proxy \
--from-file=DOWNLOAD_PROXY_API_KEY=$RELAY_KEY_FILE
kubectl -n gen0sec rollout restart deploy/g0s-download-api
Confirm it worked, because a wrong key fails silently:
kubectl -n gen0sec logs deploy/g0s-download-api | grep -i 'relayed from upstream' | tail -5
Any status=401 means the new key is wrong, or has a trailing newline. Use printf, not echo. See
Data relay.
Dashboard session signing key
Rotating it invalidates every active session and every outstanding invite link. There is no partial rotation and no grace period.
Only do this if you believe the key is compromised. Delete it and let the secret script regenerate it:
kubectl -n gen0sec delete secret g0s-db-ui
$KIT/scripts/make-db-secrets.sh $B/values/gen0sec-platform-values-onprem.yaml
kubectl -n gen0sec rollout restart deploy/g0s-ui
The script preserves an existing key, which is why deleting the secret first is the step that actually rotates it.
Certificates
| Certificate | Owned by |
|---|---|
| Ingress TLS | You. Rotate in your ingress or through cert-manager |
| Postgres pooler | The Postgres operator, self-signed, rotated by it |
| Relay to Gen0Sec | Public certificate on our side. Nothing to do |
The platform presents no certificate of its own outside the ingress you configure.
After any rotation
kubectl -n gen0sec wait --for=condition=Ready pod --all --timeout=10m
$KIT/scripts/verify-deployment.sh
The smoke test is the only check that proves the platform still serves an agent rather than merely starting.