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 exampleproduction,development).--http-port: HTTP listen port (default8080).--host: bind address for the main HTTP server (default0.0.0.0).--metrics-port: port for the dedicated/metricslistener (default8081; must differ from--http-port). Health probes stay on the HTTP port.--metrics-host: bind address for that dedicated metrics listener only (default127.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.0and keep the metrics port on an internal network only (never on a public load balancer).--log-level: one ofdebug,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 whoseX-Forwarded-Forshould 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 tofalseto disable the built-in login UI.--enable-playground: set tofalseto disable the GraphQL playground.--enable-graphql-introspection: set tofalsein 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(defaultfalse): set totrueto disable TOTP (time-based one-time password) MFA enrollment and login.--disable-email-otp(defaultfalse): set totrueto disable email OTP enrollment. Email OTP is only available when SMTP is configured (see SMTP).--disable-sms-otp(defaultfalse): set totrueto disable SMS OTP enrollment. SMS OTP is only available when Twilio is configured (see Twilio).--enforce-mfa(defaultfalse): set totrueto make MFA mandatory — all users must enroll in at least one MFA method during signup and cannot skip it. Whenfalse, 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(default2592000, 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-secretis 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 (default30). Set to0to disable.--rate-limit-burst: maximum burst size per IP (default20).--rate-limit-fail-closed: whentrue, a failing rate-limit backend returns503instead of allowing the request (defaultfalse, 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: whentrue, the server ignoresX-Authorizer-Admin-Secretand only honors the secure admin cookie. Recommended for production.--enable-graphql-introspection: disable in locked-down environments.--graphql-max-complexity(default300): max total complexity score per operation.--graphql-max-depth(default15): max selection-set nesting depth.--graphql-max-aliases(default30): max aliased fields per operation (defends against alias amplification).--graphql-max-body-bytes(default1048576, 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 ofsqlite,postgres,mysql, ormemory. 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-storeis set to a database driver.--include-permissions-in-token(defaultfalse): 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(defaultfalse): audit-log everyCheckPermissioncall, 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(defaultfalse): emitStrict-Transport-Security. Only enable behind TLS — turning HSTS on without TLS will lock browsers out for a year.--disable-csp(defaultfalse): disable the defaultContent-Security-Policyheader. 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.