Rotating secrets
Change passwords and keys safely, in the right order.
Rotate a secret at once if it may have leaked, when a person with access leaves, and at least once a year.
Where secrets live
- In env files on the server under
/etc/yanu/, one per service. For the SMPP stack:/etc/yanu/yanu-smpp.env(see.env.examplein yanu-smpp) and/etc/yanu/jasmin.env(JCLI_USER,JCLI_PASS,AMQP_USER,AMQP_PASS). - Each env file is owned by root with mode 600:
sudo chown root:root FILE && sudo chmod 600 FILE. - Never in git, chat, email or tickets. Never print them in logs.
- Make new values on the server with
scripts/gen-secret.shin yanu-infra (oropenssl rand -hex 32).
Pairs that must match
Some secrets must have the same value in two services. Change both, then restart both, close together.
| Secret | Where | Must match |
|---|---|---|
JWT_SECRET | yanu-auth | AUTH_JWT_SECRET in yanu-sms-api and in yanu-smpp |
INTERNAL_API_KEY | yanu-auth | INTERNAL_API_KEY in yanu-sms-api and in yanu-smpp |
JCLI_USER, JCLI_PASS | /etc/yanu/jasmin.env | JCLI_USER, JCLI_PASS in yanu-smpp |
MALAWI_JASMIN_USERNAME, MALAWI_JASMIN_PASSWORD | yanu-sms-api | the same names in yanu-smpp |
yanu-smpp also has its own JWT_SECRET for portal sign-ins. It is not shared with anything. Changing it signs out every portal user who signed in with a portal password.
Step by step
Sign-in token secret (JWT_SECRET and AUTH_JWT_SECRET)
- Make a new value.
- Put it in
JWT_SECRET(yanu-auth) andAUTH_JWT_SECRET(yanu-sms-api and yanu-smpp). - Restart yanu-auth first, then yanu-sms-api and yanu-smpp-api.
- Everyone is signed out and must sign in again. Do it at a quiet time and warn users.
Service-to-service key (INTERNAL_API_KEY)
- Make a new value. Put it in yanu-auth, yanu-sms-api and yanu-smpp.
- Restart all three, one right after the other.
- Test a top-up credit end to end, because payment credits use this key.
Jasmin jcli password (JCLI_USER and JCLI_PASS)
The SMPP gateway (Jasmin) has an admin console, jcli. Its user and password are used in three places that must all match:
- the gateway's config files, rendered from
/etc/yanu/jasmin.env, - the gateway's start flags
-uand-p(docker-compose passesJCLI_USERandJCLI_PASS), JCLI_USERandJCLI_PASSin/etc/yanu/yanu-smpp.env.
If they do not match, the gateway starts empty
If the -u and -p start flags do not equal the jcli admin login, Jasmin starts with no users, no connector and no routes. Every client bind fails. To recover, fix the values, then open jcli and run load to load the saved configuration.
- Pick a new password. Use only letters, digits,
.,_and-: the render script refuses anything else. - Put it in
JCLI_PASSin both/etc/yanu/jasmin.envand/etc/yanu/yanu-smpp.env. - Load
/etc/yanu/jasmin.envinto the shell and runscripts/render-jasmin-config.shin the yanu-smpp folder. It writes the config files (mode 600) and prints no secrets. - Restart the
jasmincontainer, thenyanu-smpp-api. - Check that binds, users and the upstream connector are all there: the Upstream page, Live status, or
user -lin jcli. If they are empty, runloadin jcli.
The same render script and restart apply when you change AMQP_USER or AMQP_PASS (the gateway's message queue login).
Upstream SMPP password
- Get the new password from the upstream provider.
- Update
UPSTREAM_PASSWORDin/etc/yanu/yanu-smpp.env. - Restart
yanu-smpp-api. It applies the upstream settings on start. Or press Sync to gateway on the Upstream page after the restart. - Check Upstream bind shows connected.
Database passwords
- In PostgreSQL, change the role password:
ALTER ROLE role_name WITH PASSWORD 'new value';(run it inpsqlinside thepostgrescontainer, not from a script that logs). Also update/etc/yanu/postgres.env. - Update the database URL in that service's env file.
- Restart that service. Check it is healthy.
- Do one database role at a time.
Payment gateway keys
- Make new keys in the gateway dashboard.
- Update the gateway's secret key, public key and webhook secret in the yanu-auth env file. The names are in
yanu-infra/env/yanu-auth.env.example. - Restart yanu-auth.
- Make one small test payment.
Restart order in general
- Database and Redis (only if their own passwords changed).
- yanu-auth.
- The gateway (
jasmin), then yanu-sms-api and yanu-smpp-api. - Web front ends (yanu-auth-ui, yanu-sms-web, the SMPP portal).
After each restart, check health before moving on.
Restart means recreate
A container reads its env file when it is created. After you change an env file, recreate the service from the yanu-infra folder on the server (/opt/yanu/src/yanu-infra): docker compose -f compose/docker-compose.yml --env-file /etc/yanu/compose.env up -d --no-deps <service>. A plain docker restart keeps the old values.
Env file templates (names only) for every service are in env/ in yanu-infra. The live files are /etc/yanu/<service>.env, for example /etc/yanu/yanu-auth.env and /etc/yanu/yanu-sms.env.