Skip to main content
Version: Next

Full Configuration Example

This page mirrors the current config-v2 reference structure.

For the canonical defaults from a running binary, use:

nauthilus -d

For only the changed values of a concrete file, use:

nauthilus -n --config /etc/nauthilus/nauthilus.yml

Current Reference Example

# Built-in placeholders are expanded in string values after includes and patches.
# NAUTHILUS_CONF_DIR defaults to /etc/nauthilus.
# NAUTHILUS_PLUGINS_DIR defaults to the packaged Lua plugin root.
runtime:
instance_name: "nauthilus"

process:
run_as_user: "nauthilus"
run_as_group: "nauthilus"
chroot: "/var/empty"

servers:
http:
address: "0.0.0.0:8080"
http3: false
haproxy_v2: false
trusted_proxies:
- "127.0.0.1"
- "::1"

tls:
enabled: false
skip_verify: false
min_tls_version: "TLS1.2"
cert: ""
key: ""
ca_file: ""

disabled_endpoints: {}

openapi_validation:
enabled: false
enforce: false
operations: []

middlewares:
logging: true
limit: true
recovery: true
trusted_proxies: true
request_decompression: true
response_compression: true
metrics: true
rate: true

compression:
enabled: false

keep_alive:
enabled: true
timeout: 30s
max_idle_connections: 100
max_idle_connections_per_host: 10

rate_limit:
per_second: 0
burst: 0

grpc:
authority:
enabled: false
address: "127.0.0.1:9444"

tls:
enabled: false
cert: ""
key: ""
client_ca: ""
min_tls_version: "TLS1.2"
require_client_cert: false

timeouts:
redis_read: 1s
redis_write: 2s
ldap_search: 3s
ldap_bind: 3s
ldap_modify: 5s
lua_backend: 5s
lua_script: 30s

clients:
http:
max_connections_per_host: 0
max_idle_connections: 0
max_idle_connections_per_host: 0
idle_connection_timeout: 0s
proxy: ""

tls:
skip_verify: false
min_tls_version: "TLS1.2"
cert: ""
key: ""
ca_file: ""
cipher_suites: []

dns:
resolver: ""
timeout: 5s
resolve_client_ip: false

grpc:
nauthilus_authorities:
primary:
address: "authority.internal.example:9444"
timeout: 5s
edge_cluster_id: "dmz-edge"
edge_instance_id: "edge-a"
split_strict_mode: true

tls:
enabled: true
server_name: "authority.internal.example"
ca: "${NAUTHILUS_CONF_DIR}/tls/authority-ca.pem"
cert: "${NAUTHILUS_CONF_DIR}/tls/edge-a.crt"
key: "${NAUTHILUS_CONF_DIR}/tls/edge-a.key"
min_tls_version: "TLS1.3"

caller_auth:
basic_auth:
enabled: false
username: ""
password: ""

oidc_bearer:
enabled: true
mode: "client_credentials"
token_endpoint: "https://authority.internal.example/oidc/token"
client_id: "edge-primary"
client_secret: ""
token_endpoint_auth_method: "private_key_jwt"
client_private_key_file: "${NAUTHILUS_CONF_DIR}/keys/edge-primary.key"
client_key_id: "edge-primary-rs256"
client_assertion_alg: "RS256"
audience: "https://authority.internal.example/oidc/token"
scopes:
- "nauthilus:authenticate"
- "nauthilus:lookup_identity"
- "nauthilus:list_accounts"
- "nauthilus:mfa_read"
- "nauthilus:mfa_verify"
- "nauthilus:mfa_write"
- "nauthilus:webauthn_read"
- "nauthilus:webauthn_write"
- "nauthilus:attribute_read"
static_token_file: ""
static_token_emergency_mode: false

token_cache:
backend: "redis"
key_prefix: "grpc:authority_tokens:"
refresh_before_expiry: 30s
refresh_lock_ttl: 10s

observability:
log:
json: false
color: true
level: "info"
add_source: false
debug_modules: []

profiles:
pprof:
enabled: false
block:
enabled: false

