Files
mailcloak/README.md
peio 57966de4fa
All checks were successful
release / build (amd64, linux) (push) Successful in 1m32s
feat: enhance logging and refactor database handling
2026-01-23 17:54:15 +00:00

3.0 KiB
Raw Permalink Blame History

mailcloak

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):
    • RCPT stage: accepts if the recipient exists in Keycloak (primary email) or as a local alias in SQLite.
    • MAIL stage (authenticated submissions): accepts only if the sender is the users primary Keycloak email or one of their aliases.
  • Socketmap service: exposes an alias map to Postfix, rewriting alias -> username@domain.

Project layout

  • cmd/mailcloak/ main package entrypoint
  • internal/mailcloak/ daemon sources
  • go.mod / go.sum Go module files
  • configs/config.yaml.sample sample config to copy to /etc/mailcloak/config.yaml
  • configs/openrc-mailcloak OpenRC service file
  • db-init.sql SQLite schema (also auto-created by the app)
  • mailcloakctl CLI helper to manage aliases

Build the binary

From the repository root:

make build

To install system-wide:

make install

To run locally:

make run

Configuration

Copy the sample config and edit it:

install -d -m 0750 -o root -g postfix /etc/mailcloak
cp configs/config.yaml.sample /etc/mailcloak/config.yaml

Key settings:

  • keycloak.* must point to your Keycloak realm and a client with permission to query users.
  • policy.domain is the email domain enforced by the policy.
  • sqlite.path is the aliases database path.
  • sockets.* must be under the Postfix chroot (usually /var/spool/postfix).

Mailcloak database

Aliases

You can manage aliases using the helper script:

./mailcloakctl aliases add alias@example.com username
./mailcloakctl aliases list

The script creates the schema automatically if missing.

Apps (Dovecot app passwords)

The helper script also manages application credentials. The application password is a token: updating the application ID and password is handled by the script and stored as a hash in SQLite. Dovecot can verify these credentials using plain authentication against the stored hash. Applications are restricted to sending emails only (they cannot receive them) and may use only their authorized sender addresses.

Examples:

./mailcloakctl apps add my-app-id "my-app-token"
./mailcloakctl apps allow my-app-id sender@example.com
./mailcloakctl apps list
./mailcloakctl apps disallow my-app-id sender@example.com
./mailcloakctl apps del my-app-id

Postfix integration (example)

Policy service (smtpd_recipient_restrictions):

check_policy_service unix:private/mailcloak

Socketmap (virtual_alias_maps):

socketmap:unix:private/mailcloak-socketmap:alias

OpenRC

Use the provided service file:

cp configs/openrc-mailcloak /etc/init.d/mailcloak
rc-update add mailcloak default
rc-service mailcloak start

Notes

  • If Keycloak is unavailable, the policy returns 451 by default (configurable via policy.keycloak_failure_mode).
  • The policy caches lookups for policy.cache_ttl_seconds.