Skip to main content

Environment & Configuration

helix-api is configured entirely through environment variables. Copy .env.example and edit it:

cp .env.example .env
set -a; source .env; set +a
pnpm --filter @helixid/api dev

Minimum viable configuration

The default runtime needs no external infrastructure beyond the API process itself:

NODE_ENV=development
API_BASE_URL=http://localhost:3000

HELIX_STORAGE_ADAPTER=sqlite
HELIX_SQLITE_PATH=./data/helixid.sqlite
HELIX_CACHE_ADAPTER=memory

DID_METHOD=web
DID_DOMAIN=localhost:3000

HELIX_ADMIN_API_KEY=dev-admin-key-0001
HELIX_SIGNING_KEY=<32-byte-ed25519-private-key-hex>

DID method

VariableDefaultNotes
DID_METHODwebAllowed values: web, key. Hedera issuance is planned for a future release — see did-hedera.
DID_DOMAINlocalhost:3000The domain this API is served from, for did:web hosting.
HELIX_ISSUER_DIDdid:web:${DID_DOMAIN}Optional for DID_METHOD=web. The issuer DID document must contain the public key derived from HELIX_SIGNING_KEY.

Storage

VariableDefaultNotes
HELIX_STORAGE_ADAPTERsqliteOnly sqlite is supported today. Postgres is planned.
HELIX_SQLITE_PATH./data/helixid.sqliteSQLite DB file path.

SQLite mode does not require running database migrations.

Signing and admin access

VariableNotes
HELIX_SIGNING_KEYHex-encoded Ed25519 private key used to sign VCs. This is the trust anchor for your entire domain.
HELIX_ADMIN_API_KEYRequired. Protects /v1/vcs issue/revoke/renew, /v1/status-list, /v1/vcs listing, and the audit-log routes.
openssl rand -hex 32
Never commit these

HELIX_SIGNING_KEY signs every credential in your trust domain; HELIX_ADMIN_API_KEY can issue and revoke them. Keep both out of source control, out of committed env files, and out of logs. Use at least 32 random characters for the admin key in any real environment. See the Security Model.

API

VariableDefault
PORT3000
API_BASE_URLhttp://localhost:3000
NODE_ENVdevelopment

Tokens and TTLs

Every one of these is a security parameter. See Performance & Caching.

VariableDefaultBounds
ENROLLMENT_TOKEN_TTL_SECONDS900 (15 min)How long a one-time bootstrap token stays usable
CHALLENGE_TTL_SECONDS300 (5 min)Challenge nonce validity
VP_TTL_SECONDS300 (5 min)How long a presentation is replayable before expiry
JWT_SESSION_TTL_SECONDS600 (10 min)Session-token lifetime after one verification

Cache

VariableDefaultNotes
HELIX_CACHE_ADAPTERmemoryL1 in-process cache. Redis/L2 is planned.
CACHE_ENABLEDtrueLeave enabled unless you explicitly want caching off.
DID_CACHE_L1_TTL_SECONDS300Staleness window for a rotated key.
STATUS_LIST_CACHE_L1_TTL_SECONDS60Staleness window for a revocation.

Only the L1 TTLs currently matter. Note that the verifier-side status-list cache is separate and off by default — callers inject a statusListResolver.

Session tokens

Session JWTs are signed with an API startup-ephemeral Ed25519 keypair, and the public key is served at GET /v1/sessions/public-key. Restarting the API rotates it.

JWT_SECRET is only relevant to the SDK's HS256 SessionManager, not to API-issued EdDSA tokens. A missing JWT_SECRET has no effect on verifying API-issued session tokens, but it will prevent constructing a SessionManager. See Hybrid 3-Layer Design.

Audit log

VariableDefaultNotes
AUDIT_LOG_DESTINATIONstdoutAllowed values: stdout, file, both.
AUDIT_LOG_PATH./logs/audit.logRequired only when the destination is file or both.

Testing only

VariableDefaultNotes
HEDERA_E2E_TESTNETfalseAllows E2E tests to write to Hedera testnet. Never true in standard CI pipelines.

Demo environments

The two Docker demos have their own .env.example files. Demo B additionally needs:

LLM_PROVIDER=anthropic # anthropic (default) | openai | azure
LLM_API_KEY=your-provider-key

See Examples.