Skip to main content

Configuration Reference

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.


Global / Shared Variables

Variables consumed by multiple services:

VariableServicesDefaultDescription
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 Layerlocalhost: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, Auditlocalhost:9092Comma-separated Kafka broker addresses.
VAULT_ADDRIAM, Gateway, Domain Resolverhttp://vault:8200HashiCorp Vault HTTP address.
VAULT_TOKENIAM, Gateway, Domain Resolverkernel-dev-root-tokenVault root or AppRole service token. Rotated every 90 days in prod.
LOG_LEVELAll servicesinfoLog level: debug, info, warn, error.
LOG_JSONAll servicestrueIf true, emits structured JSON via slog.NewJSONHandler.

DATABASE_URL Default:

postgres://localhost:5432/platform?sslmode=disable

Gateway (services/gateway/)

VariableDescription
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

IAM Service (services/iam/)

VariableDescription
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

Data Layer (services/data-layer/)

VariableDefaultDescription
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.

Billing Service (services/billing/)

VariableDefaultDescription
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.

Audit Service (services/audit/)

VariableDefaultDescription
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).

Event Bus (services/event-bus/)

VariableDefaultDescription
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).

Notify Service (services/notify/)

VariableDefaultDescription
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.

Files Service (services/files/)

VariableDefaultDescription
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).

Money Service (services/money/)

VariableDefaultDescription
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.

Module Registry (services/module-registry/)

VariableDefaultDescription
MODULE_REGISTRY_GRPC_PORT50060gRPC listen port.
VALKEY_ADDRvalkey:6379Valkey for module manifest cache.
DATABASE_URL(required)PostgreSQL DSN.

Integration Hub (services/integration-hub/)

VariableDefaultDescription
INTEGRATION_GRPC_PORT50056gRPC listen port.
INTEGRATION_RATE_LIMIT_PER_SEC100Max outgoing requests per second per provider.

Domain Resolver (services/domain-resolver/)

VariableDefaultDescription
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.

Feature Flags (services/integration-hub/ — GoFeatureFlag)

VariableDefaultDescription
FEATURE_FLAGS_PORT1031GoFeatureFlag HTTP port.
FLAGS_MAX_PER_TENANT0Max feature flags per tenant (0 = unlimited).

Production .env.example

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

See Also