Secrets
This page helps you keep Goiabada’s secrets safe, and back up the one you can’t afford to lose.
The setup wizard generates every secret a deployment needs. Most of them can be replaced later at the cost of a restart, or of everybody signing in again. One can’t: the AES key, which encrypts what the database holds. Back it up before anything else.
Back up the AES key
Section titled “Back up the AES key”-
Read the key where your setup keeps it:
It’s
GOIABADA_AES_ENCRYPTION_KEY, undergoiabada-authserverindocker-compose.override.yml.It’s
GOIABADA_AES_ENCRYPTION_KEYin the env file,goiabada.envas the wizard writes it.It’s in the
goiabada-encryption-keySecret. Read it out of the cluster:Terminal window kubectl get secret goiabada-encryption-key -n goiabada -o jsonpath='{.data.aes-encryption-key}' | base64 -d -
Store it where your database backups aren’t: a password manager, a secret manager, or an offline copy. Not in a repository, and not beside the backups.
-
Do it again after every rotation of the key, since the rotation puts the database under the new one.
-
Keep each old key as long as you keep a database backup taken under it. A rotation re-encrypts the live database only, so a backup from before it still needs the old key.
What each secret protects
Section titled “What each secret protects”Each server reads its own secrets from its environment, and only when it starts.
| Secret | Read by | What it protects | Replaced without a rotation |
|---|---|---|---|
GOIABADA_AES_ENCRYPTION_KEY |
auth server | Everything secret the database stores: client secrets, the SMTP password, authenticator seeds, email verification, password reset and registration codes, and the private keys that sign tokens | The auth server can decrypt none of it |
GOIABADA_AUTHSERVER_SESSION_AUTHENTICATION_KEY, GOIABADA_AUTHSERVER_SESSION_ENCRYPTION_KEY |
auth server | The auth server’s session cookie, and the session contents it stores in the database | Every user is signed out once |
GOIABADA_ADMINCONSOLE_SESSION_AUTHENTICATION_KEY, GOIABADA_ADMINCONSOLE_SESSION_ENCRYPTION_KEY |
admin console | The admin console’s session cookie, and its session contents, administrators’ tokens included, which the auth server stores for it | Every administrator is signed out of the admin console once |
GOIABADA_DB_PASSWORD |
auth server | The database user’s password. Whoever has it and can reach the database reads and changes everything Goiabada stores | The auth server can’t connect until the database user has the same password |
GOIABADA_ADMINCONSOLE_OAUTH_CLIENT_SECRET |
both | The secret of the admin console’s client, admin-console-client. The admin console presents it at every sign-in and token refresh; the auth server reads it only at its first start, to create that client |
The admin console refuses to start, and one already running can’t sign anybody in, until the client in the database has the same secret |
GOIABADA_ADMIN_PASSWORD |
auth server | The first administrator’s password, read only by the first start, which creates the account | Nothing. Change the administrator’s password in the admin console |
Rotate secrets replaces each one without those costs.
Where your setup keeps them
Section titled “Where your setup keeps them”The wizard writes every secret into docker-compose.override.yml, under the service that reads it, and none into docker-compose.yml, which you can therefore commit. The override is plain text, and its mode, 0600, is its only protection: keep it out of version control and out of shared directories.
Anyone who can run docker on the host reads the secrets too, since docker inspect shows a container’s environment, and so does root.
The wizard writes one file, goiabada.env, holding the configuration and every secret, which both servers read. It’s plain text, and its mode, 0600, is its only protection: keep it out of version control, owned by the user the servers run as, and readable by that user alone.
Root reads it whatever its mode, and the environment of the running processes too.
The wizard writes two Secrets into goiabada-secrets.yaml: goiabada-encryption-key, holding the AES key alone, and goiabada-secrets, holding every other secret. A Secret’s data is base64, which anyone can decode, so the file’s mode, 0600, is its only protection on disk.
Kubernetes secrets has the Secrets the manifest reads, other ways to create them, and who in the cluster can read the AES key.
When a secret changes
Section titled “When a secret changes”A server reads a secret when it starts and never again, so a change reaches it at its next restart, and not before. That’s what lets the rotations change a secret first and restart second.
Generate each key with openssl, as the wizard does: openssl rand -hex 64 for the two session authentication keys, and openssl rand -hex 32 for the session encryption keys and the AES key. A server refuses to start with a key that isn’t hex or isn’t that long, and names the variable.
To restore a database backup taken under an older AES key, start the auth server with that key as GOIABADA_AES_ENCRYPTION_KEY. Or start it with today’s key there and the old one as GOIABADA_AES_ENCRYPTION_KEY_PREVIOUS: it then re-encrypts the restored data to today’s key before it listens, as a rotation does.