Secrets & configuration¶
Secrets never live in the repo. They resolve at runtime through a pluggable secret
provider (shared/secrets.js). Config files that carry secrets are gitignored and commit
only an .example twin.
The secret provider¶
A "secret key" is a logical name — openai_api_key, discord_bot_token,
my_github_pat. Connectors and the core resolve it with ctx.secrets.get(key) (or
require('shared/secrets').get(key)), never by hardcoding a value or a vault-specific
command. Resolution order (first hit wins, cached):
- Environment —
process.env[key], thenprocess.env[UPPER_SNAKE(key)]. The portable, 12-factor default: put secrets in the environment or a.envfile. (openai_api_keyresolvesOPENAI_API_KEY.) - Secrets file — a JSON
{ "<key>": "<value>" }atASMLTR_SECRETS_FILE. - TRUST vault — once
ASMLTR_VAULT_URLandASMLTR_VAULT_AGENT_KEYare set, the TRUST vault is the primary store:get()resolves a credential from it before the command provider. This is how a fully migrated install resolves everything (connector tokens, voice keys, integration creds) with no external secret manager. Opt-in — skipped entirely when the vars are unset, so it never changes an install that hasn't adopted it. - Command provider —
ASMLTR_SECRET_CMD, a shell template run once per key.{key}in the template is replaced with the (validated) key; trimmed stdout is the value. Good for a Bitwarden / Vault wrapper:
The vault sits before the command provider so you can migrate at your pace: copy each secret
into the vault, verify it resolves, then disable the old provider. get() returns null when
a key can't be resolved and never throws.
*_bws_key / pat_bws_key are NAMES, not tokens
Connector config fields such as bot_token_bws_key, pat_bws_key, and
elevenlabs_key_name hold the name of a secret (a key the provider resolves), never
the token itself. The literal token stays in your environment / secrets file / vault — so
the connector config is safe to store and inspect. The bws in the name nods to
Bitwarden Secrets Manager but works with any provider.
Gitignored config (and their .example twins)¶
These files carry secrets or personal identifiers. They are gitignored; commit only the
.example version, and copy + edit the real one locally.
| Gitignored file | Committed twin | Holds |
|---|---|---|
.env |
.env.example |
Assistant name, ports, secret values / provider config, tokens. |
connectors/types/mcp/clients.json |
clients.example.json |
Pre-registered OAuth 2.1 MCP clients; each maps to a trust identity. |
connectors/types/openai/keys.json |
keys.example.json |
Bearer API keys → trust identities for the OpenAI-compatible connector. |
core/src/trust/seed.json |
seed.example.json |
Trust store seed (principals, identifiers, grants). |
connectors/types/discord/channel-aliases.json |
channel-aliases.example.json |
Real Discord channel ids ↔ aliases (e.g. TD-TSD-main). |
Local data stores (SQLite DBs under */data/, *.db, JSONL event logs), the dashboard
dist/, and per-install notes (CLAUDE.local.md) are also gitignored.
.env¶
Every entrypoint loads <repo>/.env first via shared/loadenv.js (a zero-dependency
loader). Real environment / PM2 env take precedence over the file, so production can set
values without editing it. Copy the example to start:
Add every new secret to .env.example
When you introduce a new environment variable, add it to .env.example. When you
introduce a new secret-bearing file, gitignore it and commit a <name>.example twin.
This keeps a fresh clone's onboarding complete and prevents secrets from being committed.
Moderation keys and the API-key firewall¶
The moderation classifier may use an API key (OpenAI by default, or Anthropic). It resolves
that key through the secret provider by name (ASMLTR_MODERATION_KEY, default
openai_api_key / anthropic_api_key) — not from ANTHROPIC_API_KEY.
Never set ANTHROPIC_API_KEY
The core deletes ANTHROPIC_API_KEY from its process environment at startup so agent
execution can never silently go metered. If you use the Anthropic moderation provider,
store its key via ASMLTR_SECRETS_FILE or ASMLTR_SECRET_CMD — do not export it as
ANTHROPIC_API_KEY.
For the full moderation configuration (provider, model, alert routing) see the moderation guide and Configuration & environment.
See also¶
- Trust & permissions — how identities and grants work.
- Configuration & environment — the full env var table.