tracing:
enabled: false
exporter: "none"
endpoint: ""
sampler_ratio: 0.1
service_name: "nauthilus"
propagators:
- "tracecontext"
- "baggage"
enable_redis: false
log_export_results: false

tls:
enabled: false
skip_verify: false
min_tls_version: "TLS1.2"
cert: ""
key: ""
ca_file: ""

metrics:
monitor_connections: false

prometheus_timer:
enabled: false
labels: []

endpoint_auth:
basic:
enabled: false
username: ""
password: ""

storage:
redis:
protocol: 2
database_number: 0
prefix: "nt:"
password_nonce: ""
encryption_secret: ""
pool_size: 128
idle_pool_size: 32
positive_cache_ttl: 1h
negative_cache_ttl: 2h

primary:
address: "127.0.0.1:6379"
username: ""
password: ""

replica:
address: ""
addresses: []

sentinels:
master: ""
addresses: []
username: ""
password: ""

cluster:
addresses: []
username: ""
password: ""
route_by_latency: false
route_randomly: false
route_reads_to_replicas: false
max_redirects: 0

tls:
enabled: false
skip_verify: false
min_tls_version: "TLS1.2"
cert: ""
key: ""
ca_file: ""

pool_timeout: 1s
dial_timeout: 5s
read_timeout: 1s
write_timeout: 1s
pool_fifo: true
conn_max_idle_time: 90s
max_retries: 1
identity_enabled: false
maint_notifications_enabled: false

account_local_cache:
enabled: false
ttl: 1m
shards: 32
cleanup_interval: 5m
max_items: 10000

batching:
enabled: false
max_batch_size: 16
max_wait: 2ms
queue_capacity: 8192
skip_commands: []
pipeline_timeout: 5s

client_tracking:
enabled: false
bcast: false
noloop: false
opt_in: false
opt_out: false
prefixes: []

auth:
request:
headers:
username: "Auth-User"
password: "Auth-Pass"
password_encoded: "X-Auth-Password-Encoded"
protocol: "Auth-Protocol"
login_attempt: "Auth-Login-Attempt"
auth_method: "Auth-Method"
local_ip: "X-Local-IP"
local_port: "X-Auth-Port"
client_ip: "Client-IP"
client_port: "X-Client-Port"
client_host: ""
client_id: "X-Client-ID"
oidc_cid: "X-OIDC-CID"
ssl: "X-SSL"
ssl_session_id: "X-SSL-Session-ID"
ssl_verify: "X-SSL-Client-Verify"
ssl_subject: "X-SSL-Client-DN"
ssl_client_cn: "X-SSL-Client-CN"
ssl_issuer: "X-SSL-Issuer"
ssl_client_not_before: "X-SSL-Client-NotBefore"
ssl_client_not_after: "X-SSL-Client-NotAfter"
ssl_subject_dn: "X-SSL-Subject-DN"
ssl_issuer_dn: "X-SSL-Issuer-DN"
ssl_client_subject_dn: "X-SSL-Client-Subject-DN"
ssl_client_issuer_dn: "X-SSL-Client-Issuer-DN"
ssl_cipher: "X-SSL-Cipher"
ssl_protocol: "X-SSL-Protocol"
ssl_serial: "Auth-SSL-Serial"
ssl_fingerprint: "Auth-SSL-Fingerprint"

backchannel:
basic_auth:
enabled: false
username: ""
password: ""

oidc_bearer:
enabled: false

pipeline:
max_concurrent_requests: 100
max_login_attempts: 15
wait_delay: 0
local_cache_ttl: 30s

password_history:
max_entries: 1000

master_user:
enabled: false
user_format: "{user}*{master_user}"

upstreams:
imap:
address: "127.0.0.1"
port: 143
pop3:
address: "127.0.0.1"
port: 110
smtp:
address: "127.0.0.1"
port: 25

backends:
order:
- "cache"
- "ldap"

ldap:
default:
lookup_pool_only: false
number_of_workers: 16
lookup_pool_size: 16
lookup_idle_pool_size: 4
auth_pool_size: 16
auth_idle_pool_size: 4
server_uri:
- "ldapi:///"

pools: {}
search: []

