Files
sentryagent-idp/docs/devops/environment-variables.md
SentryAgent.ai Developer 8cabc0191c docs: commit all Phase 6 documentation updates and OpenSpec archives
- devops docs: 8 files updated for Phase 6 state; field-trial.md added (946-line runbook)
- developer docs: api-reference (50+ endpoints), quick-start, 5 existing guides updated, 5 new guides added
- engineering docs: all 12 files updated (services, architecture, SDK guide, testing, overview)
- OpenSpec archives: phase-7-devops-field-trial, developer-docs-phase6-update, engineering-docs-phase6-update
- VALIDATOR.md + scripts/start-validator.sh: V&V Architect tooling added
- .gitignore: exclude session artifacts, build artifacts, and agent workspaces

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 02:24:24 +00:00

14 KiB
Raw Blame History

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. Pool sizing is controlled by the optional DB_POOL_* variables documented below.


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.


Note on Billing: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, and STRIPE_PRICE_ID are required when BILLING_ENABLED=true. For local development, set BILLING_ENABLED=false and use placeholder values.

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

BILLING_ENABLED

Required No
Default false
Values true, false
Example BILLING_ENABLED=false

Gates Stripe billing integration and free-tier agent limit enforcement. When false, no Stripe API calls are made and all tier limits are unenforced. Set to false for in-house testing.


STRIPE_SECRET_KEY

Required Only when BILLING_ENABLED=true
Format Stripe secret key string (sk_live_* or sk_test_*)
Example STRIPE_SECRET_KEY=sk_test_placeholder

Stripe API key used to create Checkout Sessions for tier upgrades. Never use a live key in development.


STRIPE_WEBHOOK_SECRET

Required Only when BILLING_ENABLED=true
Format Stripe webhook signing secret (whsec_*)
Example STRIPE_WEBHOOK_SECRET=whsec_placeholder

Used to verify the HMAC signature on incoming Stripe webhook events. Without this, the billing webhook endpoint will reject all events.


STRIPE_PRICE_ID

Required Only when BILLING_ENABLED=true
Format Stripe Price ID string (price_*)
Example STRIPE_PRICE_ID=price_placeholder

The Stripe Price object used when creating a Checkout Session for the Pro tier upgrade.


ANALYTICS_ENABLED

Required No
Default true
Values true, false
Example ANALYTICS_ENABLED=true

