Self-Hosting
Configuration Reference Complete environment variable reference for all Platform-Kernel services. All values sourced from service config.go files and docker/versions.env. No .env files at runtime — environment-only configuration (AD-1).
All Platform-Kernel services read configuration exclusively from
environment variables at startup. There is no .env file loading at
runtime (Architectural Decision AD-1). Defaults are compiled into each
service's internal/config/config.go.
The table below is the authoritative reference for all services.
Columns: Variable · Service · Default · Description .
Variables consumed by multiple services:
Variable Services Default Description DATABASE_URLIAM, Data Layer, Billing, Money, Files, Notify, Module Registry, Domain Resolver (See below) PostgreSQL connection DSN. Required — startup aborts if unset. VALKEY_URLIAM, Gateway, Data Layer localhost:6379Valkey address (host:port). Unified across all services. VALKEY_PASSWORDIAM, Data Layer (empty) Valkey AUTH password. Empty disables auth (dev only). KAFKA_BROKERSGateway, Event Bus, Billing, Money, Audit localhost:9092Comma-separated Kafka broker addresses. VAULT_ADDRIAM, Gateway, Domain Resolver http://vault:8200HashiCorp Vault HTTP address. VAULT_TOKENIAM, Gateway, Domain Resolver kernel-dev-root-tokenVault root or AppRole service token. Rotated every 90 days in prod. LOG_LEVELAll services infoLog level: debug, info, warn, error. LOG_JSONAll services trueIf true, emits structured JSON via slog.NewJSONHandler.
DATABASE_URL Default:
postgres://localhost:5432/platform?sslmode=disable
Variable Description GATEWAY_HOSTListen address. Default: 0.0.0.0 GATEWAY_PORTHTTP listen port (mapped to 8051 on host in Docker). Default: 8080 GATEWAY_GRPC_PORTgRPC listen port. Default: 50051 GATEWAY_SHUTDOWN_TIMEOUTGraceful shutdown window. Go duration string (e.g. 30s). Default: 30s IAM_URLIAM service HTTP address (internal Docker: http://iam:8080). Default: http://localhost:8081 IAM_GRPC_ADDRIAM service gRPC address. Used by Gateway for token validation. Default: iam:50050 DATA_LAYER_URLData Layer HTTP address. Do not use host-mapped port. Default: http://localhost:8080 DATA_LAYER_GRPC_ADDRData Layer gRPC address. Default: data-layer:50052 BILLING_URLBilling gRPC address (no http:// prefix — raw gRPC). Default: localhost:50055 BILLING_GRPC_ADDRBilling gRPC address (Docker service name). Default: billing:50055 NOTIFY_GRPC_ADDRNotify gRPC address. Default: notify:50054 MODULE_REGISTRY_GRPC_ADDRModule Registry gRPC address. Default: module-registry:50060 JWT_PUBLIC_KEYBase64-encoded PEM ECDSA P-256 public key for token validation. Default: (required) JWT_ISSUERExpected iss claim in incoming JWTs. Default: platform-kernel JWT_AUDIENCEExpected aud claim in incoming JWTs. Default: platform-kernel CORS_ALLOWED_ORIGINSComma-separated origin whitelist. No wildcard. MUST be set in prod. Default: (empty — deny all) CORS_ALLOWED_METHODSComma-separated allowed HTTP methods. Default: (See below) CORS_ALLOWED_HEADERSAllowed request headers. Default: (See below) CORS_MAX_AGEPreflight cache duration in seconds. Default: 3600 RATE_LIMIT_RPSPer-IP sustained request rate (token bucket). Default: 10000 RATE_LIMIT_BURSTPer-IP burst headroom. Default: 20000 RATE_LIMIT_WINDOWSliding window duration for RATE_LIMIT_MAX_REQUESTS. Default: 60s RATE_LIMIT_MAX_REQUESTSGlobal hard cap per window (Valkey-backed). Default: 1000000 BILLING_CACHE_TTLBilling plan cache TTL. Go duration string. Default: 15m OPENAPI_RESPONSE_VALIDATIONEnable OpenAPI response contract validation (perf cost in prod). Default: false
CORS Defaults:
CORS_ALLOWED_METHODS=GET,POST,PUT,PATCH,DELETE,OPTIONS
CORS_ALLOWED_HEADERS=Accept,Authorization,Content-Type,X-Request-ID,X-Tenant-ID
Variable Description PORTHTTP listen port (mapped to 8050:8080 in Docker). Default: 8081 IAM_GRPC_PORTgRPC listen port. Default: 50050 DATABASE_URLPostgreSQL DSN. Reads platform_kernel database. Default: (required) VALKEY_URLValkey address. Used for session cache and dedup. Default: localhost:6379 VALKEY_PASSWORDValkey AUTH password. Default: (empty) JWT_PRIVATE_KEYBase64-encoded PEM ECDSA P-256 private key for token signing. Default: (required) JWT_ACCESS_TTL_MINAccess token lifetime in minutes. Default: 15 JWT_REFRESH_TTL_DAYSRefresh token lifetime in days. Default: 7 DELEGATION_TOKEN_TTLDelegation token TTL in seconds. Clamped to [MinTTL, MaxTTL]. Default: 3600 AUTH_REFRESH_GRACE_WINDOW_SECRace-protection grace window for token refresh (seconds). Default: 10 MFA_ENCRYPTION_KEYHex-encoded AES-256 key (64 chars) for TOTP secret encryption. Default: (required in prod) ARGON2_MEMORYArgon2id memory cost in KB (OWASP recommended: 64 MB). Default: 65536 ARGON2_ITERATIONSArgon2id time cost (OWASP recommended). Default: 3 ARGON2_PARALLELISMArgon2id threads. Must be ≤ host vCPU count. Default: 4 ARGON2_KEY_LENGTHArgon2id output key length in bytes. Default: 32 ARGON2_SALT_LENGTHArgon2id salt length in bytes. Default: 16 OIDC_ISSUEROIDC discovery iss URL. Set to the public Gateway URL in prod. Default: http://localhost:8081 OIDC_RSA_PRIVATE_KEYPEM-encoded RSA-2048 key for OIDC RS256 token signing. Default: (required for OIDC) OIDC_SECRET_ROTATION_GRACE_HOURSHours the old client_secret remains valid post-rotation (kernel-spec §1397). Default: 24 VAULT_ADDRVault address for JWT key retrieval. Default: http://vault:8200 VAULT_TOKENVault auth token. Default: (required) VAULT_INIT_TIMEOUT_SECMax seconds to wait for Vault on startup before os.Exit(1). Default: 120 VAULT_RETRY_INITIAL_MSInitial retry backoff for Vault connection (ms). Default: 250 VAULT_RETRY_MAX_MSMax retry backoff for Vault connection (ms). Default: 16000 VAULT_WATCH_INTERVAL_SECJWT signing key rotation poll interval (seconds). Default: 30
Variable Default Description DATABASE_URL(required) PostgreSQL DSN. Required — startup aborts if unset. PORT8080HTTP listen port. DATA_LAYER_GRPC_PORT50052gRPC listen port. VALKEY_URLlocalhost:6379Valkey address. Used for query result caching and dedup. VALKEY_PASSWORD(empty) Valkey AUTH password. DB_MAX_OPEN_CONNS25PostgreSQL max open connections per service instance. DB_MAX_IDLE_CONNS5PostgreSQL max idle connections. DB_CONN_MAX_LIFETIME5mMax connection lifetime (Go duration). DB_CONN_MAX_IDLE_TIME1mMax idle connection time (Go duration). DATA_MAX_RECORD_SIZE_BYTES1048576Max record size (1 MB). Rejected at ingress. DATA_MAX_JSONB_SIZE_BYTES262144Max JSONB field size (256 KB). DATA_MAX_TABLES_PER_MODULE50Max dynamic tables a module can create.
Variable Default Description DATABASE_URL(required) PostgreSQL DSN. BILLING_GRPC_PORT50055gRPC listen port. KAFKA_BROKERSlocalhost:9092Kafka brokers for billing event publishing. DB_MAX_OPEN_CONNS25PostgreSQL pool: max open connections. DB_MAX_IDLE_CONNS5PostgreSQL pool: max idle connections. DB_CONN_MAX_LIFETIME_MIN5Connection max lifetime in minutes. DB_CONN_MAX_IDLE_TIME_MIN1Connection max idle time in minutes. BILLING_CACHE_TTL_MIN15In-memory billing plan cache TTL (minutes). BILLING_GRACE_PERIOD_DAYS7Subscription grace period after payment failure. BILLING_SUSPEND_PERIOD_DAYS30Days after grace period before account suspension. BILLING_CRYPTO_WIPE_PERIOD_DAYS30Days after suspension before GDPR wipe. BILLING_TRIAL_DAYS14Default trial plan duration. BILLING_TRIAL_WARNING_DAYS3Days before trial expiry to send warning.
Variable Default Description AUDIT_HOST0.0.0.0HTTP listen address. AUDIT_HTTP_PORT8094HTTP port (health + REST). AUDIT_GRPC_PORT50059gRPC listen port. CLICKHOUSE_ADDRlocalhost:9000ClickHouse native TCP address. CLICKHOUSE_DATABASEplatform_auditClickHouse database name. CLICKHOUSE_USERNAMEkernelClickHouse user. CLICKHOUSE_PASSWORD(empty) ClickHouse password. Required in prod. CLICKHOUSE_MAX_OPEN_CONNS10ClickHouse connection pool size. CLICKHOUSE_MAX_IDLE_CONNS5ClickHouse idle connections. CLICKHOUSE_CONN_MAX_LIFETIME10mClickHouse connection max lifetime (Go duration). CLICKHOUSE_DIAL_TIMEOUT5sClickHouse connection timeout. KAFKA_AUDIT_TOPICplatform.audit.eventsKafka topic consumed by Audit service. KAFKA_AUDIT_CONSUMER_GROUPaudit-clickhouse-writerKafka consumer group ID. KAFKA_BATCH_TIMEOUT100msKafka batch flush timeout. KAFKA_MAX_ATTEMPTS3Kafka producer retry attempts. WAL_REPLAY_INTERVAL30sPostgreSQL WAL fallback replay interval. WAL_RETENTION_DAYS7WAL fallback retention before purge. AUDIT_HOT_DAYS90ClickHouse hot storage retention (days). AUDIT_COLD_YEARS7S3 Glacier cold storage retention (years).
Variable Default Description EVENT_BUS_GRPC_PORT50053gRPC listen port. KAFKA_BROKERSlocalhost:9092Kafka broker addresses. VALKEY_ADDRvalkey:6379Valkey address (used for dedup cache). KAFKA_RETENTION_HOURS168Event topic retention (7 days). KAFKA_AUDIT_RETENTION_HOURS720Audit topic retention (30 days).
Variable Default Description NOTIFY_GRPC_PORT50054gRPC listen port. VALKEY_ADDRvalkey:6379Valkey for replay buffer and session cache. NOTIFY_RATE_LIMIT_PER_TENANT100Max notifications per minute per tenant. NOTIFY_WS_MAX_CONNECTIONS_PER_TENANT1000Max concurrent WebSocket connections per tenant. WS_REPLAY_BUFFER_SIZE100WebSocket disconnect replay buffer (messages). WS_REPLAY_BUFFER_TTL_SEC3600Replay buffer TTL (1 hour). NOTIFY_HISTORY_RETENTION_DAYS90Notification history retention in PostgreSQL.
Variable Default Description FILES_GRPC_PORT50057gRPC listen port. VALKEY_ADDRvalkey:6379Valkey for dedup and rate limiting. FILES_MAX_IMAGE_SIZE_MB10Max upload image size in MB. FILES_STAGING_TTL_HOURS24Staging bucket TTL before AV scan expiry. FILES_SOFT_DELETE_RETENTION_DAYS30Recycle bin retention before permanent deletion. FILES_ORPHAN_SCAN_INTERVAL_HOURS24Orphaned file cleanup scan interval. S3_ENDPOINT(required) S3-compatible endpoint (e.g. http://seaweedfs:8333). S3_BUCKETplatform-filesPrimary S3 bucket name. S3_ACCESS_KEY(required) S3 access key ID. S3_SECRET_KEY(required) S3 secret access key. S3_REGIONus-east-1S3 region (SeaweedFS ignores this; required by AWS SDK).
Variable Default Description MONEY_GRPC_PORT50058gRPC listen port. KAFKA_BROKERSlocalhost:9092Kafka brokers for money event publishing. VALKEY_ADDRvalkey:6379Valkey for idempotency key dedup. MONEY_HOLD_TTL_HOURS72Default wallet hold TTL (3 days). Max: 7 days. MONEY_MAX_HOLDS_PER_WALLET100Max concurrent holds per wallet. MONEY_REVERSAL_MAX_AGE_DAYS365Max age for transaction reversals (1 year). MONEY_HOLD_CLEANUP_INTERVAL_SEC60Background hold expiration ticker interval.
Variable Default Description MODULE_REGISTRY_GRPC_PORT50060gRPC listen port. VALKEY_ADDRvalkey:6379Valkey for module manifest cache. DATABASE_URL(required) PostgreSQL DSN.
Variable Default Description INTEGRATION_GRPC_PORT50056gRPC listen port. INTEGRATION_RATE_LIMIT_PER_SEC100Max outgoing requests per second per provider.
Variable Default Description DOMAIN_RESOLVER_GRPC_PORT50061gRPC listen port. DATABASE_URL(required) PostgreSQL DSN (reads platform_domain database). VAULT_ADDRhttp://vault:8200Vault address for TLS certificate storage. VAULT_TOKEN(required) Vault auth token. DOMAINS_MAX_PER_TENANT5Max custom domains per tenant. DOMAINS_VERIFY_TTL_HOURS72DNS verification TTL before challenge expiry. DOMAINS_SSL_RENEW_DAYS_BEFORE30Days before TLS cert expiry to trigger renewal.
Variable Default Description FEATURE_FLAGS_PORT1031GoFeatureFlag HTTP port. FLAGS_MAX_PER_TENANT0Max feature flags per tenant (0 = unlimited).
Copy and fill before first deployment. Store secrets in Vault —
never commit this file with real values.
# ── Database ──────────────────────────────────────────────────
DATABASE_URL = postgres://kernel:CHANGE_ME@postgres:5432/platform_kernel? sslmode = require
# ── Cache ─────────────────────────────────────────────────────
VALKEY_URL = valkey:6379
VALKEY_PASSWORD = CHANGE_ME
# ── Kafka ─────────────────────────────────────────────────────
KAFKA_BROKERS = kafka-0:9092,kafka-1:9092,kafka-2:9092
# ── HashiCorp Vault ───────────────────────────────────────────
VAULT_ADDR = https://vault.internal:8200
VAULT_TOKEN = CHANGE_ME
# ── IAM / JWT ─────────────────────────────────────────────────
# ES256 ECDSA P-256 — generate with: openssl ecparam -name prime256v1 -genkey | base64
JWT_PRIVATE_KEY = BASE64_PEM_HERE
JWT_PUBLIC_KEY = BASE64_PEM_HERE
MFA_ENCRYPTION_KEY = 64_HEX_CHARS_HERE
# ── OIDC (if provider feature enabled) ────────────────────────
OIDC_ISSUER = https://api.yourdomain.com
OIDC_RSA_PRIVATE_KEY = PEM_RSA2048_HERE
# ── Gateway ───────────────────────────────────────────────────
CORS_ALLOWED_ORIGINS = https://app.yourdomain.com,https://admin.yourdomain.com
JWT_ISSUER = platform-kernel
JWT_AUDIENCE = platform-kernel
# ── S3 ────────────────────────────────────────────────────────
S3_ENDPOINT = https://s3.yourdomain.com
S3_BUCKET = platform-files
S3_ACCESS_KEY = CHANGE_ME
S3_SECRET_KEY = CHANGE_ME
# ── ClickHouse ────────────────────────────────────────────────
CLICKHOUSE_ADDR = clickhouse:9000
CLICKHOUSE_PASSWORD = CHANGE_ME