Config & Secrets Management
The tawa config command manages environment variables and encrypted secrets for your services on the Tawa platform. Plain config vars and secrets are stored in the builder, injected into your pod on every deploy, and never need to touch your codebase.
CLI commands
All config and secret management flows through the tawa config subcommand. Changes are stored in the builder and take effect on the next deploy.
Set a plain config var
# Set one or more plain config vars (visible in logs and API responses)
tawa config set LOG_LEVEL=debug API_TIMEOUT=30000Set an encrypted secret
# Set a secret (encrypted at rest with AES-256-GCM, value never returned by API)
tawa config set STRIPE_SECRET_KEY=sk_live_... --secretList config
# List all config vars and secret key names (secret values are hidden)
tawa config listOutput shows plain config values in full. For secrets, only the key name is displayed — the value is replaced with ********.
Remove a config var
# Remove a config var or secret
tawa config unset STRIPE_SECRET_KEYPull config to local
# Pull all config + decrypted secrets to .env.local
tawa config pullWrites a .env.local file with 0600 permissions (owner read/write only). Useful for running your service locally with the same config as the deployed environment.
Push local config
# Push .env.local values to the builder
tawa config pushReads your local .env.local and uploads each key-value pair to the builder as a plain config var. Secrets must be set individually with the --secret flag.
tawa deploy for the changes to take effect in your running pod.How secrets work
Secrets follow a different path than plain config vars. Here is what happens end to end:
- You run
tawa config set MY_KEY=value --secret - The builder encrypts the value with AES-256-GCM and stores the ciphertext in its MongoDB database
- On deploy, the builder decrypts all secrets for your service and creates a Kubernetes Secret named
{service}-managed-secretsin your namespace - The secret is mounted into your pod via
envFrom.secretRef, making each key available as an environment variable - Your app reads the value with
process.env.MY_KEY— no decryption needed in your code
tawa config list, secret keys are shown but values are masked. The only way to retrieve a secret value is tawa config pull, which writes the decrypted value to .env.local on your local machine.Auto-provisioned variables
The builder automatically injects certain environment variables based on declarations in your catalog-info.yaml. You do not need to set these with tawa config — they are generated fresh on every deploy.
| Source | Variable | Provisioned from |
|---|---|---|
| Databases | MONGODB_URI | spec.databases with type: mongodb |
| Databases | REDIS_URL | spec.databases with type: redis |
| Databases | NEO4J_URI | spec.databases with type: neo4j |
| OAuth | BIO_CLIENT_ID | Auto-created OAuth client in Bio-ID |
| OAuth | BIO_CLIENT_SECRET | Auto-created OAuth client in Bio-ID |
| Internal deps | {SERVICE}_URL | spec.internalDependencies resolved to K8s DNS |
For example, if your catalog declares spec.internalDependencies with service: iec-wallet, the builder resolves it to a K8s cluster DNS URL and injects it as IEC_WALLET_URL.
Precedence
When the same variable is defined in multiple places, the highest precedence wins. From lowest to highest:
- catalog-info.yaml defaults — platform defaults derived from your catalog declarations (e.g.,
NODE_ENV) - Managed config — plain vars set via
tawa config set - Kubernetes Secret — encrypted secrets set via
tawa config set --secret, mounted viaenvFrom.secretRef
This means a secret always overrides a plain config var with the same name, and a config var always overrides a platform default. If you need to revert to the platform default, remove your override with tawa config unset.
Local development
Use tawa config pull to download your deployed config into a local .env.local file:
tawa config pull
# Writes .env.local with all config + decrypted secrets
# File permissions: 0600 (owner read/write only)The resulting file looks like a standard dotenv file:
# .env.local (auto-generated by tawa config pull)
LOG_LEVEL=debug
API_TIMEOUT=30000
STRIPE_SECRET_KEY=sk_live_abc123...
MONGODB_URI=mongodb://db.tawa.insureco.io:27017/my-svc-sandbox
REDIS_URL=redis://db.tawa.insureco.io:6379/0Most Node.js frameworks (Next.js, Vite, dotenv) load .env.local automatically. Your app code reads process.env.STRIPE_SECRET_KEY the same way whether running locally or in a pod.
.env.local to your .gitignore. This file contains decrypted secrets. Never commit it to version control.Common mistakes
Hardcoding secrets in code
// WRONG: hardcoded secret
const apiKey = "sk_live_abc123..."
// CORRECT: read from environment
const apiKey = process.env.STRIPE_SECRET_KEY
if (!apiKey) throw new Error('STRIPE_SECRET_KEY not configured')Use tawa config set --secret to store the value, then read it from process.env in your code.
Committing .env.local to git
The .env.local file contains decrypted secrets pulled from the builder. Make sure it is listed in your .gitignore:
# .gitignore
.env.local
.env*.localForgetting to redeploy after setting secrets
Running tawa config set stores the value in the builder's database, but it does not update your running pod. You must run tawa deploy for the new value to be injected into the Kubernetes Secret and picked up by your service.
Setting auto-provisioned vars manually
Variables like MONGODB_URI and BIO_CLIENT_ID are generated by the builder on every deploy. Setting them with tawa config set will create a conflict — your manual value may be overwritten by the auto-provisioned one. Instead, declare databases and OAuth in catalog-info.yaml and let the builder handle the connection strings.
Related
- Environment Variables — platform defaults and precedence rules
- Databases — declaring databases and auto-provisioned connection strings
- OAuth Integration — auto-provisioned Bio-ID credentials
- catalog-info.yaml Reference — full field reference for all declarations