Module identity
Expand description
Approval identity resolution seam.
Maps a transport-derived ApprovalPrincipal to the approver groups it belongs
to, so the broker can enforce a policy’s required-group membership and quorum.
This is a PERMANENT seam, not a stopgap. Many approvals are channel-native acts
by a user known only by their channel identity - a paired gateway user, a forge
login - who may never hold a first-class auth account. The identity such a
principal carries is transport-DERIVED (built from the resolved/paired
connection, never from a client-supplied body), so it is a legitimate trust
anchor for granting approval rights. A future auth system AUGMENTS this by adding
another resolver alongside the config-backed one (a junction of identity
sources); it does not replace channel-provided identities. That resolver is where
canonical-identity LINKING belongs: one person’s several channel identities (e.g.
github:octocat, discord:123..., email:user@example.invalid) map to a
single canonical user, so any of them resolves to the same groups. Until then,
the config-backed resolver can grant a group to each channel identity directly.
Structs§
- Local
Config Approval Identity Resolver - Config-backed resolver over
[sop.approval].groups.*.members. Stateless: it reads the config handed to it on each call, so there is no second copy of the membership map to go stale. A member entry may be source-qualified (<source>:<identity>, e.g.http:<subject>,agent:<alias>) to grant rights on ONE transport only - so a subject on the gateway and the same string on the agent tool do not collide - or a bare identity to grant it from any source. Channel principals are stricter: they match onlychannel:<channel-key>:<sender>, neverchannel:<sender>or a bare sender, so same-looking platform ids from different channel aliases cannot collide. A principal with no identity (e.g. the system tick) belongs to no group.
Traits§
- Approval
Identity Resolver - Resolve an approval principal to the approver groups it is a member of, against
the live
[sop.approval]config passed in at use-time (the single source of truth - never a cloned copy that could drift on reload).