config/default.yaml file that ships with the repository and defines all defaults, and a config/local.yaml file that you create to override specific values for your deployment. Secrets — API keys, credentials, and tokens — live in an encrypted vault, not in .env and not in YAML files. Only the four values needed to reach and unlock that vault, plus non-secret deployment config, stay in .env.
First-time setup configures everything for you.
pnpm run setup writes the four bootstrap values to .env, prompts for your Anthropic API key, and seeds it (along with the generated API token and login secret) into the encrypted vault after migrations. The in-app setup wizard then captures your assistant’s identity, voice, and decision posture conversationally. This page covers everything you might want to change later — additional channels, multiple email accounts, custom LLM routing, and adding secrets to the vault.How configuration works
When Curia starts, it mergesconfig/local.yaml on top of config/default.yaml. Any key you set in local.yaml overrides its default. Keys you omit stay at their default values. You never need to copy the entire default.yaml — only override what you need.
Environment variables
.env holds only two kinds of values: the four bootstrap secrets needed to reach and unlock the vault, and non-secret deployment config. Every other credential — LLM keys, Nylas, Signal, Tavily, the HTTP API token, the login secret — lives in the encrypted vault and is seeded with pnpm run seed-vault.
What stays in .env
| Variable | Required | Description |
|---|---|---|
DB_USER | Yes | PostgreSQL user. |
DB_PASSWORD | Yes | PostgreSQL password. |
DATABASE_URL | Yes | Postgres connection string. Constructed from DB_USER, DB_PASSWORD, and POSTGRES_PORT by pnpm run setup. |
SECRET_ENCRYPTION_KEY | Yes | Base64-encoded 32-byte AES-256 master key that encrypts the vault. Generate with openssl rand -base64 32; pnpm run setup fills it in. Back this up — losing it makes the vault unrecoverable. |
CEO_PRIMARY_EMAIL | No | Your primary email address. Ensures your messages are never held as an unknown sender at startup. |
TIMEZONE | No | IANA timezone (e.g. America/Toronto). Used to resolve relative dates in agent prompts. |
HTTP_PORT / POSTGRES_PORT | No | Host ports for the app and Postgres. Defaults 3000 / 5432. |
NYLAS_POLL_INTERVAL_MS | No | Email poll interval in ms (default 30000). Non-secret. |
NODE_EXTRA_CA_CERTS | No | Path to a CA bundle (macOS TLS workaround). |
What goes in the vault
These secrets are seeded into the encrypted vault, never written to.env. Set each transiently on the command line and run the seed script — the value is read from the process environment, encrypted, and stored:
LLM providers
LLM providers
| Env var (transient) | Vault key | Notes |
|---|---|---|
ANTHROPIC_API_KEY | anthropic_api_key | Powers all agents. Seeded automatically on first setup. |
OPENAI_API_KEY | openai_api_key | Knowledge graph embeddings (text-embedding-3-small) and semantic search. |
OPENROUTER_API_KEY | openrouter_api_key | Optional. Enables multi-model routing via OpenRouter. |
Authentication and access
Authentication and access
| Env var (transient) | Vault key | Notes |
|---|---|---|
API_TOKEN | api_token | Bearer token for all HTTP API requests. Generated and seeded by pnpm run setup. |
WEB_APP_BOOTSTRAP_SECRET | web_app_bootstrap_secret | Secret for logging in to the console. Generated and shown once by pnpm run setup. |
Email (Nylas)
Email (Nylas)
All three must be present in the vault for the single-account email channel to activate. If any is missing, the channel disables itself at startup.
For multiple email accounts, see Multiple email accounts below.
| Env var (transient) | Vault key | Notes |
|---|---|---|
NYLAS_API_KEY | nylas_api_key | Application API key from the Nylas dashboard. |
NYLAS_GRANT_ID | nylas_grant_id | Identifier for the connected email account (from Nylas Grants). |
NYLAS_SELF_EMAIL | nylas_self_email | The email address Curia reads and sends from. |
Signal
Signal
| Env var (transient) | Vault key | Notes |
|---|---|---|
SIGNAL_PHONE_NUMBER | signal_phone_number | Your E.164 phone number (e.g. +12223334444). Must match the number registered via signal-cli register + verify. |
SIGNAL_SOCKET_PATH — the deployment layer manages this automatically.Web search
Web search
| Env var (transient) | Vault key | Notes |
|---|---|---|
TAVILY_API_KEY | tavily_api_key | API key from tavily.com. Required before the web-search skill can be enabled. |
web-search skill declares tavily_api_key in its install.requires_secrets, so the registry will not let you enable it until the key is in the vault. See Managing skills, agents, and channels.Multiple email accounts
The default Nylas setup connects a single email account via environment variables. To connect multiple accounts, define them inconfig/local.yaml using channel_accounts.email.
Each account has a logical name, a Nylas grant ID, and a self-email address. Outbound sending is governed globally by the autonomy engine — when the score is below the skill’s action_risk floor, sends are blocked and saved as drafts instead.
env:VAR_NAME to reference environment variables rather than inlining credential values directly in the YAML file.
When
channel_accounts.email is present in config/local.yaml, the single-account mode sourced from the vault keys nylas_api_key / nylas_grant_id / nylas_self_email is ignored.Next steps
Set up email
Connect your inbox and configure email accounts.
Full configuration reference
Every configurable setting: rate limits, security rules, knowledge graph decay, and more.