Supply Secrets
The database has a password and the email service an API key. Neither may be written in the Context, which is in version control. The Context only names secrets; you
supply their values yourself, once per environment: in the cluster for a deployment, in the .env file for a local run.
§What is a secret
Credentials of infrastructure. An address in the Context must not contain a user name or a password. One that does is refused:
Pointer URI 'mongodb://user:pass@mongo.example.com' must not contain credentials. They are supplied as a secret with username and password keys.
Secret configuration values. A configuration value written as $NAME is a reference to a
secret, not a value. The Context toa create wrote has one, the key
of identity tokens; a component that sends email adds its API key:
# context.toa.yaml
configuration:
identity.tokens:
keys:
- id: key0
key: $IDENTITY_TOKENS_ENCRYPTION_KEY0
notifications:
sender: orders@example.com
apiKey: $EMAIL_API_KEY Configuration covers this in full, with the component that declares such a value. Other extensions have secrets of their own, such as a storage provider’s keys or the keys of identity tokens.
You do not work out the list. Ask for it.
§What a deployment needs
$ npx toa export secrets production
toa-amqp-context.default:
username
password
toa-configuration:
EMAIL_API_KEY
IDENTITY_TOKENS_ENCRYPTION_KEY0
toa-mongodb.default:
username
password
toa-storages-pictures:
ACCESS_KEY_ID (optional)
SECRET_ACCESS_KEY (optional) Each block is one Kubernetes secret and the keys it must hold. A key marked (optional) may be
absent; the workload starts without it.
Run the command again after changing addresses, configuration or storages in the Context.
§Putting secrets in the cluster
$ npx toa conceal mongodb.default username=store password=s3cret toa conceal <secret> <key=value>... creates the secret, or adds the keys to it if it exists.
Keys you do not mention are left as they are.
- The name is given without the
toa-prefix;toa concealadds it. --namespacechooses the Kubernetes namespace. Use the one you deploy into.
To be asked for every secret of an environment in turn, instead of naming them:
$ npx toa conceal --interactive --environment production To read one back:
$ npx toa reveal mongodb.default
username: store
password: s3cret Secrets can be created by other means: kubectl, an operator, a sealed-secrets workflow. They
then carry the toa- prefix themselves, exactly as toa export secrets prints the names.
§A deploy checks first
toa deploy refuses before building anything if a required key is missing, naming all of them:
Secrets are not deployed: toa-mongodb.default/username, toa-mongodb.default/password Required are the keys toa export secrets lists, except the optional ones, plus the image pull
secret named by registry.credentials. Only presence is
checked. An empty value counts as present, and a wrong password is found by the process that
uses it.
§Changing a value
Changing a secret does not restart anything. Pods read their secrets when they start, so restart the workloads that use it:
$ npx toa conceal mongodb.default password=n3w -n store
$ kubectl rollout restart deployment/composition-core -n store §Secrets for a local run
Locally, secrets are lines of the .env file. toa env writes them with empty values and offers
two ways to fill them:
$ npx toa env local --dev # fill what has a known local default
$ npx toa env local --interactive # ask for each one
$ npx toa env local -d -i # fill what can be filled, ask for the rest npm run env, and so npm run restart, runs the first. --dev fills:
developer/secretas the credentials of the default broker and database, which is what the generateddocker-compose.yamlgives the onesnpm run dockstarts;- freshly generated keys for identity tokens;
- any secret whose key is set in your shell’s environment. With
EMAIL_API_KEY=... toa env -d, the$EMAIL_API_KEYconfiguration secret takes that value.
Whatever is left is written empty. A component should treat an empty secret as “not configured” where that is meaningful locally — for example, by not sending real email.
A value already in the file is kept. Fill a secret in by hand once, and later runs of toa env, with any options and for any environment written to the same file, preserve it.
Keep .env* out of version control.
Do not read these variables from process.env in an operation. A secret reaches an operation
through what declares it: a configuration value through context.configuration, a storage’s keys
through the storage. The other lines of .env are written by toa env for the runtime; change
the Context and run toa env again instead of editing them.
§Credentials
The address of the database is an ordinary Context value
(Addresses); its user name and password are a secret. Which secret
follows from the key of the address map the component resolves to: the connector’s name, then
the key, with dots turned into dashes. The . key is .default:
Key in mongodb | Secret |
|---|---|
., or a single address | toa-mongodb.default |
store | toa-mongodb-store |
store.catalog | toa-mongodb-store-catalog |
$ npx toa conceal mongodb-store-catalog username=catalog password=s3cret Every component that resolves to a key shares its secret, and so does every address under that key.
For the broker the name is amqp-context, so the default secret is toa-amqp-context.default,
and a source’s is toa-amqp-sources-<source>.
Each such secret holds username and password. An address on a protocol without credentials — redis, http, https — has no secret.
toa export secrets prints the exact names; the rule is here so that the output is not a
surprise. Addresses and Credentials has more.
§The same names in every environment
Addresses vary by environment with the usual suffix:
mongodb@local: mongodb://localhost
mongodb@production: mongodb://mongo.internal.example.com Secret names do not vary: toa-mongodb.default is the same name everywhere. The values differ
because each environment is a different namespace or cluster, or a different .env file, holding
its own.
A deployed pod is given only the secrets and addresses of the components it runs. The database
password of store.catalog is not in a pod that does not run store.catalog.
§Checklist for a new environment
- Add the environment’s suffixed keys to the Context.
toa export secrets <environment>— see what it needs.toa conceal ...for each secret, in the target namespace.- Create the image pull secret, if the registry is private.
toa deploy <environment>.