lua:
backend:
default:
package_path: "${NAUTHILUS_PLUGINS_DIR}/share/?.lua;${NAUTHILUS_CONF_DIR}/lua/?.lua"
named_backends: {}
search: []

remote:
default:
authority: "primary"
mode: "nauthilus"
timeout: 5s
allowed_operations:
- "auth"
- "lookup_identity"
- "list_accounts"
- "mfa_read"
- "mfa_verify"
- "mfa_write"
- "webauthn_read"
- "webauthn_write"
- "attribute_read"

controls:
enabled: []

tls_encryption:
allow_cleartext_networks: []

rbl:
threshold: 0
lists: []
ip_allowlist: []

relay_domains:
static: []
allowlist: {}

brute_force:
protocols: []
ip_allowlist: []
buckets: []
learning: []
custom_tolerations: []

ip_scoping:
rwp_ipv6_cidr: 128
tolerations_ipv6_cidr: 128

tolerate_ttl: 30m
rwp_window: 15m
rwp_allowed_unique_hashes: 3
tolerate_percent: 0
min_tolerate_percent: 10
max_tolerate_percent: 50
scale_factor: 1.0
adaptive_toleration: false
pw_history_for_known_accounts: false

lua:
hooks: []

services:
enabled:
- "backend_health_checks"

backend_health_checks:
connect_timeout: 5s
tls_timeout: 5s
deep_timeout: 5s
connect_interval: 10s
deep_interval: 10s
failure_threshold: 1
recovery_threshold: 1
targets:
- protocol: "imap"
host: "imap.internal.example"
port: 993
deep_check: true
test_username: "healthcheck@example.org"
test_password: "change-me"
auth_mechanism: "auto"
tls: true
tls_skip_verify: false
haproxy_v2: false

- protocol: "smtp"
host: "smtp.internal.example"
port: 465
deep_check: true
test_username: "healthcheck@example.org"
test_password: "change-me"
auth_mechanism: "PLAIN"
tls: true
tls_skip_verify: false
haproxy_v2: false

- protocol: "http"
host: "auth-api.internal.example"
port: 443
request_uri: "/health"
deep_check: true
test_username: "healthcheck"
test_password: "change-me"
auth_mechanism: "BASIC"
tls: true
tls_skip_verify: false
haproxy_v2: false

policy:
mode: "enforce"
default_policy: "standard_auth"
registry_scripts: []
attribute_exports: []
request_headers: []
request_metadata: []

attribute_sources:
lua:
environment: []
subject: []

obligation_targets:
lua:
actions: []

sets:
networks: {}
time_windows: {}

scheduler_guards: {}

report:
enabled: false
include_fsm: true
include_checks: true
include_attributes: false

checks: []
policies: []

identity:
session:
remember_me_ttl: 0s

frontend:
enabled: false
encryption_secret: ""

assets:
html_static_content_path: ""
language_resources: ""

localization:
languages: []
default_language: "en"

links:
terms_of_service_url: ""
privacy_policy_url: ""
password_forgotten_url: ""

security_headers:
enabled: true

mfa:
totp:
issuer: "Nauthilus"
skew: 1

webauthn:
rp_display_name: "Nauthilus"
rp_id: "localhost"
rp_origins:
- "https://localhost"
authenticator_attachment: ""
resident_key: "discouraged"
user_verification: "preferred"

oidc:
enabled: false
issuer: ""
signing_keys: []
clients: []
custom_scopes: []
scopes_supported: []
response_types_supported: []
subject_types_supported: []
id_token_signing_alg_values_supported: []
token_endpoint_auth_methods_supported: []
code_challenge_methods_supported: []
claims_supported: []
access_token_type: "jwt"

consent:
ttl: 0s
mode: "all_or_nothing"

tokens:
default_access_token_lifetime: 1h
default_refresh_token_lifetime: 720h
revoke_refresh_token: true
token_endpoint_allow_get: false

logout:
front_channel_supported: true
front_channel_session_supported: false
back_channel_supported: true
back_channel_session_supported: false

device_flow:
code_expiry: 10m
polling_interval: 5
user_code_length: 8

saml:
enabled: false
entity_id: ""
cert: ""
cert_file: ""
key: ""
key_file: ""
signature_method: ""
default_expire_time: 1h
name_id_format: ""
service_providers: []

