Configuration Reference
Complete reference for all configuration directives, auto-generated from the Hexon Gateway source code. Each section corresponds to a TOML section in /etc/hexon/.
Precedence (highest to lowest): Environment variables (HEXON_*) > GitOps repository > TOML files > Built-in defaults.
Hot-reload: Most sections reload within 1 second of file changes — no restart needed.
Core Service
TOML: [service] · Env: HEXON_SERVICE_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
hostname | string | — | Public hostname for the gateway Sets OIDC issuer URL and ACME CA external URL. Changing post-deployment invalidates existing OIDC tokens Required. |
port | int | 443 | HTTPS port to listen on Ports below 1024 require elevated privileges or CAP_NET_BIND_SERVICE Range: 1–65535. |
public_port | int | none | Public-facing port for URL generation when behind NAT/LB Set when behind a load balancer on a different port than service.port |
auto_tls | bool | false | Issue wildcard TLS cert from internal ACME CA Uses internal ACME CA; must not be used together with acme_client. Wildcard covers *.hostname Requires hostname. |
auto_tls_renewal | duration | 720h | AutoTLS renewal cycle Must be less than auto_tls_validity; overlap enforced at 20-80% of validity Requires auto_tls=true. |
auto_tls_validity | duration | 1440h | AutoTLS certificate validity Must be greater than auto_tls_renewal; default 1440h = 60 days Requires auto_tls=true. |
network_interface | string | eth0 | Network interface to bind to Default for cluster.cluster_interface, health.interface, and bastion.network_interface when not set explicitly |
releases_url | string | https://downloads.hexon.io/releases | Base URL for release artifacts and version manifest |
enable_portal | bool (optional) | true | Enable unified portal SPA at /profile |
admin_socket | bool (optional) | true | Enable Unix socket for local admin CLI access Allows ‘hexon admin <command>’ on the server host without bastion |
admin_socket_path | string | /tmp/hexon-admin.sock | Unix socket path for admin CLI Override with HEXON_ADMIN_SOCK env var on the client side |
read_timeout | duration | 30s | HTTP read timeout WebSocket and streaming responses may require longer values |
write_timeout | duration | 30s | HTTP write timeout Applies to entire response delivery; set higher for large file downloads or streaming |
idle_timeout | duration | 120s | HTTP idle connection timeout |
max_header_bytes | string | 64KB | Maximum HTTP request header size |
graceful_shutdown_timeout | duration | 30s | Total time to wait for graceful shutdown Max: 10m. |
listener_drain_timeout | duration | 10s | Max time for listener connection draining during shutdown Max: 10m. |
background_task_timeout | duration | 5s | Max time for background goroutines to stop during shutdown Max: 10m. |
http2_enable | bool | true | Enable HTTP/2 support When false, JA4H fingerprinting and HTTP/2 server push are also disabled |
http2_maxstreams | int | 1000 | Max concurrent HTTP/2 streams per connection Max: 1000000. |
http2_maxframesize | int | 1048576 | Max HTTP/2 frame size in bytes Max: 16777216. |
http2_idletimeout | duration | 120s | HTTP/2 idle timeout |
http2_keepalive | bool | true | Enable HTTP/2 keepalive pings |
http2_keepalive_interval | duration | 30s | HTTP/2 keepalive ping interval |
http2_push_enabled | bool | true | Enable HTTP/2 server push Only effective when http2_enable is true |
http2_push_max_resources | int | 8 | Max resources to push per HTTP/2 request |
http2_push_timeout | duration | 100ms | HTTP/2 push operation timeout |
http2_push_cache_enabled | bool | true | Enable push cache to avoid redundant HTTP/2 pushes |
http2_push_cache_ttl | duration | 1h | HTTP/2 push cache TTL |
http2_push_only_secure | bool | true | Only push resources over secure connections |
http3_enable | bool | false | Enable HTTP/3 over QUIC alongside HTTP/2 Requires UDP port open on firewall. Activates QUIC affinity and 0-RTT replay tracking |
http3_idle_timeout | duration | 30s | QUIC idle timeout |
http3_max_streams | duration | 100 | Max bidirectional QUIC streams per connection Range: 0–1000000. |
http3_max_uni_streams | duration | 100 | Max unidirectional QUIC streams per connection Range: 0–1000000. |
http3_allow_0rtt | bool | true | Allow 0-RTT early data with replay protection |
http3_altsvc_max_age | duration | 24h | Alt-Svc header max-age |
http3_0rtt_token_ttl | duration | 2m | HTTP/3 0-RTT replay protection token TTL |
quic_affinity_enabled | bool | false | Enable QUIC affinity routing via UDP fingerprint Routes QUIC connections to the same cluster node based on connection ID |
quic_cid_mapping_limit | int | 100000 | Max tracked QUIC connection IDs |
quic_affinity_idle_timeout | duration | 5m | Idle timeout for QUIC CID mappings |
quic_migration_max_per_conn | int | 10 | Max QUIC migrations per connection before rejection Range: 0–100. |
quic_migration_cooldown | duration | 1s | Minimum time between QUIC migrations |
quic_migration_ttl | duration | 30m | Idle QUIC connection tracking timeout |
quic_migration_cleanup | duration | 5m | QUIC expired connection cleanup interval |
quic_0rtt_token_ttl | duration | 2m | QUIC 0-RTT token validity duration |
quic_0rtt_bind_to_ip | bool | true | Require IP match for QUIC 0-RTT token use |
quic_0rtt_max_tokens | int | 100000 | Maximum QUIC 0-RTT tokens to track per node Range: 0–10000000. |
quic_0rtt_cleanup | duration | 1m | QUIC 0-RTT token cleanup interval |
handshake_timeout | duration | 10s | TLS handshake timeout |
block_malformed_tls | bool | false | Block malformed TLS connections Rejects TLS connections with invalid ClientHello; may block legacy clients |
tls_min_version | string | 1.3 | Minimum TLS version for inbound connections Values: 1.2, 1.3. |
tls_max_version | string | — | Maximum TLS version for inbound connections Defaults to latest supported version if not set Values: 1.2, 1.3. |
tls_session_tickets | bool | false | Enable TLS session tickets Disabled by default for forward secrecy |
tls_renegotiation | bool | false | Allow TLS renegotiation Disabled by default for security |
tls_prefer_server_ciphers | bool | true | Server prefers its own cipher suite order |
tls_strict_cipher_suites | bool | true | Use only AEAD ciphers with forward secrecy |
outbound_tls_min_version | string | 1.3 | Minimum TLS version for outbound connections to backends Does not affect internal cluster (hexdcall) which always uses TLS 1.3 Values: 1.2, 1.3. |
pqc | bool (optional) | true | Enable hybrid post-quantum key exchange ML-KEM-768 + X25519 for service TLS RFC FIPS203. |
ech | bool (optional) | false | Enable Encrypted Client Hello — hides proxied app SNI behind service hostname All proxied apps appear as traffic to the service hostname. Requires DNS HTTPS record with ECH config for full client support Requires hostname. |
mtls_mode | string | none | Client certificate requirement level With proxy=true and mandatory mode, proxy_header_clientcert is required Values: none, optional, mandatory. |
x509_auto_auth | bool (optional) | true | Auto-authenticate clients presenting a valid TLS client certificate |
fingerprinting_enabled | bool | false | Enable composite client fingerprinting (TLS+HTTP/2+TCP) Enables JA4 TLS fingerprint extraction; used for affinity routing and security analytics |
fingerprint_max_entries | int | 10000 | Maximum fingerprint entries in cache |
fingerprint_ttl | duration | 5m | Base TTL for fingerprint cache entries |
fingerprint_cleanup | duration | 30s | Fingerprint cache cleanup interval |
quic_fingerprint_reassembly_max_packets | int | 10 | Max packets for QUIC ClientHello reassembly |
quic_fingerprint_reassembly_max_bytes | string | 15KB | Max bytes for QUIC reassembly buffer |
quic_fingerprint_reassembly_timeout | duration | 5s | QUIC reassembly state timeout |
ja4_format | string | composite | JA4 fingerprint format: composite (internal optimized) or canonical (FoxIO JA4 standard) canonical enables interop with Wireshark, Zeek, and threat intel feeds |
ja4_max_extensions | int | 200 | Max TLS extensions to parse for JA4 fingerprinting Typical clients send 10-30 extensions |
ja4_max_sigalgs | int | 100 | Max signature algorithms to parse for JA4 fingerprinting Typical clients send 10-20 signature algorithms |
http2_fingerprint_cache_size | int | 10000 | Max entries in HTTP/2 fingerprint cache |
http2_fingerprint_cache_evict_pct | int | 10 | Percentage of oldest entries to evict when HTTP/2 fingerprint cache is full |
fingerprint_max_entries_per_ip | int | 10 | Max fingerprint entries per client IP for anti-abuse |
quic_max_crypto_frame_offset | string | 64KB | Max QUIC CRYPTO frame offset for DoS protection |
proxy | bool | false | Enable proxy mode when behind a reverse proxy, load balancer, or CDN Requires proxy_header_clientip and proxy_cidr when enabled |
proxy_cidr | []string | — | Trusted proxy IP ranges for header trust Required when proxy=true; prevents header spoofing Requires proxy=true. |
hexon_edge_protocol | bool | false | Enable Hexon Edge Protocol for edge-to-gateway communication Set true when edge.enabled in Helm; parses HXEP header for real client IP |
hexon_edge_cidr | []string | — | Trusted CIDRs for Hexon Edge Protocol header parsing Defaults to trust-all (0.0.0.0/0, ::/0); set to pod network CIDR in production |
proxy_header_clientip | string | — | HTTP header containing real client IP from proxy Required when proxy=true Requires proxy=true. |
proxy_header_clientcert | string | — | HTTP header containing client certificate from proxy for mTLS passthrough |
proxy_header_clientfingerprint | string | — | HTTP header containing client fingerprint from proxy, replaces JA4 |
proxy_header_traceid | string | — | HTTP header containing trace ID from proxy for distributed tracing |
preserve_client_port | bool | true | Use client connection port in redirects for NAT/LB port mapping |
correlation_id_header | string | X-Hexon-ID | HTTP header name for request correlation ID |
disable_server_header | bool | false | Disable the Server response header |
security_headers_enabled | bool | true | Enable security response headers |
x_frame_options | string | DENY | X-Frame-Options header value Also supports ALLOW-FROM uri Values: DENY, SAMEORIGIN. |
x_content_type_options | string | nosniff | X-Content-Type-Options header value |
x_xss_protection | string | 1; mode=block | X-XSS-Protection header value Values: 0, 1, 1; mode=block. |
content_security_policy | string | — | Content-Security-Policy header value Empty means no CSP header; max 8192 characters |
e2oe | bool | false | Enable End-to-Origin Encryption (requires PoW) |
e2oe_strict | bool | false | No degradation — reject all requests without E2OE channel Requires e2oe=true. |
e2oe_tier1_pre_provision | bool (optional) | true | Enable PRF-wrapped per-origin Tier 1 pre-provisioning at auth time Requires e2oe=true. |
e2oe_tier1_pre_provision_max_hosts | int | 256 | Maximum accessible hosts to pre-provision per session Requires e2oe_tier1_pre_provision=true. |
e2oe_tier1_relay_origin | string | — | Origin where the wrap-relay endpoint is served. Defaults to service.hostname (with PublicPort/Port handling). Set explicitly only when the auth host differs from the gateway hostname. |
e2oe_tier1_per_ip_rate_limit_enabled | bool | true | Enable per-IP rate limits on Tier 1 endpoints (in addition to per-session) Requires e2oe_tier1_pre_provision=true. |
e2oe_tier1_relay_rate_limit | string | 60/1m | Per-session rate limit on /_hexon/e2oe/wrap-relay Requires e2oe_tier1_pre_provision=true. |
e2oe_tier1_upload_rate_limit | string | 5/1m | Per-session rate limit on /_hexon/e2oe/tier1/wrap-upload Requires e2oe_tier1_pre_provision=true. |
e2oe_tier1_state_rate_limit | string | 60/1m | Per-session rate limit on /_hexon/e2oe/tier1/wrap-state Requires e2oe_tier1_pre_provision=true. |
e2oe_tier1_relay_ip_rate_limit | string | 300/1m | Per-IP rate limit on /_hexon/e2oe/wrap-relay (when per_ip_rate_limit_enabled) Requires e2oe_tier1_per_ip_rate_limit_enabled=true. |
e2oe_tier1_upload_ip_rate_limit | string | 30/1m | Per-IP rate limit on /_hexon/e2oe/tier1/wrap-upload (when per_ip_rate_limit_enabled) Requires e2oe_tier1_per_ip_rate_limit_enabled=true. |
e2oe_tier1_state_ip_rate_limit | string | 300/1m | Per-IP rate limit on /_hexon/e2oe/tier1/wrap-state (when per_ip_rate_limit_enabled) Requires e2oe_tier1_per_ip_rate_limit_enabled=true. |
compression_enabled | bool | true | Enable response compression |
compression_level | string | balanced | Response compression level Values: none, fast, balanced, best. |
compression_zstd | bool (optional) | true | Enable Zstandard compression (fastest, Chrome 123+/Firefox 126+/Safari 18+) |
compression_brotli | bool (optional) | true | Enable Brotli compression (best ratio, widely supported) |
compression_gzip | bool (optional) | true | Enable gzip compression (universal fallback) |
config_hot_reload_enabled | bool | true | Enable automatic config hot-reload on file changes |
config_file_watching_enabled | bool | true | Enable file system monitoring for config changes |
config_cache_enabled | bool | true | Enable config section caching for faster access |
config_cache_max_entries | int | 100 | Maximum config cache entries Range: 0–10000. |
config_callback_throttle_ms | int | 100 | Config change callback throttle window in milliseconds Range: 0–10000. |
config_poll_interval_ms | int | 1000 | Config file polling interval in milliseconds Range: 100–60000. |
config_diff_history_enabled | bool | true | Store config change history in a ring buffer |
config_diff_history_size | int | 10 | Maximum config diff entries to retain Range: 1–100. Requires config_diff_history_enabled=true. |
inline_assets | bool | true | Embed CSS/JS directly in HTML responses Set false for external asset serving via CDN |
hide_status | bool (optional) | true | Hide HTTP status codes in user-facing message pages |
default_language | string | en | Default UI language code |
detect_browser_language | bool (optional) | true | Auto-detect language from browser Accept-Language header |
disclaimer | string | By logging in, you agree to acceptable use policy and monitoring terms. | Footer disclaimer text for emails and forms |
cookie_notice | bool (optional) | true | Show informational cookie notice banner Informational only — all cookies are essential and exempt from consent |
privacy_policy_url | string | — | Privacy policy URL linked from cookie notice Shows ‘More info’ link when set |
cookie_name | string | hexon | Default cookie name for sessions |
cookie_domain | string | — | Cookie domain for cross-subdomain session sharing Empty means current hostname only |
cookie_ttl | duration | 12h | Default session cookie TTL |
session_ttl | duration | 24h | Authenticated user session TTL |
session_password_expired | duration | 15m | Password expired session TTL |
session_mfa_pending | duration | 5m | MFA pending session TTL |
max_concurrent_sessions | int | 1 | Maximum concurrent sessions per user Set to 0 for unlimited |
runtime_metrics | bool | true | Enable runtime package metrics collection |
runtime_metrics_ttl | duration | 24h | Retention window for runtime metrics |
runtime_metrics_queue | int | 10000 | Event queue size for runtime metrics Range: 0–1000000. |
runtime_metrics_exporter | bool | false | Enable Prometheus metrics exporter endpoint |
runtime_metrics_port | int | 9090 | Prometheus metrics exporter listen port Range: 1–65535. |
runtime_metrics_network_interface | string | eth0 | Network interface for metrics exporter listener |
runtime_metrics_allow_from | []string | — | CIDR ranges allowed to scrape Prometheus metrics Empty means no IP restrictions; restrict to Prometheus scraper CIDRs in production |
debug_mode | bool | false | Enable Server-Timing debug headers with request tracing Exposes internal timing and infrastructure details; use only for debugging |
geo_enabled | bool | false | Enable geo-IP access restrictions |
geo_database | string | none | Path to MaxMind GeoLite2-Country.mmdb database Required when geo_enabled=true. Download from MaxMind GeoLite2 |
geo_asn_database | string | none | Path to MaxMind GeoLite2-ASN.mmdb database Required only when geo_allow_asn or geo_deny_asn rules are configured |
geo_allow_countries | []string | none | ISO 3166-1 alpha-2 country codes to allow Empty means allow all countries |
geo_deny_countries | []string | none | ISO 3166-1 alpha-2 country codes to deny |
geo_allow_asn | []string | none | ASN numbers to allow |
geo_deny_asn | []string | none | ASN numbers to deny |
geo_bypass_cidr | []string | none | CIDRs that bypass geo-IP checks |
geo_deny_code | int | 403 | HTTP status code for geo-IP denial Range: 400–599. |
geo_deny_message | string | Access denied from your location. | Custom message shown on geo-IP denial |
geo_country_header | string | — | CDN header containing ISO country code, skips MaxMind lookup Requires proxy=true; common values: CF-IPCountry, CloudFront-Viewer-Country |
time_enabled | bool | false | Enable time-based access restrictions Global default inherited by proxy, bastion, forward_proxy, and webshell; each can override |
time_bypass_cidr | []string | none | CIDRs that bypass time-based checks Service-level bypass; per-service bypass CIDRs are merged with this list |
time_deny_code | int | 403 | HTTP status code for time-based denial Range: 400–599. |
time_deny_message | string | Access not permitted at this time. | Custom message shown on time-based denial |
time_default_timezone | string | UTC | Default IANA timezone for time-based restrictions |
time_default_allow_days | []string | — | Default allowed days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
time_default_deny_days | []string | — | Default denied days of the week Deny takes precedence over allow Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
time_default_allow_hours | string | — | Default allowed hours range in 24h format Format: HH:MM-HH:MM |
time_default_deny_hours | string | — | Default denied hours range in 24h format Deny takes precedence over allow; format: HH:MM-HH:MM |
Cross-Origin Resource Sharing configuration for API endpoints
TOML: [service.cors] · Env: HEXON_SERVICE_CORS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable Cross-Origin Resource Sharing |
allowed_origins | []string | — | Allowed CORS origins Required when CORS is enabled; use * for all origins (not with credentials) Requires enabled=true. |
allow_credentials | bool | false | Allow cookies and credentials in CORS requests Cannot be true when allowed_origins contains * Requires enabled=true. |
allowed_methods | []string | — | Allowed HTTP methods for CORS Values: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS. Requires enabled=true. |
allowed_headers | []string | — | Allowed request headers for CORS Requires enabled=true. |
exposed_headers | []string | — | Response headers exposed to browser via CORS Requires enabled=true. |
max_age | int | 3600 | CORS preflight response cache duration in seconds Range: 0–86400. Requires enabled=true. |
UI theme configuration for colors and branding (hot-reloadable)
TOML: [service.theme] · Env: HEXON_SERVICE_THEME_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
mode | string | auto | Theme behavior mode Values: light, dark, auto. |
allow_user_override | bool (optional) | true | Allow browser to select dark/light based on OS preferences Only applies when mode is auto |
Color configuration for theme
TOML: [service.theme.colors] · Env: HEXON_SERVICE_THEME_COLORS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
success | string | 142 71% 45% | Success state color in HSL format |
warning | string | 38 92% 50% | Warning state color in HSL format |
info | string | 217 91% 60% | Info state color in HSL format |
radius | string | 0.5rem | Border radius as CSS length value |
Light mode color overrides
TOML: [service.theme.colors.light] · Env: HEXON_SERVICE_THEME_COLORS_LIGHT_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
background | string | — | Page background color in HSL format Light default: 60 9% 98%; Dark default: 60 3% 15% |
foreground | string | — | Primary text color in HSL format |
card | string | — | Card/panel background color in HSL format |
card_foreground | string | — | Card text color in HSL format |
primary | string | — | Primary action color in HSL format |
primary_hover | string | — | Primary hover state color in HSL format |
primary_foreground | string | — | Primary action text color in HSL format |
secondary | string | — | Secondary action color in HSL format |
secondary_hover | string | — | Secondary hover state color in HSL format |
destructive | string | — | Destructive action color in HSL format |
destructive_foreground | string | — | Destructive action text color in HSL format |
muted | string | — | Muted background color in HSL format |
muted_foreground | string | — | Muted text color in HSL format |
accent | string | — | Accent background color in HSL format |
accent_foreground | string | — | Accent text color in HSL format |
border | string | — | Border color in HSL format |
input | string | — | Input border color in HSL format |
Dark mode color overrides
TOML: [service.theme.colors.dark] · Env: HEXON_SERVICE_THEME_COLORS_DARK_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
background | string | — | Page background color in HSL format Light default: 60 9% 98%; Dark default: 60 3% 15% |
foreground | string | — | Primary text color in HSL format |
card | string | — | Card/panel background color in HSL format |
card_foreground | string | — | Card text color in HSL format |
primary | string | — | Primary action color in HSL format |
primary_hover | string | — | Primary hover state color in HSL format |
primary_foreground | string | — | Primary action text color in HSL format |
secondary | string | — | Secondary action color in HSL format |
secondary_hover | string | — | Secondary hover state color in HSL format |
destructive | string | — | Destructive action color in HSL format |
destructive_foreground | string | — | Destructive action text color in HSL format |
muted | string | — | Muted background color in HSL format |
muted_foreground | string | — | Muted text color in HSL format |
accent | string | — | Accent background color in HSL format |
accent_foreground | string | — | Accent text color in HSL format |
border | string | — | Border color in HSL format |
input | string | — | Input border color in HSL format |
Branding assets configuration
TOML: [service.theme.branding] · Env: HEXON_SERVICE_THEME_BRANDING_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
logo | string | — | Default logo path or URL, used if mode-specific logos not set |
logo_light | string | — | Logo for light mode and emails |
logo_dark | string | — | Logo for dark mode |
favicon | string | — | Favicon path or URL |
allow_http_images | bool | false | Allow HTTP (non-HTTPS) URLs for branding images Enabling is a security risk; use HTTPS URLs instead |
assets_base_path | string | /opt/hexon/assets | Base directory for local branding asset files Must be an absolute path |
Sign-in authentication flow configuration
TOML: [service.signin] · Env: HEXON_SERVICE_SIGNIN_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
primary | string | — | Primary authentication method |
secondary | []string | — | Alternative authentication methods |
require_mfa | []string | — | Authentication methods that require MFA step |
mfa_methods | []string | — | Allowed MFA methods |
Magic link passwordless sign-in configuration
TOML: [service.signin.magiclink] · Env: HEXON_SERVICE_SIGNIN_MAGICLINK_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable magic link passwordless sign-in Requires SMTP to be configured; auto-enables device code module |
code_length | int | 10 | Magic link token length (BASE-20 encoding) 10 chars = ~43 bits entropy; sufficient with short TTL and rate limiting Range: 6–40. Requires enabled=true. |
code_ttl | duration | 10m | Magic link validity duration Requires enabled=true. |
rate_limit | rate_limit | 5/1m | Rate limit for magic link requests per IP Requires enabled=true. |
rate_limit_email | rate_limit | 3/10m | Rate limit per email address Prevents inbox flooding for a single user Requires enabled=true. |
Sign-up registration flow configuration
TOML: [service.signup] · Env: HEXON_SERVICE_SIGNUP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
primary | string | — | Primary signup/registration method |
secondary | []string | — | Alternative signup methods |
signin | []string | — | Sign-in methods enabled after signup Inherits MFA requirements from signin config |
Time access windows by country or CIDR
TOML: [service.time_windows] · Env: HEXON_SERVICE_TIME_WINDOWS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
countries | []string | — | ISO 3166-1 alpha-2 country codes for this time window |
cidr | []string | — | IP ranges for this time window Takes precedence over country matching |
timezone | string | — | IANA timezone for this time window |
allow_days | []string | — | Allowed days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
deny_days | []string | — | Denied days of the week Deny takes precedence over allow Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
allow_hours | string | — | Allowed hours range in 24h format Format: HH:MM-HH:MM |
deny_hours | string | — | Denied hours range in 24h format Deny takes precedence over allow; format: HH:MM-HH:MM |
Cluster
TOML: [cluster] · Env: HEXON_CLUSTER_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
cluster_mode | bool | false | Enable cluster mode for distributed multi-node operation |
cluster_peers | []string | — | Static list of cluster peer addresses including self (IPs or hostnames) Minimum 2 entries (includes self). When set, cluster_dns is ignored. Hostnames are resolved to IPs on each refresh cycle Min: 2. Requires cluster_mode=true. |
cluster_dns | string | — | DNS name used for peer discovery in cluster mode Used for DNS-based node discovery. Ignored when cluster_peers is set Requires cluster_mode=true. |
cluster_dnssec | bool (optional) | true | Enable DNSSEC validation for cluster DNS lookups Nil means not set (defaults to true for security); set explicitly to false to disable Requires cluster_mode=true. |
cluster_dns_resolvers | []string | — | Custom DNS resolvers for cluster peer discovery Port defaults to :53 if not specified; leave empty to use OS DNS resolvers Requires cluster_mode=true. |
cluster_port | int | 7946 | NATS messaging port for inter-node cluster communication Range: 1–65535. Requires cluster_mode=true. |
cluster_port_routing | int | none | NATS cluster routing port for route gossip protocol Defaults to cluster_port+1 at runtime Range: 1–65535. Requires cluster_mode=true. |
cluster_interface | string | — | Network interface for cluster communication Defaults to the value of [service].network_interface if not set Requires cluster_mode=true. |
cluster_path | string | — | Shared filesystem path for NATS JetStream persistence NFS mount shared across all cluster nodes. Without this, JetStream is memory-only and persistent state is lost on restart Requires cluster_mode=true. |
cluster_refresh | duration | 15s | Interval for refreshing peer list and affinity ring Range: 1s–24h. Requires cluster_mode=true. |
cluster_startup_delay | duration | 0s | Delay before starting cluster operations after boot Allows time for peers to become available before joining the cluster Range: 0s–5m. Requires cluster_mode=true. |
cluster_affinity | bool | false | Enable consistent hashing for affinity-based request routing Routes requests to the same node based on fingerprint for session stickiness Requires cluster_mode=true. |
max_concurrent_forwards | int | 1000 | Maximum number of concurrent connection forwards between cluster nodes Set to 0 for unlimited (not recommended); applied only when cluster_mode is enabled Range: 0–100000. Requires cluster_mode=true. |
cluster_min_nodes | int | 0 | Minimum number of nodes required before the server starts accepting traffic Use 0 to start immediately or 2+ for quorum; value of 1 is not allowed Range: 0–100. Requires cluster_mode=true. |
config_file_shared | bool | true | Whether the config file is shared across nodes via NFS When false, each node reads its own local config file; hot-reload propagates only locally |
persist_memory | bool | true | Persist memory module data to JetStream file storage Requires cluster_path; enables restart-resilient sessions, PATs, audit trail, etc. Requires cluster_path. |
memory_kv_max_write | int | 10 | Maximum concurrent KV write operations for memory persistence Controls how many entries are written to JetStream KV simultaneously; increase for large directories Range: 1–100. Requires persist_memory=true. |
threshold_required | bool | false | Require threshold signing for OIDC JWTs (fail-closed after bootstrap grace) When true, token issuance fails (503) if threshold signing unavailable after grace period Requires cluster_mode=true. |
threshold_bootstrap_grace | duration | 2m | Grace period for DKG completion before enforcing threshold requirement Fallback to deterministic key during this period; after expiry, fail-closed (503) Range: 30s–10m. Requires threshold_required=true. |
threshold_nodes | int | 0 | Minimum signers required (t value; t+1 nodes cooperate to sign) 0 = auto (majority quorum: n/2). For 3-node cluster, t=2 means any 2 of 3 can sign Range: 0–100. Requires cluster_mode=true. |
Operations
TOML: [operations] · Env: HEXON_OPERATIONS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
leader_election_interval | duration | 5s | How often to run leader election check |
health_check_interval | duration | 10s | How often to check NATS health |
nats_ready_timeout | duration | 30s | How long to wait for NATS to be ready at startup |
max_concurrent_ops | int | 2000 | Maximum concurrent operations Range: 0–100000. |
operation_timeout | duration | 5m | Timeout for operation execution |
max_payload_bytes | string | 8MB | Maximum NATS message payload size |
once_dedupe_ttl | duration | 5m | TTL for Once operation deduplication |
wait_timeout | duration | 2s | Timeout for Wait() on single operations |
fire_and_forget_timeout | duration | 25ms | Auto-cleanup timeout for fire-and-forget detection |
quorum_timeout | duration | 5s | Timeout for WaitBroadcast() with quorum |
cluster_timeout | duration | 10s | Timeout for WaitBroadcast() waiting for all nodes |
encryption_ready_timeout | duration | 10s | Timeout waiting for encryption key sync during startup |
cluster_operational_timeout | duration | 2m | Timeout for cluster operational readiness before accepting traffic |
metrics_retention_window | duration | 1h | How long to retain operations metrics |
shutdown_timeout | duration | 30s | Timeout for graceful shutdown of operations |
max_queued_once_ops | int | 1000 | Maximum queued Once operations during leadership gap Range: 0–1000000. |
max_dedupe_map_size | int | 10000 | Maximum deduplication map entries Range: 0–10000000. |
publish_max_retries | int | 3 | Maximum retries for NATS publish failures Range: 0–100. |
publish_retry_delay | duration | 10ms | Initial retry delay for NATS publish with exponential backoff |
publish_timeout | duration | 5s | Per-attempt timeout for NATS publish |
broadcast_dedupe_ttl | duration | none | TTL for Broadcast deduplication to prevent echo races Auto-calculated as publish_timeout * 3 (min 2s) if not set |
circuit_breaker_failure_threshold | int | 5 | Consecutive failures before tripping circuit breaker Range: 0–1000. |
circuit_breaker_open_duration | duration | 30s | How long circuit breaker stays open before half-open |
circuit_breaker_half_open_successes | int | 2 | Consecutive successes to close circuit from half-open Range: 0–100. |
mtls | bool | true | Enable mTLS for NATS cluster communication |
internal_ca_valid_since | string | 2025-01-01T00:00:00Z | Internal CA certificate valid-from date ISO 8601 format. Changing invalidates all previously issued internal mTLS certificates |
internal_ca_valid_for | duration | 17520h | Internal CA validity duration 17520h=2 years |
internal_cert_max_validity | duration | 8760h | Maximum validity for internal certificates and CA overlap period 8760h=1 year |
internal_ca_subject_cn | string | Hexon Internal CA Root Subsystem | Internal CA Subject Common Name |
acme_ca_valid_since | string | none | ACME CA certificate valid-from date ISO 8601; changing invalidates all previously issued ACME CA certificates |
acme_ca_valid_for | duration | 175200h | ACME CA validity duration 175200h=20 years |
acme_ca_subject_cn | string | Hexon ACME CA Root Subsystem | ACME CA Subject Common Name |
acme_ca_renewal | duration | 8760h | ACME CA rotation and refresh interval 8760h=1 year |
acme_cert_max_validity | duration | 8760h | Maximum validity for ACME-issued certificates and CA overlap period 8760h=1 year |
acme_ca_threshold | bool | false | Enable threshold signing for ACME CA private key (algorithm determined by ca_algorithm) Fail-closed: no ACME certs until DKG completes (~30s). CA key never exists on any single node. Requires cluster_mode=true. |
ca_algorithm | string | ES256 | CA signature algorithm (ES256 or EdDSA) Immutable after first bootstrap; EdDSA selects FROST when acme_ca_threshold=true, ES256 selects GG18 |
ca_key_encipherment_compat | bool (optional) | true | Keep legacy KeyUsageKeyEncipherment on ECDSA leaf certs false drops the bit on ECDSA — strictly RFC-compliant but may break legacy mTLS clients |
ca_threshold_signer_wait_timeout | duration | 5s | Max time ACME/SPIFFE/CRL/OCSP signing requests wait for the threshold CA to return to Active during resharing Set higher (e.g., 15s) for very large clusters or high-latency networks; lower (e.g., 2s) to fail faster Max: 5m. |
ca_threshold_protocol_timeout | duration | 2m | Max time the threshold CA DKG and resharing protocols may run before aborting Applies to both GG18 ECDSA and FROST Ed25519. Raise for very large clusters or high-latency networks Max: 10m. |
encrypt_payloads | bool | true | Enable HMAC-authenticated AES-256-GCM payload encryption Disabling removes application-layer encryption from hexdcall RPC; mTLS still protects transport. Only disable for debugging |
forward_secrecy | bool | true | Enable forward secrecy with X3DH key exchange Requires JetStream KV with persistent storage (cluster_path). On single-node without cluster_path, pre-keys are memory-only and lost on restart |
forward_secrecy_key_interval | duration | 1h | Forward secrecy key rotation interval |
forward_secrecy_grace_period | duration | 5s | Grace period for accepting old keys during rotation |
forward_secrecy_prekey_rotation | duration | 168h | Pre-key rotation interval 168h = 7 days |
forward_secrecy_prekey_batch_size | int | 100 | Number of pre-keys to generate per batch Range: 0–10000. |
forward_secrecy_prekey_low_watermark | int | 20 | Minimum pre-keys to maintain before replenishment Must be less than or equal to prekey_batch_size Min: 0. |
forward_secrecy_prekey_ttl | duration | 168h | Time-to-live for pre-keys 168h = 7 days |
cluster_pqc | bool (optional) | true | Enable hybrid post-quantum key exchange (ML-KEM-768 + X25519) for cluster TLS FIPS 203 compliant |
scheduler_max_workers | int | 8 | Maximum concurrent scheduler workers Range: 0–1000. |
scheduler_queue_size | int | 100 | Priority queue buffer size per priority level Range: 0–100000. |
scheduler_adaptive_enabled | bool | false | Enable adaptive worker scaling based on CPU load Automatically adjusts task scheduling based on cluster load |
scheduler_cpu_threshold | string | 80 | CPU utilization threshold for adaptive scaling Percentage value, with or without % suffix Range: 10–99. |
scheduler_load_check_interval | duration | 5s | Interval for checking system load for adaptive scaling |
persistent_max_value_bytes | string | 1MB | Maximum value size for persistent storage Range: 1KB to 8MB |
Telemetry & Logging
TOML: [telemetry] · Env: HEXON_TELEMETRY_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
service_name | string | none | Service name for telemetry identification Appears in OTLP trace spans and log entries |
service_version | string | none | Service version for telemetry metadata Appears in OTLP trace metadata |
environment | string | none | Deployment environment name Appears in OTLP trace metadata; common values: production, staging, development |
log_level | string | info | Global log level Recommended: info for production, debug for troubleshooting Values: trace, debug, info, warn, error, fatal. |
log_format | string | json | Log output format json for machine parsing; human for interactive debugging Values: json, human. |
output | string | stdout | Log output destination otlp requires otlp_endpoint; both sends to stdout and OTLP Values: stdout, otlp, both. |
otlp_endpoint | string | none | OTLP gRPC endpoint for telemetry export Required when output is otlp or both Requires output=otlp. |
log_buffer_size | int | 0 | Ring buffer entries for log queries 0 disables the ring buffer Range: 0–10000000. |
audit | bool (optional) | true | Enable audit log class (always displayed regardless of log level) Audit-class events (SFTP, bastion, admin CLI) bypass level filtering when enabled |
DNS
TOML: [dns] · Env: HEXON_DNS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
timeout | duration | 5s | DNS query timeout |
cache_ttl | duration | 5m | Cache TTL, used when server TTL is unavailable or cache_override is true |
cache_override | bool | false | Ignore DNS server TTL and always use cache_ttl value |
dnssec_strict | bool | false | Fail DNS queries if DNSSEC is requested but the zone is not signed |
dnssec_full_validation | bool | false | Perform full cryptographic RRSIG/DNSKEY/DS chain-of-trust verification Recommended with DoT/DoH for maximum security; disabling trusts the resolver AD bit |
dnssec_sha1_policy | string | warn | Controls how SHA-1 usage in DNSSEC is handled Rejecting SHA-1 may break zones still using NSEC3-SHA1 Values: allow, warn, deprecate, reject. |
resolvers | []string | — | DNS resolver addresses for the infrastructure DNS module Separate from cluster.cluster_dns_resolvers. Empty = use OS resolver. Port defaults to :53 |
dot_enabled | bool | false | Enable DNS-over-TLS for encrypted DNS queries RFC 7858. |
dot_port | int | 853 | DNS-over-TLS port RFC 7858 mandates port 853 for interoperability RFC 7858. |
dot_verify_server_cert | bool | true | Verify TLS server certificates for DoT connections Disabling is not recommended as it removes authentication of DNS servers RFC 7858. |
dot_connection_pool_enabled | bool | true | Enable TLS connection pooling for DoT resolvers Reduces TLS handshake overhead when querying same resolvers Requires dot_enabled=true. |
dot_connection_pool_max_size | int | 100 | Maximum pooled connections per resolver Maximum persistent TLS connections to DoT resolvers Requires dot_connection_pool_enabled=true. |
dot_connection_pool_idle_timeout | duration | 5m | Close idle pooled connections after this duration Requires dot_connection_pool_enabled=true. |
flatten_cname | bool | true | Follow CNAME chains to resolve final A/AAAA records RFC 1034. |
max_cname_depth | int | 16 | Maximum CNAME chain depth to prevent resolution loops RFC 1034 Section 3.6.2 recommends a limit of 16 Min: 1. RFC 1034. |
health_check_enabled | bool (optional) | true | Enable periodic health checks on DNS resolvers |
health_failure_threshold | int | 2 | Consecutive failures before marking a resolver unhealthy Min: 1. |
health_check_interval | duration | 30s | Health check interval |
health_check_query | string | google.com | Domain name used for resolver health check queries |
adaptive_selector_enabled | bool | true | Enable intelligent performance-based resolver selection Selects fastest resolver based on observed latency |
adaptive_exploration_rate | float | 0.10 | Fraction of queries sent to non-optimal resolvers for exploration Higher values discover faster resolvers sooner but reduce short-term performance Range: 0.0–1.0. |
adaptive_smoothing_factor | float | 0.3 | Exponential moving average smoothing factor for latency tracking Higher values weight recent measurements more heavily Range: 0.0–1.0. |
adaptive_min_sample_size | int | 100 | Minimum query count per resolver before adaptive selection activates Min: 1. |
adaptive_load_balance_enabled | bool | true | Distribute queries across resolvers weighted by performance Requires adaptive_selector_enabled=true. |
Health
TOML: [health] · Env: HEXON_HEALTH_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable health monitoring and endpoints |
interface | string | — | Network interface name for health server IP address is resolved automatically from the interface Requires enabled=true. |
port | int | none | Port for health endpoints (plain HTTP, no TLS) Required when health monitoring is enabled Range: 1–65535. Requires enabled=true. |
allowed_cidrs | []string | 0.0.0.0/0 | Allowed CIDR ranges for health endpoint access Requires enabled=true. |
check_interval | duration | 10s | Health check interval for component monitoring Range: 1s–1h. Requires enabled=true. |
self_healing_enabled | bool | false | Enable self-healing for listener restarts When enabled, automatically restarts failed listeners within configured limits Requires enabled=true. |
max_listener_restarts | int | 3 | Max listener restarts in window before giving up After this many restarts in restart_window, listener is left stopped Range: 0–1000. Requires self_healing_enabled=true. |
restart_window | duration | 5m | Time window for counting listener restarts Rolling window for counting restart attempts Min: 1s. Requires self_healing_enabled=true. |
restart_backoff_multiplier | float | 2.0 | Exponential backoff multiplier for restart delays Each restart delay = previous delay * multiplier; prevents rapid restart loops Range: 0–100. Requires self_healing_enabled=true. |
Memory
TOML: [memory] · Env: HEXON_MEMORY_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable the memory management module |
leak_detection_enabled | bool | true | Enable goroutine and memory leak detection Monitors goroutine count growth and memory allocation trends Requires enabled=true. |
resource_management_enabled | bool | true | Enable tracking and cleanup of idle resources Tracks idle HTTP connections, file handles, and temporary buffers Requires enabled=true. |
goroutine_check_interval | duration | 30s | How often to check for goroutine leaks More frequent checks detect leaks faster but add minor overhead Requires leak_detection_enabled=true. |
memory_check_interval | duration | 1m | How often to check memory usage against thresholds Compares heap usage against max_memory threshold Requires enabled=true. |
cleanup_interval | duration | 5m | How often to run idle resource cleanup Runs idle resource cleanup; lower values free resources faster Requires resource_management_enabled=true. |
max_memory | string | 1GB | Maximum memory usage before triggering alerts e.g. 1GB, 512MB Requires enabled=true. |
max_goroutines | int | 10000 | Maximum number of goroutines before triggering alerts Alert fires when goroutine count exceeds this; typical idle: 50-200 Range: 100–1000000. Requires leak_detection_enabled=true. |
max_http_connections | int | 5000 | Maximum number of HTTP connections before triggering alerts Alert fires when total HTTP connection count exceeds this Range: 100–100000. Requires enabled=true. |
alert_interval | duration | 5m | Minimum time between repeated memory/resource alerts Prevents alert flooding; one alert per interval per threshold Min: 1m. Requires enabled=true. |
resource_timeout | duration | 30m | Maximum idle time before a resource is eligible for cleanup Resources idle longer than this are eligible for cleanup Min: 5m. Requires resource_management_enabled=true. |
max_resource_age | duration | 2h | Maximum total age of a resource before forced cleanup regardless of activity Forces cleanup regardless of activity; prevents long-lived resource leaks Min: 30m. Requires resource_management_enabled=true. |
cold_enabled | bool (optional) | true | Enable two-tier hot/cold cache for large-scale deployments When enabled (default), idle entries are evicted from memory and loaded on demand from JetStream KV. Required by memorystorage.List for cluster-wide key enumeration. |
cold_ttl | duration | 72h | How long idle entries stay in hot cache before cold eviction Entries not accessed within this window are evicted from memory but remain in JetStream KV for on-demand reload Min: 5m. |
SMTP
TOML: [smtp] · Env: HEXON_SMTP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
host | string | — | SMTP server hostname Required by magic link, OTP email delivery, WebAuthn expiry reminders, and X.509 renewal notifications Required. |
port | int | 587 | SMTP server port 587 for STARTTLS, 465 for SSL, 25 for plain Range: 1–65535. Requires host. |
encryption | string | none | SMTP encryption mode Empty defaults to plaintext; always set ssl or starttls in production to protect credentials Values: ssl, starttls, none. Requires host. |
user | string | none | SMTP authentication username SMTP AUTH username; leave empty if server does not require authentication Requires host. |
from | string | none | Sender email address RFC 5322 sender address (e.g., noreply@example.com); required for email delivery Requires host. |
reply_to | string | none | Reply-To email address Reply-To address; defaults to From address if empty Requires host. |
name | string | none | Sender display name Display name shown in From header (e.g., Hexon Gateway) Requires host. |
skip_tls | bool | false | Skip TLS certificate verification Skips server certificate validation for SSL/STARTTLS; NOT recommended for production — use only when the SMTP server presents an untrusted or mismatched certificate Requires host. |
Notifications
TOML: [notify] · Env: HEXON_NOTIFY_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
digest_window | duration | 5m | Batch window for digest notifications Batches notifications within this window into a single digest |
Email notification settings (requires SMTP module)
TOML: [notify.email] · Env: HEXON_NOTIFY_EMAIL_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable email notifications via existing SMTP module |
Outgoing webhook endpoints for notifications
TOML: [notify.webhooks] · Env: HEXON_NOTIFY_WEBHOOKS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Unique webhook name (used in notify_webhook param) Required. |
format | string | generic | Builtin payload format Values: slack, teams, discord, pagerduty, generic. |
body_template | string | — | Custom Go text/template for JSON body (overrides format) Template variables: {{.Subject}}, {{.Body}}, {{.Severity}} (info/warning/critical), {{.Username}}, {{.Hostname}}, {{.Timestamp}} (RFC3339), {{.Metadata}} (map), {{.Items}} (digest list), {{.ItemCount}}. Helper: {{json .Field}} for JSON-safe escaping |
content_type | string | application/json | HTTP Content-Type header |
timeout | duration | 10s | HTTP request timeout |
ACME CA (Internal)
TOML: [acme] · Env: HEXON_ACME_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable ACME certificate authority server RFC 8555. |
allowed_cidrs | []string | — | Allowed CIDRs for ACME API access If empty, no IP restrictions apply Requires enabled=true. |
allowed_identifiers | []string | — | Allowed domain patterns for certificate issuance Supports wildcards; if empty, any domain allowed Requires enabled=true. |
challenges_enabled | []string | http-01 | Enabled ACME challenge types Values: http-01, dns-01, tls-alpn-01. RFC 8555. Requires enabled=true. |
challenge_validity | duration | 15m | Challenge validity period RFC 8555. Requires enabled=true. |
dns_deterministic | bool | false | Enable deterministic DNS challenges for internal domains Generates deterministic DNS challenge tokens from cluster_key HMAC Requires enabled=true. |
dns_deterministic_cidrs | []string | — | CIDRs where deterministic DNS is allowed Only domains resolving within these CIDRs can use deterministic DNS Requires dns_deterministic. |
nonce_validity | duration | 15m | Nonce validity period for anti-replay protection RFC 8555. Requires enabled=true. |
max_validity | duration | 2160h | Maximum certificate validity period 2160h=90 days, 8760h=1 year RFC 8555. Requires enabled=true. |
default_validity | duration | 2160h | Default certificate validity when client does not specify 720h=30 days, 2160h=90 days RFC 8555. Requires enabled=true. |
max_san_count | int | 100 | Maximum Subject Alternative Names per certificate Matches Let’s Encrypt limit Min: 0. Requires enabled=true. |
enable_ip_identifiers | bool (optional) | true | Allow IP address identifiers in certificates IP challenges use http-01 or tls-alpn-01 only RFC 8738. Requires enabled=true. |
caa_checking | bool | false | Enable CAA record checking before issuance Verifies DNS CAA records authorize this CA RFC 8659. Requires enabled=true. |
caa_identifiers | []string | — | CAA identifiers that authorize this CA Defaults to service hostname if empty RFC 8659. Requires caa_checking. |
rate_limit_orders_per_ip | int | 50 | Maximum new orders per IP per hour Min: 0. Requires enabled=true. |
rate_limit_certs_per_domain | int | 50 | Maximum certificates per domain per week Min: 0. Requires enabled=true. |
path_prefix | string | /acme | Path prefix for ACME endpoints Endpoints: {prefix}/directory, {prefix}/newNonce, etc. Requires enabled=true. |
external_url | string | — | External URL for ACME directory responses Must end with path_prefix value. When empty, derived as https://<service.hostname><path_prefix> Requires enabled=true. |
terms_of_service | string | none | Terms of Service text served at /acme/tos URL to CA terms of service; displayed to ACME clients Requires enabled=true. |
ocsp_enabled | bool (optional) | true | Enable OCSP responder endpoint Serves real-time certificate status at /acme/ocsp RFC 6960. Requires enabled=true. |
ocsp_cache_ttl | duration | 5m | OCSP response cache TTL RFC 6960. Requires ocsp_enabled. |
ocsp_cidrs | []string | 0.0.0.0/0,::/0 | Allowed CIDRs for OCSP endpoint RFC 6960. Requires ocsp_enabled. |
crl_enabled | bool (optional) | true | Enable CRL distribution endpoint Serves Certificate Revocation List at /acme/crl RFC 5280. Requires enabled=true. |
crl_cidrs | []string | 0.0.0.0/0,::/0 | Allowed CIDRs for CRL endpoint RFC 5280. Requires crl_enabled. |
crl_next_update | duration | 48h | CRL NextUpdate offset from ThisUpdate Determines client CRL cache lifetime RFC 5280. Requires crl_enabled. |
Advanced multi-dimensional rate limiting configuration
TOML: [acme.rate_limits] · Env: HEXON_ACME_RATE_LIMITS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Enable comprehensive rate limiting |
orders_per_account | int | 5000 | Maximum orders per account within window Let’s Encrypt: 300 Min: 0. Requires enabled=true. |
orders_per_account_window | duration | 3h | Sliding window for orders per account Requires enabled=true. |
certs_per_domain | int | 500 | Maximum certificates per registered domain (eTLD+1) within window Let’s Encrypt: 50; applies across all subdomains Min: 0. Requires enabled=true. |
certs_per_domain_window | duration | 168h | Sliding window for certificates per domain Requires enabled=true. |
certs_per_exact_set | int | 50 | Maximum certificates for exact same domain set within window Let’s Encrypt: 5; prevents duplicate issuance Min: 0. Requires enabled=true. |
certs_per_exact_set_window | duration | 168h | Sliding window for certificates per exact set Requires enabled=true. |
auth_failures_per_domain | int | 50 | Maximum authorization failures per domain within window Let’s Encrypt: 5; throttles misconfigured domains Min: 0. Requires enabled=true. |
auth_failures_window | duration | 1h | Sliding window for authorization failures Requires enabled=true. |
orders_per_ip | int | 1000 | Maximum orders per IP address within window Let’s Encrypt: ~50; IPv6 grouped by /64 prefix Min: 0. Requires enabled=true. |
orders_per_ip_window | duration | 1h | Sliding window for orders per IP Requires enabled=true. |
failed_finalizations_per_order | int | 10 | Maximum failed finalization attempts per order Prevents CSR spam on a single order Min: 0. Requires enabled=true. |
min_order_interval | duration | 100ms | Minimum interval between orders (global throttle) Prevents thundering herd scenarios Requires enabled=true. |
buffer_percent | int | 10 | Buffer percentage below limits to trigger warnings Warnings logged at (100-buffer)% capacity Range: 0–100. Requires enabled=true. |
max_issued_at_entries | int | 10000 | Maximum timestamps to track per rate limit entity Higher values use more memory but improve precision Min: 0. Requires enabled=true. |
ACME Client (External)
TOML: [acme_client] · Env: HEXON_ACMECLIENT_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable ACME client for automatic certificate management RFC 8555. |
directory_url | string | https://acme-v02.api.letsencrypt.org/directory | ACME directory URL RFC 8555. Requires enabled=true. |
email | string | — | Contact email for ACME account Requires enabled=true. Required. |
accept_tos | bool | — | Accept CA Terms of Service Requires enabled=true. Required. |
reset | bool | false | Delete all ACME data on startup and start fresh Removes account, certificates, and keys Requires enabled=true. |
renewal_threshold | duration | 720h | Renew when cert expires within this duration 720h=30 days, 2160h=90 days Requires enabled=true. |
renewal_check_interval | duration | 6h | How often to check for renewals Range: 1m–24h. Requires enabled=true. |
challenge_port | int | 80 | Port for HTTP-01 challenge server Range: 1–65535. RFC 8555. Requires enabled=true. |
additional_domains | []string | — | Additional domains beyond main service hostname Requires enabled=true. |
auto_proxy_domains | bool (optional) | true | Auto-include proxy mapping hosts in certificate Requires enabled=true. |
key_type | string | ecdsa256 | Certificate key type Values: ecdsa256, ecdsa384, rsa2048, rsa4096. Requires enabled=true. |
timeout | duration | 60s | Timeout for ACME operations Range: 10s–5m. Requires enabled=true. |
max_retries | int | 10 | Max issuance retries before marking domain as failed Range: 0–100. Requires enabled=true. |
network_retries | int | 3 | Max retries for ACME network requests Range: 0–10. Requires enabled=true. |
allow_bootstrap_fallback | bool (optional) | true | Allow self-signed bootstrap certificate on ACME failure Generates temporary cert so server can start Requires enabled=true. |
startup_timeout | duration | 60s | Max time to wait for ACME on startup before fallback Range: 10s–5m. Requires enabled=true. |
startup_retries | int | 3 | Retries within startup_timeout before fallback Range: 0–10. Requires enabled=true. |
ari_enabled | bool (optional) | true | Enable ARI for optimal renewal timing Enables rate-limit-exempt renewals via CA-provided windows RFC 8739. Requires enabled=true. |
ari_check_interval | duration | 6h | How often to refresh ARI data Range: 1m–24h. RFC 8739. Requires enabled=true. |
Client-side rate limit tracking to avoid hitting CA limits
TOML: [acme_client.rate_limits] · Env: HEXON_ACMECLIENT_RATE_LIMITS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Enable client-side rate limit tracking |
orders_per_account | int | 300 | Max orders per account per window Min: 0. Requires enabled=true. |
orders_window | duration | 3h | Orders window duration Time window for counting certificate orders Requires enabled=true. |
certs_per_domain | int | 50 | Max certs per registered domain per window Min: 0. Requires enabled=true. |
certs_per_domain_window | duration | 168h | Certs per domain window duration 168h = 7 days Requires enabled=true. |
certs_per_exact_set | int | 5 | Max certs per exact domain set per window Min: 0. Requires enabled=true. |
certs_per_exact_set_window | duration | 168h | Exact set window duration 168h = 7 days Requires enabled=true. |
auth_failures_per_domain | int | 5 | Max auth failures per domain per window Min: 0. Requires enabled=true. |
auth_failures_window | duration | 1h | Auth failures window duration Time window for counting authorization failures Requires enabled=true. |
buffer_percent | int | 10 | Percent of limit to reserve as safety margin Range: 0–90. Requires enabled=true. |
min_order_interval | duration | 1s | Min time between orders Minimum time between certificate order attempts Requires enabled=true. |
max_retry_after_wait | duration | 1h | Max wait time before scheduling retry Maximum time to honor Retry-After headers from ACME server Requires enabled=true. |
respect_retry_after | bool (optional) | true | Honor server Retry-After header Requires enabled=true. |
Authentication
TOML: [authentication] · Env: HEXON_AUTHENTICATION_<KEY>
One-Time Password (email OTP) configuration
TOML: [authentication.otp] · Env: HEXON_AUTHENTICATION_OTP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
length | int | 6 | OTP code length Range: 4–12. |
type | string | base20 | OTP encoding type Values: numeric, base20. |
valid | duration | 5m | OTP validity duration |
domains | []string | — | Allowed email domains for OTP delivery. Empty or [”*”] allows all domains Leave empty or set to * to allow any email domain |
resend_time | duration | 60s | Minimum interval between OTP resend requests |
max_retries | int | 5 | Maximum failed validation attempts before OTP invalidation Range: 0–100. |
rate_limit_request | rate_limit | 10/1m | Rate limit for OTP requests |
rate_limit_verify | rate_limit | 20/1m | Rate limit for OTP verification |
mask_email | bool (optional) | true | Mask email address in MFA template When enabled, user@example.com shows as u***@example.com |
TOTP authenticator app configuration
TOML: [authentication.totp] · Env: HEXON_AUTHENTICATION_TOTP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable TOTP authenticator app |
issuer | string | HexonGateway | Issuer name shown in authenticator app (2-16 chars, no spaces) Range: 2–16. Requires enabled=true. |
algorithm | string | SHA1 | HMAC algorithm SHA1 required for Google Authenticator, Authy, and most apps. Changing after enrollment breaks existing codes Values: SHA1, SHA256, SHA512. Requires enabled=true. |
digits | int | 6 | TOTP code digits Values: 6, 8. Requires enabled=true. |
period | duration | 30s | TOTP time step duration Requires enabled=true. |
skew | int | 1 | Allowed time skew steps Range: 0–2. Requires enabled=true. |
recovery_codes | int | 10 | Number of recovery codes Range: 0–20. Requires enabled=true. |
recovery_code_length | int | 6 | Length of each recovery code Range: 4–16. Requires enabled=true. |
rate_limit_auth | rate_limit | 10/1m | TOTP verification rate limit Requires enabled=true. |
OpenID Connect Provider configuration
TOML: [authentication.oidc] · Env: HEXON_AUTHENTICATION_OIDC_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable OIDC provider Issuer URL derives from [service].hostname |
signing_algorithm | string | ES256 | ID token signing algorithm ES256/384/512 (ECDSA) are compatible with Kubernetes kube-apiserver; EdDSA (Ed25519) is faster but not supported by all OIDC consumers Values: ES256, ES384, ES512, EdDSA. Requires enabled=true. |
access_token_ttl | duration | 1h | Access token lifetime Shorter TTLs improve security but increase token refresh traffic Range: 1m–24h. RFC 6749. Requires enabled=true. |
refresh_token_ttl | duration | 720h | Refresh token lifetime RFC 6749. Requires enabled=true. |
id_token_ttl | duration | 1h | ID token lifetime RFC 7519. Requires enabled=true. |
auth_code_ttl | duration | 10m | Authorization code lifetime RFC 6749. Requires enabled=true. |
refresh_token_rotation | bool | true | Rotate refresh tokens on each use Prevents refresh token replay attacks; disabling allows unlimited reuse of refresh tokens Requires enabled=true. |
force_dpop | bool | false | Require DPoP proof-of-possession for all clients Binds tokens to the client’s key pair, preventing token theft RFC 9449. Requires enabled=true. |
dpop_strict_replay | bool | false | Wait for cluster quorum on DPoP JTI storage Eliminates replay window but adds latency due to quorum write RFC 9449. Requires force_dpop=true. |
dpop_proactive_nonce | bool (optional) | true | Send DPoP-Nonce in all token responses Encourages nonce-based replay protection per RFC 9449 Section 8 RFC 9449. Requires force_dpop=true. |
disable_wildcard_redirects | bool | false | Disable wildcard matching in redirect URIs Recommended for production to prevent open redirect attacks Requires enabled=true. |
enable_test_client | bool | false | Enable built-in OIDC test client Exposes /_hexon/oidc/test endpoint for authorization code flow testing; disable in production Requires enabled=true. |
groups_test_client | []string | — | Groups allowed to access the test client Empty means any authenticated user can access Requires enable_test_client=true. |
rate_limit_auth | rate_limit | 100/1m | Authorization endpoint rate limit Requires enabled=true. |
rate_limit_auth_code | rate_limit | — | Per-user-per-client auth code generation rate limit Empty means unlimited (not recommended); prevents auth code flooding per user per client Requires enabled=true. |
rate_limit_token | rate_limit | 60/1m | Token endpoint rate limit Requires enabled=true. |
rate_limit_introspect | rate_limit | 300/1m | Introspection endpoint rate limit RFC 7662. Requires enabled=true. |
device_code_ttl | duration | 10m | Device code expiration RFC 8628. Requires enabled=true. |
par_enabled | bool | true | Enable Pushed Authorization Request endpoint PAR improves security by keeping authorization parameters server-side RFC 9126. Requires enabled=true. |
par_required | bool | false | Require PAR for all authorization requests RFC 9126. Requires par_enabled=true. |
par_ttl | duration | 5m | PAR request_uri lifetime Range: 1m–10m. RFC 9126. Requires par_enabled=true. |
rate_limit_par | rate_limit | — | PAR endpoint rate limit Requires par_enabled=true. |
enable_dcr | bool | false | Enable Dynamic Client Registration (RFC 7591) Allows native OAuth clients to register dynamically via POST /oidc/register RFC 7591. Requires enabled=true. |
rate_limit_dcr | rate_limit | 10/1m | DCR endpoint rate limit RFC 7591. Requires enable_dcr=true. |
allow_dcr_from | []string | — | IP/CIDR allowlist for DCR endpoint Empty means allow from any IP. Restrict to trusted networks in production Requires enable_dcr=true. |
allow_dcr_redirect_domains | []string | — | Allowed redirect URI domains for DCR clients Loopback always allowed. Use * to allow any HTTPS domain. Supports exact match and wildcard subdomains (*.example.com). Non-loopback requires HTTPS Requires enable_dcr=true. |
disable_plain_pkce | bool (optional) | false | Reject plain PKCE method, requiring S256 OAuth 2.1 recommends S256 only. Enable this to reject plain PKCE code challenges Requires enabled=true. |
pat_enabled | bool (optional) | — | Enable Personal Access Tokens for CLI and automation When false (default), the PAT subsystem is completely disabled — no UI, no CLI, no API Requires enabled=true. |
pat_max_ttl | duration | 2160h | Maximum PAT lifetime Default 90 days (2160h), maximum 365 days (8760h). Supports Go duration format. Requires enabled=true,pat_enabled=true. |
pat_max_per_user | int | 10 | Maximum active PATs per user Range: 1–100. Requires enabled=true,pat_enabled=true. |
pat_required_groups | []string | — | Groups allowed to create PATs; empty allows any authenticated user User must have ANY of the listed groups to create or hold PATs Requires enabled=true,pat_enabled=true. |
OIDC client configurations
TOML: [authentication.oidc.clients] · Env: HEXON_AUTHENTICATION_OIDC_CLIENTS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Unique client identifier Required. |
require_pkce | bool | false | Require Proof Key for Code Exchange Must be true for public clients (no client_secret) RFC 7636. |
origin_urls | []string | — | Allowed CORS origins |
redirect_urls | []string | — | Allowed OAuth redirect URIs after authentication |
allow_auth_from | []string | * | Who can authenticate through this client Use * for any origin, or restrict to specific patterns |
allow_client_from | []string | 0.0.0.0/0 | IP/CIDR allowlist for token endpoint access Restricts /token endpoint access by client IP; tighten to backend IP ranges for confidential clients |
allowed_scopes | []string | — | Scopes this client can request Values: openid, profile, email, groups, ssh_keys, certificates. |
skip_consent | bool (optional) | false | Skip consent screen for trusted first-party clients When true, authorization is granted silently for authenticated users. Not recommended for third-party clients |
allowed_grant_types | []string | authorization_code,refresh_token | Allowed OAuth grant types Values: authorization_code, refresh_token, client_credentials, jwt-bearer. RFC 6749. |
client_credentials_ttl | duration | — | Token TTL for machine-to-machine client credentials grant RFC 6749. Requires allowed_grant_types=client_credentials. |
public | bool | false | Public client (no secret required) For SPAs, native apps, and device code flow. Must enable require_pkce |
jwt_public_key | string | — | PEM-encoded public key for JWT bearer assertion verification RFC 7523. Requires allowed_grant_types=jwt-bearer. |
jwt_algorithm | string | ES256 | JWT signature algorithm Values: RS256, RS384, RS512, ES256, ES384, ES512, EdDSA. RFC 7523. Requires allowed_grant_types=jwt-bearer. |
jwt_issuer | string | — | Expected issuer claim in JWT assertion Recommended for security — prevents token reuse across clients Requires allowed_grant_types=jwt-bearer. |
jwt_subject | string | — | Expected subject claim in JWT assertion Requires allowed_grant_types=jwt-bearer. |
token_endpoint_auth_method | string | client_secret_basic | Client authentication method at token endpoint Values: client_secret_basic, private_key_jwt, tls_client_auth. RFC 8705. |
tls_client_auth_subject_dn | string | — | Expected Subject DN for mTLS client certificate Must match Go pkix.Name.String() format, e.g. CN=client,O=Org,C=US RFC 8705. Requires token_endpoint_auth_method=tls_client_auth. |
tls_client_auth_san_uri | string | — | Expected URI SAN in client certificate (spiffe:// or https://) RFC 8705. Requires token_endpoint_auth_method=tls_client_auth. |
tls_client_auth_san_dns | string | — | Expected DNS SAN in client certificate RFC 8705. Requires token_endpoint_auth_method=tls_client_auth. |
tls_client_auth_san_email | string | — | Expected Email SAN in client certificate RFC 8705. Requires token_endpoint_auth_method=tls_client_auth. |
certificate_bound_tokens | bool | false | Bind issued tokens to the client certificate thumbprint Prevents token use without the original certificate RFC 8705. Requires token_endpoint_auth_method=tls_client_auth. |
client_ca_pem | string | — | CA PEM to verify client certificate issuer Inline PEM or file path. Per-client CA trust for defense-in-depth Requires token_endpoint_auth_method=tls_client_auth. |
WebAuthn/Passkey authentication configuration
TOML: [authentication.webauthn] · Env: HEXON_AUTHENTICATION_WEBAUTHN_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable WebAuthn/Passkey authentication |
rpid | string | — | Relying Party ID (typically the domain) Requires enabled=true. Required. |
origin | string | — | Expected origin URL for WebAuthn ceremonies Typically https://[service].hostname; exact origin match required Requires enabled=true. Required. |
skip_port_check | bool (optional) | true | Skip port check in origin validation Useful for K8s/Docker where external port differs from internal Requires enabled=true. |
domain | string | — | Cookie domain for WebAuthn sessions Requires enabled=true. |
name | string | — | Relying Party display name shown to users Requires enabled=true. |
type | string | preferred | Authenticator attachment preference platform=built-in (TouchID/Windows Hello), cross-platform=USB keys, preferred=any Values: platform, cross-platform, preferred. Requires enabled=true. |
user_verification | string | preferred | User Verification policy ‘preferred’ (default) lets the authenticator decide — TouchID/Windows Hello where available, skipped otherwise; non-UV-capable credentials can enroll AND authenticate. Best UX, no fallback prompts on macOS. ‘required’ demands TouchID/PIN every ceremony AND server-side rejects authData with UV=0 — strongest phishing resistance per FIDO2 §7.2.9, but on macOS can fall back to the account-password prompt if Touch ID isn’t accepted first-try. ‘discouraged’ skips UV. The same value MUST drive registration and authentication so a ‘preferred’ enrollment of a non-UV credential does not later fail a ‘required’ auth with no recovery path. Values: required, preferred, discouraged. Requires enabled=true. |
validity | duration | 8760h | Passkey validity duration Default 8760h (1 year). Set to 0 for no expiry — matches platform-passkey UX (Apple/Google/Microsoft) where credentials live until explicit revocation. Renewal reminders are skipped automatically when validity=0. Requires enabled=true. |
algorithms | []string | ES256,RS256,EdDSA | COSE signature algorithms offered to authenticators (in preference order) Authenticator picks the first it supports. ES256 (P-256 ECDSA) is universally supported. RS256 (RSA-2048) covers older smartcards. EdDSA (Ed25519) is supported by modern hardware keys (recent YubiKeys, Solo Keys) and offers smaller signatures. The server can verify all three; no other COSE algorithms are accepted (the parser supports kty=2 P-256 / kty=3 RSA / kty=1 Ed25519 only). Values: ES256, RS256, EdDSA. Requires enabled=true. |
attestation | string | none | Attestation conveyance preference sent to the authenticator at registration ‘none’ (default, recommended): authenticator omits attestation metadata — best privacy, fewest browser prompts. ‘indirect’: authenticator may send anonymized attestation. ‘direct’: full attestation including AAGUID, certificate chain, and provenance — required for AAGUID allow/deny enforcement. ‘enterprise’: escalation that surfaces non-anonymized identifiers; most authenticators require an allow-listed RP ID configured at the manufacturer policy level — coordinate before flipping. The server validates whatever attestation is returned regardless of this preference. Values: none, indirect, direct, enterprise. Requires enabled=true. |
allowed_aaguids | []string | — | Operator-defined allowlist of authenticator AAGUIDs (UUID format). Empty = any AAGUID. Requires attestation=direct (other modes may anonymize the AAGUID). Use to restrict registration to specific authenticator make/models — e.g. only YubiKey/Solo/Feitian. Examples in tools/config/authentication/webauthn.toml. AAGUID values come from the FIDO Metadata Service; verify before deploying. Requires enabled=true. |
denied_aaguids | []string | — | Operator-defined denylist of authenticator AAGUIDs (UUID format). Checked before the allowlist — a denied AAGUID is rejected even if it appears in allowed_aaguids. Empty = no exclusions. Requires attestation=direct. Use to block known-revoked devices or specific software passkey managers (iCloud Keychain, password managers) in hardware-key-only deployments. Requires enabled=true. |
rate_limit_register | rate_limit | 5/1h | Passkey registration rate limit Requires enabled=true. |
rate_limit_auth | rate_limit | 20/1m | Passkey authentication rate limit Requires enabled=true. |
renewal_reminder_enabled | bool (optional) | true | Enable passkey expiration reminder emails Requires [smtp] to be configured; silently no-ops if SMTP is not set up Requires enabled=true. |
renewal_reminder_interval | duration | 24h | How often to check for expiring passkeys Requires renewal_reminder_enabled. |
renewal_reminder_before | duration | 360h | How long before expiry to start sending reminders Requires renewal_reminder_enabled. |
renewal_reminder_timeout | duration | 5m | Timeout for each reminder check run Requires renewal_reminder_enabled. |
renewal_reminder_retries | int | 3 | Retry count on transient reminder failures Requires renewal_reminder_enabled. |
renewal_reminder_retry_delay | duration | 30s | Delay between reminder retries Requires renewal_reminder_enabled. |
Kerberos authentication configuration
TOML: [authentication.kerberos] · Env: HEXON_AUTHENTICATION_KERBEROS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
realm | string | — | Kerberos realm name Must be uppercase by convention |
kdc | string | — | Primary Key Distribution Center address |
kdc_fallback | []string | — | Fallback KDC addresses for HA Tried in order if primary KDC fails Requires kdc. |
ticket_ttl | duration | 8h | Kerberos ticket lifetime for sessions |
password_change | bool | false | Enable password change via kpasswd protocol Requires realm. |
kpasswd_path | string | — | Path to kpasswd binary Auto-detected in PATH if not specified Requires password_change=true. |
spnego_enabled | bool | false | Enable SPNEGO/Negotiate browser SSO for domain-joined workstations Requires realm. |
keytab_path | string | — | Path to service keytab file containing HTTP/<hostname>@REALM principal Requires spnego_enabled=true. |
keytab_base64 | string | — | Service keytab as base64 string (alternative to keytab_path, for K8s/containers) Requires spnego_enabled=true. |
service_principal | string | — | Service principal name override Defaults to HTTP/<service.hostname> if empty Requires spnego_enabled=true. |
spnego_auto_auth | bool | false | Transparent SPNEGO for proxy routes (like x509_auto_auth) Tries Negotiate challenge before OIDC redirect Requires spnego_enabled=true. |
spnego_exclude_nets | []string | — | CIDRs to exclude from auto-SPNEGO challenges External/non-domain networks Requires spnego_auto_auth=true. |
X.509 client certificate authentication
TOML: [authentication.x509] · Env: HEXON_AUTHENTICATION_X509_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable X.509 client certificate authentication |
ca_pem | string | — | Trusted CA certificate(s) in PEM format Can contain root + intermediate CAs. If omitted, only hexdcall ACME CA bundle is used Requires enabled=true. |
ocsp_enabled | bool | false | Enable OCSP revocation checking Requires enabled=true. |
ocsp_url | string | — | OCSP responder URL Requires ocsp_enabled=true. |
ocsp_url_fallback | []string | — | Fallback OCSP URLs for HA Tried in order if primary OCSP responder fails Requires ocsp_enabled=true. |
ocsp_cache | duration | 15m | OCSP response cache duration Requires ocsp_enabled=true. |
ocsp_timeout | duration | 5s | OCSP HTTP request timeout Range: 1s–60s. Requires ocsp_enabled=true. |
ocsp_soft_fail | bool (optional) | true | Allow auth if OCSP responder unreachable Revoked certs are always blocked regardless of this setting Requires ocsp_enabled=true. |
crl_enabled | bool | false | Enable CRL revocation checking Requires enabled=true. |
crl_url | string | — | CRL download URL Requires crl_enabled=true. |
crl_url_fallback | []string | — | Fallback CRL URLs for HA Tried in order if primary CRL URL fails Requires crl_enabled=true. |
crl_refresh | duration | 1h | CRL refresh interval Requires crl_enabled=true. |
crl_timeout | duration | 30s | CRL download HTTP timeout Requires crl_enabled=true. |
crl_max_size | string | 0 | Maximum CRL size 0 means unlimited Requires crl_enabled=true. |
enroll_enabled | bool | false | Enable self-service certificate enrollment Requires enabled=true. |
enroll_validity | duration | 2160h | Certificate validity duration Requires enroll_enabled=true. |
enroll_algorithm | string | ECDSA-P256 | Key algorithm for enrolled certificates Values: ECDSA-P256, RSA-2048. Requires enroll_enabled=true. |
enroll_pkcs12_profile | string | LegacyDES | PKCS#12 encryption profile LegacyDES uses 3DES (all macOS versions). Modern2023 uses AES-256 (requires macOS Ventura 13.0+ or Windows 10 v1607+) Values: LegacyDES, Modern2023. Requires enroll_enabled=true. |
enroll_organization | string | Hexon Authenticated Users | Organization name in certificate Subject Requires enroll_enabled=true. |
enroll_max_active_certs | int | 10 | Maximum active certificates per user Oldest certificate is auto-revoked when limit is reached Range: 1–50. Requires enroll_enabled=true. |
enroll_rate_limit | rate_limit | 3/1h | Enrollment rate limit per user Requires enroll_enabled=true. |
revoke_rate_limit | rate_limit | 5/1h | Revocation rate limit per user Requires enroll_enabled=true. |
enroll_p12_min_entropy | int | 60 | Minimum entropy bits for PKCS#12 password Higher values enforce stronger passwords for certificate export Requires enroll_enabled=true. |
enroll_auto_renew | bool (optional) | true | Enable automatic certificate renewal before expiry Renews silently; notification emails require [smtp] Requires enroll_enabled=true. |
enroll_auto_renew_days | int | 15 | Days before expiry to trigger auto-renewal Must be less than enroll_validity in days Requires enroll_enabled=true. |
enroll_auto_renew_interval | duration | 24h | How often to check for certificates needing renewal Min: 1h. Requires enroll_enabled=true. |
enroll_auto_renew_timeout | duration | 5m | Timeout for each renewal check run Requires enroll_enabled=true. |
enroll_auto_renew_retries | int | 3 | Retry count on transient renewal failures Requires enroll_enabled=true. |
enroll_auto_renew_retry_delay | duration | 30s | Delay between renewal retries Requires enroll_enabled=true. |
Device Authorization Grant (RFC 8628)
TOML: [authentication.devicecode] · Env: HEXON_AUTHENTICATION_DEVICECODE_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable device authorization grant RFC 8628. |
device_code_ttl | duration | 10m | Device code validity duration RFC 8628. Requires enabled=true. |
user_code_length | int | 8 | User code length (BASE-20 encoding) 8 chars gives ~37 bits of entropy, sufficient for human-typed codes Range: 6–12. Requires enabled=true. |
polling_interval | duration | 5s | Minimum polling interval Clients polling faster receive slow_down error response (RFC 8628 §3.5) RFC 8628. Requires enabled=true. |
rate_limit_authorize | rate_limit | 10/1m | Device authorization endpoint rate limit Requires enabled=true. |
SCIM 2.0 server for identity provisioning
TOML: [authentication.scim] · Env: HEXON_AUTHENTICATION_SCIM_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable SCIM 2.0 server |
allow_from | []string | — | Default IP/CIDR allowlist for SCIM clients Requires enabled=true. |
rate_limit | rate_limit | 100/1m | Default rate limit for SCIM clients Requires enabled=true. |
max_results | int | 100 | Default max items per page Max: 1000. Requires enabled=true. |
default_results | int | 20 | Default items per page when not specified Must not exceed max_results Requires enabled=true. |
Per-client SCIM configurations
TOML: [authentication.scim.clients] · Env: HEXON_AUTHENTICATION_SCIM_CLIENTS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Client identifier Required. |
allow_from | []string | — | IP/CIDR allowlist (overrides global) Empty uses global allow_from default |
rate_limit | rate_limit | — | Rate limit (overrides global) Empty uses global rate_limit default |
max_results | int | — | Max items per page (overrides global) 0 uses global max_results default |
valid_from | string | — | Token valid from RFC3339 format. Empty means always valid |
valid_until | string | — | Token valid until RFC3339 format. Empty means never expires |
Identity
TOML: [identity] · Env: HEXON_IDENTITY_<KEY>
LDAP directory provider configuration
TOML: [identity.ldap] · Env: HEXON_IDENTITY_LDAP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
url | string | — | LDAP server URL |
url_fallback | []string | — | Fallback LDAP URLs for HA, tried in order if primary fails |
base_dn | string | — | LDAP base distinguished name |
user_attribute | string | — | Primary user identifier attribute |
user_base_dn | string | — | Base DN for user searches |
group_base_dn | string | — | Base DN for group searches |
user_filter | string | — | LDAP filter for user searches RFC 4515 LDAP filter syntax. Common: (objectClass=posixAccount), (&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) for AD active users |
delta_sync | duration | — | Delta sync interval Only active when sync_mode=delta; requires delta_field to be set Requires sync_mode=delta. |
delta_field | string | — | LDAP attribute used for delta sync timestamps LDAP attribute used as watermark; modifyTimestamp is the standard choice Requires sync_mode=delta. |
full_sync | duration | — | Full sync interval |
sync_mode | string | delta | Directory synchronization mode persistent=LDAP persistent search (real-time, requires server support). delta=poll using modifyTimestamp (delta_field). syncrepl=RFC 4533 sync replication (most efficient) Values: persistent, delta, syncrepl. |
max_persistent_failures | int | — | Switch to delta sync after this many persistent search failures 0 means never fall back; after switching to delta sync, restart required to re-enable persistent search Range: 0–1000. Requires sync_mode=persistent. |
nested_groups | bool | — | Enable transitive nested group resolution Resolves groups recursively; can increase LDAP query load with deep hierarchies |
page_size | int | 100 | LDAP paged search result size Range: 0–10000. |
ldap_connection_pool | int | 5 | Number of pooled LDAP connections Range: 0–1000. |
bind_dn | string | — | Bind DN for LDAP authentication |
ignore_group_prefixes | []string | — | Ignore groups whose names start with these prefixes |
ca_pem | string | — | Custom CA certificate in PEM format for LDAP TLS verification Inline PEM or file path. When empty, system CA pool is used |
search_timeout | duration | 30s | Timeout for LDAP search operations |
bind_timeout | duration | 10s | Timeout for LDAP bind operations |
connection_timeout | duration | 10s | Timeout for new LDAP connection establishment |
pool_wait_timeout | duration | 5s | Timeout waiting for an available pool connection |
LDAP attribute-to-user field mapping
TOML: [identity.ldap_attribute_map] · Env: HEXON_IDENTITY_LDAP_ATTRIBUTE_MAP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
username | string | none | LDAP attribute for user identifier |
full_name | string | none | LDAP attribute for user full name |
email | string | none | LDAP attribute for email address |
given_name | string | none | LDAP attribute for given/first name |
surname | string | none | LDAP attribute for surname/last name |
member_of | string | none | LDAP attribute for group membership |
cert_attribute | string | none | LDAP attribute for user X.509 certificate |
group_name_attr | string | none | RDN attribute to extract group name from group DNs Extracts ‘admins’ from ‘cn=admins,cn=groups,dc=example,dc=com’ |
account_lock | string | none | LDAP attribute indicating account lock status |
password_expiry | string | none | LDAP attribute for password expiration timestamp |
modify_timestamp | string | none | LDAP attribute for entry modification timestamp |
create_timestamp | string | none | LDAP attribute for entry creation timestamp |
krb_principal | string | none | LDAP attribute for Kerberos principal name |
krb_last_pwd | string | none | LDAP attribute for Kerberos last password change |
employee_id | string | none | LDAP attribute for employee ID |
title | string | none | LDAP attribute for job title |
phone | string | none | LDAP attribute for phone number |
X.509 certificate subject field mapping
TOML: [identity.cert_subject_map] · Env: HEXON_IDENTITY_CERT_SUBJECT_MAP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
username | string | — | X.509 subject field to use as username Common values: cn, uid, emailAddress |
External OIDC identity providers for federated login
TOML: [identity.oidc_providers] · Env: HEXON_IDENTITY_OIDC_PROVIDERS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Internal provider identifier Required. |
display_name | string | — | UI display name, falls back to name if empty |
icon | string | — | UI icon URL or identifier for the provider |
issuer | string | — | OIDC issuer URL, must use HTTPS Required. |
client_id | string | — | OAuth 2.0 client identifier Required. |
scopes | []string | openid,profile,email | OAuth 2.0 scopes to request, must include openid |
pkce_required | bool | true | Require Proof Key for Code Exchange Must be true for public clients (no client_secret) RFC 7636. |
dpop_enabled | bool | — | Enable Demonstrating Proof of Possession token binding RFC 9449. |
redirect_uris | []string | — | Allowed OAuth 2.0 callback URLs, exact match required Must use HTTPS except localhost for development RFC 6749. |
dev_mode | bool | false | Enable relaxed validation for development NEVER enable in production |
suppress_error_details | bool | true | Hide internal error details in responses Defaults to true in production (non-dev) mode |
clock_skew_tolerance | duration | 2m | Allowed clock skew for token validation Max: 5m. |
strict_key_expiry | bool | false | Reject tokens signed with expired JWKS keys Enable to reject tokens when JWKS signing key has expired |
required_amr | []string | — | Required Authentication Method Reference values Empty means no AMR requirement |
par_preferred | bool (optional) | true | Prefer Pushed Authorization Requests when provider supports it RFC 9126. |
timeout | duration | 30s | HTTP client timeout for provider requests Range: 1s–60s. |
discovery_ttl | duration | 24h | OIDC discovery document cache TTL Range: 1h–720h. |
External SCIM identity providers for directory sync
TOML: [identity.scim_providers] · Env: HEXON_IDENTITY_SCIM_PROVIDERS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Internal provider identifier, must be unique Required. |
display_name | string | — | UI display name, falls back to name if empty |
enabled | bool | — | Enable this SCIM provider |
priority | int | — | Merge priority for multi-provider conflicts, lower wins Lower value = higher priority Range: 0–1000. Requires enabled=true. |
base_url | string | — | SCIM server base URL, must use HTTPS in production Requires enabled=true. Required. |
auth_type | string | — | Authentication method for SCIM API Values: bearer, basic, oauth2. Requires enabled=true. Required. |
basic_username | string | — | Username for auth_type=basic Requires auth_type=basic. |
oauth2_token_url | string | — | Token endpoint URL for auth_type=oauth2 Requires auth_type=oauth2. |
oauth2_client_id | string | — | Client ID for auth_type=oauth2 Requires auth_type=oauth2. |
oauth2_scope | string | scim.read | OAuth2 scope for auth_type=oauth2 Requires auth_type=oauth2. |
sync_interval | duration | 5m | Background incremental sync interval Range: 1m–24h. Requires enabled=true. |
full_sync_interval | duration | 24h | Full directory sync interval Range: 1h–168h. Requires enabled=true. |
sync_mode | string | full | Synchronization strategy full=periodic full directory pull. incremental=poll for changes since last sync. push=webhook-driven from IdP. all=full+incremental+push combined Values: full, incremental, push, all. Requires enabled=true. |
sync_users | bool | true | Sync user resources from this provider Requires enabled=true. |
sync_groups | bool | true | Sync group resources from this provider Requires enabled=true. |
sync_group_members | bool | — | Include member lists when syncing groups Requires enabled=true. |
page_size | int | 100 | SCIM list pagination page size Range: 0–1000. Requires enabled=true. |
nested_groups | bool | — | Enable transitive nested group resolution Requires enabled=true. |
nested_groups_direction | string | up | Direction for nested group traversal up=resolve parent groups (user→team→dept). down=resolve child groups (dept→team→members). both=resolve in both directions Values: up, down, both. Requires nested_groups=true. |
max_nesting_depth | int | 10 | Maximum recursion depth for nested group resolution Range: 0–100. Requires nested_groups=true. |
ca_pem | string | — | Custom CA certificate in PEM format for TLS verification Requires enabled=true. |
insecure_skip_verify | bool | — | Skip TLS certificate verification NEVER enable in production Requires enabled=true. |
timeout | duration | 30s | HTTP client timeout for SCIM API requests Range: 1s–5m. Requires enabled=true. |
Map SCIM attributes to internal directory fields
TOML: [identity.scim_providers.attribute_map] · Env: HEXON_IDENTITY_SCIM_PROVIDERS_ATTRIBUTE_MAP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
username | string | userName | SCIM attribute for user identifier |
full_name | string | displayName | SCIM attribute for display name |
email | string | emails[primary eq true].value | SCIM path expression for primary email SCIM path syntax: dot notation for nested (name.givenName), bracket filter for arrays (emails[primary eq true].value), [] for all items (groups[].display) |
given_name | string | name.givenName | SCIM path expression for given name |
surname | string | name.familyName | SCIM path expression for family name |
groups | string | groups[].display | SCIM path expression for group membership |
active | string | active | SCIM attribute for account active status |
employee_id | string | employeeNumber | SCIM attribute for employee ID |
title | string | title | SCIM attribute for job title |
phone | string | phoneNumbers[primary eq true].value | SCIM path expression for primary phone number |
department | string | urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department | SCIM attribute for department Uses SCIM enterprise extension schema |
Proxy
TOML: [proxy] · Env: HEXON_PROXY_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable the reverse proxy service |
hostname | string | none | Hostname for proxy landing page Hostname only, no scheme or port Requires enabled=true. |
header_user | string | X-Hexon-User | Header name for authenticated username Requires enabled=true. |
header_mail | string | X-Hexon-Mail | Header name for authenticated user email Requires enabled=true. |
header_name | string | X-Hexon-Name | Header name for authenticated user full name Requires enabled=true. |
header_groups | string | X-Hexon-Groups | Header name for authenticated user groups Requires enabled=true. |
brotli_support | bool (optional) | true | Enable Brotli decode/reencode for HTML rewriting Requires enabled=true. |
zstd_support | bool (optional) | true | Enable Zstandard decode/reencode for HTML rewriting Requires enabled=true. |
speculation_prefetch | string | off | Speculative prefetch eagerness for navigation Values: off, conservative, moderate, eager. Requires enabled=true. |
speculation_prerender | string | off | Speculative prerender eagerness for navigation Values: off, conservative, moderate, eager. Requires enabled=true. |
expose_circuit_state | bool (optional) | true | Include X-Circuit-State header in 503 responses when circuit is open Requires enabled=true. |
signing_enabled | bool | true | Enable HMAC-SHA256 signing of auth headers Shared rotating HMAC key used by per-mapping sign_request=true. Disabling breaks all sign_request verifications Requires enabled=true. |
signing_rotation | duration | 15m | HMAC signing key rotation interval Requires enabled=true. |
verify_max_body_size | string | 4KB | Max request body size for signature verify endpoint Requires enabled=true. |
verify_rate_limit | string | 100/1s | Rate limit for signature verify endpoint Requires enabled=true. |
max_idle_conns | int | 100 | Total idle connections across all backend hosts Requires enabled=true. |
max_idle_conns_per_host | int | 50 | Idle connections per backend host Requires enabled=true. |
max_conns_per_host | int | 100 | Max total connections per backend host Requires enabled=true. |
idle_conn_timeout | duration | 90s | Idle backend connection timeout Requires enabled=true. |
response_header_timeout | duration | 30s | Timeout waiting for backend response headers Requires enabled=true. |
expect_continue_timeout | duration | 1s | Timeout waiting for HTTP 100-Continue response Requires enabled=true. |
tls_handshake_timeout | duration | 10s | TLS handshake timeout with backends Requires enabled=true. |
force_attempt_http2 | bool | true | Enable HTTP/2 for backend connections Requires enabled=true. |
cache_enabled | bool | false | Enable in-memory response caching for static assets Requires enabled=true. |
cache_size | string | 100MB | Maximum response cache size Requires cache_enabled=true. |
cache_ttl | duration | 5m | Response cache time-to-live Requires cache_enabled=true. |
enable_http3 | bool | false | Enable HTTP/3 (QUIC) for backend connections Requires enabled=true. |
http3_fallback_enabled | bool | true | Fall back to HTTP/2 or HTTP/1.1 if HTTP/3 fails Requires enable_http3=true. |
default_0rtt | bool | true | Enable 0-RTT early data for backend HTTP/3 connections Requires enable_http3=true. |
quic_idle_timeout | duration | 30s | QUIC idle timeout for backend connections Requires enable_http3=true. |
quic_max_streams | int | 100 | Max concurrent streams per QUIC backend connection Requires enable_http3=true. |
maglev_table_size | int | 65537 | Maglev consistent hash lookup table size Must be prime number; ~256KB memory per load balancer Min: 10007. Requires enabled=true. |
proxy_protocol | bool (optional) | false | Enable HAProxy PROXY protocol for backend connections Requires enabled=true. |
proxy_protocol_version | string | v2 | PROXY protocol version v1=text format, v2=binary format (more efficient) Values: v1, v2. Requires proxy_protocol. |
disable_affinity_hosts | []string | none | Hostnames where cluster affinity forwarding is disabled Use for CDN, static content, stateless APIs Requires enabled=true. |
group_refresh_interval | duration | 15m | Interval for checking OIDC proxy session group membership changes Only applies to OIDC-authenticated proxy sessions. LDAP group changes reflected via directory sync. Set to 0 to disable Requires enabled=true. |
bearer_cache_ttl | duration | 5m | Cache TTL for verified JWT Bearer tokens Caches Ed25519 verification result. Set to 0 to disable. Per-mapping override available Requires enabled=true. |
Array of reverse proxy route mappings
TOML: [proxy.mapping] · Env: HEXON_PROXY_MAPPING_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
app | string | — | Application display name Required. |
host | string | — | Frontend hostname to match via SNI/Host header Required. |
path | string | — | Path regex pattern to match Go regexp syntax; anchored with ^…$ automatically. Use /api/.* not /api/. Literal dots need escaping: /api/v1.0/. Required. |
allowed_methods | []string | — | Allowed HTTP methods; empty allows all Empty allows all HTTP methods Values: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH. |
priority | int | none | Route matching priority nil (omit)=auto-calculated from path specificity. 0-1000=auto range. >1000=manual override, higher wins. Most specific path should have highest priority |
service | []string | — | Backend service URLs Required. |
auth | bool | false | Require authentication for this mapping Requires [authentication] to be configured |
auth_flow | string | none | Named auth flow profile References [auth_flow.name]. Defaults to ‘default’ when omitted. Requires auth=true |
oidc_providers | []string | internal | OIDC providers for authentication Provider names from [authentication.oidc] clients. Requires auth=true Requires auth=true. |
mtls | bool | false | Require client certificate (mTLS) for this mapping Uses mapping cert/key if set, falls back to service certificate. Configure x509.ca_pem for client CA trust |
bypass_auth_cidrs | []string | — | CIDR ranges that bypass authentication (auth + JIT-2FA) for this mapping Client IP from proxy_header_clientip (proxy=true) or RemoteAddr. Requests from matching IPs pass straight to backend without auth |
lb_strategy | string | adaptive | Load balancing algorithm for multiple backends Values: adaptive, round_robin, weighted, least_connections, hash, random, maglev. |
lb_hash_key | string | none | Hash key source for hash/maglev strategies Used with lb_strategy=hash or lb_strategy=maglev. Variables: header:<name>, cookie:<name>, query:<param>, ip, uri Requires lb_strategy=hash. |
lb_weights | []int | none | Backend weights for weighted strategy Must match service count; only valid with lb_strategy=weighted Min: 1. Requires lb_strategy=weighted. |
maglev_table_size | int | 65537 | Maglev lookup table size override Only valid with lb_strategy=maglev; must be prime Min: 10007. Requires lb_strategy=maglev. |
dns_discovery | bool | false | Enable STRICT_DNS service discovery mode Resolves single service hostname to multiple endpoints; requires exactly one service URL |
dns_refresh | duration | none | DNS refresh interval for service discovery Default respects TTL Min: 5s. Requires dns_discovery=true. |
groups | []string | none | Required group memberships for access Group names from [identity] directory. Requires auth=true |
allowed_subnets | []string | none | Restrict access to specific CIDR subnets Empty allows all client IPs |
add_auth_headers | bool | false | Add X-Hexon-User/Mail/Name/Groups headers to backend requests Injects X-Hexon-User/Mail/Name/Groups headers to backend |
add_extended_auth_headers | bool | false | Add X-Hexon-Auth-Method and X-Hexon-JA4 headers (in addition to add_auth_headers basics) Auth-Method values: passkey, oidc, x509, magiclink, jit2fa, pat. JA4 is the TLS client fingerprint. Useful for backends that branch on authentication strength or do fraud detection. Requires add_auth_headers=true. |
add_bearer | bool | false | Inject signed JWT Bearer token into backend requests Backend must trust HexonGateway OIDC issuer. Verify via /oidc/cert JWKS endpoint |
forward_request_headers | bool | true | Forward original client request headers to backend Forward all original request headers to backend |
forward_response_headers | bool | true | Forward backend response headers to client Forward all backend response headers to client |
allow_upgrade | bool | false | Allow WebSocket and HTTP upgrade requests |
host_header | string | none | Override Host header sent to backend Overrides Host header sent to backend; empty uses original request host |
cookie_domain | string | none | Cookie domain for OIDC session Use leading dot for multi-subdomain; must have at least two labels |
tls_check | bool | false | Verify backend TLS certificates When false, skips TLS certificate verification for this backend |
rewrite_hosts | [][2]string | none | Host rewriting rules as [from, to] pairs Array of [from, to] pairs. Rewrites Location headers and HTML href/src attributes in responses |
folder | string | none | Folder for grouping mappings in the UI |
tags | []string | none | Tags for search and filtering in the UI UI metadata only; does not affect routing or access control |
display | bool (optional) | true | Show this mapping in the portal and access list Set to false to hide API-only or internal mappings from the user portal |
audience | string | none | Audience claim for header signing Defaults to the mapping’s app name if not set (stable across deployments, doesn’t drift with backend URL changes). Falls back to the service URL only when both audience and app are empty. |
disable_rate_limit | bool | false | Bypass global rate limiting for this mapping |
rate_limit | string | none | Custom rate limit override for this mapping Per-mapping rate limit; overrides global protection.rate_limit |
rate_limit_per_user | bool | false | Track rate limits per authenticated user instead of globally per mapping Requires rate_limit and auth=true. Limits are cluster-wide. Returns X-RateLimit-* headers. Requires rate_limit,auth. |
disable_size_limit | bool | false | Bypass global size limiting for this mapping |
max_bytes | string | none | Custom max request body size override Per-mapping body size limit; overrides global protection.max_bytes |
disable_dlp | bool | false | Skip DLP scanning entirely for this mapping |
dlp_inbound | string | none | DLP policy name for inbound (request body) scanning |
dlp_outbound | string | none | DLP policy name for outbound (response body) scanning |
disable_cache | bool | false | Bypass response caching for this mapping |
disable_pow | bool | false | Bypass proof-of-work protection for this mapping |
disable_e2oe | bool | false | Bypass End-to-Origin Encryption for this mapping Use for apps with their own Service Worker (e.g., GitLab) that conflict with E2OE |
e2oe_tier1_excluded | bool | false | Skip this route from PRF-wrapped Tier 1 pre-provisioning Use for low-trust subdomains where Baseline encryption is acceptable |
dnssec | bool (optional) | none | Override DNSSEC validation for this mapping’s backend resolution Inherits from global proxy setting when not set |
dns_resolvers | []string | none | Override DNS resolvers for this mapping’s backend resolution |
rewrite_host | bool (optional) | true | Enable URL rewriting in HTML responses When false, HTML responses are streamed without rewriting href/src attributes — use for SSE or binary content |
inject_toolbar | bool (optional) | true | Inject logout toolbar into HTML responses Only effective when auth=true |
brotli_support | bool (optional) | none | Override global Brotli decode/reencode for this route Inherits from global proxy setting when not set |
zstd_support | bool (optional) | none | Override global Zstandard decode/reencode for this route Inherits from global proxy setting when not set |
speculation_prefetch | string | — | Override speculative prefetch eagerness Inherits from global [proxy] when empty Values: off, conservative, moderate, eager. |
speculation_prerender | string | — | Override speculative prerender eagerness Inherits from global [proxy] when empty Values: off, conservative, moderate, eager. |
cobrowse | bool | false | Enable co-browse capability for this mapping |
cobrowse_mask_inputs | bool (optional) | true | Mask all input field values in co-browse replay Requires cobrowse=true. |
cobrowse_block_selector | string | none | CSS selector to block from co-browse recording Requires cobrowse=true. |
max_idle_conns_per_host | int | none | Override idle connections per backend host Inherits from global setting when not set |
max_conns_per_host | int | none | Override max connections per backend host Inherits from global setting when not set |
idle_conn_timeout | duration | none | Override idle connection timeout |
response_header_timeout | duration | none | Override response header timeout |
expect_continue_timeout | duration | none | Override HTTP 100-Continue timeout |
tls_handshake_timeout | duration | none | Override TLS handshake timeout |
force_attempt_http2 | bool (optional) | none | Override HTTP/2 backend connection setting Inherits from global proxy setting when not set |
enable_http3 | bool (optional) | none | Override HTTP/3 (QUIC) for this backend Inherits from global proxy setting when not set |
force_http3 | bool | false | Force HTTP/3 only, fail if unavailable Requires enable_http3=true Requires enable_http3. |
enable_0rtt | bool (optional) | none | Override 0-RTT early data for this backend Inherits from global proxy setting when not set Requires enable_http3. |
protocol_preference | string | auto | HTTP protocol version preference Values: prefer_http3, prefer_http2, force_http3, auto. |
proxy_protocol | bool (optional) | none | Override HAProxy PROXY protocol for this backend Inherits from global proxy setting when not set |
sign_request | bool | false | Enable HMAC request signing for backend verification |
sign_request_max_body | string | 10MB | Max body size to include in request signature Use 0 to skip body hashing |
bearer_cache_ttl | duration | none | Override Bearer token cache TTL for this mapping Inherits from global proxy setting when not set. Set to 0 to disable caching |
grpc | bool | false | Enable gRPC mode with streaming, trailer extraction, and gRPC-aware circuit breaker |
site | string | none | Connector site ID for remote proxying When set, requests route through the named connector tunnel instead of direct backend connection. Site must be defined in [connector.sites] |
fcgi_script_root | string | none | Document root for SCRIPT_FILENAME/DOCUMENT_ROOT envs Required when any service URL uses fastcgi:// or fastcgi+tls://. Must be absolute path. |
fcgi_index | string | index.php | Front-controller filename for paths that don’t contain a SplitPath suffix |
fcgi_split_path | []string | [“.php”] | Suffixes that mark the boundary between SCRIPT_NAME and PATH_INFO Lowercased ASCII suffixes; first match wins |
fcgi_inject_identity | bool (optional) | true | Inject HEXON_USER/MAIL/NAME/GROUPS/AUTH_METHOD/JA4 envs from the request’s identity headers PHP code reads $_SERVER[‘HEXON_USER’] etc. without manual fastcgi_param config. AUTH_METHOD/JA4 require add_extended_auth_headers=true to populate. |
fcgi_dial_timeout | duration | 5s | Backend dial timeout |
fcgi_read_timeout | duration | 60s | Backend response read timeout (covers full response, not just headers) Heavier PHP apps (Composer-driven deploys, large reports) may need to bump this |
fcgi_write_timeout | duration | 10s | Backend write timeout (request body upload) |
fcgi_idle_timeout | duration | 90s | Idle time before a pooled FCGI connection is closed |
fcgi_max_idle_conns | int | 32 | Maximum idle FCGI connections kept in the pool per backend Set to 0 to disable pooling (fresh dial per request); leave unset to use the default. Pointer type so explicit 0 is preserved by the loader instead of being filled with the default. Min: 0. |
expose_circuit_state | bool (optional) | none | Override X-Circuit-State header exposure for this mapping Inherits from global proxy setting when not set |
geo_enabled | bool (optional) | none | Override service-level geo-IP access check Inherits from global proxy setting when not set |
geo_allow_countries | []string | none | Override allowed countries (replaces global list) ISO 3166-1 alpha-2 codes |
geo_deny_countries | []string | none | Override denied countries (replaces global list) ISO 3166-1 alpha-2 codes |
geo_allow_asn | []string | none | Override allowed ASNs for this mapping |
geo_deny_asn | []string | none | Override denied ASNs for this mapping |
geo_bypass_cidr | []string | none | Additional geo bypass CIDRs (merged with service level) |
geo_deny_code | int | none | Override HTTP status code for geo denial Inherits from global setting when not set Range: 400–599. |
geo_deny_message | string | none | Override denial message for geo-blocked requests Inherits from global setting when not set |
time_enabled | bool (optional) | none | Override service-level time-based access check Inherits from global proxy setting when not set |
time_bypass_cidr | []string | none | Additional time-check bypass CIDRs (merged with service level) |
time_deny_code | int | none | Override HTTP status code for time-based denial Inherits from global setting when not set Range: 400–599. |
time_deny_message | string | none | Override denial message for time-blocked requests Inherits from global setting when not set |
time_default_timezone | string | none | Override default timezone for time checks Inherits from global setting when not set |
time_default_allow_days | []string | — | Override default allowed days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
time_default_deny_days | []string | — | Override default denied days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
time_default_allow_hours | string | none | Override default allowed hours range Format: HH:MM-HH:MM |
time_default_deny_hours | string | none | Override default denied hours range Format: HH:MM-HH:MM |
permissions_policy | string | none | Permissions-Policy response header override Empty=inherit from backend, dash=strip, value=override |
referrer_policy | string | none | Referrer-Policy response header override Empty=inherit from backend, dash=strip, value=override |
Just-In-Time 2FA configuration
TOML: [proxy.mapping.jit2fa] · Env: HEXON_PROXY_MAPPING_JIT2FA_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable JIT-2FA for this mapping |
inject_credentials | bool (optional) | true | Encrypt and replay credentials to backend after OTP When false, backend must trust auth headers (requires add_auth_headers=true) Requires enabled=true. |
login_url | string | — | Redirect URL when user is not authenticated Requires enabled=true. Required. |
login_path_regex | string | — | Regex to match login POST requests Requires enabled=true. Required. |
logout_path_regex | string | — | Regex to match logout requests Requires enabled=true. |
username_field | string | username | Form field name for username Requires enabled=true. |
password_field | string | password | Form field name for password Requires enabled=true. |
error_no_email | string | none | Error message when webhook returns no email Empty uses built-in default message Requires enabled=true. |
error_credentials | string | none | Error message for invalid credentials Empty uses built-in default message Requires enabled=true. |
error_otp_expired | string | none | Error message when OTP code expires Empty uses built-in default message Requires enabled=true. |
error_otp_invalid | string | none | Error message for invalid OTP code Empty uses built-in default message Requires enabled=true. |
error_max_retries | string | none | Error message when max OTP retries exceeded Empty uses built-in default message Requires enabled=true. |
cookie_name | string | jit2fa_key | Cookie name for session key storage Requires enabled=true. |
cookie_path | string | / | Cookie path Requires enabled=true. |
cookie_domain | string | — | Cookie domain (empty = current domain) Requires enabled=true. |
session_ttl | duration | 8h | Authenticated session time-to-live Requires enabled=true. |
Webhook configuration for credential validation
TOML: [proxy.mapping.jit2fa.webhook] · Env: HEXON_PROXY_MAPPING_JIT2FA_WEBHOOK_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
url | string | — | Webhook URL for credential validation Required. |
method | string | POST | HTTP method for webhook request Values: GET, POST, PUT. |
request_format | string | json | Request body encoding format query format requires method=GET Values: json, query, form. |
username_param | string | username | Parameter name for username in query/form formats Requires request_format=query. |
password_param | string | password | Parameter name for password in query/form formats Requires request_format=query. |
body_template | string | — | Custom request body template for POST/PUT Supports {{username}} and {{password}} placeholders Requires request_format=json. |
timeout | duration | 5s | Webhook request timeout Range: 1s–60s. |
success_field | string | — | JSONPath to success field in response JSONPath syntax: $.field, $.nested.field, $.array[0].field. Either success_field or success_regex is required |
success_value | string | — | Expected value for success field Exact string match against the JSONPath result. Required when using success_field |
extract_email | string | — | JSONPath to email field in response JSONPath syntax: $.field, $.nested.field. Either extract_email or email_regex is required |
success_regex | string | — | Regex pattern to detect successful authentication Fallback for non-JSON responses; either this or success_field required |
email_regex | string | — | Regex with capture group to extract email from response Must have at least one capture group |
tls_skip_verify | bool (optional) | false | Skip TLS certificate verification for webhook |
tls_cert | string | — | Client certificate for mTLS to webhook (PEM) Must be specified together with tls_key |
tls_ca | string | — | Custom CA certificate for webhook TLS verification (PEM) |
max_idle_conns | int | 50 | Total idle connections in pool Range: 0–1000. |
max_idle_conns_per_host | int | 20 | Idle connections per host Range: 0–200. |
force_attempt_http2 | bool (optional) | true | Force HTTP/2 connection attempts |
disable_compression | bool (optional) | true | Disable transport compression Auth payloads are too small to benefit from compression |
write_buffer_size | string | 32KB | HTTP transport write buffer size |
read_buffer_size | string | 32KB | HTTP transport read buffer size |
dial_timeout | duration | 30s | TCP dial timeout for webhook connections Range: 1s–120s. |
keep_alive | duration | 30s | TCP keepalive interval for webhook connections Range: 0s–300s. |
OTP generation and validation settings
TOML: [proxy.mapping.jit2fa.otp] · Env: HEXON_PROXY_MAPPING_JIT2FA_OTP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
length | int | 6 | OTP code length Range: 4–12. |
type | string | — | OTP code type Empty = use global OTP type config Values: numeric, base20. |
valid | duration | 5m | OTP validity duration Range: 1m–30m. |
max_retries | int | 3 | Maximum OTP entry attempts before lockout Range: 1–10. |
resend_time | duration | 30s | Interval before OTP resend is allowed Range: 10s–5m. |
rate_limit | rate_limit | 10/1m | Rate limit for OTP verification attempts |
Mint signed bearer tokens after JIT-2FA auth for callable clients (mobile/SPA/CLI).
TOML: [proxy.mapping.jit2fa.token_handoff] · Env: HEXON_PROXY_MAPPING_JIT2FA_TOKEN_HANDOFF_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable the token handoff flow for callable clients |
entry_path | string | /_jit2fa/authorize | Path on the mapping where callers start the flow Requires enabled=true. |
allowed_return_urls | []string | — | Operator-defined whitelist of caller return URL glob patterns. Glob-style: ’*’ matches any sequence, everything else literal, anchored on both ends. Requires enabled=true. |
access_token_ttl | duration | 12h | Access token lifetime (1m-24h) Range: 1m–24h. Requires enabled=true. |
refresh_token_ttl | duration | — | Max session lifetime / refresh token TTL (requires require_dpop=true, 1h-90d) Requires enabled=true. |
audience | string | — | Audience (aud) claim baked into minted tokens Requires enabled=true. Required. |
require_dpop | bool (optional) | false | Require DPoP (RFC 9449) proof-of-possession binding on token handoff Requires enabled=true. |
accept_bearer | bool (optional) | true | Accept minted bearer tokens on subsequent requests to this mapping Requires enabled=true. |
Per-path re-authentication rules requiring re-verification for sensitive paths
TOML: [proxy.mapping.reauth] · Env: HEXON_PROXY_MAPPING_REAUTH_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
paths | []string | — | Regex patterns for paths requiring re-authentication Go regexp syntax, same as proxy path field. When multiple rules match, last wins. Required. |
hosts | []string | none | Optional hostnames this rule applies to When omitted, applies to the parent mapping host and all rewrite hosts. |
max_age | duration | — | How long a re-authentication remains valid After this duration, the user must re-authenticate again Required. |
Envoy-style outlier detection for endpoint ejection
TOML: [proxy.mapping.outlier_detection] · Env: HEXON_PROXY_MAPPING_OUTLIER_DETECTION_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Enable outlier detection for endpoint ejection Auto-enabled when multiple backends are configured |
consecutive_5xx | int | 5 | Eject endpoint after N consecutive 5xx responses Min: 1. Requires enabled=true. |
consecutive_gateway_failure | int | 3 | Eject endpoint after N consecutive 502/503/504 responses Min: 1. Requires enabled=true. |
consecutive_local_origin_failure | int | 5 | Eject endpoint after N consecutive connection failures Min: 1. Requires enabled=true. |
interval | duration | 10s | Outlier detection evaluation interval Min: 1s. Requires enabled=true. |
base_ejection_time | duration | 30s | Initial ejection duration before re-evaluation Min: 1s. Requires enabled=true. |
max_ejection_time | duration | 5m | Maximum ejection duration cap Min: 1s. Requires enabled=true. |
max_ejection_percent | int | 50 | Max percentage of endpoints that can be ejected simultaneously Range: 0–100. Requires enabled=true. |
success_rate_minimum_hosts | int | 3 | Min healthy hosts required for success rate calculation Min: 1. Requires enabled=true. |
success_rate_request_volume | int | 100 | Min requests per host required for success rate calculation Min: 1. Requires enabled=true. |
success_rate_stdev_factor | int | 1900 | Standard deviation factor x1000 for success rate ejection 1900 means 1.9 standard deviations Min: 0. Requires enabled=true. |
failure_percentage_threshold | int | 50 | Eject endpoint if failure percentage exceeds this value Range: 0–100. Requires enabled=true. |
failure_percentage_minimum_hosts | int | 3 | Min hosts required for failure percentage calculation Min: 1. Requires enabled=true. |
failure_percentage_request_volume | int | 50 | Min requests required for failure percentage calculation Min: 1. Requires enabled=true. |
Active health check configuration for backend probing
TOML: [proxy.mapping.health_check] · Env: HEXON_PROXY_MAPPING_HEALTH_CHECK_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Enable active health checking for backends Probes backends on a schedule to detect failures before traffic is affected |
type | string | http | Health check protocol Values: tcp, http, http3, grpc. |
path | string | /health | HTTP path for health check requests Requires type=http,type=http3. |
method | string | GET | HTTP method for health check requests Values: GET, HEAD. Requires type=http,type=http3. |
expected_status | []int | none | Expected HTTP status codes from healthy backends. Empty means any non-5xx response is healthy. Range: 100–599. Requires type=http,type=http3. |
grpc_service | string | none | gRPC service name for grpc.health.v1.Health/Check Empty checks the overall server health Requires type=grpc. |
interval | duration | 10s | Interval between health check probes Min: 1s. |
timeout | duration | 5s | Timeout per health check probe Min: 100ms. |
unhealthy_threshold | int | 3 | Consecutive failures before marking backend unhealthy Min: 1. |
healthy_threshold | int | 2 | Consecutive successes before marking backend healthy Min: 1. |
tls_skip_verify | bool (optional) | none | Skip TLS certificate verification for health checks Inherits from mapping tls_check when not set |
Override circuit breaker settings for this mapping
TOML: [proxy.mapping.circuit_breaker] · Env: HEXON_PROXY_MAPPING_CIRCUIT_BREAKER_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Enable circuit breaker for backend health tracking |
error_ratio_threshold | float | 0.25 | Trip circuit if 5xx error ratio exceeds this threshold Range: 0.0–1.0. Requires enabled=true. |
error_ratio_window | duration | 10s | Rolling window for error ratio calculation Requires enabled=true. |
latency_p95_threshold | duration | 1s | Trip circuit if P95 latency exceeds this duration Requires enabled=true. |
latency_p99_threshold | duration | none | Trip circuit if P99 latency exceeds this duration Requires enabled=true. |
network_error_threshold | float | 0.15 | Trip circuit if network error ratio exceeds this threshold Range: 0.0–1.0. Requires enabled=true. |
fallback_duration | duration | 30s | Duration the circuit stays open before entering half-open Requires enabled=true. |
recovery_duration | duration | 10s | Duration in half-open state before deciding to close or re-open Requires enabled=true. |
success_threshold | int | 2 | Successful requests needed in half-open state to close circuit Min: 1. Requires enabled=true. |
response_code | int | 503 | HTTP status code returned when circuit is open Range: 400–599. Requires enabled=true. |
fallback_mode | string | error | How to handle requests when circuit is open Values: error, service. Requires enabled=true. |
fallback_service | []string | none | Backend URLs for fallback when mode is service Required when fallback_mode=service Requires fallback_mode=service. |
fallback_site | string | none | Connector site ID for fallback backend routing When set, fallback requests route through the named connector tunnel. Site must be defined in [connector.sites] Requires fallback_mode=service. |
fallback_timeout | duration | 5s | Timeout for fallback service requests Requires fallback_mode=service. |
include_fallback_header | bool (optional) | true | Include X-Circuit-Breaker and Retry-After headers in responses Requires enabled=true. |
combine_mode | string | or | How to combine trigger conditions or=any condition trips, and=all must trip Values: or, and. Requires enabled=true. |
trip_expression | string | none | Custom boolean expression for circuit trip evaluation expr-lang boolean expression. Variables: error_rate, success_rate, latency_p50/p95/p99/avg (seconds), network_error_rate, timeout_rate, status_5xx_rate, status_4xx_rate, requests_total, requests_per_second. gRPC: grpc_error_rate, grpc_success_rate, grpc_unavailable_rate, grpc_internal_rate, grpc_timeout_rate, grpc_requests_total. Overrides threshold-based evaluation when set Requires enabled=true. |
grpc_health_check | bool (optional) | false | Enable active gRPC health checks using grpc.health.v1 protocol Requires enabled=true. |
grpc_health_check_interval | duration | 10s | Interval between gRPC health check probes Min: 1s. Requires grpc_health_check. |
grpc_health_check_timeout | duration | 5s | Timeout per gRPC health check probe Min: 100ms. Requires grpc_health_check. |
Override time windows with country/CIDR-specific schedules
TOML: [proxy.mapping.time_windows] · Env: HEXON_PROXY_MAPPING_TIME_WINDOWS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
countries | []string | — | ISO 3166-1 alpha-2 country codes for this time window |
cidr | []string | — | IP ranges for this time window Takes precedence over country matching |
timezone | string | — | IANA timezone for this time window |
allow_days | []string | — | Allowed days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
deny_days | []string | — | Denied days of the week Deny takes precedence over allow Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
allow_hours | string | — | Allowed hours range in 24h format Format: HH:MM-HH:MM |
deny_hours | string | — | Denied hours range in 24h format Deny takes precedence over allow; format: HH:MM-HH:MM |
Shadow/mirror targets for request duplication
TOML: [proxy.mapping.shadow] · Env: HEXON_PROXY_MAPPING_SHADOW_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Unique identifier for this shadow target Required. |
service | string | — | Shadow target URL Required. |
host_header | string | none | Override Host header sent to shadow target |
timeout | duration | none | Override request timeout for this shadow |
max_body_size | string | none | Override max body size for this shadow |
add_headers | bool (optional) | none | Override X-Hexon-Shadow-* header injection Inherits from global proxy setting when not set |
site | string | none | Connector site ID for remote shadow target When set, shadow requests route through the named connector tunnel. Site must be defined in [connector.sites] |
Sampling rate for shadow requests
TOML: [proxy.mapping.shadow.runtime_fraction] · Env: HEXON_PROXY_MAPPING_SHADOW_RUNTIME_FRACTION_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
percent | int | none | Sampling percentage of requests to mirror Range: 0–100. |
numerator | int | none | Fractional sampling numerator Use with denominator for precise low rates, e.g. 1/1000 = 0.1% Min: 0. |
denominator | int | none | Fractional sampling denominator Must be >= numerator Min: 1. |
Weighted traffic splitting for canary deployments
TOML: [proxy.mapping.canary] · Env: HEXON_PROXY_MAPPING_CANARY_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable canary traffic splitting |
service | []string | — | Canary backend URL(s) — simple two-version mode Requires enabled=true. |
weight | int | 10 | Percentage of traffic to canary in simple mode (0-100) Range: 0–100. Requires enabled=true. |
sticky | bool | true | Same user always hits same version (deterministic hash) Requires enabled=true. |
sticky_key | string | user | Value to hash for sticky routing Values: user, fingerprint, ip. Requires sticky=true. |
header | string | none | Inject version routing header into backend request Requires enabled=true. |
bypass_groups | []string | none | Groups that always route to canary/first version (100%) Requires enabled=true. |
label | string | canary | Prometheus version label for simple mode Requires enabled=true. |
site | string | none | Connector site ID for canary backends (overrides mapping-level site) When set, canary requests route through this connector tunnel instead of the mapping’s site Requires enabled=true. |
Multi-version traffic splitting (A/B/C routing)
TOML: [proxy.mapping.canary.versions] · Env: HEXON_PROXY_MAPPING_CANARY_VERSIONS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
service | []string | — | Backend URL(s) for this version (first URL used for routing) |
weight | int | — | Percentage of traffic for this version (0-100) Range: 0–100. |
label | string | — | Prometheus version label |
site | string | none | Connector site ID for this version (overrides canary-level and mapping-level site) |
Automatic retry with budget for failed backend requests
TOML: [proxy.mapping.retry] · Env: HEXON_PROXY_MAPPING_RETRY_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable automatic retries for failed requests |
max_attempts | int | 3 | Total attempts including first request Range: 1–10. Requires enabled=true. |
retry_on | []string | 5xx,connect-failure,reset | Conditions that trigger retry Values: 5xx, connect-failure, reset, retriable-4xx. Requires enabled=true. |
retriable_methods | []string | GET,HEAD,OPTIONS,PUT,DELETE | HTTP methods safe to retry Requires enabled=true. |
backoff_base | duration | 50ms | Initial backoff duration Requires enabled=true. |
backoff_max | duration | 1s | Maximum backoff duration cap Requires enabled=true. |
backoff_jitter | bool | true | Add random jitter to backoff to prevent thundering herd Requires enabled=true. |
budget_ratio | float | 0.10 | Max retries as fraction of total requests in window (0 = default 10%) Range: 0.0–1.0. Requires enabled=true. |
budget_window | duration | 10s | Sliding window for budget calculation Requires enabled=true. |
budget_min_retries | int | 3 | Minimum retries always allowed regardless of budget Min: 0. Requires enabled=true. |
max_body_size | string | 1MB | Maximum request body size for retry buffering Bodies larger than this are not retried |
Hedged requests for tail latency reduction
TOML: [proxy.mapping.hedge] · Env: HEXON_PROXY_MAPPING_HEDGE_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable hedged requests for tail latency reduction |
delay | duration | 100ms | Delay before firing hedge request Requires enabled=true. |
max_hedges | int | 1 | Maximum additional parallel requests Each hedge fires to a different backend after delay. More hedges = better tail latency but higher backend load. Requires at least max_hedges+1 backends. Range: 1–3. Requires enabled=true. |
Default health check applied to all mappings without explicit health_check config. Active by default even without this section.
TOML: [proxy.default_health_check] · Env: HEXON_PROXY_DEFAULT_HEALTH_CHECK_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Enable active health checking for backends Probes backends on a schedule to detect failures before traffic is affected |
type | string | http | Health check protocol Values: tcp, http, http3, grpc. |
path | string | /health | HTTP path for health check requests Requires type=http,type=http3. |
method | string | GET | HTTP method for health check requests Values: GET, HEAD. Requires type=http,type=http3. |
expected_status | []int | none | Expected HTTP status codes from healthy backends. Empty means any non-5xx response is healthy. Range: 100–599. Requires type=http,type=http3. |
grpc_service | string | none | gRPC service name for grpc.health.v1.Health/Check Empty checks the overall server health Requires type=grpc. |
interval | duration | 10s | Interval between health check probes Min: 1s. |
timeout | duration | 5s | Timeout per health check probe Min: 100ms. |
unhealthy_threshold | int | 3 | Consecutive failures before marking backend unhealthy Min: 1. |
healthy_threshold | int | 2 | Consecutive successes before marking backend healthy Min: 1. |
tls_skip_verify | bool (optional) | none | Skip TLS certificate verification for health checks Inherits from mapping tls_check when not set |
Default circuit breaker settings for all routes
TOML: [proxy.circuit_breaker] · Env: HEXON_PROXY_CIRCUIT_BREAKER_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Enable circuit breaker for backend health tracking |
error_ratio_threshold | float | 0.25 | Trip circuit if 5xx error ratio exceeds this threshold Range: 0.0–1.0. Requires enabled=true. |
error_ratio_window | duration | 10s | Rolling window for error ratio calculation Requires enabled=true. |
latency_p95_threshold | duration | 1s | Trip circuit if P95 latency exceeds this duration Requires enabled=true. |
latency_p99_threshold | duration | none | Trip circuit if P99 latency exceeds this duration Requires enabled=true. |
network_error_threshold | float | 0.15 | Trip circuit if network error ratio exceeds this threshold Range: 0.0–1.0. Requires enabled=true. |
fallback_duration | duration | 30s | Duration the circuit stays open before entering half-open Requires enabled=true. |
recovery_duration | duration | 10s | Duration in half-open state before deciding to close or re-open Requires enabled=true. |
success_threshold | int | 2 | Successful requests needed in half-open state to close circuit Min: 1. Requires enabled=true. |
response_code | int | 503 | HTTP status code returned when circuit is open Range: 400–599. Requires enabled=true. |
fallback_mode | string | error | How to handle requests when circuit is open Values: error, service. Requires enabled=true. |
fallback_service | []string | none | Backend URLs for fallback when mode is service Required when fallback_mode=service Requires fallback_mode=service. |
fallback_site | string | none | Connector site ID for fallback backend routing When set, fallback requests route through the named connector tunnel. Site must be defined in [connector.sites] Requires fallback_mode=service. |
fallback_timeout | duration | 5s | Timeout for fallback service requests Requires fallback_mode=service. |
include_fallback_header | bool (optional) | true | Include X-Circuit-Breaker and Retry-After headers in responses Requires enabled=true. |
combine_mode | string | or | How to combine trigger conditions or=any condition trips, and=all must trip Values: or, and. Requires enabled=true. |
trip_expression | string | none | Custom boolean expression for circuit trip evaluation expr-lang boolean expression. Variables: error_rate, success_rate, latency_p50/p95/p99/avg (seconds), network_error_rate, timeout_rate, status_5xx_rate, status_4xx_rate, requests_total, requests_per_second. gRPC: grpc_error_rate, grpc_success_rate, grpc_unavailable_rate, grpc_internal_rate, grpc_timeout_rate, grpc_requests_total. Overrides threshold-based evaluation when set Requires enabled=true. |
grpc_health_check | bool (optional) | false | Enable active gRPC health checks using grpc.health.v1 protocol Requires enabled=true. |
grpc_health_check_interval | duration | 10s | Interval between gRPC health check probes Min: 1s. Requires grpc_health_check. |
grpc_health_check_timeout | duration | 5s | Timeout per gRPC health check probe Min: 100ms. Requires grpc_health_check. |
DNS module usage settings for backend resolution
TOML: [proxy.dns] · Env: HEXON_PROXY_DNS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
use_cluster | bool | false | Use DNS module instead of system DNS for backend resolution |
dnssec | bool (optional) | none | Override cluster DNSSEC setting for proxy backends Only effective when use_cluster=true Requires use_cluster=true. |
resolvers | []string | none | Override cluster DNS resolvers for proxy backends Only effective when use_cluster=true Requires use_cluster=true. |
Global shadow/mirror defaults for request duplication
TOML: [proxy.shadow] · Env: HEXON_PROXY_SHADOW_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Global enable/disable shadow mirroring |
timeout | duration | 5s | Request timeout for shadow requests Requires enabled=true. |
max_body_size | string | 10MB | Max request body size to buffer for shadow Requires enabled=true. |
add_headers | bool (optional) | true | Add X-Hexon-Shadow-* headers to shadow requests Requires enabled=true. |
max_idle_conns | int | 50 | Total idle connections in shadow transport pool Min: 0. Requires enabled=true. |
max_idle_conns_per_host | int | 10 | Idle connections per shadow backend host Min: 0. Requires enabled=true. |
max_conns_per_host | int | 100 | Max total connections per shadow backend host Min: 0. Requires enabled=true. |
idle_conn_timeout | duration | 90s | Idle shadow connection timeout Requires enabled=true. |
tls_handshake_timeout | duration | 10s | TLS handshake timeout for shadow backends Requires enabled=true. |
tls_verify | bool (optional) | true | Verify TLS certificates of shadow backends Requires enabled=true. |
Connection Pool
TOML: [connection_pool] · Env: HEXON_CONNECTIONPOOL_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable optimized connection pools |
max_pools_per_type | int | 10 | Maximum pools per type (HTTP/SQL/LDAP) Min: 1. Requires enabled=true. |
metrics_collection_interval | duration | 30s | How often to collect pool metrics Requires enabled=true. |
global_health_check_interval | duration | 60s | Global health check interval across all pools Requires enabled=true. |
default_connection_timeout | duration | 30s | Default connection timeout for new pools Requires enabled=true. |
default_idle_timeout | duration | 5m | Default idle timeout before connection is reclaimed Requires enabled=true. |
enable_adaptive_scaling | bool | true | Enable adaptive pool scaling based on utilization Requires enabled=true. |
enable_circuit_breaker | bool | true | Enable circuit breaker for backend failure protection Requires enabled=true. |
log_level | string | info | Logging level for connection pool subsystem Values: debug, info, warn, error. Requires enabled=true. |
HTTP-specific pool settings
TOML: [connection_pool.http] · Env: HEXON_CONNECTIONPOOL_HTTP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
max_connections | int | 100 | Maximum connections per pool Hard cap on total connections; increase for high-traffic backends Min: 1. |
min_connections | int | 10 | Minimum connections per pool Must be less than or equal to max_connections Min: 1. |
connection_timeout | duration | 30s | Timeout for establishing a new connection Includes DNS resolution and TCP handshake; increase for high-latency backends |
idle_timeout | duration | 5m | Idle time before a connection is closed Close idle connections after this duration to free resources |
health_check_interval | duration | 1m | Interval between pool health checks Lower values detect backend failures faster but increase probe traffic |
scale_up_threshold | float | 0.8 | Utilization threshold to trigger pool scale-up Pool grows when usage exceeds this fraction of max_connections Range: 0–1. |
scale_down_threshold | float | 0.3 | Utilization threshold to trigger pool scale-down Must be less than scale_up_threshold Range: 0–1. |
max_scale_per_minute | int | 3 | Maximum scaling operations allowed per minute Prevents rapid pool resizing oscillation under fluctuating load Min: 1. |
failure_threshold | int | 5 | Consecutive failures before opening circuit breaker Lower values trip faster but may cause false positives under transient errors Min: 1. |
failure_window | duration | 1m | Time window for counting failures Failures outside this window are not counted toward the threshold |
recovery_timeout | duration | 30s | Time to wait before attempting half-open state After this delay, one probe request is sent to test backend recovery |
success_threshold | int | 3 | Consecutive successes to close circuit from half-open Higher values ensure backend stability before fully resuming traffic Min: 1. |
max_idle_conns | int | 200 | Total maximum idle connections across all hosts Global idle connection limit; excess idle connections are closed immediately Min: 1. |
max_idle_conns_per_host | int | 50 | Maximum idle connections per host Per-host idle connection limit; higher values improve throughput to frequently accessed backends Min: 1. |
max_conns_per_host | int | 100 | Maximum total connections per host Caps active plus idle connections; prevents a single backend from consuming all pool capacity Min: 1. |
idle_conn_timeout | duration | 90s | Idle connection timeout before closure Close idle connections after this duration to free resources |
tls_handshake_timeout | duration | 10s | Timeout for TLS handshake completion Increase for backends with slow certificate chain validation or OCSP stapling |
response_header_timeout | duration | 30s | Timeout waiting for response headers from backend Time from request sent to first response header received; does not limit body transfer |
expect_continue_timeout | duration | 1s | Timeout waiting for 100-Continue response Only applies to requests with Expect: 100-continue header |
force_attempt_http2 | bool | true | Force HTTP/2 connection attempts Uses HTTP/2 even with custom TLS config; disable if backends do not support HTTP/2 |
insecure_skip_verify | bool | false | Skip TLS certificate verification for backends Not recommended for production use |
write_buffer_size | string | 32KB | Write buffer size Tuned for high-throughput proxy |
read_buffer_size | string | 32KB | Read buffer size Tuned for high-throughput proxy |
disable_compression | bool | true | Disable HTTP transport compression Recommended true for proxy to avoid double compression |
enable_metrics | bool | true | Enable connection pool metrics collection Feeds pool utilization data to adaptive scaling and Prometheus exporter |
metrics_interval | duration | 30s | Interval between metrics collection cycles Lower values give finer-grained data but increase collection overhead |
Subrequest
TOML: [subrequest] · Env: HEXON_SUBREQUEST_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable subrequest authentication endpoint Used by nginx auth_request or similar reverse proxy authentication |
path | string | /authrequest | Path for subrequest endpoint |
group_param | string | group | Query parameter name for required group |
allowed_origins | []string | — | Allowed origins for CORS-like protection Empty list allows all origins |
header_user | string | X-Hexon-User | Response header name for username |
header_email | string | X-Hexon-Email | Response header name for email |
header_name | string | X-Hexon-Name | Response header name for full name |
header_groups | string | X-Hexon-Groups | Response header name for groups (comma-separated) |
Forward Proxy
TOML: [forward_proxy] · Env: HEXON_FORWARDPROXY_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable QUIC forward proxy Provides browser-native access to backend services using MASQUE (RFC 9298) |
hostname | string | — | Hostname for forward proxy connections Use when running behind a CDN that doesn’t support HTTP CONNECT; defaults to service hostname Requires enabled=true. |
port | int | 8443 | Dedicated port for forward proxy listener Must differ from service.port. Must be reachable by browsers (open firewall for this port) Range: 1–65535. Requires enabled=true. Required. |
network_interface | string | — | Network interface to bind to Defaults to service.network_interface if not set Requires enabled=true. |
public_port | int | — | Public-facing port for PAC URL generation Use when behind NAT/load balancer; defaults to port value Range: 0–65535. Requires enabled=true. |
preserve_client_port | bool (optional) | true | Use client connection port in Alt-Svc header When false, Alt-Svc advertises public_port instead Requires enabled=true. |
cert | string | — | TLS certificate for forward proxy hostname File path or inline PEM; falls back to service certificate if not set Requires enabled=true. |
auth_mode | string | session_fingerprint | Authentication mode for forward proxy ‘none’ disables all authentication — the forward proxy becomes an open proxy; use only in controlled environments Values: session_fingerprint, none. Requires enabled=true. |
session_cookie | string | hexon_session | Session cookie name Requires enabled=true. |
fingerprint_binding | bool | true | Enable JA4Q fingerprint binding for session security Requires enabled=true. |
fingerprint_binding_ttl | duration | 8h | Fingerprint binding TTL Requires fingerprint_binding=true. |
enable_tcp | bool | true | Enable HTTP/3 CONNECT (RFC 9114) for TCP proxying Requires enabled=true. |
enable_udp | bool | true | Enable CONNECT-UDP (RFC 9298) for UDP proxying Requires enabled=true. |
connect_timeout | duration | 10s | Backend connection timeout Requires enabled=true. |
idle_timeout | duration | 5m | Idle connection timeout Requires enabled=true. |
max_connection_duration | duration | 24h | Maximum connection lifetime Requires enabled=true. |
rate_limit_per_user | int | 1000 | Requests per second per user 0 means unlimited Min: 0. Requires enabled=true. |
rate_limit_per_destination | int | 100 | Requests per second per destination 0 means unlimited Min: 0. Requires enabled=true. |
bandwidth_limit_per_user | string | 100mbps | Bandwidth limit per user Supports mbps, gbps, kbps, mb/s, gb/s, kb/s Requires enabled=true. |
buffer_size | string | 32KB | TCP relay buffer size Requires enabled=true. |
udp_buffer_size | string | 1500B | UDP buffer size Requires enabled=true. |
max_http_response_size | string | 512MB | Maximum response body size for plain HTTP proxy requests Limits response body for non-CONNECT HTTP forwarding; 0 means unlimited Requires enabled=true. |
proxy_protocol | bool | false | Enable PROXY protocol for backend connections Disabled by default; most internet servers do not support PROXY protocol Requires enabled=true. |
proxy_protocol_version | string | v2 | PROXY protocol version v1 is text format, v2 is binary format (more efficient) Values: v1, v2. Requires proxy_protocol=true. |
probe_resistance_mode | string | off | Probe-resistance gate ‘off’ = legacy 407 on every CONNECT; ‘fingerprint’ = JA4Q-binding gate (recommended); ‘ip’ = recent-auth IP gate; ‘secret_host’ = static hostname gate Values: off, fingerprint, ip, secret_host. Requires enabled=true. |
probe_resistance_secret_host | string | — | Hostname that legitimate clients use to receive 407 challenges in secret_host mode Only used when probe_resistance_mode=secret_host Requires enabled=true. |
probe_resistance_decoy | string | 404 | Decoy response served to unauthenticated probes ‘404’ returns generic Not Found; ‘empty’ returns 204 No Content with no body Values: 404, empty. Requires enabled=true. |
probe_resistance_ttl | duration | — | TTL for fingerprint/ip recent-auth cache used by probe-resistance gates Defaults to fingerprint_binding_ttl when empty Requires enabled=true. |
udp_proxy_path | string | /masque | URL path for CONNECT-UDP requests Requires enabled=true. |
token_ttl | duration | 5m | Extension token validity duration Min: 30s. Requires enabled=true. |
token_refresh_interval | duration | 60s | Extension token refresh interval Min: 5s. Requires enabled=true. |
geo_enabled | bool | — | Enable geo-IP restrictions for forward proxy Overrides service-level geo settings when set Requires enabled=true. |
geo_allow_countries | []string | — | ISO 3166-1 alpha-2 country codes to allow Requires geo_enabled=true. |
geo_deny_countries | []string | — | Country codes to deny Takes precedence over allow list Requires geo_enabled=true. |
geo_allow_asn | []string | — | ASN numbers to allow Requires geo_enabled=true. |
geo_deny_asn | []string | — | ASN numbers to deny Takes precedence over allow list Requires geo_enabled=true. |
geo_bypass_cidr | []string | none | CIDRs that bypass geo checks Requires geo_enabled=true. |
geo_deny_code | int | 403 | HTTP status code for geo denials Requires geo_enabled=true. |
geo_deny_message | string | — | Custom denial message for geo-blocked requests Requires geo_enabled=true. |
time_enabled | bool | — | Enable time-based restrictions for forward proxy Overrides service-level time settings when set Requires enabled=true. |
time_timezone | string | — | Default timezone for time restrictions IANA timezone format Requires time_enabled=true. |
time_allow_days | []string | — | Allowed days of the week Requires time_enabled=true. |
time_deny_days | []string | — | Denied days of the week Takes precedence over allow list Requires time_enabled=true. |
time_allow_hours | string | — | Allowed hours range Format: HH:MM-HH:MM Requires time_enabled=true. |
time_deny_hours | string | — | Denied hours range Takes precedence over allow hours; format: HH:MM-HH:MM Requires time_enabled=true. |
time_bypass_cidr | []string | none | CIDRs that bypass time checks Requires time_enabled=true. |
time_deny_code | int | 403 | HTTP status code for time denials Requires time_enabled=true. |
time_deny_message | string | — | Custom denial message for time-blocked requests Requires time_enabled=true. |
PAC (Proxy Auto-Configuration) file settings
TOML: [forward_proxy.pac] · Env: HEXON_FORWARDPROXY_PAC_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable PAC file endpoint Serves auto-generated PAC files for browser proxy configuration |
path | string | /proxy.pac | URL path for PAC file Requires enabled=true. |
cache_ttl | duration | 15m | Browser cache TTL for PAC file Min: 1m. Requires enabled=true. |
use_firewall_targets | bool | true | Use firewall rules to determine proxy targets PAC file includes targets from firewall rules for the authenticated user Requires enabled=true. |
group | string | — | Group required to access PAC file If empty, any authenticated user can access; if set, only members of this group Requires enabled=true. |
Per-country or per-CIDR time windows
TOML: [forward_proxy.time_windows] · Env: HEXON_FORWARDPROXY_TIME_WINDOWS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
countries | []string | — | ISO 3166-1 alpha-2 country codes for this time window |
cidr | []string | — | IP ranges for this time window Takes precedence over country matching |
timezone | string | — | IANA timezone for this time window |
allow_days | []string | — | Allowed days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
deny_days | []string | — | Denied days of the week Deny takes precedence over allow Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
allow_hours | string | — | Allowed hours range in 24h format Format: HH:MM-HH:MM |
deny_hours | string | — | Denied hours range in 24h format Deny takes precedence over allow; format: HH:MM-HH:MM |
Connector
TOML: [connector] · Env: HEXON_CONNECTOR_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable QUIC connector listener for remote site access |
hostname | string | — | Hostname for connector listener Use when running behind a CDN; defaults to service hostname Requires enabled=true. |
port | int | — | Dedicated QUIC port for connector connections Must differ from service.port and forward_proxy.port Range: 1–65535. Requires enabled=true. Required. |
network_interface | string | — | Network interface to bind connector listener Defaults to service.network_interface if not set Requires enabled=true. |
cert | string | — | TLS certificate for connector hostname File path or inline PEM; falls back to service certificate if not set Requires enabled=true. |
handshake_timeout | duration | 10s | Maximum time for connector handshake Requires enabled=true. |
heartbeat_interval | duration | 30s | Interval between heartbeat messages Requires enabled=true. |
adaptive_min_sample_size | int | 10 | Round-robin until N samples per instance Range: 1–1000. Requires enabled=true. |
adaptive_exploration_rate | float | 0.1 | Exploration rate (0.0-1.0) Range: 0.0–1.0. Requires enabled=true. |
adaptive_smoothing_factor | float | 0.3 | EMA smoothing factor for latency (0.0-1.0) Range: 0.0–1.0. Requires enabled=true. |
Remote site definitions
TOML: [connector.sites] · Env: HEXON_CONNECTOR_SITES_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique site identifier Required. |
name | string | — | Human-readable site name Required. |
cidrs | []string | — | Restrict connector source IPs to these CIDR ranges Empty means any source IP is allowed |
max_instances | int | 0 | Maximum concurrent connector instances 0 means unlimited Min: 0. |
rebalance | bool (optional) | true | Enable cluster-wide connector load balancing Soft-rejects excess connectors so they redistribute across nodes |
rebalance_retries | int | 5 | Max soft-reject attempts before accepting Range: 1–10. Requires rebalance=true. |
client_ip_header | string | X-Forwarded-For | Header for client IP forwarding |
SSH Bastion
TOML: [bastion] · Env: HEXON_BASTION_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable SSH bastion server |
port | int | — | SSH listen port Range: 1–65535. Requires enabled=true. Required. |
enable_admin | bool | — | Enable admin CLI shell for privileged users Requires enabled=true. |
use_llm | bool | — | Enable AI assistant in bastion shell Requires [llm] section to be enabled and configured Requires llm.enabled. |
admin_groups | []string | — | Groups allowed to access the admin CLI Groups from [identity] directory. Required when enable_admin=true Requires enable_admin=true. |
network_interface | string | eth0 | Network interface to bind SSH listener to Requires enabled=true. |
ca_user_comment | string | hexon-user-ca@hexon.io | Comment identifier for the User CA key Requires enabled=true. |
ca_host_comment | string | hexon-host-ca@hexon.io | Comment identifier for the Host CA key Requires enabled=true. |
ca_threshold | bool | false | Enable threshold Ed25519 (FROST) for SSH User CA signing Fail-closed: no SSH user certs until FROST DKG completes (~3s). User CA key never exists on any single node. Requires cluster.cluster_mode=true,enabled=true. |
allow_internal_cert_auth | bool | true | Allow certificate authentication from localhost for web shell connections Requires enabled=true. |
internal_cert_ttl | duration | 5m | TTL for internal service certificates used by web shell Requires enabled=true. |
required_groups | []string | — | Groups required for bastion access; empty allows any authenticated user Groups from [identity] directory Requires enabled=true. |
device_code_timeout | duration | 5m | Timeout for device code authorization flow Requires enabled=true. |
idle_timeout | duration | 30m | Session idle timeout before automatic disconnect Requires enabled=true. |
max_session_duration | duration | 24h | Maximum allowed session duration Requires enabled=true. |
refresh_access_token | duration | 45m | Interval to refresh OAuth access token during active sessions Requires enabled=true. |
refresh_user_info | duration | 5m | Interval to refresh user info from IdP during active sessions Requires enabled=true. |
enable_syntax_highlighting | bool | true | Enable command syntax highlighting in the shell Requires enabled=true. |
cursor_style | string | default | Terminal cursor appearance style Values: default, blinking_block, steady_block, blinking_underline, steady_underline, blinking_bar, steady_bar. Requires enabled=true. |
banner | string | — | Message displayed after login before the greeting Supports multiline text Requires enabled=true. |
enable_autosuggestions | bool | — | Enable fish-style auto-suggestions in the shell Requires enabled=true. |
anomaly_watch | bool | — | Enable background anomaly alerts from log intelligence Requires enabled=true. |
anomaly_watch_interval | duration | 30s | Anomaly polling interval Requires anomaly_watch=true. |
enable_status_bar | bool (optional) | true | Enable persistent status bar at bottom of terminal by default Requires enabled=true. |
enable_suggestions | bool | — | Show contextual follow-up suggestions after commands Requires enabled=true. |
client_alive_interval | duration | 30s | Interval between SSH keepalive requests to prevent idle connection drops Set to 0 to disable; prevents firewalls/NAT from dropping idle SSH connections Requires enabled=true. |
ssh_connection_timeout | duration | 30s | Timeout for outbound SSH dial connections Requires enabled=true. |
port_forward_timeout | duration | 10s | Timeout for port forwarding TCP connections Requires enabled=true. |
sql_connection_timeout | duration | 10s | Timeout for SQL database connections Requires enabled=true. |
session_cleanup_interval | duration | 5m | Interval between session cleanup sweeps Requires enabled=true. |
blocked_cidrs | []string | — | CIDR ranges blocked for SSH and port forwarding (SSRF protection) Empty allows all; use for DMZ bastions to block private networks Requires enabled=true. |
admin_max_history_size | int | 100 | Maximum commands stored in admin shell history per session Range: 10–10000. Requires enable_admin=true. |
persist_history | bool | true | Persist command history across sessions (requires hexon backend) Requires enabled=true. |
history_persist_max | int | 100 | Maximum commands to persist across sessions Range: 10–10000. Requires persist_history=true. |
history_enabled | bool | true | Enable command history Requires enabled=true. |
history_case_insensitive | bool | — | Enable case-insensitive history search Requires enabled=true. |
history_ignore_dups | bool | true | Ignore consecutive duplicate commands in history Requires enabled=true. |
history_ignore_space | bool | — | Ignore commands starting with a space from history Requires enabled=true. |
history_bang_expansion | bool | true | Enable bang (!) history expansion Requires enabled=true. |
geo_enabled | bool | — | Enable geo-IP restrictions for bastion Overrides [service] geo settings when set Requires enabled=true. |
geo_allow_countries | []string | — | ISO 3166-1 alpha-2 country codes to allow Requires geo_enabled=true. |
geo_deny_countries | []string | — | Country codes to deny (takes precedence over allow) Requires geo_enabled=true. |
geo_allow_asn | []string | — | ASN numbers to allow Requires geo_enabled=true. |
geo_deny_asn | []string | — | ASN numbers to deny Requires geo_enabled=true. |
geo_bypass_cidr | []string | — | CIDRs that bypass geo-IP checks Requires geo_enabled=true. |
time_enabled | bool | — | Enable time-based access restrictions for bastion Overrides [service] time settings when set Requires enabled=true. |
time_timezone | string | — | Default timezone for time-based restrictions IANA timezone format Requires time_enabled=true. |
time_allow_days | []string | — | Allowed days of the week Requires time_enabled=true. |
time_deny_days | []string | — | Denied days of the week (takes precedence over allow) Requires time_enabled=true. |
time_allow_hours | string | — | Allowed hours range in 24h format Requires time_enabled=true. |
time_deny_hours | string | — | Denied hours range (takes precedence over allow) Requires time_enabled=true. |
time_bypass_cidr | []string | — | CIDRs that bypass time-based restrictions Requires time_enabled=true. |
time_deny_message | string | — | Custom message shown when access is denied by time restrictions Requires time_enabled=true. |
Session recording configuration in asciinema v2 format
TOML: [bastion.recording] · Env: HEXON_BASTION_RECORDING_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable session recording in asciinema v2 format |
path | string | — | Base directory for recording storage Recordings stored in hierarchical structure: {path}/YYYY/MM/DD/ Requires enabled=true. |
record_input | bool | true | Record user input keystrokes WARNING: captures passwords and sensitive data typed by users Requires enabled=true. |
record_output | bool | true | Record terminal output Requires enabled=true. |
compress | bool | true | Gzip compress recordings after session closes (.cast.gz) Requires enabled=true. |
max_file_size | string | 500MB | Maximum recording file size Requires enabled=true. |
max_file_disconnect | bool | true | Disconnect user when max recording file size is reached If false, recording stops but session continues Requires enabled=true. |
replay_allowed | bool | true | Allow users to replay their own session recordings Requires enabled=true. |
replay_admin_groups | []string | — | Groups with access to replay any user’s session recordings Empty means no admin replay access Requires enabled=true. |
SFTP subsystem relay configuration
TOML: [bastion.sftp] · Env: HEXON_BASTION_SFTP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | false | Enable SFTP subsystem relay |
required_groups | []string | — | Groups required for SFTP access; empty allows any bastion user Groups from [identity] directory Requires enabled=true. |
idle_timeout | duration | 10m | Idle timeout for SFTP sessions Requires enabled=true. |
Port forwarding access control configuration
TOML: [bastion.port_forwarding_acl] · Env: HEXON_BASTION_PORT_FORWARDING_ACL_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable port forwarding through the bastion |
required_groups | []string | — | Groups required for port forwarding access Requires enabled=true. |
allowed_destinations | []string | — | Static whitelist of allowed forwarding destinations Format: host:port, host:*, or *:port Requires enabled=true. |
dynamic_acl | bool | — | Enable per-user dynamic ACL from directory service Requires enabled=true. |
default_allow | bool | — | Allow all destinations when no ACL rules match Dangerous - use only for testing Requires enabled=true. |
max_forwards_per_session | int | — | Maximum concurrent port forwards per session Min: 0. Requires enabled=true. |
idle_timeout | duration | — | Idle timeout for port forward connections Requires enabled=true. |
Per-group/destination port forwarding access rules
TOML: [bastion.port_forwarding_acl.rules] · Env: HEXON_BASTION_PORT_FORWARDING_ACL_RULES_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Optional identifier for this forwarding rule |
groups | []string | — | Groups this rule applies to; empty means all groups |
destinations | []string | — | Destinations this rule applies to Supports hostnames, globs (*.example.com), CIDRs (10.0.0.0/8) |
allowed_ports | []string | — | Allowed destination ports Supports single ports, ranges (3306-3307), wildcard (*) |
allowed_types | []string | — | Allowed forwarding types; empty means all local (-L), remote (-R), dynamic (-D) Values: local, remote, dynamic. |
source_cidrs | []string | — | Client IP ranges allowed to use this rule Empty means no restriction |
max_forwards_per_session | int | — | Maximum concurrent forwards per session override for this rule Min: 0. |
DoS protection configuration for SSH bastion
TOML: [bastion.dos_protection] · Env: HEXON_BASTION_DOS_PROTECTION_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
max_global_connections | int | 0 | Maximum total concurrent SSH connections 0 means unlimited Min: 0. |
max_connections_per_ip | int | 0 | Maximum concurrent connections per source IP 0 means unlimited Min: 0. |
connection_rate_limit | rate_limit | none | New connection rate limit per IP Empty disables; format: count/duration |
auth_rate_limit | rate_limit | none | Authentication attempt rate limit per IP Empty disables; limits auth attempts per IP |
auth_failure_threshold | int | 0 | Failed auth attempts before IP ban 0 disables lockout Min: 0. |
auth_failure_ban_duration | duration | — | Ban duration after auth failure threshold exceeded |
max_sessions_per_user | int | 0 | Maximum concurrent sessions per username 0 means unlimited Min: 0. |
max_sessions_per_ip | int | 0 | Maximum concurrent sessions per source IP 0 means unlimited Min: 0. |
max_total_sessions | int | 0 | Global maximum active bastion sessions 0 means unlimited Min: 0. |
session_creation_rate | rate_limit | none | Session creation rate limit per IP Empty disables; limits new sessions per user |
command_rate_limit | rate_limit | none | Command execution rate limit per session Empty disables; limits commands per session |
command_timeout | duration | none | Maximum execution time per command Empty disables; maximum execution time per command |
max_command_length | string | 4KB | Maximum command length |
max_history_size | int | 1000 | Maximum commands stored in session history Min: 0. |
qr_generation_rate | rate_limit | none | QR code generation rate limit per IP Empty disables; limits QR code generation per user |
SSH user certificate generation configuration
TOML: [bastion.ssh_cert] · Env: HEXON_BASTION_SSH_CERT_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Enable SSH user certificate generation Disabling prevents all SSH certificate-based outbound connections via bastion |
cert_ttl | duration | 1m | Certificate validity duration Requires enabled=true. |
source_cidrs | []string | — | Restrict certificate usage to specific source IP ranges Empty means no restriction Requires enabled=true. |
force_command | string | — | Restrict certificate to execute only this command Empty means no restriction Requires enabled=true. |
permit_pty | bool | true | Allow PTY allocation in certificate Requires enabled=true. |
permit_port_forwarding | bool | — | Allow port forwarding in certificate Requires enabled=true. |
permit_agent_forwarding | bool | — | Allow SSH agent forwarding in certificate Requires enabled=true. |
permit_x11_forwarding | bool | — | Allow X11 forwarding in certificate Requires enabled=true. |
permit_user_rc | bool | — | Allow user rc script execution in certificate Requires enabled=true. |
Per-group/destination certificate rules; most-privileged-wins on match
TOML: [bastion.ssh_cert.rules] · Env: HEXON_BASTION_SSH_CERT_RULES_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Optional identifier for this certificate rule |
groups | []string | — | Groups this rule applies to; empty means all groups |
destinations | []string | — | Destinations this rule applies to Supports hostnames, globs (*.example.com), CIDRs (10.0.0.0/8) |
site | string | none | Connector site ID for remote SSH access When set, SSH connections route through connector tunnel |
principals | []string | — | Usernames allowed in the certificate Multiple principals allow user selection |
cert_ttl | duration | — | Certificate TTL override for this rule |
source_cidrs | []string | — | Source CIDR restriction override for this rule |
force_command | string | — | Forced command override for this rule |
permit_pty | bool (optional) | — | Allow PTY allocation override for this rule |
permit_port_forwarding | bool (optional) | — | Allow port forwarding override for this rule |
permit_agent_forwarding | bool (optional) | — | Allow agent forwarding override for this rule |
permit_x11_forwarding | bool (optional) | — | Allow X11 forwarding override for this rule |
permit_user_rc | bool (optional) | — | Allow user rc execution override for this rule |
SSH CA auto-setup endpoint for target host enrollment
TOML: [bastion.sshca_setup] · Env: HEXON_BASTION_SSHCA_SETUP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool (optional) | true | Enable SSH CA auto-setup endpoint for target host enrollment |
allowed_cidrs | []string | — | Source CIDRs allowed to access enrollment endpoints Empty allows all source IPs |
cert_validity | duration | 90d | Host certificate validity duration |
Per-country or per-CIDR time access windows
TOML: [bastion.time_windows] · Env: HEXON_BASTION_TIME_WINDOWS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
countries | []string | — | ISO 3166-1 alpha-2 country codes for this time window |
cidr | []string | — | IP ranges for this time window Takes precedence over country matching |
timezone | string | — | IANA timezone for this time window |
allow_days | []string | — | Allowed days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
deny_days | []string | — | Denied days of the week Deny takes precedence over allow Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
allow_hours | string | — | Allowed hours range in 24h format Format: HH:MM-HH:MM |
deny_hours | string | — | Denied hours range in 24h format Deny takes precedence over allow; format: HH:MM-HH:MM |
SQL Bastion
TOML: [sql_bastion] · Env: HEXON_SQLBASTION_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable SQL bastion for interactive database access |
Available SQL database site configurations
TOML: [sql_bastion.sites] · Env: HEXON_SQLBASTION_SITES_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Unique identifier for this database site Required. |
type | string | — | Database engine type Values: mysql, postgres. Required. |
host | string | — | Database server hostname or IP address Required. |
port | int | 3306 | Database server port TOML default is 3306; explicitly set to 5432 for PostgreSQL Range: 1–65535. |
site | string | none | Connector site ID for remote database access When set, database connections route through connector tunnel |
user | string | — | Database connection username Required. |
database | string | — | Default database/schema to connect to |
ssl | bool | — | Enable SSL/TLS for this database connection |
skip_tls | bool | — | Skip server certificate verification (TLS on, no cert check) For self-signed certs; MySQL: tls=skip-verify, PostgreSQL: sslmode=require Requires ssl=true. |
ssl_mode | string | — | PostgreSQL SSL mode Ignored for MySQL Values: disable, require, verify-ca, verify-full. Requires type=postgres. |
ssl_cert | string | — | Path to client certificate for mutual TLS Requires ssl=true. |
ssl_ca | string | — | Path to CA certificate for server verification Requires ssl=true. |
connect_timeout | duration | 10s | Connection timeout |
tls_min_version | string | 1.2 | Minimum TLS version Values: 1.2, 1.3. |
Access control rules for this site; least restrictive match wins
TOML: [sql_bastion.sites.acls] · Env: HEXON_SQLBASTION_SITES_ACLS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
acl | string | — | Group name required for this ACL; user must be a member Required. |
readonly | bool | — | Restrict to read-only queries (SELECT, SHOW, DESCRIBE, EXPLAIN) |
query_timeout | duration | — | Maximum query execution time |
query_must_contain | []string | — | Required patterns in query (all must match, case-insensitive) |
query_must_not_contain | []string | — | Forbidden patterns in query (none may match, case-insensitive) |
query_max_limit | int | — | Maximum LIMIT value enforced on queries Queries exceeding this are rewritten; queries without LIMIT get this added Min: 0. |
allowed_tables | []string | — | Table whitelist; * for all, supports wildcards (app.) PostgreSQL: use schema-qualified names (public., analytics.*) |
forbidden_tables | []string | — | Table blacklist (takes precedence over allowed_tables) |
case_sensitive_tables | bool | — | Enable case-sensitive table name matching MySQL is case-insensitive by default on most systems |
masked_columns | []string | — | Column name patterns to mask in results (glob: credit_card_*, *_email) |
mask_strategy | string | partial | Masking display strategy Values: full, partial, hash, optional. |
Query rate limiting configuration
TOML: [sql_bastion.sites.acls.rate_limit] · Env: HEXON_SQLBASTION_SITES_ACLS_RATE_LIMIT_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
queries_per_minute | int | — | Maximum queries allowed per window Multi-statement queries count as multiple Min: 0. |
burst_allowed | int | — | Extra queries allowed beyond rate limit (burst capacity) Total allowed = queries_per_minute + burst_allowed Min: 0. |
window_size | duration | — | Rate limit sliding window duration |
Database server-side resource limit configuration
TOML: [sql_bastion.sites.acls.query_limits] · Env: HEXON_SQLBASTION_SITES_ACLS_QUERY_LIMITS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
max_complexity_score | int | — | Maximum allowed query complexity score Base:10, JOIN:+20, subquery:+30, LIKE:+15, GROUP BY:+25, ORDER BY:+15, HAVING:+20, aggregate:+10, UNION:+25 Min: 0. |
max_execution_time | duration | — | Database-enforced query execution time limit MySQL: max_execution_time; PostgreSQL: statement_timeout |
max_rows | int | — | Maximum rows returned per query MySQL: sql_select_limit; PostgreSQL: not supported (use LIMIT) Min: 0. |
max_memory | string | — | Memory limit for sorting and aggregate operations MySQL: max_sort_length; PostgreSQL: work_mem |
Web Shell
TOML: [webshell] · Env: HEXON_WEBSHELL_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable the web shell terminal service |
required_groups | []string | — | Groups required for web shell access User must be a member of at least one group; empty inherits from bastion.required_groups Requires enabled=true. |
max_sessions_per_user | int | 3 | Max concurrent web shell sessions per user Min: 1. Requires enabled=true. |
session_timeout | duration | 30m | Inactive session timeout duration Requires enabled=true. |
geo_enabled | bool | false | Enable geo-IP restrictions for web shell Overrides [service] geo settings when set Requires enabled=true. |
geo_allow_countries | []string | — | ISO 3166-1 alpha-2 country codes to allow Requires geo_enabled=true. |
geo_deny_countries | []string | — | Country codes to deny (takes precedence over allow) Requires geo_enabled=true. |
geo_allow_asn | []string | — | ASN numbers to allow Requires geo_enabled=true. |
geo_deny_asn | []string | — | ASN numbers to deny Requires geo_enabled=true. |
geo_bypass_cidr | []string | — | CIDRs that bypass geo-IP checks Requires geo_enabled=true. |
time_enabled | bool | — | Enable time-based restrictions for web shell Overrides [service] time settings when set Requires enabled=true. |
time_timezone | string | — | Default timezone in IANA format IANA timezone format (e.g., America/New_York) Requires time_enabled=true. |
time_allow_days | []string | — | Allowed days of the week Requires time_enabled=true. |
time_deny_days | []string | — | Denied days of the week (takes precedence over allow) Requires time_enabled=true. |
time_allow_hours | string | — | Allowed hours range Requires time_enabled=true. |
time_deny_hours | string | — | Denied hours range (takes precedence over allow) Requires time_enabled=true. |
time_bypass_cidr | []string | — | CIDRs that bypass time-based checks Requires time_enabled=true. |
time_deny_message | string | — | Custom message shown when access is denied by time restriction Requires time_enabled=true. |
Per-country or per-CIDR time windows
TOML: [webshell.time_windows] · Env: HEXON_WEBSHELL_TIME_WINDOWS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
countries | []string | — | ISO 3166-1 alpha-2 country codes for this time window |
cidr | []string | — | IP ranges for this time window Takes precedence over country matching |
timezone | string | — | IANA timezone for this time window |
allow_days | []string | — | Allowed days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
deny_days | []string | — | Denied days of the week Deny takes precedence over allow Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
allow_hours | string | — | Allowed hours range in 24h format Format: HH:MM-HH:MM |
deny_hours | string | — | Denied hours range in 24h format Deny takes precedence over allow; format: HH:MM-HH:MM |
Firewall
TOML: [firewall] · Env: HEXON_FIREWALL_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable firewall ACL system for proxy access control |
blocked_networks | []string | — | Networks to block globally for all proxy users Defaults to RFC1918, link-local, loopback, multicast if empty Requires enabled=true. |
dns_refresh_enabled | bool | true | Enable automatic DNS refresh for ACL hostnames Requires enabled=true. |
dns_refresh_min_interval | duration | 1m | Minimum DNS refresh interval Requires dns_refresh_enabled=true. |
dns_refresh_max_interval | duration | 1h | Maximum DNS refresh interval Must be >= dns_refresh_min_interval Requires dns_refresh_enabled=true. |
dns_refresh_jitter | int | 10 | DNS refresh jitter percentage Range: 0–100. Requires dns_refresh_enabled=true. |
dns_refresh_init_timeout | duration | 10s | DNS resolution timeout at startup Requires dns_refresh_enabled=true. |
nft_pool_size | int | 5 | nftables connection pool size Range: 1–100. Requires enabled=true. |
max_rules_per_chain | int | 1000 | Maximum nftables rules per peer chain Set to 0 for unlimited Requires enabled=true. |
Reusable host and port alias definitions for ACL rules
TOML: [firewall.aliases] · Env: HEXON_FIREWALL_ALIASES_<KEY>
Named sets of destination hosts for ACL rules
TOML: [firewall.aliases.hosts] · Env: HEXON_FIREWALL_ALIASES_HOSTS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Unique alias name Required. |
hosts | []string | — | Destination IPs, CIDRs, or hostnames Supports IPs, CIDRs, hostnames, and wildcard domains (*.example.com) Required. |
site | string | none | Connector site ID for remote access When set, destinations resolve on the remote site via connector tunnel |
Named sets of protocol/port combinations for ACL rules
TOML: [firewall.aliases.ports] · Env: HEXON_FIREWALL_ALIASES_PORTS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Unique alias name Required. |
Protocol and port combinations
TOML: [firewall.aliases.ports.entries] · Env: HEXON_FIREWALL_ALIASES_PORTS_ENTRIES_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
proto | string | — | Network protocol Values: tcp, udp, icmp, esp, any. Required. |
ports | []int | — | Port numbers; leave empty for icmp/esp/any Range: 1–65535. |
Group-based firewall access control rules
TOML: [firewall.rules] · Env: HEXON_FIREWALL_RULES_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
rule | string | — | Unique rule identifier Required. |
src | []string | — | Source LDAP groups; users in any group match (OR logic) LDAP groups from [identity] directory Required. |
dst | []string | — | Destination host alias names from aliases.hosts Required. |
ports | []string | — | Port alias names from aliases.ports; use ‘any’ for all Required. |
Protection
TOML: [protection] · Env: HEXON_PROTECTION_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
pow | bool | — | Enable Proof-of-Work challenge for bot protection |
pow_difficulty | int | 4 | PoW hash difficulty level Range: 1–32. Requires pow=true. |
pow_difficulty_time | duration | 5m | TTL for PoW tokens Requires pow=true. |
pow_session_ttl | duration | 30m | How long a PoW session remains valid after successful challenge Requires pow=true. |
pow_cookie_name | string | hexon_pow | Cookie name for PoW sessions Must differ from session cookie name Requires pow=true. |
pow_random_fields | bool | true | Use random form field names to deter bots Requires pow=true. |
pow_decoy_fields | int | 5 | Number of honeypot decoy fields in PoW form Range: 0–100. Requires pow=true. |
pow_min_render_time | duration | 200ms | Minimum time before form submission is accepted Requires pow=true. |
pow_max_render_time | duration | 30s | Maximum time a form may sit before submission is accepted (staged-replay defense) Requires pow=true. |
pow_body_ttl | duration | 5m | TTL for stored POST bodies during PoW challenge Requires pow=true. |
pow_body_max_size | string | 1MB | Maximum POST body size to preserve during PoW Requires pow=true. |
rate_limit | rate_limit | none | Request rate limit Empty disables global rate limiting; format: count/duration (e.g., 100/1m) |
rate_limit_type | string | fingerprint | Client identification method for rate limiting fingerprint uses TLS+HTTP/2+TCP composite Values: fingerprint, ip. |
rate_limit_bantime | duration | — | Duration to ban client after rate limit exceeded Empty disables banning; client is rate-limited momentarily but not blocked long-term |
rate_limit_max_clients | int | 100000 | Maximum number of clients to track for rate limiting Prevents memory exhaustion Range: 0–10000000. |
max_bytes | string | none | Default maximum request body size Empty disables body size limiting; applies to all request bodies |
password_min_length | int | 12 | Minimum password length Range: 0–128. |
password_min_score | int | 3 | Minimum zxcvbn password strength score Range: 0–4. |
password_min_entropy | float | 40.0 | Minimum password entropy in bits Range: 0–256. |
password_require_upper | bool | false | Require at least one uppercase letter |
password_require_lower | bool | false | Require at least one lowercase letter |
password_require_digit | bool | false | Require at least one digit |
password_require_special | bool | false | Require at least one special character |
Per-host/path exceptions for request body size limits
TOML: [protection.max_bytes_exceptions] · Env: HEXON_PROTECTION_MAX_BYTES_EXCEPTIONS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
host | string | — | Hostname to match; empty matches all hosts |
path | string | — | Path pattern (exact, wildcard, or regex) Exact: /upload/large. Wildcard: /upload/* (shell glob). Regex: /upload/[0-9]+ (set regex=true) |
bytes | string | — | Size limit for matching requests Required. |
regex | bool | false | Treat path as regular expression |
Data Loss Prevention configuration
TOML: [protection.dlp] · Env: HEXON_PROTECTION_DLP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable Data Loss Prevention scanning |
default_policy | string | — | Global default policy name; empty = per-mapping only |
max_body_size | string | — | Global maximum body size to scan |
exclude_groups | []string | — | Groups globally exempt from DLP scanning |
fail_closed | bool | false | Block on scan errors instead of pass-through |
Binary content extraction settings
TOML: [protection.dlp.extraction] · Env: HEXON_PROTECTION_DLP_EXTRACTION_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable binary content extraction |
formats | []string | — | Formats to extract |
max_entry_size | string | — | Max bytes per archive entry |
max_total_size | string | — | Max total extracted text |
max_entries | int | 1000 | Max archive entries to process |
max_depth | int | 3 | Recursion depth for nested content Range: 1–10. |
Ordered rules for group/mapping/direction-based policy routing
TOML: [protection.dlp.rules] · Env: HEXON_PROTECTION_DLP_RULES_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Rule name for logging and display |
groups | []string | — | User must be in one of these groups (empty = any user) |
mappings | []string | — | Applies to these mappings only (empty = all mappings) |
direction | string | both | Traffic direction Values: inbound, outbound, both. |
policy | string | — | Policy name to apply when rule matches Required. |
unauthenticated | bool | false | Match unauthenticated requests (no user/groups) |
WAF
TOML: [waf] · Env: HEXON_WAF_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable WAF protection |
paranoia | int | 1 | OWASP CRS paranoia level 1=low (few false positives), 2=medium, 3=high, 4=paranoid (many false positives) Values: 1, 2, 3, 4. Range: 1–4. Requires enabled=true. |
detection_only | bool | false | Log-only mode without blocking requests Useful for rule calibration; monitor logs for false positives before enforcing Requires enabled=true. |
self_contained | bool | false | Use self-contained blocking instead of anomaly scoring Self-contained: each rule blocks immediately. Anomaly scoring (default): accumulates scores and blocks if threshold exceeded Requires enabled=true. |
max_body_size | string | none | Maximum request body size to inspect Accepts units: B, KB, MB, GB, TB Requires enabled=true. |
inspect_body | bool | false | Inspect request bodies for attacks Enables request body inspection for injection attacks; requires max_body_size Requires enabled=true. |
inspect_response | bool | — | Inspect response bodies for data leakage Enabling this has a performance impact on every proxied response Requires enabled=true. |
disabled_rules | []int | — | OWASP CRS rule IDs to disable Use to suppress specific false positives by rule ID Requires enabled=true. |
disabled_tags | []string | — | OWASP CRS rule tags to disable Disables all rules with the given tag (e.g., attack-sqli, attack-xss) Requires enabled=true. |
Operator-defined custom WAF rules loaded alongside OWASP CRS
TOML: [waf.custom_rule] · Env: HEXON_WAF_CUSTOM_RULE_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
id | int | — | Unique rule ID Use 10000+ to avoid conflicts with OWASP CRS rule IDs Min: 10000. Required. |
name | string | — | Descriptive rule name Required. |
severity | string | — | Rule severity level Determines alert level in WAF logs; empty inherits from OWASP CRS defaults Values: CRITICAL, ERROR, WARNING, NOTICE. |
phase | int | — | Request processing phase 1=request headers, 2=request body, 3=response headers, 4=response body Values: 1, 2, 3, 4. Range: 1–4. Required. |
variable | string | — | Target variable to inspect Valid: ARGS, ARGS_NAMES, REQUEST_URI, REQUEST_HEADERS, REQUEST_BODY, REQUEST_COOKIES, RESPONSE_HEADERS, RESPONSE_BODY, REMOTE_ADDR, REQUEST_METHOD, REQUEST_FILENAME, FILES, FILES_NAMES Required. |
operator | string | — | Match operator type Valid: rx (regex), eq (equals), contains, beginsWith, endsWith, within, pm (phrase match), ge/gt/le/lt (numeric), streq (string equals), validateByteRange, validateUrlEncoding, validateUtf8Encoding Required. |
pattern | string | — | Pattern to match against the variable For rx operator, uses regex syntax; validated for ReDoS safety |
transform | []string | — | Transformations to apply before matching Valid: lowercase, uppercase, removeWhitespace, compressWhitespace, removeNulls, urlDecode, urlDecodeUni, htmlEntityDecode, jsDecode, cssDecode, base64Decode, hexDecode, length, normalizePath, trim, none |
action | string | pass | Action to take when rule matches deny=block with status code, pass=log only, drop=silent close, allow=skip remaining rules Values: deny, allow, pass, drop, redirect. |
status | int | 403 | HTTP status code for deny action Range: 100–599. Requires action=deny. |
message | string | none | Log message recorded when rule matches Recorded in WAF logs when rule matches; useful for identifying custom rules |
tags | []string | none | Tags for rule categorization and filtering Used for bulk rule management via disabled_tags |
SPIFFE
TOML: [spiffe] · Env: HEXON_SPIFFE_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable SPIFFE workload identity service Serves a separate ACME directory for workload certificate issuance |
default_ttl | duration | 24h | Default certificate TTL for workloads Short-lived certificates are preferred for zero-trust Min: 1m. Requires enabled=true. |
max_ttl | duration | 168h | Maximum certificate TTL Overrides per-workload TTL if exceeded; must be >= default_ttl Min: 1m. Requires enabled=true. |
order_timeout | duration | 1h | ACME order expiration timeout Orders not finalized within this duration are automatically expired Min: 1s. Requires enabled=true. |
path_prefix | string | /acme/spiffe | ACME path prefix for SPIFFE directory Directory served at https://<hostname><path_prefix>/directory Requires enabled=true. |
allowed_cidrs | []string | — | Global allowed CIDRs for SPIFFE ACME endpoints Per-workload allowed_cidrs further restricts via intersection Requires enabled=true. |
rate_limit_per_workload | int | 100 | Rate limit per workload in certificates per hour Prevents a compromised workload from exhausting CA resources Range: 0–10000. Requires enabled=true. |
allowed_key_algorithms | []string | EC-P256,EC-P384,RSA-2048,RSA-3072,RSA-4096,Ed25519 | Allowed key algorithms for account and CSR keys Values: EC-P256, EC-P384, RSA-2048, RSA-3072, RSA-4096, Ed25519. Requires enabled=true. |
Workload identity definitions
TOML: [spiffe.workloads] · Env: HEXON_SPIFFE_WORKLOADS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
identity | string | — | Workload identity name Becomes SPIFFE path /workload/<identity>; lowercase alphanumeric with hyphens, 2-63 chars Required. |
account_public_key | string | — | Account public key in PEM format PEM-encoded public key; workload holds private key in K8s Secret (never in Git) Required. |
sans | []string | — | Allowed DNS SANs for this workload’s certificates Empty means client-authentication-only certificate |
allowed_peers | []string | — | Allowed peer workload identities for mTLS Embedded in AllowedPeers OID extension; empty list means no peer mTLS allowed |
ttl | duration | — | Certificate TTL override for this workload Falls back to spiffe.default_ttl if not set; cannot exceed spiffe.max_ttl Min: 1m. |
allowed_cidrs | []string | — | Per-workload CIDR restriction Intersected with global allowed_cidrs; both must allow |
MCP
TOML: [mcp] · Env: HEXON_MCP_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable the MCP server endpoint Exposes admin CLI commands as tools for AI assistants. For OAuth-based MCP clients, also enable DCR in [authentication.oidc] |
path | string | /_hexon/mcp | URL path where the MCP endpoint is mounted Requires enabled=true. |
read_only | bool | true | Read-only mode blocks mutation subcommands When false, write operations still require two-phase confirmation code. When true, revoke/disconnect/reset/uneject are blocked Requires enabled=true. |
allowed_groups | []string | — | Groups allowed to use the MCP server MCP will not start if this is empty Requires enabled=true. Required. |
allowed_cidrs | []string | — | Allowed CIDR ranges for MCP access If empty, no IP restrictions apply Requires enabled=true. |
stateless | bool (optional) | true | Disable in-memory session tracking for stateless operation When false, enables SSE-based stateful sessions. When true (default), uses stateless HTTP polling Requires enabled=true. |
Named workflow playbooks exposed as MCP prompts
TOML: [mcp.playbooks] · Env: HEXON_MCP_PLAYBOOKS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Unique playbook name (lowercase alphanumeric + hyphens) Required. |
title | string | — | Display title for this playbook |
description | string | — | Short description of the playbook’s purpose |
category | string | — | Category for organizing playbooks Values: troubleshooting, deployment, maintenance, audit, security. |
steps | string | — | Markdown workflow steps the AI follows Plain markdown; reference arguments by name and the AI will substitute values Required. |
Named input arguments for this playbook
TOML: [mcp.playbooks.arguments] · Env: HEXON_MCP_PLAYBOOKS_ARGUMENTS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Argument name Required. |
description | string | — | Description shown to the user |
required | bool | false | Whether this argument must be provided |
LLM Assistant
TOML: [llm] · Env: HEXON_LLM_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable the LLM module for AI-powered admin interaction |
api_url | string | — | LLM provider API endpoint URL Requires enabled=true. Required. |
model | string | — | Model identifier to use for completions Check provider docs for current model IDs. Anthropic: claude-opus-4-6, claude-sonnet-4-5-20250929 Requires enabled=true. Required. |
provider | string | auto | API provider type; auto-detected from api_url when set to auto Values: auto, openai, anthropic, azure, ollama, gemini. Requires enabled=true. |
temperature | float | 0.3 | Sampling temperature for response generation Range: 0–2. Requires enabled=true. |
max_tokens | int | 4096 | Maximum tokens in LLM response Range: 256–32768. Requires enabled=true. |
timeout | duration | 60s | Maximum time to wait for an LLM API response Requires enabled=true. |
rate_limit | rate_limit | 10/1m | Per-user query rate limit Requires enabled=true. |
auto_execute_readonly | bool (optional) | true | Execute read-only commands without operator confirmation Requires enabled=true. |
allowed_commands | []string | none | Commands the LLM can execute; empty allows all MCP-visible commands Empty allows all MCP-visible commands Requires enabled=true. |
approval_required | []string | none | Commands that always require operator confirmation before execution Empty means only write operations require approval Requires enabled=true. |
approval_timeout | duration | 60s | Max time to wait for operator approval of write operations Requires enabled=true. |
max_write_ops_per_query | int | 3 | Max write operations requiring approval per AI query Range: 1–20. Requires enabled=true. |
max_tool_rounds | int | 15 | Max tool-calling rounds per AI query Range: 1–50. Requires enabled=true. |
required_groups | []string | — | Groups allowed to use LLM features LLM will not start if this is empty Requires enabled=true. Required. |
redact_sensitive | bool (optional) | true | Redact secrets and sensitive data from LLM context Requires enabled=true. |
max_history | int | 25 | Maximum conversation exchanges to retain per session for context continuity Range: 0–100. Requires enabled=true. |
custom_instructions | string | — | Custom persona and behavioral instructions for the AI assistant Empty uses built-in SRE persona. Supports multi-line TOML strings. Requires enabled=true. |
max_context_entries | int | 10 | Maximum session context entries per operator Range: 1–50. Requires enabled=true. |
max_context_length | int | 500 | Maximum character length per session context entry Range: 50–2000. Requires enabled=true. |
max_memory_entries | int | 50 | Maximum number of memory entries (insights + rules combined) Range: 0–500. Requires enabled=true. |
max_memory_length | int | 500 | Maximum character length per memory entry Range: 50–2000. Requires enabled=true. |
memory_ttl | duration | 8760h | Time-to-live for memory entries in cluster storage Default 1 year (8760h). Set to 0 for no expiry Requires enabled=true. |
prompt_caching_ttl | duration | — | Anthropic prompt caching TTL; empty=disabled, 5m=default, 1h=extended (2x write cost) Only applies to Anthropic provider. 5m is recommended. Requires enabled=true. |
token_tracking_weeks | int | 18 | Weeks of per-user token consumption history to retain; 0 disables tracking Range: 0–104. Requires enabled=true. |
ai_disclaimer | string | — | Disclaimer shown once per session when entering AI mode Empty uses default. Set to a single space to disable. Requires enabled=true. |
max_sleep_duration | duration | 5m | Max duration per sleep call in monitoring loops Requires enabled=true. |
max_sleeps_per_query | int | 60 | Max sleep iterations per AI query for monitoring loops Range: 1–500. Requires enabled=true. |
Log Intelligence
TOML: [log_intelligence] · Env: HEXON_LOGINTELLIGENCE_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | — | Enable log pattern analysis and anomaly detection |
window | duration | 60s | Analysis window size Sliding window for pattern frequency analysis Range: 10s–1h. Requires enabled=true. |
max_patterns | int | 1000 | Maximum unique patterns to track Memory-bound; higher values detect more unique log patterns Range: 100–10000. Requires enabled=true. |
anomaly_buffer_size | int | 100 | Maximum anomalies to retain Circular buffer; oldest anomalies evicted when full Range: 10–1000. Requires enabled=true. |
co_occurrence_window | duration | 5s | Co-occurrence proximity window Patterns occurring within this window are tracked as correlated Range: 1s–60s. Requires enabled=true. |
trace_max_age | duration | 5m | Maximum trace tracking age Traces older than this are evicted from tracking Range: 30s–1h. Requires enabled=true. |
trace_max_entries | int | 5000 | Maximum concurrent traces to track Memory-bound; limits concurrent trace correlation tracking Range: 100–50000. Requires enabled=true. |
RADIUS
TOML: [radius] · Env: HEXON_RADIUS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable RADIUS authentication service |
radsec_only | bool (optional) | true | RADSEC-only mode (TCP+TLS). When false, also accepts plain UDP RADIUS Requires enabled=true. |
network_interface | string | — | Network interface to bind RADIUS listeners to Defaults to service.network_interface if not set Requires enabled=true. |
radsec_port | int | 2083 | RADSEC TCP+TLS listener port (RFC 6614) Range: 1–65535. Requires enabled=true. |
plain_port | int | 1812 | Plain UDP RADIUS listener port (RFC 2865, only when radsec_only=false) Ignored when radsec_only=true Range: 1–65535. Requires enabled=true. |
accounting_port | int | 2083 | Accounting port (reserved for future) Range: 1–65535. Requires enabled=true. |
auth_methods | []string | — | Authentication methods evaluated in order x509 validates RADSEC peer certificate via authentication.x509 module. password uses LDAP bind. Values: x509, password. Requires enabled=true. |
ca_pem | string | — | External CA certificates for x509 client validation Requires enabled=true. |
idle_timeout | duration | 30s | RADSEC connection idle timeout Requires enabled=true. |
session_ttl | duration | 1h | How long RADIUS auth events are visible in session list Range: 1m-24h. Stateless protocol — sessions represent authorization events. Requires enabled=true. |
tls_min_version | string | 1.2 | Minimum TLS version for RADSEC connections 1.2 recommended, 1.1 only for legacy NAS devices Values: 1.1, 1.2, 1.3. Requires enabled=true. |
tls_cert | string | — | Server TLS certificate (file path or inline PEM) Requires enabled=true. |
auto_tls | bool | false | Issue TLS cert from internal ACME CA Requires enabled=true. |
geo_enabled | bool | — | Enable geo-IP restrictions for RADIUS Overrides [service] geo settings when set Requires enabled=true. |
geo_allow_countries | []string | — | ISO 3166-1 alpha-2 country codes to allow Requires geo_enabled=true. |
geo_deny_countries | []string | — | Country codes to deny (takes precedence over allow) Requires geo_enabled=true. |
geo_allow_asn | []string | — | ASN numbers to allow Requires geo_enabled=true. |
geo_deny_asn | []string | — | ASN numbers to deny Requires geo_enabled=true. |
geo_bypass_cidr | []string | — | CIDRs that bypass geo-IP checks Requires geo_enabled=true. |
time_enabled | bool | — | Enable time-based access restrictions for RADIUS Overrides [service] time settings when set Requires enabled=true. |
time_timezone | string | — | Default timezone for time-based restrictions IANA timezone format Requires time_enabled=true. |
time_allow_days | []string | — | Allowed days of the week Requires time_enabled=true. |
time_deny_days | []string | — | Denied days of the week (takes precedence over allow) Requires time_enabled=true. |
time_allow_hours | string | — | Allowed hours range in 24h format Requires time_enabled=true. |
time_deny_hours | string | — | Denied hours range (takes precedence over allow) Requires time_enabled=true. |
time_bypass_cidr | []string | — | CIDRs that bypass time-based restrictions Requires time_enabled=true. |
time_deny_message | string | — | Custom deny message for time restrictions Requires time_enabled=true. |
Per-country or per-CIDR time access windows
TOML: [radius.time_windows] · Env: HEXON_RADIUS_TIME_WINDOWS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
countries | []string | — | ISO 3166-1 alpha-2 country codes for this time window |
cidr | []string | — | IP ranges for this time window Takes precedence over country matching |
timezone | string | — | IANA timezone for this time window |
allow_days | []string | — | Allowed days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
deny_days | []string | — | Denied days of the week Deny takes precedence over allow Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
allow_hours | string | — | Allowed hours range in 24h format Format: HH:MM-HH:MM |
deny_hours | string | — | Denied hours range in 24h format Deny takes precedence over allow; format: HH:MM-HH:MM |
Multi-factor authentication (Access-Challenge or append mode)
TOML: [radius.mfa] · Env: HEXON_RADIUS_MFA_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable MFA for RADIUS password authentication |
mode | string | challenge | MFA mode ‘challenge’ uses Access-Challenge (RFC 2865). ‘append’ concatenates password+code. Values: challenge, append. Requires enabled=true. |
methods | []string | totp | MFA methods in priority order ‘totp’ checks enrollment first. ‘otp’ sends email OTP (requires challenge mode). Values: totp, otp. Requires enabled=true. |
separator | string | : | Separator between password and code in append mode Split at last occurrence to handle passwords containing the separator. Requires enabled=true. |
challenge_timeout | duration | 60s | Time allowed for user to respond to Access-Challenge Range: 10s-300s Requires enabled=true. |
required_groups | []string | — | Only require MFA for users in these groups (empty = all users) Requires enabled=true. |
skip_if_unavailable | bool | false | Allow auth without MFA if no method available When false, users without TOTP enrollment are rejected. Requires enabled=true. |
otp_ttl | duration | 5m | Email OTP validity period Range: 1m-10m Requires enabled=true. |
otp_code_length | int | 6 | Email OTP code length Range: 4–8. Requires enabled=true. |
Rate limiting and DoS protection
TOML: [radius.rate_limit] · Env: HEXON_RADIUS_RATE_LIMIT_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
max_requests_per_second_per_nas | int | 100 | Per-NAS request rate limit Range: 1–100000. |
max_auth_attempts_per_user | int | 5 | Failed attempts before lockout Range: 1–100. |
auth_lockout_duration | duration | 5m | Lockout period after max failures |
max_concurrent_authentications | int | 1000 | Global concurrent auth limit Range: 1–100000. |
NAS (Network Access Server) client definitions
TOML: [radius.client] · Env: HEXON_RADIUS_CLIENT_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Unique client identifier Required. |
description | string | — | Optional description for audit logs |
cidr | string | — | IP range of the NAS (defaults to 0.0.0.0/0 if empty) |
mfa_override | string | — | Override MFA mode for this client Empty inherits global [radius.mfa]. ‘off’ disables MFA for this client. Values: “, off, challenge, append. |
geo_enabled | bool (optional) | — | Override geo-IP restriction for this client nil=inherit, false=disable, true=use client settings |
geo_allow_countries | []string | — | Override allowed countries for this client |
geo_deny_countries | []string | — | Override denied countries for this client |
geo_allow_asn | []string | — | Override allowed ASNs for this client |
geo_deny_asn | []string | — | Override denied ASNs for this client |
geo_bypass_cidr | []string | — | Override bypass CIDRs for this client |
time_enabled | bool (optional) | — | Override time restriction for this client nil=inherit, false=disable, true=use client settings |
time_timezone | string | — | Override timezone for this client |
time_allow_days | []string | — | Override allowed days for this client |
time_deny_days | []string | — | Override denied days for this client |
time_allow_hours | string | — | Override allowed hours for this client |
time_deny_hours | string | — | Override denied hours for this client |
time_bypass_cidr | []string | — | Override bypass CIDRs for this client |
time_deny_message | string | — | Override deny message for this client |
tls_cert | string | — | Server cert override for this NAS (file path or inline PEM) |
client_ca_pem | string | — | CA to verify this NAS device’s client certificate (mTLS) |
Override time windows for this client
TOML: [radius.client.time_windows] · Env: HEXON_RADIUS_CLIENT_TIME_WINDOWS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
countries | []string | — | ISO 3166-1 alpha-2 country codes for this time window |
cidr | []string | — | IP ranges for this time window Takes precedence over country matching |
timezone | string | — | IANA timezone for this time window |
allow_days | []string | — | Allowed days of the week Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
deny_days | []string | — | Denied days of the week Deny takes precedence over allow Values: Mon, Tue, Wed, Thu, Fri, Sat, Sun. |
allow_hours | string | — | Allowed hours range in 24h format Format: HH:MM-HH:MM |
deny_hours | string | — | Denied hours range in 24h format Deny takes precedence over allow; format: HH:MM-HH:MM |
Group-based authorization mappings
TOML: [radius.mapping] · Env: HEXON_RADIUS_MAPPING_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
name | string | — | Display name for logging/metrics Required. |
groups | []string | — | Required groups (ANY match, empty = catch-all) |
priority | int | 0 | Evaluation order (higher = first) |
Client Access
TOML: [client_access] · Env: HEXON_CLIENTACCESS_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable QUIC client access listener for transparent L3 network access |
hostname | string | — | Hostname for client access listener Use when running behind a CDN; defaults to service hostname Requires enabled=true. |
port | int | — | Dedicated QUIC port for client access connections Must differ from service.port, forward_proxy.port, and connector.port Range: 1–65535. Requires enabled=true. Required. |
network_interface | string | — | Network interface to bind client access listener Defaults to service.network_interface if not set Requires enabled=true. |
cert | string | — | TLS certificate for client access hostname File path or inline PEM; falls back to service certificate if not set Requires enabled=true. |
subnet | string | 100.64.208.0/22 | Virtual IP pool subnet for client access CGN space (RFC 6598); use a dedicated subnet to avoid conflicts with other internal networks Requires enabled=true. |
gateway_ip | string | 100.64.208.1 | Gateway virtual IP within the subnet Requires enabled=true. |
dns_upstream | []string | — | Internal DNS servers for split DNS resolution Requires enabled=true. |
dns_domains | []string | — | Split DNS domains pushed to clients Requires enabled=true. |
cidrs | []string | — | Additional CIDR routes pushed to all clients Merged with per-user routes from firewall rules; use when firewall aliases only have hostname wildcards Requires enabled=true. |
heartbeat_interval | duration | 30s | Heartbeat interval Requires enabled=true. |
token_refresh_interval | duration | 45m | Token refresh interval Requires enabled=true. |
max_idle_timeout | duration | 5m | Disconnect after idle period with no streams Requires enabled=true. |
max_clients | int | 1000 | Maximum concurrent client connections 0 means unlimited Min: 0. Requires enabled=true. |
max_streams_per_client | int | 100 | Maximum concurrent streams per client Min: 1. Requires enabled=true. |
required_groups | []string | — | Groups required for client access; empty allows any authenticated user Groups from [identity] directory. User must have ANY of the listed groups Requires enabled=true. |
dns_rate_limit | int | 100 | Maximum DNS queries per second per client Min: 1. Requires enabled=true. |
vip_reservation_ttl | duration | 5m | How long to reserve VIP after disconnect for reconnecting clients Set to 0 to disable; reconnecting clients get the same VIP within this window Requires enabled=true. |
Admin
TOML: [admin] · Env: HEXON_ADMIN_<KEY>
| Key | Type | Default | Description |
|---|---|---|---|
audit_trail | bool (optional) | true | Enable command audit trail Records all admin CLI commands cluster-wide for operational visibility |
audit_ttl | duration | 24h | Audit entry retention duration |
audit_max_entries | int | 10000 | Maximum audit entries to retain (0 = TTL-only) Min: 0. |