2.3 KiB
2.3 KiB
kc-policy
Postfix policy + socketmap daemon that validates recipients/senders against Keycloak and serves a local aliases SQLite database.
What it does
- Policy service (Postfix policy delegation):
RCPTstage: accepts if the recipient exists in Keycloak (primary email) or as a local alias in SQLite.MAILstage (authenticated submissions): accepts only if the sender is the user’s primary Keycloak email or one of their aliases.
- Socketmap service: exposes an
aliasmap to Postfix, rewriting alias ->username@domain.
Project layout
src/– Go module and daemon sourcesconfigs/config.yaml.sample– sample config to copy to/etc/kc-policy/config.yamlconfigs/openrc-kc-policy– OpenRC service filedb-init.sql– SQLite schema (also auto-created by the app)aliasctl.py– CLI helper to manage aliases
Build the binary
From the repository root:
cd src
go mod download
go build -o ../kc-policy .
To install system-wide:
install -m 0755 ../kc-policy /usr/local/sbin/kc-policy
Configuration
Copy the sample config and edit it:
install -d -m 0750 -o root -g postfix /etc/kc-policy
cp configs/config.yaml.sample /etc/kc-policy/config.yaml
Key settings:
keycloak.*must point to your Keycloak realm and a client with permission to query users.policy.domainis the email domain enforced by the policy.sqlite.pathis the aliases database path.sockets.*must be under the Postfix chroot (usually/var/spool/postfix).
Alias database
You can manage aliases using the helper script:
./aliasctl.py --db /var/lib/kc-policy/aliases.db add alias@example.com username
./aliasctl.py --db /var/lib/kc-policy/aliases.db list
The script creates the schema automatically if missing.
Postfix integration (example)
Policy service (smtpd_recipient_restrictions):
check_policy_service unix:private/kc-policy
Socketmap (virtual_alias_maps):
socketmap:unix:private/kc-socketmap:alias
OpenRC
Use the provided service file:
cp configs/openrc-kc-policy /etc/init.d/kc-policy
rc-update add kc-policy default
rc-service kc-policy start
Notes
- If Keycloak is unavailable, the policy returns
451by default (configurable viapolicy.keycloak_failure_mode). - The policy caches lookups for
policy.cache_ttl_seconds.