How configuration is loaded
- The server reads the process environment. It also loads a
.envfile, found by walking up from the package directory, but a variable already set in the process environment always wins over the file. - In production, set variables in your platform (Vercel, Fly.io, your container runtime) and do not ship a
.envfile. - Values are read once at startup. Change a variable, then restart or redeploy.
- A wrong value fails at startup with a message that names the variable. It does not fail later under traffic.
NODE_ENV is anything other than test, which includes production. “If” means it is required only under the
stated condition. “No” means optional.
The minimum for a production start
These are the variables you must set for a production server that uses local signing keys and Supabase storage. Everything else has a safe default.
Follow Production deployment for the full procedure.
Core
Caller authentication
The format of PARMANA_API_KEYS
A JSON array. Each entry is an object:
Generate an entry and its raw key with:
PARMANA_API_KEYS. Give the raw key to the caller
and never store it anywhere else. To make a human key add --credential-holder-type USER, and add
--generate-step-up-key to also generate the step up signing key.
If the value is not valid JSON, is not an array, or an entry is malformed, the server stops at startup with a message
that names PARMANA_API_KEYS.
Policies
Storage
Signing keys and gateway identity
Generate the key files with:
PARMANA_KEY_DIR, or ./keys if it is unset, and refuse to overwrite existing files unless you add
--force. Keep the private files secret, and never commit them.
Cryptography
Authorization and receipts
Rate limits
With
DATABASE_URL set, the counters are shared across instances. Without it they are per process, so the effective limit
is the value multiplied by the number of instances, and the server logs rate_limit_store_not_durable.
Secrets
Connectors
A connector registers only when its credentials are present. A missing connector does not stop the server. It logs an event such asslack_connector_unavailable and requests for that connector’s actions fail.