Environment Variables
Every TOML configuration field can be overridden with an environment variable. This is the primary mechanism for Kubernetes deployments, Docker, and CI/CD pipelines where you need per-environment configuration without modifying files.
Precedence
Configuration values are resolved in this order (highest priority wins):
HEXON_*environment variables — auto-computed overrides (highest priority)${VAR}template substitution — arbitrary env var names embedded in TOML values- TOML literal values — from config files (single file, directory, or Git repository)
- Defaults — security-focused defaults applied automatically
Naming Convention
Every TOML field maps to an environment variable:
HEXON_<SECTION>_<KEY>- Section and key names are uppercased
- Dots become underscores
- Non-alphanumeric characters become underscores
Examples
| TOML Field | Environment Variable |
|---|---|
[service] hostname | HEXON_SERVICE_HOSTNAME |
[service] port | HEXON_SERVICE_PORT |
[cluster] cluster_key | HEXON_CLUSTER_CLUSTER_KEY |
[vpn.network] subnet | HEXON_VPN_NETWORK_SUBNET |
[telemetry] log_level | HEXON_TELEMETRY_LOG_LEVEL |
[smtp] host | HEXON_SMTP_HOST |
Array Items
For array elements (like OIDC clients or proxy mappings), the item’s name or app field becomes part of the variable name:
HEXON_<SECTION>_<ARRAY>_<ITEMNAME>_<KEY>Item names are sanitized: uppercased, non-alphanumeric characters replaced with underscores.
| TOML Field | Environment Variable |
|---|---|
[[authentication.oidc.clients]] name=“MyApp” → client_secret | HEXON_AUTHENTICATION_OIDC_CLIENTS_MYAPP_CLIENTSECRET |
Important: Only items already defined in the TOML file can be overridden via environment variables. You cannot create new array items with env vars — define them in TOML first, then override specific fields.
Type Conversion
Environment variables are automatically converted to the correct type:
| Type | Format | Example |
|---|---|---|
| String | As-is | HEXON_SERVICE_HOSTNAME=access.example.com |
| Integer | Numeric | HEXON_SERVICE_PORT=8443 |
| Boolean | true/false, 1/0, yes/no (case-insensitive) | HEXON_CLUSTER_CLUSTER_MODE=true |
| Duration | Go duration string | HEXON_BASTION_SESSION_TTL=8h |
| Array | Comma-separated | HEXON_SERVICE_PROXY_CIDR=10.0.0.0/8,172.16.0.0/12 |
Template Substitution
Embed arbitrary environment variable names directly in TOML values using ${VAR} syntax:
[authentication.oidc.clients]name = "my-app"client_secret = "${VAULT_OIDC_SECRET}"
[smtp]password = "${SMTP_PASSWORD}"This lets operators use their own naming conventions (e.g., Vault-injected secrets) without being constrained to the HEXON_* prefix.
Rules:
- Pattern:
${VARNAME}— braces are required ($VARwithout braces is not expanded) - Unset variables are left as the literal string
${VARNAME} - No recursive expansion
- Variable names must match
[a-zA-Z_][a-zA-Z0-9_]*
GitOps Variables
These dedicated environment variables control Git-based configuration loading:
| Variable | Description | Default |
|---|---|---|
CONFIG_GIT_REPO | Repository URL (HTTPS or SSH) | — |
CONFIG_GIT_BRANCH | Branch name | — |
CONFIG_GIT_PATH | Local clone path | /tmp/hexon-config |
CONFIG_GIT_POLLING | Enable remote polling | false |
CONFIG_GIT_POLLING_TIME | Polling interval (min: 30s) | 5m |
CONFIG_GIT_USER | HTTPS authentication username | — |
CONFIG_GIT_TOKEN | HTTPS authentication token/PAT | — |
CONFIG_GIT_SSH_KEY | SSH private key (inline PEM or file path) | — |
Directory-Based Config
Pass a directory path instead of a file:
./hexongateway -config /etc/hexon/conf.d/All *.toml files are merged recursively in alphabetical order:
- Maps merge recursively (nested sections combine)
- Arrays concatenate (proxy mappings from multiple files combine)
- Scalars use last-wins (later files override earlier ones)
Use numeric prefixes to control ordering:
/etc/hexon/conf.d/ 00-base.toml # Core service config 10-identity.toml # LDAP/SCIM identity 50-proxy.toml # Proxy mappings 90-overrides.toml # Environment-specific overridesWorld-writable files (chmod 0002) are rejected for security.
Discovering Variable Names
Use the admin CLI to see the exact environment variable for every field:
# Show all fields with their env var namesconfig describe service
# Show which HEXON_* variables are currently in effectconfig envDocker / Kubernetes Example
environment: HEXON_SERVICE_HOSTNAME: "access.example.com" HEXON_SERVICE_PORT: "443" HEXON_CLUSTER_CLUSTER_MODE: "true" HEXON_CLUSTER_CLUSTER_KEY: "your-32-character-secret-key" HEXON_SMTP_HOST: "smtp.example.com" HEXON_SMTP_PORT: "465" HEXON_SMTP_ENCRYPTION: "ssl" HEXON_SMTP_PASSWORD: "${VAULT_SMTP_PASSWORD}"# Kubernetes ConfigMap + SecretapiVersion: v1kind: ConfigMapmetadata: name: hexon-configdata: HEXON_SERVICE_HOSTNAME: "access.example.com" HEXON_CLUSTER_CLUSTER_MODE: "true"---apiVersion: v1kind: Secretmetadata: name: hexon-secretsstringData: HEXON_CLUSTER_CLUSTER_KEY: "your-32-character-secret-key" HEXON_SMTP_PASSWORD: "smtp-password"Hot Reload
Configuration changes are detected automatically via SHA-256 hash comparison — not file modification time. When a change is detected:
- Callbacks fire within a 100ms throttle window (rapid changes coalesce)
- Only changed sections trigger reloads
- Per-key diff history is maintained (viewable via
config diff) - Cold restart required only for: listener bind address/port, TLS certificate paths at startup