Feature flag that gates the /api/v1/analytics/* routes. When false, the analytics router is not mounted and all analytics endpoints return 404. Events are still recorded internally regardless of this flag.


TIER_ENFORCEMENT

Required No
Default true
Values true, false
Example TIER_ENFORCEMENT=true

Enables Redis-backed tier limit enforcement per tenant. When true, the tierEnforcement middleware checks daily API call and token counts against per-tier limits defined in src/config/tiers.ts. Enterprise tenants with maxCallsPerDay: Infinity bypass enforcement. When false, no tier limits are enforced.


COMPLIANCE_ENABLED

Required No
Default true
Values true, false
Example COMPLIANCE_ENABLED=true

Feature flag that gates the report and agent-card export endpoints under /api/v1/compliance/*. When false, those endpoints return 404. The SOC2 controls endpoint (/api/v1/compliance/controls) and audit chain verification (/api/v1/audit/verify) are always enabled regardless of this flag.


REDIS_RATE_LIMIT_ENABLED

Required No
Default false
Values true, false
Example REDIS_RATE_LIMIT_ENABLED=true

When true, rate limiting uses a Redis-backed sliding-window counter per client_id. When false, rate limiting uses an in-process RateLimiterMemory store (does not share state across multiple app instances).


RATE_LIMIT_WINDOW_MS

Required No
Default 60000
Format Integer (milliseconds)
Example RATE_LIMIT_WINDOW_MS=60000

Duration of the sliding-window rate limit period in milliseconds. Only effective when REDIS_RATE_LIMIT_ENABLED=true.


RATE_LIMIT_MAX_REQUESTS

Required No
Default 100
Format Integer
Example RATE_LIMIT_MAX_REQUESTS=100

Maximum number of requests allowed per client_id within RATE_LIMIT_WINDOW_MS. Requests exceeding this limit receive 429 RATE_LIMIT_EXCEEDED.


DB_POOL_MAX

Required No
Default 20
Format Integer
Example DB_POOL_MAX=20

Maximum number of PostgreSQL connections in the pool. Increase for high-throughput production deployments. Ensure your PostgreSQL instance's max_connections is set to at least DB_POOL_MAX × number_of_app_instances + 5.


DB_POOL_MIN

Required No
Default 2
Format Integer
Example DB_POOL_MIN=2

Minimum number of idle connections kept alive in the pool.


DB_POOL_IDLE_TIMEOUT_MS

Required No
Default 30000
Format Integer (milliseconds)
Example DB_POOL_IDLE_TIMEOUT_MS=30000

Milliseconds a connection can sit idle before being evicted from the pool.


DB_POOL_CONNECTION_TIMEOUT_MS

Required No
Default 5000
Format Integer (milliseconds)
Example DB_POOL_CONNECTION_TIMEOUT_MS=5000

Milliseconds the pool waits for a connection to become available before throwing a connection timeout error.


VAULT_KV_MOUNT

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

KV v2 secrets engine mount path used by VaultService. Equivalent to the existing VAULT_MOUNT variable — note that .env.example uses VAULT_KV_MOUNT; the underlying service reads either.


OPA_URL

Required No
Format URL string
Example OPA_URL=http://localhost:8181

URL of a running OPA server for external policy evaluation. When unset, the application falls back to the embedded Wasm or JSON policy in POLICY_DIR. Used for health check reporting.


KAFKA_BROKERS

Required No
Format Comma-separated broker addresses
Example KAFKA_BROKERS=localhost:9092

When set, the KafkaAdapter publishes domain events to Kafka. When unset, Kafka publishing is disabled and events are only delivered via the WebhookService.


ENFORCE_TLS

Required No
Default false
Values true, false
Example ENFORCE_TLS=true

When true, the tlsEnforcementMiddleware redirects all HTTP requests to HTTPS. Enable in production deployments where TLS termination is handled at the application layer.


POLICY_DIR

Directory containing OPA policy files (authz.rego, authz.wasm, data/scopes.json).

Required No
Default <cwd>/policies
Format Absolute or relative directory path
Example POLICY_DIR=/etc/sentryagent/policies

At startup the OPA authorization middleware loads ${POLICY_DIR}/authz.wasm (Wasm mode) if present; otherwise it loads ${POLICY_DIR}/data/scopes.json (fallback mode). Send SIGHUP to the process to hot-reload the policy files without a restart.


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

# ── Server ──────────────────────────────────────────────────────────────────
NODE_ENV=development
PORT=3000
CORS_ORIGIN=http://localhost:3001

# ── Database ─────────────────────────────────────────────────────────────────
DATABASE_URL=postgresql://sentryagent:sentryagent@localhost:5432/sentryagent_idp
DB_POOL_MAX=20
DB_POOL_MIN=2
DB_POOL_IDLE_TIMEOUT_MS=30000
DB_POOL_CONNECTION_TIMEOUT_MS=5000

# ── Redis ────────────────────────────────────────────────────────────────────
REDIS_URL=redis://localhost:6379
REDIS_RATE_LIMIT_ENABLED=true
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100

# ── JWT Keys (generate with openssl — see docs/devops/security.md) ──────────
JWT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEow...\n-----END RSA PRIVATE KEY-----"
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIIBIj...\n-----END PUBLIC KEY-----"

# ── Billing (Stripe) — set BILLING_ENABLED=false for local/in-house testing ─
BILLING_ENABLED=false
STRIPE_SECRET_KEY=sk_test_placeholder
STRIPE_WEBHOOK_SECRET=whsec_placeholder
STRIPE_PRICE_ID=price_placeholder

# ── Phase 6 Feature Flags ─────────────────────────────────────────────────────
ANALYTICS_ENABLED=true
TIER_ENFORCEMENT=true
COMPLIANCE_ENABLED=true

# ── HashiCorp Vault (optional) ────────────────────────────────────────────────
# VAULT_ADDR=http://127.0.0.1:8200
# VAULT_TOKEN=hvs.XXXXXXXXXXXXXXXXXXXXXX
# VAULT_KV_MOUNT=secret

# ── OPA (optional) ───────────────────────────────────────────────────────────
# POLICY_DIR=/etc/sentryagent/policies
# OPA_URL=http://localhost:8181

# ── Kafka (optional) ─────────────────────────────────────────────────────────
# KAFKA_BROKERS=localhost:9092

# ── TLS ──────────────────────────────────────────────────────────────────────
# ENFORCE_TLS=true

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.

Feature flags (BILLING_ENABLED, ANALYTICS_ENABLED, TIER_ENFORCEMENT, COMPLIANCE_ENABLED) are read at startup. ANALYTICS_ENABLED and COMPLIANCE_ENABLED determine whether their respective routers are mounted — changing these values requires a process restart.