Configuration
Storsko is configured entirely through environment variables. All variables are read at startup. Changes require a process restart.
Configuration
Storsko is configured entirely through environment variables. All variables are read at startup. Changes require a process restart.
make setup
Running make setup generates a .env file with safe defaults and auto-generated secrets. You should only need to manually set variables for non-default database URLs, LLM provider keys, or commercial features.
Configuration File
Storsko reads from a .env file in the repository root, or from environment variables set in your shell / container runtime. Environment variables always take precedence over .env file values.
A complete .env template:
Database
DATABASE_URL
The PostgreSQL connection string.
| Field | Value |
|---|---|
| Required | Yes |
| Default | None |
| Format | postgresql://[user]:[password]@[host]:[port]/[database] |
For production, use a connection pooler (e.g. PgBouncer) and set ?pgbouncer=true in the query string if using Prisma-style pooling. With Drizzle ORM and plain pg, no special flags are needed.
SSL in Production
Always use ?sslmode=require in production to encrypt the database connection.
DATABASE_POOL_MIN
Minimum number of database connections in the pool.
| Field | Value |
|---|---|
| Required | No |
| Default | 2 |
DATABASE_POOL_MAX
Maximum number of database connections in the pool.
| Field | Value |
|---|---|
| Required | No |
| Default | 10 |
Auth
ROOT_API_KEY_SECRET
The secret used to sign and verify the root API key. This is generated automatically by make setup.
| Field | Value |
|---|---|
| Required | Yes |
| Default | None (auto-generated by make setup) |
| Format | 32+ byte random hex string |
Rotation
If you rotate ROOT_API_KEY_SECRET, all existing API keys signed with the old secret will be invalidated. Users and integrations must be issued new keys.
JWT_SECRET
The secret used to sign JSON Web Tokens issued by the API server.
| Field | Value |
|---|---|
| Required | Yes |
| Default | None (auto-generated by make setup) |
| Format | 32+ byte random string |
| Minimum length | 32 characters |
In production, this should be a cryptographically random string of at least 64 characters:
JWT_EXPIRES_IN
How long issued JWTs are valid.
| Field | Value |
|---|---|
| Required | No |
| Default | 7d |
| Format | ms duration string |
Production Recommendation
Use shorter token expiry in production (1h or 24h). Pair with refresh token support for long-lived sessions.
API Server
PORT
The port the Fastify API server listens on.
| Field | Value |
|---|---|
| Required | No |
| Default | 3000 |
NODE_ENV
The Node.js environment. Affects logging verbosity, error detail in responses, and some internal behaviours.
| Field | Value |
|---|---|
| Required | No |
| Default | development |
| Allowed values | development, production, test |
Always set `NODE_ENV=production` in production. In development mode, stack traces are included in error responses.
LOG_LEVEL
The minimum log level. Storsko uses Pino for structured JSON logging.
| Field | Value |
|---|---|
| Required | No |
| Default | info |
| Allowed values | trace, debug, info, warn, error, fatal |
CORS_ORIGINS
Comma-separated list of allowed CORS origins. Applies to the API server.
| Field | Value |
|---|---|
| Required | No |
| Default | http://localhost:3001 (the web dashboard) |
HITL_DEFAULT_TIMEOUT_MINUTES
How many minutes a HITL request stays pending before it times out automatically.
| Field | Value |
|---|---|
| Required | No |
| Default | 30 |
When a HITL request times out, a hitl.timeout event is written to the audit log. The requesting agent receives a HITL_TIMEOUT error.
LLM Gateway
The LLM gateway is optional. It is only used if you call POST /api/v1/llm/chat. You can configure one or both providers.
OPENAI_API_KEY
The OpenAI API key. Required to route LLM requests to OpenAI models.
| Field | Value |
|---|---|
| Required | No |
| Default | None |
ANTHROPIC_API_KEY
The Anthropic API key. Required to route LLM requests to Anthropic models (e.g. Claude).
| Field | Value |
|---|---|
| Required | No |
| Default | None |
LLM_GATEWAY_PII_DETECTION
Whether to run PII detection on LLM request and response content before logging.
| Field | Value |
|---|---|
| Required | No |
| Default | true |
| Allowed values | true, false |
When enabled, detected PII patterns (email addresses, phone numbers, national ID numbers, credit card numbers) are redacted in audit log entries.
LLM_GATEWAY_RATE_LIMIT_RPM
Maximum LLM requests per minute across all agents.
| Field | Value |
|---|---|
| Required | No |
| Default | 60 |
Application URLs (Commercial)
These variables are used by the Next.js web dashboard (apps/web). Prefix NEXT_PUBLIC_ makes them available to the browser bundle.
NEXT_PUBLIC_API_URL
The base URL of the Storsko API server, as seen from the browser.
| Field | Value |
|---|---|
| Required | Yes (for web dashboard) |
| Default | http://localhost:3000 |
NEXT_PUBLIC_LANDING_URL
The base URL of the public landing site.
| Field | Value |
|---|---|
| Required | No |
| Default | http://localhost:3002 |
Keycloak SSO (Commercial — Enterprise Tier)
Keycloak integration enables SAML, LDAP, and enterprise SSO. It is only available on the Enterprise commercial tier.
KEYCLOAK_URL
The base URL of your Keycloak instance.
| Field | Value |
|---|---|
| Required | Commercial Enterprise only |
| Default | None |
KEYCLOAK_REALM
The Keycloak realm name for Storsko.
| Field | Value |
|---|---|
| Required | Commercial Enterprise only |
| Default | storsko |
KEYCLOAK_CLIENT_ID
The Keycloak client ID for the Storsko API.
| Field | Value |
|---|---|
| Required | Commercial Enterprise only |
| Default | storsko-api |
KEYCLOAK_CLIENT_SECRET
The Keycloak client secret. Found in Keycloak Admin → Clients → storsko-api → Credentials.
| Field | Value |
|---|---|
| Required | Commercial Enterprise only |
| Default | None |
Keycloak Setup
For a full guide on configuring Keycloak SSO with Storsko, see Commercial Platform.
Stripe Billing (Commercial)
Stripe integration handles subscription management for the commercial platform.
STRIPE_SECRET_KEY
Your Stripe secret key. Use test keys (sk_test_...) in development and live keys (sk_live_...) in production.
| Field | Value |
|---|---|
| Required | Commercial only |
| Default | None |
STRIPE_WEBHOOK_SECRET
The Stripe webhook signing secret. Used to verify that webhook events come from Stripe.
| Field | Value |
|---|---|
| Required | Commercial only |
| Default | None |
To get the webhook secret:
- Go to stripe.com/dashboard → Webhooks
- Add an endpoint pointing to
https://your-domain.com/api/v1/billing/webhook - Copy the signing secret
Webhook Secret Rotation
If you rotate the Stripe webhook secret, update STRIPE_WEBHOOK_SECRET immediately. Requests signed with the old secret will be rejected.
Summary Table
| Variable | Required | Default | Section |
|---|---|---|---|
DATABASE_URL | Yes | — | Database |
DATABASE_POOL_MIN | No | 2 | Database |
DATABASE_POOL_MAX | No | 10 | Database |
ROOT_API_KEY_SECRET | Yes | auto-generated | Auth |
JWT_SECRET | Yes | auto-generated | Auth |
JWT_EXPIRES_IN | No | 7d | Auth |
PORT | No | 3000 | API Server |
NODE_ENV | No | development | API Server |
LOG_LEVEL | No | info | API Server |
CORS_ORIGINS | No | http://localhost:3001 | API Server |
HITL_DEFAULT_TIMEOUT_MINUTES | No | 30 | API Server |
OPENAI_API_KEY | No | — | LLM Gateway |
ANTHROPIC_API_KEY | No | — | LLM Gateway |
LLM_GATEWAY_PII_DETECTION | No | true | LLM Gateway |
LLM_GATEWAY_RATE_LIMIT_RPM | No | 60 | LLM Gateway |
NEXT_PUBLIC_API_URL | Web only | http://localhost:3000 | App URLs |
NEXT_PUBLIC_LANDING_URL | No | http://localhost:3002 | App URLs |
KEYCLOAK_URL | Enterprise | — | Keycloak |
KEYCLOAK_REALM | Enterprise | storsko | Keycloak |
KEYCLOAK_CLIENT_ID | Enterprise | storsko-api | Keycloak |
KEYCLOAK_CLIENT_SECRET | Enterprise | — | Keycloak |
STRIPE_SECRET_KEY | Commercial | — | Stripe |
STRIPE_WEBHOOK_SECRET | Commercial | — | Stripe |