# ============================================================================= # Cordum Environment Configuration # Copy to .env and customize for your deployment # ============================================================================= # ----------------------------------------------------------------------------- # Core Settings # ----------------------------------------------------------------------------- # Environment mode (set to "production" for strict security defaults) CORDUM_ENV=development # CORDUM_PRODUCTION=true # TLS minimum version (1.2 or 1.3, default 1.3 in production) # CORDUM_TLS_MIN_VERSION=1.3 # Enable gRPC reflection (for debugging only) # CORDUM_GRPC_REFLECTION=1 # Log format (json or text) # CORDUM_LOG_FORMAT=json # ----------------------------------------------------------------------------- # Infrastructure - NATS # ----------------------------------------------------------------------------- # NATS connection NATS_URL=nats://localhost:4222 NATS_USE_JETSTREAM=1 # JetStream settings # NATS_JS_ACK_WAIT=30s # NATS_JS_MAX_AGE=168h # NATS_JS_REPLICAS=3 # NATS TLS (optional) # NATS_TLS_CA=/path/to/ca.crt # NATS_TLS_CERT=/path/to/client.crt # NATS_TLS_KEY=/path/to/client.key # NATS_TLS_INSECURE=false # NATS_TLS_SERVER_NAME=nats.example.com # NATS auth + overrides # Configure at least one auth mechanism in production. NewNatsBus refuses to # start in production with no auth unless CORDUM_NATS_ALLOW_NOAUTH=true. # Username/password (set both): # NATS_USERNAME= # NATS_PASSWORD= # Token auth (alternative to username/password): # NATS_TOKEN= # NKey seed auth (alternative to username/password): # NATS_NKEY= # Escape hatches — DO NOT enable in production unless the broker itself enforces # ACLs out-of-band. Safe default is no override (leave commented). # CORDUM_NATS_ALLOW_PLAINTEXT=true # allow nats:// (non-TLS) in production # CORDUM_NATS_ALLOW_NOAUTH=true # allow no NATS_USERNAME/PASSWORD/TOKEN/NKEY in production # ----------------------------------------------------------------------------- # Infrastructure - Redis # ----------------------------------------------------------------------------- # Redis authentication password # REQUIRED in production — generate with: openssl rand -hex 32 # WARNING: The default 'cordum-dev' is for LOCAL DEVELOPMENT ONLY. # Production deployments MUST override this value. REDIS_PASSWORD=cordum-dev # Redis connection (include password if REDIS_PASSWORD is set) REDIS_URL=redis://:${REDIS_PASSWORD}@localhost:6379 # Redis clustering (comma-separated host:port seeds) # REDIS_CLUSTER_ADDRESSES=redis-0:6379,redis-1:6379,redis-2:6379 # Data TTLs REDIS_DATA_TTL=24h # REDIS_DATA_TTL_SECONDS=86400 # Redis TLS (optional) # REDIS_TLS_CA=/path/to/ca.crt # REDIS_TLS_CERT=/path/to/client.crt # REDIS_TLS_KEY=/path/to/client.key # REDIS_TLS_INSECURE=false # REDIS_TLS_SERVER_NAME=redis.example.com # ----------------------------------------------------------------------------- # Gateway - Authentication # ----------------------------------------------------------------------------- # API key (required - set a strong random key) CORDUM_API_KEY= # Alternative: JSON array of keys with metadata # CORDUM_API_KEYS=[{"key":"key1","tenant":"default","role":"admin"}] # Or load from file (reloads on change) # CORDUM_API_KEYS_PATH=/etc/cordum/api-keys.json # Default tenant for single-tenant mode TENANT_ID=default # Allow anonymous auth (dev only - NEVER in production) # CORDUM_ALLOW_INSECURE_NO_AUTH=1 # Allow X-Principal-Id header override (disabled by default in production) # CORDUM_ALLOW_HEADER_PRINCIPAL=true # ----------------------------------------------------------------------------- # Gateway - User Authentication (optional) # ----------------------------------------------------------------------------- # Enable user/password authentication (stores users in Redis) CORDUM_USER_AUTH_ENABLED=true # Default admin user (created on first start if password is set) CORDUM_ADMIN_USERNAME=admin # Required when CORDUM_USER_AUTH_ENABLED=true. Policy: >= 12 characters, with at # least one uppercase letter, one digit, and one special character. The gateway # refuses to start (and silently fails to seed the admin) if user auth is # enabled and this is empty or non-compliant. CHANGE THIS before any real use. # (tools/scripts/quickstart.sh seeds this same default into a fresh .env.) CORDUM_ADMIN_PASSWORD=ChangeMe123! CORDUM_ADMIN_EMAIL=admin@cordum.local # ----------------------------------------------------------------------------- # Gateway - JWT Authentication (optional) # ----------------------------------------------------------------------------- # JWT validation (use HMAC secret OR public key, not both) # CORDUM_JWT_HMAC_SECRET=your-256-bit-secret # CORDUM_JWT_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----... # CORDUM_JWT_PUBLIC_KEY_PATH=/path/to/public.pem # CORDUM_JWT_ISSUER=https://auth.example.com # CORDUM_JWT_AUDIENCE=cordum-api # CORDUM_JWT_DEFAULT_ROLE=user # CORDUM_JWT_CLOCK_SKEW=5m # CORDUM_JWT_REQUIRED=true # ----------------------------------------------------------------------------- # Gateway - Network & Limits # ----------------------------------------------------------------------------- # Listen addresses # GATEWAY_GRPC_ADDR=:8080 # GATEWAY_HTTP_ADDR=:8081 # GATEWAY_METRICS_ADDR=:9092 # Allow non-loopback metrics bind in production # GATEWAY_METRICS_PUBLIC=1 # Rate limiting (per tenant, falls back to client IP) # These match the gateway defaults; lower for local development if needed. API_RATE_LIMIT_RPS=2000 API_RATE_LIMIT_BURST=4000 # CORS allowed origins (comma-separated, multiple var names supported) # CORDUM_ALLOWED_ORIGINS=https://dashboard.example.com # CORDUM_CORS_ALLOW_ORIGINS=https://dashboard.example.com # CORS_ALLOW_ORIGINS=https://dashboard.example.com # HTTP TLS (optional) # GATEWAY_HTTP_TLS_CERT=/path/to/server.crt # GATEWAY_HTTP_TLS_KEY=/path/to/server.key # gRPC TLS (optional) # GRPC_TLS_CERT=/path/to/server.crt # GRPC_TLS_KEY=/path/to/server.key # ----------------------------------------------------------------------------- # Gateway - Tunable Parameters # ----------------------------------------------------------------------------- # HSTS max-age in seconds (default: 63072000 = 2 years). Set lower during rollout. # CORDUM_HSTS_MAX_AGE=63072000 # Session token TTL (Go duration, default: 24h) # CORDUM_SESSION_TTL=24h # HTTP server timeouts (Go durations) # GATEWAY_HTTP_READ_TIMEOUT=15s # GATEWAY_HTTP_WRITE_TIMEOUT=30s # GATEWAY_HTTP_IDLE_TIMEOUT=60s # Login brute-force protection # MAX_LOGIN_ATTEMPTS=5 # LOGIN_LOCKOUT_PERIOD=15m # bcrypt cost factor for password and API key hashing (default: 12) # CORDUM_BCRYPT_COST=12 # OIDC JWKS refresh interval (Go duration, default: 6h) # CORDUM_OIDC_JWKS_REFRESH_INTERVAL=6h # NATS JetStream MaxAckPending (default: 2048) # NATS_MAX_ACK_PENDING=2048 # Audit export retry and buffer settings # CORDUM_AUDIT_EXPORT_MAX_RETRIES=3 # CORDUM_AUDIT_BUFFER_SIZE=1000 # ----------------------------------------------------------------------------- # Gateway - Artifacts # ----------------------------------------------------------------------------- # Artifact size limit (bytes, default 10MB) # ARTIFACT_MAX_BYTES=10485760 # Artifact TTLs by retention class # ARTIFACT_TTL_SHORT=1h # ARTIFACT_TTL_STANDARD=168h # ARTIFACT_TTL_AUDIT=8760h # ----------------------------------------------------------------------------- # Gateway - Pack Marketplace # ----------------------------------------------------------------------------- # Default pack catalog # CORDUM_PACK_CATALOG_URL=https://packs.cordum.io/catalog.json # CORDUM_PACK_CATALOG_ID=official # CORDUM_PACK_CATALOG_TITLE=Official Packs # CORDUM_PACK_CATALOG_DEFAULT_DISABLED=1 # Marketplace settings # CORDUM_MARKETPLACE_HTTP_TIMEOUT=15s # ----------------------------------------------------------------------------- # Scheduler # ----------------------------------------------------------------------------- # Config file paths POOL_CONFIG_PATH=/etc/cordum/pools.yaml TIMEOUT_CONFIG_PATH=/etc/cordum/timeouts.yaml # Job metadata TTL JOB_META_TTL=168h # JOB_META_TTL_SECONDS=604800 # Worker snapshot interval WORKER_SNAPSHOT_INTERVAL=5s # Config reload interval # SCHEDULER_CONFIG_RELOAD_INTERVAL=30s # Metrics # SCHEDULER_METRICS_ADDR=:9090 # SCHEDULER_METRICS_PUBLIC=1 # Worker trust handshake and session-token gate. Scheduler boot requires one # explicit value; unset/unknown values refuse to start: # off — handshake responder and session gate disabled # warn — sessions govern dispatch; token-less heartbeat/capability is telemetry only # enforce — signed handshake and bound token required for worker dispatch CORDUM_SDK_HANDSHAKE=off # Heartbeat authority must transition with the handshake mode. Valid classes: # authority — only with handshake off (legacy TTL authority) # warn/telemetry — with handshake warn or enforce (session authority) # Recommended rollout: off+authority -> warn+warn -> enforce+telemetry. CORDUM_HEARTBEAT_MODE=authority # Active handshake modes are incompatible with legacy bearer attestation because # both interpret BusPacket.auth_token differently. Keep this off for warn/enforce. WORKER_ATTESTATION=off # warn/enforce require the complete P-256 scheduler proof bundle below. The # public SPKI file is the pinned export distributed to workers and is verified # byte-for-key against the private key at boot. # CORDUM_HANDSHAKE_SCHEDULER_ID=cordum-scheduler # CORDUM_HANDSHAKE_SCHEDULER_KEY_ID=scheduler-key-v1 # CORDUM_HANDSHAKE_PRIVATE_KEY_FILE=/run/secrets/cordum-handshake-private.pem # CORDUM_HANDSHAKE_PUBLIC_KEY_FILE=/etc/cordum/trust/cordum-handshake-public.pem # # Ed25519 session/control-plane token signing. warn/enforce schedulers and the # gateway require this authority for signed worker-session minting. Under # enforce the scheduler, # api-gateway, and workflow-engine also each mint a short-TTL # service token on their internal JobResult/JobCancel broadcasts so peer # schedulers admit them. ALL THREE services must share the SAME Ed25519 signing # key (single kid). Locally the key is derived from a shared dev seed; in # production supply a real key via CORDUM_POLICY_SIGNING_KEY (or _PATH). The # fixed worker-session audience is cordum-scheduler. # CORDUM_POLICY_SIGNING_KEY_ID=dev-local # CORDUM_POLICY_DEV_SIGNING_SEED=cordum-local-policy-signing-v1 # CORDUM_POLICY_SIGNING_KEY= # base64/PEM Ed25519 private key (prod) # CORDUM_POLICY_SIGNING_KEY_PATH= # file alternative to the inline key # CORDUM_POLICY_PUBLIC_KEY_= # matching trusted Ed25519 public key # ----------------------------------------------------------------------------- # Workflow Engine # ----------------------------------------------------------------------------- # HTTP address for health checks # WORKFLOW_ENGINE_HTTP_ADDR=:9093 # Scan settings WORKFLOW_ENGINE_SCAN_INTERVAL=5s WORKFLOW_ENGINE_RUN_SCAN_LIMIT=200 # Under CORDUM_SDK_HANDSHAKE=enforce the workflow-engine mints a control-plane # service token on its internal cancel broadcasts and so needs the shared # Ed25519 signing key — see CORDUM_POLICY_SIGNING_* in the Scheduler section. # ----------------------------------------------------------------------------- # Safety Kernel # ----------------------------------------------------------------------------- # gRPC address SAFETY_KERNEL_ADDR=localhost:50051 # Policy source (file or URL) SAFETY_POLICY_PATH=/etc/cordum/safety.yaml # SAFETY_POLICY_URL=https://policies.example.com/safety.yaml # SAFETY_POLICY_URL_ALLOWLIST=policies.example.com,internal.example.com # SAFETY_POLICY_URL_ALLOW_PRIVATE=1 # Policy signature verification (required in production) # SAFETY_POLICY_PUBLIC_KEY=/path/to/policy-signing.pub # SAFETY_POLICY_SIGNATURE=/path/to/safety.yaml.sig # SAFETY_POLICY_SIGNATURE_PATH=/path/to/safety.yaml.sig # SAFETY_POLICY_SIGNATURE_REQUIRED=true # Policy reload and overlays # SAFETY_POLICY_RELOAD_INTERVAL=30s # SAFETY_POLICY_CONFIG_SCOPE=tenant # SAFETY_POLICY_CONFIG_ID=default # SAFETY_POLICY_CONFIG_KEY=policy # SAFETY_POLICY_CONFIG_DISABLE=false # Decision caching # SAFETY_DECISION_CACHE_TTL=5s # TLS server # SAFETY_KERNEL_TLS_CERT=/path/to/server.crt # SAFETY_KERNEL_TLS_KEY=/path/to/server.key # TLS client verification # SAFETY_KERNEL_TLS_CA=/path/to/ca.crt # SAFETY_KERNEL_TLS_REQUIRED=true # ----------------------------------------------------------------------------- # Context Engine # ----------------------------------------------------------------------------- # gRPC address # CONTEXT_ENGINE_ADDR=:50070 # TLS server # CONTEXT_ENGINE_TLS_CERT=/path/to/server.crt # CONTEXT_ENGINE_TLS_KEY=/path/to/server.key # TLS client # CONTEXT_ENGINE_TLS_CA=/path/to/ca.crt # CONTEXT_ENGINE_TLS_REQUIRED=true # ----------------------------------------------------------------------------- # Dashboard # ----------------------------------------------------------------------------- # API base URL (for dashboard to reach gateway) # Leave empty to use relative /api/v1 through nginx proxy (recommended) # Set to full URL only when dashboard accesses gateway directly # CORDUM_API_BASE_URL=http://localhost:8081 # Embed API key in dashboard frontend bundle (default: false) # WARNING: Setting to true exposes the API key in browser JavaScript. # Only use in local development — NEVER enable in production. # CORDUM_DASHBOARD_EMBED_API_KEY=true # Default tenant/principal for dashboard CORDUM_TENANT_ID=default # CORDUM_PRINCIPAL_ID= # CORDUM_PRINCIPAL_ROLE= # ----------------------------------------------------------------------------- # Audit — Chain HMAC (REQUIRED in production) # ----------------------------------------------------------------------------- # The audit chain underwrites ProvenanceGate's audit_chain_compromised signal. # Without HMAC, a Redis-write attacker can forge a chain that still verifies # under SHA-256 — defeating tamper detection. In production # (CORDUM_ENV=production), the gateway refuses to start unless either # CORDUM_AUDIT_HMAC_KEY is set or CORDUM_AUDIT_HMAC_OPTIONAL=true is set as an # explicit override. # # Generate with: openssl rand -hex 32 # CORDUM_AUDIT_HMAC_KEY= # REQUIRED in production (hex-encoded, ≥32 bytes) # CORDUM_AUDIT_HMAC_OPTIONAL=false # escape hatch: allow unsigned chain in prod (weakens ProvenanceGate) # ----------------------------------------------------------------------------- # Audit — SIEM Export (optional) # ----------------------------------------------------------------------------- # Export type: webhook | syslog | datadog | cloudwatch | none (default: none) # CORDUM_AUDIT_EXPORT_TYPE=none # Webhook — HTTP POST with JSON payload # CORDUM_AUDIT_EXPORT_WEBHOOK_URL=https://siem.example.com/api/events # CORDUM_AUDIT_EXPORT_WEBHOOK_SECRET=your-hmac-secret # Syslog — RFC 5424 (tcp:// or udp://) # CORDUM_AUDIT_EXPORT_SYSLOG_ADDR=tcp://syslog.corp.com:514 # Datadog — Log Intake API # CORDUM_AUDIT_EXPORT_DD_API_KEY=your-datadog-api-key # CORDUM_AUDIT_EXPORT_DD_SITE=us1 # CORDUM_AUDIT_EXPORT_DD_TAGS=env:production,service:cordum-gateway # AWS CloudWatch Logs # CORDUM_AUDIT_EXPORT_CW_LOG_GROUP=/cordum/audit # CORDUM_AUDIT_EXPORT_CW_LOG_STREAM=gateway # AWS_ACCESS_KEY_ID=... # AWS_SECRET_ACCESS_KEY=... # AWS_REGION=us-east-1 # Optional MCP session-taint destructive GraphQL mutation overrides. Defaults catch GraphQL proxy deletes (delete/remove/archive fields in query/mutation/gql/graphql args). # CORDUM_MCP_DESTRUCTIVE_MUTATION_GLOBS=delete_*,remove_*,archive_*,delete,remove,archive # CORDUM_MCP_DESTRUCTIVE_MUTATION_ARG_KEYS=query,mutation,gql,graphql # Optional default-OFF hardening: when true, a destructive MCP call whose session-taint lookup errors is held for human approval instead of treated as clean. # CORDUM_MCP_TAINT_FAILCLOSED_DESTRUCTIVE=false