slo:
enabled: true
front_channel_enabled: true
back_channel_enabled: false
request_timeout: 3s
max_participants: 64
back_channel_max_retries: 1

Split Edge/Authority Profiles

The reference example above shows both the authority-side listener keys and the edge-side remote backend keys. In a real split deployment, use separate configuration files and separate Redis instances.

An authority instance owns local backend credentials, persistent identity data, MFA/WebAuthn data, backend-reference handles, and authority-side token/cache state:

runtime:
instance_name: "nauthilus-authority"

servers:
grpc:
authority:
enabled: true
address: "0.0.0.0:9444"

tls:
enabled: true
cert: "${NAUTHILUS_CONF_DIR}/tls/authority.crt"
key: "${NAUTHILUS_CONF_DIR}/tls/authority.key"
client_ca: "${NAUTHILUS_CONF_DIR}/tls/edge-client-ca.pem"
min_tls_version: "TLS1.3"
require_client_cert: true

storage:
redis:
primary:
address: "authority-redis.internal:6379"

auth:
backchannel:
oidc_bearer:
enabled: true

backends:
order:
- "ldap"
ldap:
default:
server_uri:
- "ldaps://ldap.internal.example:636"

An edge instance owns public IdP endpoints, browser sessions, OIDC/SAML flow state, and the cached caller token used for authority RPCs. A strict remote-only edge uses only the remote backend and does not configure LDAP or Lua backend credentials:

runtime:
instance_name: "nauthilus-edge-a"

clients:
grpc:
nauthilus_authorities:
primary:
address: "authority.internal.example:9444"
timeout: 5s
edge_cluster_id: "dmz-edge"
edge_instance_id: "edge-a"
split_strict_mode: true
tls:
enabled: true
server_name: "authority.internal.example"
ca: "${NAUTHILUS_CONF_DIR}/tls/authority-ca.pem"
cert: "${NAUTHILUS_CONF_DIR}/tls/edge-a.crt"
key: "${NAUTHILUS_CONF_DIR}/tls/edge-a.key"
min_tls_version: "TLS1.3"
caller_auth:
oidc_bearer:
enabled: true
mode: "client_credentials"
token_endpoint: "https://authority.internal.example/oidc/token"
client_id: "edge-primary"
token_endpoint_auth_method: "private_key_jwt"
client_private_key_file: "${NAUTHILUS_CONF_DIR}/keys/edge-primary.key"
client_key_id: "edge-primary-rs256"
client_assertion_alg: "RS256"
audience: "https://authority.internal.example/oidc/token"
scopes:
- "nauthilus:authenticate"
- "nauthilus:lookup_identity"
- "nauthilus:list_accounts"
- "nauthilus:mfa_read"
- "nauthilus:mfa_verify"
- "nauthilus:mfa_write"
- "nauthilus:webauthn_read"
- "nauthilus:webauthn_write"
- "nauthilus:attribute_read"
token_cache:
backend: "redis"
key_prefix: "grpc:authority_tokens:"
refresh_before_expiry: 30s
refresh_lock_ttl: 10s

storage:
redis:
primary:
address: "edge-redis.internal:6379"

auth:
backends:
order:
- "remote"
remote:
default:
authority: "primary"
mode: "nauthilus"
timeout: 5s
allowed_operations:
- "auth"
- "lookup_identity"
- "list_accounts"
- "mfa_read"
- "mfa_verify"
- "mfa_write"
- "webauthn_read"
- "webauthn_write"
- "attribute_read"

Keep these boundaries intact:

  • the edge Redis address is different from the authority Redis address;
  • the edge token cache under caller_auth.oidc_bearer.token_cache uses edge Redis;
  • the authority stores backend references, idempotency outcomes, backend cache, MFA data, and WebAuthn data in authority-owned state;
  • the edge must not connect to authority Redis directly;
  • the authority must not connect to edge Redis directly;
  • the edge must not carry LDAP bind credentials or Lua backend secrets unless it is intentionally configured as a local fallback edge.

For a step-by-step build guide, see Distributed Identity Proxy.