feat: centralize access explanation subject selection

This commit is contained in:
2026-08-20 06:16:43 +02:00
parent 0aae6f0539
commit fd90b60430
6 changed files with 163 additions and 2 deletions
+24
View File
@@ -24,6 +24,9 @@ CAPABILITY_ACCESS_TENANT_PROVISIONER = "access.tenantProvisioner"
CAPABILITY_ACCESS_FIRST_ADMIN_PROVISIONER = "access.firstAdminProvisioner"
CAPABILITY_ACCESS_ADMINISTRATION = "access.administration"
CAPABILITY_ACCESS_GOVERNANCE_MATERIALIZER = "access.governanceMaterializer"
CAPABILITY_POLICY_ACCESS_EXPLANATION_SUBJECTS = (
"policy.access_explanation_subjects"
)
CAPABILITY_TENANCY_TENANT_RESOLVER = "tenancy.tenantResolver"
CAPABILITY_AUDIT_SINK = "audit.sink"
CAPABILITY_AUDIT_RECORDER = "audit.recorder"
@@ -177,6 +180,15 @@ class PrincipalRef:
)
@dataclass(frozen=True, slots=True)
class AccessExplanationSubjectDecision:
allow_other_users: bool
reason: str
source: str
required_scope: str | None = None
provenance: Mapping[str, object] = field(default_factory=dict)
def _optional_str(value: object | None) -> str | None:
return str(value) if value is not None else None
@@ -564,6 +576,18 @@ class AccessExplanationService(Protocol):
...
@runtime_checkable
class AccessExplanationSubjectPolicy(Protocol):
def decide_subject_selection(
self,
session: object,
principal: PrincipalRef,
*,
tenant_id: str,
) -> AccessExplanationSubjectDecision:
...
@runtime_checkable
class TenantAccessProvisioner(Protocol):
def ensure_default_roles(self, session: object, tenant: object | None = None) -> Mapping[str, object]: