Skip to main content
Version: 2.x (Latest)

Server Configuration (v2)

Authorizer v2 uses CLI flags only for configuration. Nothing is loaded from .env files or dashboard-managed env, and config is not persisted in the database or cache.

If you are migrating from v1, first skim the high-level Migration v1 to v2 guide and then use this page as a reference.


1. Core flags

./authorizer \
--env=production \
--http-port=8080 \
--host=0.0.0.0 \
--metrics-port=8081 \
--metrics-host=127.0.0.1 \
--log-level=info
  • --env: environment name (for example production, development).
  • --http-port: HTTP listen port (default 8080).
  • --host: bind address for the main HTTP server (default 0.0.0.0).
  • --metrics-port: port for the dedicated /metrics listener (default 8081; must differ from --http-port). Health probes stay on the HTTP port.
  • --metrics-host: bind address for that dedicated metrics listener only (default 127.0.0.1). The main app can listen on all interfaces while metrics stay on loopback. For Docker/Kubernetes scraping from another container/pod, set --metrics-host=0.0.0.0 and keep the metrics port on an internal network only (never on a public load balancer).
  • --log-level: one of debug, info, warn, error, fatal, panic.

2. Database and session store

Database

./authorizer \
--database-type=postgres \
--database-url="postgres://user:pass@host/db" \
--database-name=authorizer \
--database-host=db-host \
--database-port=5432

Key flags:

  • --database-type: postgres, mysql, planetscale, sqlite, sqlserver, mongodb, arangodb, yugabyte, mariadb, cassandradb, scylladb, couchbase, dynamodb, etc.
  • --database-url: connection string.
  • Optional per-driver flags (name, host, port, TLS certs, etc.) -- see the mapping table in Migration v1 to v2.

Session / cache

./authorizer \
--redis-url=redis://user:pass@redis-host:6379/0
  • --redis-url: Redis connection string used for session storage. If omitted, sessions are stored in memory (suitable only for dev / single-node setups).

3. OAuth / app behavior

These flags replace v1 env such as CLIENT_ID, CLIENT_SECRET, and app behavior toggles.

./authorizer \
--client-id=YOUR_CLIENT_ID \
--client-secret=YOUR_CLIENT_SECRET \
--admin-secret=your-admin-secret \
--allowed-origins=https://your-app.com,http://localhost:3000 \
--default-authorize-response-type=code \
--default-authorize-response-mode=query
  • --client-id (required): instance/client identifier.
  • --client-secret (required): secret used for token-related operations.
  • --admin-secret (required, non-empty): super-admin secret for admin operations. Breaking change as of April 2026: there is no default any more — empty causes the server to exit at startup. Pick any non-empty value; the strength of the secret is your responsibility. See Security Hardening.
  • --allowed-origins: comma-separated list of allowed origins (default *). A startup warning is logged when the value contains * — set an explicit allowlist for production. See CORS, CSRF and origin enforcement.
  • --trusted-proxies (default empty): comma-separated CIDRs of reverse proxies whose X-Forwarded-For should be honoured. Breaking change as of April 2026: defaults to none — operators behind a proxy must set this explicitly or rate limiting and audit logs will key on the proxy IP. See Trusted proxies.

Organization / UI:

./authorizer \
--organization-name="Your Company" \
--organization-logo="https://your-cdn/logo.png" \
--enable-login-page=true \
--enable-playground=false \
--enable-graphql-introspection=false
  • --enable-login-page: set to false to disable the built-in login UI.
  • --enable-playground: set to false to disable the GraphQL playground.
  • --enable-graphql-introspection: set to false in hardened environments.

4. Auth behavior and cookies

Roles and auth flows

./authorizer \
--roles=user,admin \
--default-roles=user \
--protected-roles=admin \
--enable-strong-password=true \
--enable-basic-authentication=true \
--enable-email-verification=true \
--enable-magic-link-login=true \
--enable-signup=true

These replace v1 flags such as DISABLE_BASIC_AUTHENTICATION, DISABLE_EMAIL_VERIFICATION, etc. See the Auth behavior mapping for exact correspondences.

Multi-factor authentication (MFA)

./authorizer \
--disable-totp-login=false \
--disable-email-otp=false \
--disable-sms-otp=false \
--enforce-mfa=false

MFA is enabled by default in v2. The following flags allow you to disable specific methods:

  • --disable-totp-login (default false): set to true to disable TOTP (time-based one-time password) MFA enrollment and login.
  • --disable-email-otp (default false): set to true to disable email OTP enrollment. Email OTP is only available when SMTP is configured (see SMTP).
  • --disable-sms-otp (default false): set to true to disable SMS OTP enrollment. SMS OTP is only available when Twilio is configured (see Twilio).
  • --enforce-mfa (default false): set to true to make MFA mandatory — all users must enroll in at least one MFA method during signup and cannot skip it. When false, MFA enrollment is optional.

MFA is considered "available" when at least one method is enabled and its provider (SMTP for email, Twilio for SMS) is configured. The public meta query exposes which methods are available via is_totp_mfa_enabled, is_email_otp_mfa_enabled, and is_sms_otp_mfa_enabled fields, allowing the login UI to conditionally show MFA enrollment prompts.

Cookies

./authorizer \
--app-cookie-secure=true \
--admin-cookie-secure=true

Use true for HTTPS-only cookies in production.


5. JWT configuration

./authorizer \
--jwt-type=HS256 \
--jwt-secret=your-jwt-secret \
--jwt-role-claim=role

Or for asymmetric keys:

./authorizer \
--jwt-type=RS256 \
--jwt-private-key="$(cat /path/to/private.key)" \
--jwt-public-key="$(cat /path/to/public.key)"

Additional flags:

  • --custom-access-token-script: path/string for custom token augmentation logic (advanced use only).
  • --refresh-token-expires-in (default 2592000, 30 days): refresh-token lifetime in seconds. Previously hardcoded — now operator-configurable.

In v2, the _generate_jwt_keys mutation is deprecated and returns an error; configure keys only via flags.

Note on key rotation: --jwt-secret is also used to encrypt TOTP shared secrets at rest and to HMAC OTPs. Rotating it will lock out every user with an enrolled TOTP authenticator until they re-enrol. See OTP and TOTP at rest.


6. SMTP and SMS

SMTP

./authorizer \
--smtp-host=smtp.mailprovider.com \
--smtp-port=587 \
--smtp-username=user@example.com \
--smtp-password=strong-password \
--smtp-sender-email=auth@example.com \
--smtp-sender-name="Auth Team" \
--smtp-local-name=authorizer \
--smtp-skip-tls-verification=false

Twilio (SMS OTP)

./authorizer \
--twilio-account-sid=AC... \
--twilio-api-key=... \
--twilio-api-secret=... \
--twilio-sender=+123456789

7. Social / OAuth providers

Each provider uses its own set of flags:

./authorizer \
--google-client-id=... \
--google-client-secret=... \
--google-scopes="openid,email,profile" \
--github-client-id=... \
--github-client-secret=... \
--github-scopes="read:user,user:email"

Other supported providers follow the same pattern:

  • --facebook-client-id, --facebook-client-secret, --facebook-scopes
  • --microsoft-client-id, --microsoft-client-secret, --microsoft-tenant-id, --microsoft-scopes
  • --apple-client-id, --apple-client-secret, --apple-scopes
  • --linkedin-client-id, --linkedin-client-secret, --linkedin-scopes
  • --discord-client-id, --discord-client-secret, --discord-scopes
  • --twitter-client-id, --twitter-client-secret, --twitter-scopes
  • --twitch-client-id, --twitch-client-secret, --twitch-scopes
  • --roblox-client-id, --roblox-client-secret, --roblox-scopes

8. Rate limiting

./authorizer \
--rate-limit-rps=30 \
--rate-limit-burst=20 \
--rate-limit-fail-closed=false
  • --rate-limit-rps: maximum sustained requests per second per IP (default 30). Set to 0 to disable.
  • --rate-limit-burst: maximum burst size per IP (default 20).
  • --rate-limit-fail-closed: when true, a failing rate-limit backend returns 503 instead of allowing the request (default false, fail-open).

Rate limiting is always enabled by default. When --redis-url is set, limits are shared across replicas via Redis. See Rate Limiting for full details.


9. Admin and GraphQL security flags

New in v2:

./authorizer \
--disable-admin-header-auth=true \
--enable-graphql-introspection=false \
--graphql-max-complexity=300 \
--graphql-max-depth=15 \
--graphql-max-aliases=30 \
--graphql-max-body-bytes=1048576
  • --disable-admin-header-auth: when true, the server ignores X-Authorizer-Admin-Secret and only honors the secure admin cookie. Recommended for production.
  • --enable-graphql-introspection: disable in locked-down environments.
  • --graphql-max-complexity (default 300): max total complexity score per operation.
  • --graphql-max-depth (default 15): max selection-set nesting depth.
  • --graphql-max-aliases (default 30): max aliased fields per operation (defends against alias amplification).
  • --graphql-max-body-bytes (default 1048576, 1 MiB): max GraphQL request body size.

GET /graphql is no longer accepted — clients must POST. Rejections are counted in the authorizer_graphql_limit_rejections_total Prometheus metric, labelled by limit kind. See GraphQL hardening for details.

Authorization (FGA)

./authorizer \
--fga-store=postgres \
--fga-store-url="postgres://user:pass@host/db" \
--include-permissions-in-token=false \
--authorization-log-all-checks=false
  • --fga-store: backing store for the embedded OpenFGA engine — one of sqlite, postgres, mysql, or memory. Only needed when the main database is NoSQL (see paragraph below); for SQL main databases the engine reuses that database automatically.
  • --fga-store-url: connection string for the FGA store when --fga-store is set to a database driver.
  • --include-permissions-in-token (default false): when true, the access token's claims include the caller's flat (resource, scope) grant list. Useful for stateless downstream services that don't want to round-trip back to Authorizer per check.
  • --authorization-log-all-checks (default false): audit-log every CheckPermission call, not just denials. Diagnostic; expensive at scale.

Authorizer ships an embedded OpenFGA (ReBAC) engine. It is enabled by default when the main database is SQL-compatible (SQLite/Postgres/MySQL) and reuses that database. For NoSQL main databases (MongoDB, DynamoDB, …) it is off unless you set --fga-store (one of sqlite/postgres/mysql/memory) and --fga-store-url. Checks fail closed. See Authorization (FGA).


9. Security headers

./authorizer \
--enable-hsts=true \
--disable-csp=false
  • --enable-hsts (default false): emit Strict-Transport-Security. Only enable behind TLS — turning HSTS on without TLS will lock browsers out for a year.
  • --disable-csp (default false): disable the default Content-Security-Policy header. CSP is on by default.

The defaults are conservative and documented at Security response headers.


10. Full security reference

See the dedicated Security Hardening page for:

  • The complete list of security CLI flags introduced in April 2026
  • Trusted-proxy configuration for various deployment topologies
  • CSRF, CORS, OAuth flow, and webhook SSRF protections (all automatic)
  • OTP and TOTP at-rest hardening, including the rolling-deploy note for multi-replica clusters
  • Login error normalization and user-enumeration defences

11. Discovering all flags

To list all available flags and their defaults, run:

./authorizer --help

For a v1 to v2 mapping table, see Configuration Mapping.