Add opt-in tenant-to-client bindings for invitation mail
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 35s
Account journey acceptance / journeys (push) Failing after 7s

User-engine side of EMAIL-WP-0008: USER_ENGINE_MAIL_CLIENT_BINDINGS maps
tenant globs to a single client_id carried on invitation mail envelopes
only. Unmatched or conflicting tenants fail as mail_binding_denied before
either lane is contacted, and the outbox now records that reason instead
of collapsing it to delivery_unavailable. Unset keeps legacy envelopes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 445231@bnt-lap001
Assistant-Session: 024a807e-0cc5-4f2c-bc8a-b83322d1395d
This commit is contained in:
tegwick 2026-10-09 11:21:17 +02:00
parent a9360842f8
commit adf6e992a6
9 changed files with 199 additions and 2 deletions

View file

@ -71,6 +71,17 @@ Enabling it also requires the verification adapter and allow-lists:
The service fails closed when those settings are absent. Do not add a
placeholder or reused credential to turn the flag on.
`USER_ENGINE_MAIL_CLIENT_BINDINGS` is optional and unset by default. When
unset, invitation mail envelopes keep the legacy shape (no `client_id`). When
set, it is a JSON list of `[tenant_glob, client_id]` pairs (1–128 rows, unique
globs, case-sensitive whole-string `*`/`?` matching), for example
`[["tenant:*-family", "coulomb-social"]]`. Each invitation mail carries the
single matching `client_id`, so email-connect can admit it as a scoped caller
(EMAIL-WP-0008). A tenant with no match, or with matches naming different
clients, is denied as `mail_binding_denied` before either delivery lane is
contacted; the platform event never carries `client_id`. An invalid value stops
startup — it never falls back to the legacy shape.
## Authenticator management handoff