Skip to main content

Module identity

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§

LocalConfigApprovalIdentityResolver
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 only channel:<channel-key>:<sender>, never channel:<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§

ApprovalIdentityResolver
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).