3. Configuration
halon-web loads the non-reloadable configuration from /etc/halon/web.yaml.
It is described by, and can be validated with, the
web.schema.json
JSON schema (included in our Visual Studio Code integration).
The default startup configuration file in /opt/halon/web/share can normally be used as a base:
# cp /opt/halon/web/share/web.yaml /etc/halon/
3.1. Listener directives
- listeners[]
The web administration must have one or more listen directives, which specify which TCP port and address to listen on. Required.
- listeners[].port
Which TCP port to listen on. Required.
- listeners[].baseurl
An optional public base URL (scheme, host and optional port, e.g. https://web.example.com).
- listeners[].basepath
An optional URL path prefix under which the web administration is served, for example /web.
- listeners[].address
IPv4 or IPv6 address to listen on. The default is to listen to all IPv4 and IPv6 addresses.
- listeners[].tls
TLS settings for the listener.
- listeners[].tls.pki
The X.509 certificate and private key. The private key and certificate should have either a
pathordataproperty.pki: certificate: data: |- -----BEGIN CERTIFICATE----- ... privatekey: data: |- -----BEGIN PRIVATE KEY----- ...
- listeners[].tls.ciphers
Cipher suite specification
- listeners[].tls.protocols.min
Minimum TLS version to allow
- listeners[].tls.protocols.max
Maximum TLS version to allow
- listeners[].proxy.trust
Can either be a boolean or a list of IP addresses and subnets to trust as being reverse proxies. If it’s a boolean and it’s set to true it will trust all IP-addresses and subnets as being reverse proxies.
listeners: - proxy: trust: - 1.2.3.4 ...
- listeners[].proxy.userheader
This setting allows for automatic login when behind a reverse proxy. If configured, this header should be set by the reverse proxy and contain the username for the session.
listeners: - proxy: userheader: X-Proxy-User ...
- listeners[].proxy.groupheader
When logging in via reverse proxy. This header is set to assign group permissions for the user.
3.2. Host directives
- hosts[]
The web administration must have one or more host directives, which specify which HTTP/JSON endpoints to connect to. Required.
- hosts[].port
Which TCP port to connect to. Required.
- hosts[].address
Hostname, IPv4 address or IPv6 address to connect to. Required.
- hosts[].name
The display name. The default is the address. Cannot be combined with the expand option.
- hosts[].expand
Add all IP addresses for the hostname as unique hosts. The default is false. Mutually exclusive with
hosts[].kubernetes.
- hosts[].kubernetes
The Kubernetes settings. Mutually exclusive with
hosts[].expand.
- hosts[].kubernetes.namespace
The namespace for the smtpd StatefulSet`.
- hosts[].kubernetes.name
The name for the smtpd StatefulSet.
- hosts[].kubernetes.address
How to address each pod: ip (default, e.g. 10.42.0.12), hostname (e.g. halon-smtpd-0.halon-smtpd.default), or ip-hostname (e.g. 10-42-0-12.halon-smtpd.default). DNS names use the pod’s subdomain and namespace. Resolution requires a matching service endpoint record. CoreDNS uses an endpoint’s hostname when set; the dashed IP is a fallback for unnamed endpoints, so the two DNS forms are not interchangeable.
- hosts[].kubernetes.clusterdomain
The cluster DNS domain, e.g. cluster.local, used by the DNS address modes. A non-empty value appends .svc.<clusterdomain>; otherwise the resolver must supply that suffix through its DNS search list.
- hosts[].tls.enabled
If TLS should be used for the requests. The default is false.
- hosts[].tls.verify
If the server certificate should be verified. The default is true.
- hosts[].tls.verifyname
Hostname to verify against the server certificate’s CN and SAN.
- hosts[].secret
The secret that will be sent in the requests using the X-API-Key header.
- hosts[].processes[]
The processes that are running on the host. The default is smtpd and rated.
- hosts[].timeout
The timeout against the node (in seconds). The default is 5.
- reresolve
Automatically re-resolve the hostnames of the hosts every x seconds.
3.3. Group directives
- groups[]
You can set up groups to easily manage permissions instead of setting them on each user. Groups can also be used when logging in via reverse proxy.
- groups[].name
The name of the group Required
- groups[].features.preview.enabled
If the user should be able to preview messages. The default is true.
- groups[].features.readonly
If the user should only have readonly access. The default is false.
- groups[].features.writable
If group[].features.readonly is set to true you can set an array of commands that the group should be able to execute.
- groups[].features.memory.enabled
If the user should be able to view the memory page. The default is true.
- groups[].features.rates.enabled
If the user should be able to view the rates page. The default is true.
- groups[].features.datamasking
Configure the group datamasking settings
Note
Enabling
localpart,subject,retryreason, orsaslusernamemasking also disablesgroups[].features.preview.enabledWarning
The
localpart,subject,retryreason, andsaslusernamesettings do not apply for the history feature. Use thehistorydatamasking setting to hide history source paths in the web administration. To redact data in the stored history logs, use theredactoption in the history-elastic plugin.
- groups[].features.datamasking.localpart
If the localpart of a mail should be masked for the user. The default is false
- groups[].features.datamasking.subject
If the subject of a mail should be masked for the user. The default is false
- groups[].features.datamasking.retryreason
If the retryreason of a mail should be masked for the user. The default is false
- groups[].features.datamasking.saslusername
If the salusername of a mail should be masked for the user. The default is false
- groups[].features.datamasking.history
History source paths to hide and disallow in queries. True masks the path and its descendants. The timestamp and transaction identifier are reserved. Charts that read or filter on masked paths are hidden.
The following example uses the delivery-attempts index template:
datamasking: history: sender: true senderlocalpart: true recipient: true recipientlocalpart: true smtpreasonnormalized: true smtpreason: true
3.4. User directives
- users[]
The web administration must have one or more user directives, which specify which users can log in to the web administration. Required.
- users[].username
The username. Required.
- users[].password
The password.
Note
The password needs to be encrypted using bcrypt. You can run the following command to generate a password:
$ /opt/halon/web/bin/generatepass
- users[].group
The group the user should be assigned to.
- users[].features.preview.enabled
If the user should be able to preview messages. The default is true.
- users[].features.readonly
If the user should only have readonly access. The default is false.
- users[].features.writable
If users[].features.readonly is set to true you can set an array of commands that the user should be able to execute.
- users[].features.memory.enabled
If the user should be able to view the memory page. The default is true.
- users[].features.rates.enabled
If the user should be able to view the rates page. The default is true.
- users[].features.datamasking
Configure the users datamasking settings
Note
Enabling
localpart,subject,retryreason, orsaslusernamemasking also disablesusers[].features.preview.enabledWarning
The
localpart,subject,retryreason, andsaslusernamesettings do not apply for the history feature. Use thehistorydatamasking setting to hide history source paths in the web administration. To redact data in the stored history logs, use theredactoption in the history-elastic plugin.
- users[].features.datamasking.localpart
If the localpart of a mail should be masked for the user. The default is false
- users[].features.datamasking.subject
If the subject of a mail should be masked for the user. The default is false
- users[].features.datamasking.retryreason
If the retryreason of a mail should be masked for the user. The default is false
- users[].features.datamasking.saslusername
If the salusername of a mail should be masked for the user. The default is false
- users[].features.datamasking.history
History source paths to hide and disallow in queries. True masks the path and its descendants. The timestamp and transaction identifier are reserved. Charts that read or filter on masked paths are hidden.
The following example uses the delivery-attempts index template:
datamasking: history: senderlocalpart: true recipientlocalpart: true smtpreason: true smtpreasonnormalized: true
3.5. OIDC directives
- oidc
OpenID Connect (OIDC) settings. This is an object with two required fields:
enabledandprovider.
- oidc.enabled
If OIDC should be enabled. Required.
- oidc.provider
The OIDC provider configuration object. Required. The provider must contain the unique provider ID, discovery URL, client ID and client secret.
- oidc.provider.providerid
The unique provider ID. Required.
- oidc.provider.discoveryurl
The OIDC discovery URL. Required.
- oidc.provider.clientid
The OIDC client ID. Required.
- oidc.provider.clientsecret
The OIDC client secret. Required.
- oidc.provider.pkce
If PKCE should be used. The default is
true.
- oidc.provider.groupclaim
The claim containing the user’s group(s). Values from this claim are matched against configured groups in the YAML config. If this option is set,
oidc.provider.allowedgroups[]becomes required.
- oidc.provider.allowedgroups[]
List of allowed config group names that OIDC users may belong to. Each entry is a non-empty string. This option is required when
oidc.provider.groupclaimis set and must not be present otherwise.
- oidc.provider.displayname
The display name for the provider.
- oidc.provider.displayicon
An icon for the provider. Two alternatives supported:
Inline data + extension:
displayicon: data: |- iVBORw0KGgoAAAANSUhEUg... extension: .png
Path to file + extension (optional):
displayicon: path: /opt/halon/web/share/icons/myprovider.svg
Supported extensions are
.pngand.svg.
3.6. MCP directives
A MCP server that provides tools to interact with Halon hosts and their processes.
Important
When mcp.enabled is true, every listener must have a listeners[].baseurl.
When both MCP and OAuth are enabled, the following requirements also apply:
databasemust be configured.environment.session.secretmust be configured.A custom
listeners[].basepathis not supported.Every listener’s
listeners[].baseurlmust use HTTPS, except for loopback hosts:localhostor[::1].
Use users[].features.datamasking or groups[].features.datamasking to hide sensitive data from the LLM when using MCP.
- mcp.enabled
If the MCP endpoint should be enabled. The default is false. The MCP endpoint will be available at
https://<your-web-instance>/mcp.
- mcp.oauth.enabled
If OAuth should be enabled for the MCP endpoint. The default is true. The MCP client inherits the permissions of the user who signed in.
Warning
Disabling OAuth means no authentication is required to access the MCP endpoint. Only disable it in a trusted environment or when behind an MCP gateway.
- mcp.oauth.accesstoken.expiresin
How long an MCP access token is valid (in seconds). Clients refresh it when it expires. The default is 3600.
- mcp.oauth.refreshtoken.expiresin
How long an MCP client stays signed in without being used (in seconds). Each token refresh starts the period again. The default is 2592000.
3.7. Database directives
- database
The database settings (knex) for storing per-user settings.
Note
A SQLite3 example would look like this. In this example make sure the
/var/lib/halon/webfolder is writeable by theenvironment.privdrop.userorenvironment.privdrop.group.database: client: sqlite3 connection: filename: /var/lib/halon/web/web.sqlite
- database.client
The included client drivers are sqlite3, pg and mysql.
- database.connection
The client driver connection string or object. See knex manual for specifics of each database driver.
3.8. Elasticsearch directives
This enables the history feature in the web administration.
- elasticsearch
The settings for Elasticsearch.
- elasticsearch.index.history
The index pattern for the history logs.
- elasticsearch.index.policyd
The index pattern for the policyd logs.
- elasticsearch.nodes[]
A list of Elasticsearch nodes.
- elasticsearch.nodes[].url
The Elasticsearch URL to connect to.
- elasticsearch.auth
Specify any credentials for authentication.
- elasticsearch.auth.username
The username for basic authentication.
- elasticsearch.auth.password
The password for basic authentication.
3.9. Other directives
- instance
The name that will be shown in the document title.
- solution
The solution, can be either engage or protect.
- accounting
If accounting logs should be generated. The default is false.
- maxmind.geoip.path
The directory to MaxMind’s GeoIP database. The default is /var/lib/GeoIP/GeoLite2-Country.mmdb.
- policyd.port
The port for the
policydservice.
- policyd.address
The address for the
policydservice.
- policyd.tls.enabled
If TLS should be used for the requests. The default is false.
- policyd.tls.verify
If the server certificate should be verified. The default is true.
- policyd.secret
The secret that will be sent in the requests using the X-API-Key header.
- trustedorigins[]
A list of trusted origins. This list should only contain domains or wildcard domains (eg.
*.example.com).
3.10. Environment directives
- environment.privdrop.user
The user to run the process as.
- environment.privdrop.group
The group to run the process as.
Tip
The privdrop.user and privdrop.group settings to use will depend on your Linux distribution:
For Ubuntu, suitable values are
nobodyandnogroupFor RHEL and related distibutions, the values are
nobodyandnobody.
- environment.session.secret
The secret used for encryption, signing, and hashing. The default is to generate a unique UUID during startup.
Note
The minimum length is 32 characters.
- environment.session.secure
If secure cookies should be used. The default is
trueiflisteners[].tls.pkiis configured, otherwise false.Note
It’s recommended to set this to true when doing SSL termination at a reverse proxy.