Files
sentryagent-idp/docs/devops/environment-variables.md
SentryAgent.ai Developer 90a4addb21 feat(phase-2): workstream 1 — HashiCorp Vault credential storage
Vault is optional — server falls back to bcrypt (Phase 1 behaviour)
when VAULT_ADDR is not set. Full coexistence: existing bcrypt credentials
continue to work until rotated.

Changes:
- src/vault/VaultClient.ts — wraps node-vault KV v2; writeSecret,
  readSecret, verifySecret (constant-time), deleteSecret
- src/db/migrations/005_add_vault_path.sql — vault_path column on credentials
- CredentialRepository — createWithVaultPath, updateVaultPath methods
- CredentialService — routes generate/rotate through Vault when configured;
  bcrypt path unchanged
- OAuth2Service — verifies via Vault when vaultPath set, bcrypt otherwise
- src/app.ts — createVaultClientFromEnv() wired into service layer
- ICredentialRow — vaultPath field added
- docs/devops/environment-variables.md — VAULT_ADDR, VAULT_TOKEN, VAULT_MOUNT
- docs/devops/vault-setup.md — dev quickstart, production config, migration guide
- tests: 33/33 unit tests pass (VaultClient + CredentialService Vault path)
- node-vault + @types/node-vault installed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 15:02:33 +00:00

5.3 KiB

Environment Variables

Complete reference for all environment variables consumed by AgentIdP.

Variables are loaded from a .env file at startup via dotenv. In production, inject them directly into the process environment — do not commit .env to version control.


Required Variables

These variables must be set. The server will throw and exit immediately if any are missing.

DATABASE_URL

PostgreSQL connection string.

Required Yes
Format postgresql://<user>:<password>@<host>:<port>/<database>
Example postgresql://sentryagent:sentryagent@localhost:5432/sentryagent_idp

The application uses pg.Pool with this connection string. Connection pool size uses the pg default (10 connections).


REDIS_URL

Redis connection URL.

Required Yes
Format redis://<host>:<port> or redis://<user>:<password>@<host>:<port>
Example redis://localhost:6379

Used for token revocation, rate limiting, and monthly token counters.


JWT_PRIVATE_KEY

PEM-encoded RSA-2048 private key for signing JWT access tokens (RS256).

Required Yes
Format PEM string, including -----BEGIN RSA PRIVATE KEY----- header and footer
Example See Security guide for key generation

In a .env file, use double quotes and encode newlines as \n:

JWT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEow...\n-----END RSA PRIVATE KEY-----"

Alternatively, read from a file at startup (see Security guide).


JWT_PUBLIC_KEY

PEM-encoded RSA-2048 public key for verifying JWT access tokens.

Required Yes
Format PEM string, including -----BEGIN PUBLIC KEY----- header and footer
Example Derived from JWT_PRIVATE_KEY — see Security guide

Every authenticated request verifies the JWT signature using this key. If this key does not match the private key used to sign tokens, all authentication will fail.


Optional Variables

These variables have defaults and do not need to be set for local development.

VAULT_ADDR

HashiCorp Vault server address. Required to enable Vault integration (Phase 2).

Required No (Vault is optional)
Format URL string
Example VAULT_ADDR=http://127.0.0.1:8200

When set alongside VAULT_TOKEN, new credentials are stored in Vault KV v2 instead of as bcrypt hashes in PostgreSQL. Existing bcrypt credentials continue to work unchanged until rotated. See Vault setup guide.


VAULT_TOKEN

Vault authentication token. Required when VAULT_ADDR is set.

Required Only when VAULT_ADDR is set
Format String
Example VAULT_TOKEN=hvs.XXXXXXXXXXXXXXXXXXXXXX

Use a Vault service token scoped to read, write, and delete on {VAULT_MOUNT}/data/agentidp/* and {VAULT_MOUNT}/metadata/agentidp/*.


VAULT_MOUNT

KV v2 secrets engine mount path.

Required No
Default secret
Format String (no leading or trailing slash)
Example VAULT_MOUNT=agentidp

PORT

HTTP port the Express server listens on.

Required No
Default 3000
Format Integer
Example PORT=8080

NODE_ENV

Node.js environment flag.

Required No
Default undefined (treated as development)
Values development, test, production
Example NODE_ENV=production

Effect: When NODE_ENV=test, HTTP request logging (Morgan) is disabled.


CORS_ORIGIN

Allowed origin(s) for Cross-Origin Resource Sharing.

Required No
Default * (all origins)
Format URL string or *
Example CORS_ORIGIN=https://app.mycompany.ai

In production, set this to the specific origin(s) that should be permitted to call the API. The default * is acceptable for a public API but restricts cookie-based auth flows (not applicable here — Bearer tokens only).


Complete .env Example

# Database
DATABASE_URL=postgresql://sentryagent:sentryagent@localhost:5432/sentryagent_idp

# Redis
REDIS_URL=redis://localhost:6379

# Application
PORT=3000
NODE_ENV=development
CORS_ORIGIN=*

# JWT Keys (generate with openssl — see docs/devops/security.md)
JWT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA...
-----END RSA PRIVATE KEY-----"

JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
MIIBIjANBgkq...
-----END PUBLIC KEY-----"

# HashiCorp Vault (Phase 2 — optional, omit to use bcrypt mode)
# VAULT_ADDR=http://127.0.0.1:8200
# VAULT_TOKEN=hvs.XXXXXXXXXXXXXXXXXXXXXX
# VAULT_MOUNT=secret

Do not commit .env to version control. Add it to .gitignore.


Variable Validation at Startup

The application validates required variables at startup in this order:

  1. JWT_PRIVATE_KEY and JWT_PUBLIC_KEY — checked in createApp() before the server starts
  2. DATABASE_URL — checked when getPool() is first called (during createApp())
  3. REDIS_URL — checked when getRedisClient() is first called (during createApp())

If any required variable is missing, the process exits with an error before binding to any port.