feat: add access module boundary migrations
This commit is contained in:
177
docs/IDENTITY_ACCOUNT_FUNCTION_MODEL.md
Normal file
177
docs/IDENTITY_ACCOUNT_FUNCTION_MODEL.md
Normal 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.
|
||||
Reference in New Issue
Block a user