SMS YANU documentation home

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.example in 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.sh in yanu-infra (or openssl rand -hex 32).

Pairs that must match

Some secrets must have the same value in two services. Change both, then restart both, close together.

SecretWhereMust match
JWT_SECRETyanu-authAUTH_JWT_SECRET in yanu-sms-api and in yanu-smpp
INTERNAL_API_KEYyanu-authINTERNAL_API_KEY in yanu-sms-api and in yanu-smpp
JCLI_USER, JCLI_PASS/etc/yanu/jasmin.envJCLI_USER, JCLI_PASS in yanu-smpp
MALAWI_JASMIN_USERNAME, MALAWI_JASMIN_PASSWORDyanu-sms-apithe 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)

  1. Make a new value.
  2. Put it in JWT_SECRET (yanu-auth) and AUTH_JWT_SECRET (yanu-sms-api and yanu-smpp).
  3. Restart yanu-auth first, then yanu-sms-api and yanu-smpp-api.
  4. 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)

  1. Make a new value. Put it in yanu-auth, yanu-sms-api and yanu-smpp.
  2. Restart all three, one right after the other.
  3. 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 -u and -p (docker-compose passes JCLI_USER and JCLI_PASS),
  • JCLI_USER and JCLI_PASS in /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.

  1. Pick a new password. Use only letters, digits, ., _ and -: the render script refuses anything else.
  2. Put it in JCLI_PASS in both /etc/yanu/jasmin.env and /etc/yanu/yanu-smpp.env.
  3. Load /etc/yanu/jasmin.env into the shell and run scripts/render-jasmin-config.sh in the yanu-smpp folder. It writes the config files (mode 600) and prints no secrets.
  4. Restart the jasmin container, then yanu-smpp-api.
  5. Check that binds, users and the upstream connector are all there: the Upstream page, Live status, or user -l in jcli. If they are empty, run load in 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

  1. Get the new password from the upstream provider.
  2. Update UPSTREAM_PASSWORD in /etc/yanu/yanu-smpp.env.
  3. Restart yanu-smpp-api. It applies the upstream settings on start. Or press Sync to gateway on the Upstream page after the restart.
  4. Check Upstream bind shows connected.

Database passwords

  1. In PostgreSQL, change the role password: ALTER ROLE role_name WITH PASSWORD 'new value'; (run it in psql inside the postgres container, not from a script that logs). Also update /etc/yanu/postgres.env.
  2. Update the database URL in that service's env file.
  3. Restart that service. Check it is healthy.
  4. Do one database role at a time.

Payment gateway keys

  1. Make new keys in the gateway dashboard.
  2. 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.
  3. Restart yanu-auth.
  4. Make one small test payment.

Restart order in general

  1. Database and Redis (only if their own passwords changed).
  2. yanu-auth.
  3. The gateway (jasmin), then yanu-sms-api and yanu-smpp-api.
  4. 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.

On this page