This page covers configuration steps for ZITADEL deployments, including advanced settings for production environments.
ZITADEL supports multiple configuration methods:
The primary configuration file (config.yaml) supports the following sections:
# Database configuration
database:
postgres:
host: localhost
port: 5432
database: zitadel
user: zitadel
password: your_secure_password
ssl:
mode: require # Options: disable, require, verify-ca, verify-full
root_cert_file: /path/to/ca.crt
cert_file: /path/to/client.crt
key_file: /path/to/client.key
# External endpoint configuration
external:
issuer: https://your-domain.com
cors:
allowed_origins:
- https://your-domain.com
- https://console.your-domain.com
allowed_headers:
- Content-Type
- Authorization
allowed_methods:
- GET
- POST
- PUT
- DELETE
# Server configuration
http:
addr: 0.0.0.0:8080
tls:
mode: custom
cert_file: /path/to/server.crt
key_file: /path/to/server.key
grpc:
addr: 0.0.0.0:8081
tls:
mode: custom
cert_file: /path/to/grpc.crt
key_file: /path/to/grpc.key
# Keys and cryptography
keys:
crypto:
- algorithm: CHACHA20_POLY1305
key: "your-encryption-key-here"
primary: true
jwt:
- algorithm: RS256
key_file: /path/to/jwt-private.pem
public_key_file: /path/to/jwt-public.pem
primary: true
# Features
features:
unique_org_id: true
preview: false
experimental: false
sequential_verification: true
# Lockout configuration
lockout:
max_attempts: 5
find_automatically: true
# Login policy
login_policy:
allow_username_password: true
allow_register: true
allow_external_idps: true
force_mfa: false
force_session: false
hide_password_reset: false
passwordless_type: NOT_ALLOWED
multi_factor_gateway_type: SMTP
second_factors:
- OTP
multi_factors:
- OTP
# IDP configuration
idp_configs:
- idp_config_id: google-idp
name: Google
stategy_type: GOOGLE
oidc_config:
client_id: your-google-client-id
client_secret: your-google-client-secret
issuer: https://accounts.google.com
For containerized deployments, use environment variables prefixed with ZITADEL_:
# Database configuration
ZITADEL_DATABASE_POSTGRES_HOST=localhost
ZITADEL_DATABASE_POSTGRES_PORT=5432
ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel
ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=your_secure_password
# External configuration
ZITADEL_EXTERNAL_ISSUER=https://your-domain.com
ZITADEL_CORS_ALLOWEDORIGINS_0=https://your-domain.com
ZITADEL_CORS_ALLOWEDORIGINS_1=https://console.your-domain.com
# TLS configuration
ZITADEL_TLS_MODE=custom
ZITADEL_TLS_CERTIFICATE_FILE=/path/to/cert.pem
ZITADEL_TLS_KEY_FILE=/path/to/key.pem
# Cryptography keys
ZITADEL_KEYS_CRYPTOGRAPHY_0_KEY=your-encryption-key
ZITADEL_KEYS_CRYPTOGRAPHY_0_ALGORITHM=CHACHA20_POLY1305
ZITADEL_KEYS_CRYPTOGRAPHY_0_PRIMARY=true
Configure external identity providers for SSO:
idp_configs:
- idp_config_id: google-idp
name: Google
stategy_type: GOOGLE
is_oidc: true
oidc_config:
client_id: your-google-client-id
client_secret: your-google-client-secret
issuer: https://accounts.google.com
scopes:
- openid
- email
- profile
is_auto_creation: true
is_linking_allowed: true
is_creation_allowed: true
is_management: false
Configure authentication policies for different user types:
# Password complexity
password_complexity:
min_length: 12
has_lowercase: true
has_uppercase: true
has_number: true
has_symbol: true
# MFA policies
mfa_settings:
otp:
allowed: true
u2f:
allowed: true
is_verifiable: true
name: "Hardware Security Key"
Configure multi-tenant settings:
# Default organization settings
default_org:
name: "Default Organization"
primary_domain: "default-org.com"
is_init_user_required: true
init_user:
username: admin
first_name: Admin
last_name: User
email: admin@default-org.com
password: "SecurePassword123!"
Configure audit logging for compliance:
logging:
level: info
format: json
stacktrace: false
sampling:
enabled: true
initial: 100
thereafter: 100
# Custom domain configuration
domains:
primary: your-domain.com
is_generated: true
is_smtp_enforced: true
# Branding configuration
branding:
default_theme: DARK
primary_color: "#007acc"
secondary_color: "#005a9e"
warn_color: "#ffcc00"
font_color: "#ffffff"
background_color: "#000000"
# Rate limiting configuration
rate_limiting:
human_password_check:
burst: 5
rate: 1h
human_user_login:
burst: 10
rate: 1h
human_grpc_request:
burst: 100
rate: 1m
human_rest_request:
burst: 100
rate: 1m
Store configuration files in version control:
# Example directory structure
/etc/zitadel/
├── config.yaml
├── config.yaml.backup
├── keys/
│ ├── crypto.key
│ └── jwt-keys/
├── tls/
│ ├── server.crt
│ └── server.key
└── secrets/
└── database-password.txt
Use external secret management systems:
# Using HashiCorp Vault
export ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=$(vault kv get -field=password database/zitadel)
# Using Kubernetes secrets
kubectl create secret generic zitadel-config \
--from-literal=masterkey=your-master-key \
--from-literal=db-password=your-db-password
Validate configuration before applying:
# Test configuration syntax
zitadel check-config --config /etc/zitadel/config.yaml
# Dry-run initialization
zitadel database setup --config /etc/zitadel/config.yaml --dry-run
sudo systemctl restart zitadel
docker compose down
docker compose up -d
After configuration changes:
Check service status:
# For systemd
sudo systemctl status zitadel
# For Docker
docker compose ps
Verify API accessibility:
curl -I https://your-domain.com/healthz
Test authentication flows through the UI
Review logs for any configuration-related errors
Running ZITADEL in regulated environments? We assist with:
Secure your deployment: office@linux-server-admin.com | Contact Page