Skip to main content

Rotate credentials

Credentials rotates differently, and some of them have a consequence worth knowing before you start.

CredentialRotating it interruptsReversible
Database role passwordsThe services that use them, brieflyYes
Object store keysEverything that reads the object storeYes, if you kept the old values
Registry pull credentialsNothing running. New pulls onlyYes
Your Gen0Sec API keyArtifact delivery, brieflyYes
Dashboard session signing keyEvery session and every invite linkNo

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.

Do not lose these

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

This signs everyone out

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

CertificateOwned by
Ingress TLSYou. Rotate in your ingress or through cert-manager
Postgres poolerThe Postgres operator, self-signed, rotated by it
Relay to Gen0SecPublic 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.