Ory Kratos is configured using a YAML file, environment variables, or command-line flags. This guide covers the complete configuration structure.
Configuration file
Kratos looks for configuration in these locations (in order):
--config / -c flag: kratos serve -c /path/to/config.yml
$HOME/.kratos.yaml
$PWD/kratos.yaml
Basic configuration
Minimal production configuration:
version: v0.13.0
dsn: postgres://kratos:secret@postgres:5432/kratos?sslmode=require
serve:
public:
base_url: https://auth.example.com/
cors:
enabled: true
allowed_origins:
- https://example.com
admin:
base_url: https://admin.example.com/
selfservice:
default_browser_return_url: https://example.com/
allowed_return_urls:
- https://example.com
- https://app.example.com
flows:
login:
ui_url: https://example.com/auth/login
lifespan: 10m
registration:
ui_url: https://example.com/auth/register
lifespan: 10m
after:
default_browser_return_url: https://example.com/dashboard
recovery:
enabled: true
ui_url: https://example.com/auth/recovery
lifespan: 10m
verification:
enabled: true
ui_url: https://example.com/auth/verification
lifespan: 10m
settings:
ui_url: https://example.com/auth/settings
lifespan: 10m
privileged_session_max_age: 15m
identity:
default_schema_id: default
schemas:
- id: default
url: file:///etc/config/identity.schema.json
secrets:
cookie:
- your-32-character-secret-here
cipher:
- your-32-character-secret-here
cookies:
domain: example.com
path: /
same_site: Lax
Core configuration sections
Database (DSN)
Database connection string. See Database setup for details.dsn: postgres://user:password@host:5432/kratos?sslmode=require
Server configuration
Public API server configuration:serve:
public:
base_url: https://auth.example.com/
host: 0.0.0.0
port: 4433
cors:
enabled: true
allowed_origins:
- https://example.com
allowed_methods:
- POST
- GET
- PUT
- PATCH
- DELETE
allowed_headers:
- Authorization
- Content-Type
exposed_headers:
- Content-Type
allow_credentials: true
max_age: 300
Admin API server configuration:serve:
admin:
base_url: https://admin.example.com/
host: 0.0.0.0
port: 4434
# Typically no CORS needed for admin API
Self-service flows
selfservice:
flows:
login:
ui_url: https://example.com/auth/login
lifespan: 10m
after:
default_browser_return_url: https://example.com/dashboard
password:
hooks:
- hook: require_verified_address
- hook: revoke_active_sessions
selfservice.flows.registration
selfservice:
flows:
registration:
ui_url: https://example.com/auth/register
lifespan: 10m
after:
default_browser_return_url: https://example.com/welcome
password:
hooks:
- hook: session
- hook: show_verification_ui
selfservice.flows.recovery
selfservice:
flows:
recovery:
enabled: true
ui_url: https://example.com/auth/recovery
lifespan: 10m
use: code # or 'link'
notify_unknown_recipients: false
selfservice.flows.verification
selfservice:
flows:
verification:
enabled: true
ui_url: https://example.com/auth/verification
lifespan: 10m
use: code # or 'link'
notify_unknown_recipients: false
selfservice.flows.settings
selfservice:
flows:
settings:
ui_url: https://example.com/auth/settings
lifespan: 10m
privileged_session_max_age: 15m
required_aal: aal1 # or 'highest_available', 'aal2'
Authentication methods
selfservice.methods.password
selfservice:
methods:
password:
enabled: true
config:
haveibeenpwned_enabled: true
identifier_similarity_check_enabled: true
min_password_length: 8
max_breaches: 0
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: google
provider: google
client_id: your-client-id
client_secret: your-client-secret
mapper_url: file:///etc/config/oidc.google.jsonnet
scope:
- email
- profile
selfservice.methods.webauthn
selfservice:
methods:
webauthn:
enabled: true
config:
rp:
display_name: My Application
id: example.com
origins:
- https://example.com
- https://app.example.com
passwordless: true
selfservice:
methods:
totp:
enabled: true
config:
issuer: MyApp
Identity schemas
identity:
default_schema_id: default
schemas:
- id: default
url: file:///etc/config/identity.default.schema.json
- id: customer
url: file:///etc/config/identity.customer.schema.json
- id: employee
url: base64://eyJpZCI6Imh0dHA...
Sessions
session:
lifespan: 24h
earliest_possible_extend: 1h
whoami:
required_aal: aal1
cookie:
name: ory_session
persistent: true
same_site: Lax
Secrets
Secrets must be at least 32 characters long. Use cryptographically secure random strings.
secrets:
default:
- your-32-character-secret-here
- old-secret-for-rotation
cookie:
- your-32-character-cookie-secret
cipher:
- your-32-character-cipher-secret
Generate secure secrets:
Cookies
cookies:
domain: example.com
path: /
same_site: Lax # Strict, Lax, or None
secure: true
Hashers
hashers:
algorithm: bcrypt
bcrypt:
cost: 12
argon2:
memory: 131072
iterations: 3
parallelism: 4
salt_length: 16
key_length: 32
Courier (email/SMS)
courier:
smtp:
connection_uri: smtps://username:[email protected]:465/
from_address: [email protected]
from_name: My Application
templates:
recovery:
valid:
email:
subject: Recover access to your account
body:
plaintext: file:///etc/config/templates/recovery.plaintext.gotmpl
html: file:///etc/config/templates/recovery.html.gotmpl
courier:
delivery_strategy: http
http:
request_config:
url: https://api.example.com/send-email
method: POST
body: file:///etc/config/courier-body.jsonnet
headers:
Authorization: Bearer your-api-token
auth:
type: basic
config:
user: username
password: password
Logging
log:
level: info # trace, debug, info, warn, error, fatal, panic
format: json # json or text
leak_sensitive_values: false
Environment variables
All configuration options can be set via environment variables using uppercase and underscores:
# Database
export DSN="postgres://user:pass@host/db"
# Server
export SERVE_PUBLIC_BASE_URL="https://auth.example.com"
export SERVE_PUBLIC_PORT="4433"
export SERVE_ADMIN_BASE_URL="https://admin.example.com"
export SERVE_ADMIN_PORT="4434"
# Secrets
export SECRETS_COOKIE="your-32-character-secret"
export SECRETS_CIPHER="your-32-character-secret"
# Logging
export LOG_LEVEL="info"
export LOG_FORMAT="json"
Configuration validation
Validate your configuration:
kratos serve -c /path/to/config.yml --config-only
Next steps
Run migrations
Set up your database schema
Security best practices
Harden your deployment