feat: add access module boundary migrations

This commit is contained in:
2026-07-10 12:51:16 +02:00
parent 37828fe340
commit 04681f1d75
41 changed files with 7229 additions and 738 deletions

View File

@@ -0,0 +1,177 @@
# Identity, Account, Function, Role, And Right Model
GovOPlaN access distinguishes identity facts, organizational responsibility,
and authorization decisions. This is groundwork for postboxes, workflows,
service directories, portals, delegation, and audit review.
Directory services, identity providers, and IDM systems can authenticate people
and provide external facts. GovOPlaN access owns the normalized runtime
projection used for sessions, tenant memberships, groups, functions, roles,
delegations, and permission decisions.
## Semantic Layers
- Identity: the real person, service, or external subject. An identity can have
multiple accounts, for example a normal account and a privileged
administration account.
- Account: the login or technical account used to authenticate. Access
decisions are account-based because the account is the acting credential.
- Tenant membership: the account's participation in a tenant.
- Organization unit: the administrative unit where responsibility applies.
Organization units are hierarchical; access must know when a function applies
only to one unit or to that unit and all subunits.
- Function: a named responsibility held by an account in an organization unit,
such as case clerk, intake desk, treasurer, dean's office assistant, or
committee secretary. A function can map to one or more access roles.
- Role: a permission bundle or workflow authority attached to a function,
group, or explicit assignment.
- Right: the concrete scope or action permission evaluated at runtime.
The UI and API must not collapse these layers into a generic group concept.
Directory groups can feed mappings, but they must not silently become business
authority without a governed mapping rule.
## Organizational Function Scope
A function is meaningful only with organizational scope. The stable contract
therefore separates:
- `FunctionRef`: the organization-bound function definition, including tenant,
organization unit, role mappings, and delegation policy flags.
- `FunctionAssignmentRef`: the account-held assignment for that function,
including identity provenance and whether the assignment applies to all
subunits of the function's organization unit.
The assignment is the runtime authority. A role mapped to a function does not
grant rights until an account has an active assignment for that function.
Example:
- Identity `Anna Becker` owns accounts `anna` and `anna-admin`.
- Account `anna` has function `Registry Clerk` in organization unit
`Student Registry`.
- The assignment has `applies_to_subunits = true`, so the same function applies
to subordinate registry offices unless policy narrows it.
- The function maps to role `registry.case_editor`, which grants rights such as
`cases:case:update`.
## Delegation And Acting In Place
Functions can be delegated only if the function policy permits it. GovOPlaN
distinguishes two delegation modes:
- Delegation: the delegate acts as themself, with provenance showing the
delegated function assignment.
- Acting in place: the actor performs an action in another holder's function
context. Audit and explain responses must show both the real actor account
and the account being represented.
Both modes should be time-bound, revocable, auditable, and visible in access
explain output. Module code must not infer delegation from ordinary group
membership.
## IDM Boundary
`govoplan-idm` owns synchronization with external IDM systems: SCIM, LDAP,
SAML/OIDC claims, directory attributes, preview, rollback, and mapping import.
It does not own GovOPlaN's internal identity, organization, function, role, or
permission evaluation tables.
`govoplan-identity` owns canonical identity records and identity/account links.
`govoplan-organizations` owns canonical organization units, functions, and
function assignments. During the transition, access keeps a security projection
of those concepts for compatibility and authorization, but new integrations
should target the identity and organization capabilities first.
`govoplan-access` owns the platform projection created from those mappings:
- accounts and tenant membership projection
- identity-to-account links used for explainability
- groups, roles, function assignments, and delegation facts
- permission decisions and explain responses
- access-owned identity and membership change events
- mapping effects after an IDM import is accepted
Access does not own:
- mailboxes, calendars, files, cases, tasks, postboxes, or other module data
- canonical organization structure once `govoplan-organizations` is enabled
- canonical identity records once `govoplan-identity` is enabled
- module-specific ACL records beyond stable principal/group/role references
- external provider internals except where they mutate access-owned state
## Kernel Contracts
The stable DTO and protocol surface lives in
`govoplan_core.core.access`. The current groundwork adds:
- `IdentityRef`
- `OrganizationUnitRef`
- `FunctionRef`
- `FunctionAssignmentRef`
- `FunctionDelegationRef`
- `AccessDecisionProvenance`
- `AccessSemanticDirectory`
- `AccessExplanationService`
Feature modules should consume those contracts instead of importing access ORM
models. Storage, migration, and admin UI work can evolve behind the contract
without changing module integrations.
## Required Explainability
Access decisions must be explainable in concrete terms:
- actor identity and account
- tenant membership
- organization unit
- function assignment or group membership
- role source
- permission or right checked
- delegation or acting-in-place context
- policy, lock, or maintenance state that changed the result
This shape is required for role-bound postboxes, workflow authorization,
service directory personalization, delegated administration, and audit review.
## Consumer Expectations
- Postbox can grant access to a role-bound or function-bound postbox without
tying the postbox to a specific login account.
- Portal/service directory can show services relevant to a user's current
organization functions and tenant membership.
- Workflow can ask whether the current account can act in a function context
for a given organization unit.
- Audit can show who acted, with which account, under which function, and
whether delegation or acting-in-place was involved.
## Implementation Sequence
Implemented backend foundation:
- Kernel DTOs/protocols are covered by focused contract tests.
- Access-owned storage exists for identities, account links, organization
units, functions, function-role mappings, function assignments, and function
delegations.
- Admin APIs exist under `/api/v1/admin/identities`,
`/api/v1/admin/organization-units`, `/api/v1/admin/functions`,
`/api/v1/admin/function-assignments`, and
`/api/v1/admin/function-delegations`.
- `PrincipalRef` population includes identity, role, function assignment, and
delegation identifiers when those facts exist.
- The access manifest registers `access.semanticDirectory` and
`access.explanation` capabilities.
Remaining rollout:
1. Move canonical identity and organization reads to `identity.directory` and
`organizations.directory`, keeping access-owned rows as a compatibility
projection until migration is complete.
2. Add dedicated WebUI management panels for identities, organization units,
functions, assignments, and delegations.
3. Add explicit acting-in-place context selection; `act_in_place` delegation
facts are stored now but do not silently grant permissions without a selected
acting context.
4. Retrofit postbox, workflow, portal, and audit consumers to use identity,
organization, and access explanation capabilities rather than local access
assumptions.