Configuration

The FerrisKey API is configured entirely through command-line flags, each of which has a matching environment variable. Every setting has a default that works for local development, so you only override what your deployment needs.

Run ferriskey-api --help to see the flags and their long descriptions straight from the binary.

Environment variables

Admin

The admin account is created on first boot in the master realm.

VariableDefaultDescription
ADMIN_USERNAMEadminInitial admin username
ADMIN_PASSWORDadminInitial admin password
ADMIN_EMAILadmin@localInitial admin email

Database

VariableDefaultDescription
DATABASE_HOSTlocalhostPostgreSQL host
DATABASE_PORT5432PostgreSQL port
DATABASE_NAMEferriskeyDatabase name
DATABASE_USERferriskeyDatabase user
DATABASE_PASSWORDferriskeyDatabase password
DATABASE_SCHEMApublicDatabase schema

Server

VariableDefaultDescription
SERVER_HOST0.0.0.0Bind address
SERVER_PORT3333HTTP port
SERVER_ROOT_PATHemptyURL path prefix, for deployments behind a reverse proxy. A leading / is added if you omit it
SERVER_PUBLIC_URLunsetThe origin browsers and service providers reach this deployment at, as scheme://host[:port]
ALLOWED_ORIGINSemptyComma-separated browser origins allowed on every route
WEBAPP_URLhttp://localhost:5555URL of the admin console, used when building links
ENVdevelopmentDeprecated. Kept for compatibility and ignored by new code

ALLOWED_ORIGINS deserves a note of its own. Each entry must be a serialized origin (scheme://host[:port]), with no path and no wildcard. It applies to every route, including the ones that carry no realm: /config, the health probes, and the API documentation. Clients also declare their own web origins per realm, but those only cover realm-scoped routes, so a console served from a different origin than the API still needs its origin listed here.

SERVER_PUBLIC_URL and SAML

Leave SERVER_PUBLIC_URL unset and FerrisKey derives the public origin from each request’s Host header, which is the historical behaviour. SAML needs it set: the entity id is signed into every assertion, so it must not change when a request arrives through a different hostname.

TLS

Both variables are required together. Set neither to serve plain HTTP and terminate TLS at your proxy.

VariableDefaultDescription
SERVER_TLS_CERTunsetPath to the certificate file, in PEM format
SERVER_TLS_KEYunsetPath to the private key file, in PEM format

Logging

VariableDefaultDescription
LOG_FILTERinfoEnvFilter directives, for example info,ferriskey_core=debug
LOG_JSONfalseEmit structured JSON logs instead of human-readable lines

Observability

VariableDefaultDescription
ACTIVE_OBSERVABILITYfalseTurn on tracing and metrics export
OTLP_ENDPOINTunsetOTLP collector endpoint for traces
METRICS_ENDPOINTunsetCollector endpoint for metrics

Prometheus metrics are also exposed directly on /metrics, with no collector needed.

Generating the OpenAPI spec

The API binary carries a subcommand that prints its OpenAPI document without touching the database:

ferriskey-api gen-api --output openapi.json

Omit --output to write the spec to stdout.

Deployment examples

Docker Compose

services:
  api:
    environment:
      - DATABASE_HOST=db
      - DATABASE_PORT=5432
      - DATABASE_NAME=ferriskey
      - DATABASE_USER=ferriskey
      - DATABASE_PASSWORD=a-strong-password
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=a-strong-admin-password
      - ADMIN_EMAIL=admin@yourorg.com
      - ALLOWED_ORIGINS=https://iam.yourorg.com
      - WEBAPP_URL=https://iam.yourorg.com
      - LOG_FILTER=info

Bare metal

Set the variables directly, or drop a .env file next to the binary:

DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=ferriskey
DATABASE_USER=ferriskey
DATABASE_PASSWORD=a-strong-password
ADMIN_USERNAME=admin
ADMIN_PASSWORD=a-strong-admin-password
ADMIN_EMAIL=admin@yourorg.com
ALLOWED_ORIGINS=https://iam.yourorg.com
WEBAPP_URL=https://iam.yourorg.com
SERVER_PORT=3333
LOG_FILTER=info

Then run the server:

./ferriskey-api

SMTP configuration

Email delivery for magic links, password resets, and email verification is configured per realm, in the database, not through environment variables. Open the admin console, go to Realm Settings → Email, and fill in the host, port, sender address, credentials, and encryption mode.

No global SMTP

Every realm carries its own SMTP configuration and can point at a different mail provider. The Email & Templates guide has the full field reference and the API endpoints.