Configuration
oikapi is configured via config.yaml or environment variables with the OIKAPI_ prefix.
Server
Section titled “Server”server: port: 8080 metrics_port: 9090 # internal port for /metrics, /livez, /readyz request_timeout: "30s" shutdown_timeout: "30s" allowed_origins: # CORS origins; wildcards ("*") are rejected — list origins explicitly - "https://app.example.com" cors: max_age: 300 # seconds preflight results are cached base_url: "" # external URL used in invite/reset email linksSecurity
Section titled “Security”security: session: backend: "memory" # memory, valkey, postgres (auto-selects valkey when enabled) lifetime: "168h" # max session lifetime (7 days) idle_timeout: "8h" # logout after inactivity cookie_name: "session" cookie_same_site: "Lax" # Lax (default), Strict, None — see the warning below bcrypt_cost: 12 # 10-14 recommendedMulti-factor authentication (TOTP) is also configurable under security.mfa.
Logging
Section titled “Logging”log: level: "info" # trace, debug, info, warn, error pretty: false # true for human-readable (dev), false for JSON (prod) no_color: falseCaching
Section titled “Caching”cache: invalidation: method: "auto" # local, pubsub, auto (pubsub uses ValKey for multi-instance)File storage
Section titled “File storage”file_storage: provider: "local" # local, s3 (AWS S3 or any S3-compatible store), or seaweedfs local: base_path: "./uploads" s3: endpoint: "" # for SeaweedFS or other S3-compatible stores region: "us-east-1" bucket_name: "oikapi-files" access_key_id: "" secret_access_key: "" use_ssl: trueExported .oikapp packages are stored separately under package_storage (same structure).
Background jobs
Section titled “Background jobs”jobs: enabled: true workers: 4 scheduler_enabled: true scheduler_interval: "60s" # how often the scheduler sweeps for due scheduled rulesRate limiting
Section titled “Rate limiting”Auth rate limiting (login, registration, password reset) is always active regardless of rate_limiting.enabled. The enabled flag only gates general API rate limiting.
rate_limiting: enabled: true backend: "auto" # auto, local, valkey auth: login_per_minute: 10 register_per_minute: 3 password_reset_per_hour: 5The general per-IP API request limit is no longer a config.yaml key. It is now
the runtime setting rate_limiting.api_requests_per_minute (default 600;
0 disables general API limiting) — see Runtime settings.
HTTP client (for business rules)
Section titled “HTTP client (for business rules)”Controls the fetch() function available in business rules.
http_client: enabled: false max_timeout: "10s" max_response_size: 1048576 # 1MB allow_private_ips: false # SSRF protection system_blocked_domains: [] follow_redirects: false max_redirects: 0Runtime settings
Section titled “Runtime settings”A number of values that used to be config.yaml keys are now runtime settings,
stored per-instance in the database and editable without a restart. They are read
through the settings registry and take effect immediately.
Each setting resolves in this precedence: an OIKAPI_FLAG_<KEY> environment
override (dots uppercased to underscores, e.g. security.registration.mode →
OIKAPI_FLAG_SECURITY_REGISTRATION_MODE) beats the stored value, which beats the
built-in default.
Manage them via the admin API (admin session required):
oi api /api/settings # list all settingsoi api /api/settings/security.registration.mode # read oneoi api PATCH /api/settings/security.registration.mode '{"value":"invite_only"}'Registration (security.registration.*)
| Key | Default | Notes |
|---|---|---|
security.registration.mode | open | open, disabled, domain_allowlist, invite_only |
security.registration.allowed_domains | [] | used when mode is domain_allowlist |
security.registration.require_email_verify | false |
Account lockout (security.lockout.*)
| Key | Default |
|---|---|
security.lockout.max_attempts | 5 |
security.lockout.window_minutes | 15 |
security.lockout.duration_minutes | 15 |
security.lockout.escalation_factor | 2.0 |
Token lifetimes (security.tokens.*)
| Key | Default | Notes |
|---|---|---|
security.tokens.password_reset_expiry_hours | 1 | whole hours |
security.tokens.email_verify_expiry_hours | 24 | whole hours |
API rate limiting
| Key | Default | Notes |
|---|---|---|
rate_limiting.api_requests_per_minute | 600 | per-IP general API limit; 0 disables |
(Auth rate limiting — login, registration, password reset — stays under
rate_limiting.auth in config.yaml and is always active.)
Environment variables
Section titled “Environment variables”Every config key can be set via environment variable with the OIKAPI_ prefix and underscores for nesting:
OIKAPI_SERVER_PORT=8080OIKAPI_SECURITY_SESSION_LIFETIME=168hOIKAPI_LOG_LEVEL=infoOIKAPI_DB_USER_PASSWORD=secret # OIKAPI_DB_USER_PASSWORD -> db.user.passwordArrays use comma-separated values:
OIKAPI_SERVER_ALLOWED_ORIGINS=https://a.example.com,https://b.example.com