Skip to content
Browse documentation
Start/Current

Configuration

Environment variables, local defaults, secrets and persistence modes.

Reviewed 2026-08-17 4 min read configuration.md

CAPYN uses environment variables at the API and web process boundaries. .env.example is safe to copy for local development; .env files are ignored and must not be committed.

API variables

VariableLocal defaultRequiredPurpose
NODE_ENVdevelopmentNoSelects development, test or production behavior.
HOST0.0.0.0NoAPI listen address.
PORT4000NoAPI listen port. Hosting platforms may supply it.
TRUST_PROXYfalseReverse-proxy deploymentsTrusts the controlled ingress proxy's forwarded client address for per-client rate limiting.
CAPYN_STORAGEmemory in .env.exampleNoSelects memory or postgres.
DATABASE_URLLocal example onlyPostgreSQL modePrisma connection URL.
API_KEY_PEPPERNo safe deployment defaultYesHigh-entropy secret used to HMAC agent credentials.
WEB_ORIGINhttp://localhost:3010NoExact browser origin allowed by API CORS.
DEMO_HUMAN_AUTHtrue locallyNoEnables the development-only x-capyn-user-id adapter. Must be false outside a demo.
DEMO_HUMAN_USER_IDusr_demo_owner locallyProduction demoPins the demo header adapter to exactly one seeded user. Required when demo auth is enabled with NODE_ENV=production.
BOOTSTRAP_TOKENLocal placeholderNoEnables organisation bootstrap when present. Omit after controlled onboarding.
STRIPE_SECRET_KEYunsetHosted billingServer-side Stripe key. Never expose it to the web bundle.
STRIPE_WEBHOOK_SECRETunsetHosted billingVerifies the exact raw body delivered by Stripe.
STRIPE_PRICE_TEAM_MONTHLYunsetHosted billingStripe recurring base-price ID for Team.
STRIPE_PRICE_BUSINESS_MONTHLYunsetHosted billingStripe recurring base-price ID for Business.

The API refuses to start in PostgreSQL mode without DATABASE_URL, with an API_KEY_PEPPER shorter than 32 characters, when production demo auth is not pinned to one user, or when only part of the Stripe configuration is present. Leave all four Stripe variables absent to keep checkout disabled while the free/internal plan remains usable.

Web variables

VariableLocal defaultPurpose
NEXT_PUBLIC_API_URLhttp://localhost:4000Browser-visible API origin used by the control plane.
NEXT_PUBLIC_DEMO_USER_IDusr_demo_ownerDevelopment user sent only when demo human auth is intentionally enabled.
NEXT_PUBLIC_DEMO_USER_NAMEAcme OwnerSynthetic identity label displayed in the control plane.
NEXT_PUBLIC_DEMO_USER_ROLEOwnerSynthetic identity role label displayed in the control plane.
NEXT_PUBLIC_DEMO_MANAGEMENT_ENABLEDtrueHides administrative controls when false; server-side role checks remain the security boundary.
NEXT_PUBLIC_SITE_URLhttp://localhost:3010Canonical origin for metadata, sitemap and social cards.
PORTplatform supplied in productionNext.js listen port for pnpm --filter @capyn/web start. Development stays on 3010.
CAPYN_SERVICEunset locallySet to web or api for the preferred split deployment, or combined only for the constrained synthetic demo.
CAPYN_INTERNAL_API_PORT4100Private API port used only by the combined demo launcher.
CAPYN_INTERNAL_WEB_PORT3100Private Next.js port used only by the combined demo launcher.

NEXT_PUBLIC_* values are embedded into the browser bundle at build time. Changing them requires a new web build.

Persistence modes

Memory

Use CAPYN_STORAGE=memory for the demo, tests and local interface work. State resets when the API process stops. The seeded organisation, users, agent, credential and mandate are recreated on startup.

PostgreSQL

Use CAPYN_STORAGE=postgres with a provisioned PostgreSQL instance for durable state:

corepack pnpm db:migrate
corepack pnpm db:seed

The seed is for local demonstrations only. Do not run it against a production organisation database.

Secret handling

  • generate API_KEY_PEPPER and BOOTSTRAP_TOKEN with a cryptographically secure secret manager;
  • scope secrets per environment;
  • never expose the pepper, database URL or bootstrap token through NEXT_PUBLIC_* variables;
  • rotate agent credentials through CAPYN rather than editing hashes;
  • redact authorization and bootstrap headers from every log sink;
  • redact Stripe signatures and never log Checkout payloads or billing secrets;
  • keep TRUST_PROXY=false unless the API is behind a controlled ingress proxy; Railway API services should set it to true;
  • disable demo human authentication for every real or customer-data environment. A deliberately public demo may enable it only with synthetic, disposable state, mock execution and DEMO_HUMAN_USER_ID pinned to a least-privilege approver.

See Billing for plan and webhook behavior, Security for the deployment gate and Deployment for service-level configuration.