From 181bceb8f0b33b5ffcefd94bac37b267c54dd832 Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Tue, 28 Jul 2026 15:08:17 +0200 Subject: [PATCH] Sync wiki from project files --- Repo-README.md | 75 ++++++-- Repo-docs-ACCESS-MODULE-BOUNDARY.md | 105 +++++++++-- Repo-docs-IDENTITY-ACCOUNT-FUNCTION-MODEL.md | 176 ++++++++++++++++--- 3 files changed, 300 insertions(+), 56 deletions(-) diff --git a/Repo-README.md b/Repo-README.md index efc4e43..860d8cc 100644 --- a/Repo-README.md +++ b/Repo-README.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-access/README.md`. > Origin: `repository`. @@ -7,32 +7,46 @@ --- # GovOPlaN Access + +**Repository type:** module (platform). + + `govoplan-access` is the platform module for GovOPlaN identity, authentication, sessions, API keys, RBAC, groups, users, and access administration. The repository contains the extracted access seed implementation under `src/govoplan_access/backend`. Session, API-key, and password helper services, -interactive auth routes, and administration routers are owned here. The public -FastAPI request dependency API is exported from `govoplan_access.auth`; modules -must not import the backend dependency module directly. Access-side admin -service helpers remain +interactive auth routes, and administration routers are owned here. Access +still exports `govoplan_access.auth` for compatibility, but sibling modules +should import the core `govoplan_core.auth` facade so auth can become a +provider-neutral capability. Modules must not import the backend dependency +module directly. Access-side admin service helpers remain here for users, groups, roles, system accounts, sessions, API keys, tenant access enforcement, admin/audit lookup capabilities, tenant owner provisioning, and governance-template materialization into access-owned groups -and roles. Governance-template metadata CRUD lives in `govoplan-admin`. The +and roles. The module also enforces narrowly declared managed +`RoleTemplate.default_authenticated` baselines. Their explicit permissions are +derived from the active manifest set for every authenticated tenant member, +without writing assignments during an authorization read. The optional role +row is a non-assignable administration projection, not the source of the +automatic grant. Domain permissions and resource policy remain separate checks. +Governance-template metadata CRUD lives in `govoplan-admin`. The transitional administration WebUI route shell and access-owned panels live under `webui/src` as `@govoplan/access-webui`. Generic system administration panels are contributed by `@govoplan/admin-webui` through core's `admin.sections` UI capability. Live access ORM models are defined here -with `access_*` table names; tenant records live in `govoplan-tenancy`, -governance templates in `govoplan-admin`, audit logs in `govoplan-audit`, and -system settings in `govoplan-core`. The current access boundary is documented -in: +with `access_*` table names. Access stores current scope identifiers in +`tenant_id` columns but does not hard-depend on the tenancy module package. +Tenancy-specific tenant administration and tenant resolver behavior live in +`govoplan-tenancy`; governance templates in `govoplan-admin`, audit logs in +`govoplan-audit`, and system settings in `govoplan-core`. The current access +boundary is documented in: - `/mnt/DATA/git/govoplan-core/docs/ACCESS_RBAC_MODEL.md` - `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md` - `docs/ACCESS_MODULE_BOUNDARY.md` +- `docs/IDENTITY_ACCOUNT_FUNCTION_MODEL.md` - `docs/OPENDESK_IDENTITY_BOUNDARY.md` ## Initial Ownership @@ -44,13 +58,17 @@ This module will own: - API keys - legacy administration route contribution during the transition - tenant-local users +- identity-to-account projection for explainable access decisions +- organization-bound functions and function assignments +- explicit delegation and acting-in-place facts - groups and memberships - roles and role assignments - principal resolution - permission evaluation - access administration backend routes - access administration WebUI route contributions -- published FastAPI auth dependency API at `govoplan_access.auth` +- compatibility FastAPI auth dependency API at `govoplan_access.auth` +- provider-facing auth facade consumed by sibling modules at `govoplan_core.auth` - access administration, tenant provisioning, and governance materializer capabilities - access-owned migrations @@ -58,20 +76,29 @@ This module will own: The governance-template routes under `/admin/system/governance-templates` are contributed by `govoplan-admin`; access must not register those routes. -`govoplan-access` depends on `govoplan-tenancy`; the registry loads tenancy -before access for authenticated platform composition. +`govoplan-access` treats `govoplan-tenancy` as optional. Access can run in the +single-scope compatibility mode used by the core/access baseline, and tenancy +adds tenant administration plus tenant resolver behavior when installed. ## Principal Context The stable principal DTO is `govoplan_core.core.access.PrincipalRef`. Access resolves sessions, API keys, and future service accounts into that DTO and serializes it as `principal` in auth API responses. Feature modules should use -that DTO, primitive IDs, or the published `govoplan_access.auth` dependency API +that DTO, primitive IDs, or the core `govoplan_core.auth` dependency facade instead of importing access ORM models or backend dependency internals. The detailed module boundary and serialization fields are documented in [docs/ACCESS_MODULE_BOUNDARY.md](docs/ACCESS_MODULE_BOUNDARY.md). +For scheduled and event-driven work, Access provides +`auth.automationPrincipalProvider`. Automation records store only an owner +account/membership reference and an explicit least-privilege scope grant, not +a session or API token. At delivery time Access rebuilds the principal from +current roles, groups, functions, and delegations and intersects that +authorization with the stored grant. Missing, inactive, moved, or +under-authorized owners fail closed before module work starts. + ## WebUI Package The repository root and `webui/` directory both expose the package @@ -96,7 +123,7 @@ available: ```bash cd /mnt/DATA/git/govoplan-core -./scripts/gitea-sync-labels.py --root /mnt/DATA/git/govoplan-access --apply +/mnt/DATA/git/govoplan/tools/gitea/gitea-sync-labels.py --root /mnt/DATA/git/govoplan-access --apply ``` ## Development Install @@ -107,3 +134,21 @@ From the core checkout: cd /mnt/DATA/git/govoplan-core ./.venv/bin/python -m pip install -e ../govoplan-access ``` + +## Login Throttling + +Interactive password login is throttled by normalized global login identity and by +the directly connected client address. The deployment defaults are 10 identity +failures and 100 client failures in a 15-minute window. Counters use +`REDIS_URL` when Redis is reachable, allowing all API workers to share the same +limits. Local development and Redis outages fall back automatically to a +bounded, process-local counter; authentication remains available, but limits +then apply per API process. + +The deployment settings are `AUTH_LOGIN_THROTTLE_ENABLED`, +`AUTH_LOGIN_THROTTLE_IDENTITY_LIMIT`, `AUTH_LOGIN_THROTTLE_CLIENT_LIMIT`, +`AUTH_LOGIN_THROTTLE_WINDOW_SECONDS`, and +`AUTH_LOGIN_THROTTLE_REDIS_RETRY_SECONDS`. Client-supplied forwarding headers +are not trusted for throttling. A reverse proxy should pass the real peer +address only through the platform's separately configured trusted-proxy +boundary. diff --git a/Repo-docs-ACCESS-MODULE-BOUNDARY.md b/Repo-docs-ACCESS-MODULE-BOUNDARY.md index b64d7f4..949e969 100644 --- a/Repo-docs-ACCESS-MODULE-BOUNDARY.md +++ b/Repo-docs-ACCESS-MODULE-BOUNDARY.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-access/docs/ACCESS_MODULE_BOUNDARY.md`. > Origin: `repository`. @@ -20,8 +20,12 @@ contracts. - interactive authentication routes and session lifecycle - API-key creation, verification, revocation, and scope delegation - tenant-local users, memberships, groups, roles, and role assignments +- identity-to-account projection used for explainability +- organization-bound functions, function assignments, and delegation facts - principal resolution and request authentication dependencies - permission evaluation for access-owned scopes and legacy access aliases +- access-decision explain output with identity/account/function/role/right + provenance - access administration backend routes for users, groups, roles, system accounts, sessions, and API keys - access administration WebUI route contribution for `/admin` @@ -45,16 +49,48 @@ importing access internals: - database engine/session lifecycle and migration orchestration - capability registry and capability names in `govoplan_core.core.access` - access DTO/protocol contracts such as `PrincipalRef`, `AccountRef`, - `UserRef`, `GroupRef`, `RoleRef`, `PrincipalResolver`, - `AccessDirectory`, `PermissionEvaluator`, `TenantAccessProvisioner`, - `AccessAdministration`, and `AccessGovernanceMaterializer` + `UserRef`, `GroupRef`, `RoleRef`, `IdentityRef`, + `OrganizationUnitRef`, `FunctionRef`, `FunctionAssignmentRef`, + `FunctionDelegationRef`, `AccessDecisionProvenance`, + `ApiPrincipalProvider`, `TenantContextSwitcher`, `PrincipalResolver`, + `AccessDirectory`, `AccessSemanticDirectory`, `PermissionEvaluator`, + `AccessExplanationService`, `TenantAccessProvisioner`, + `AccessAdministration`, and + `AccessGovernanceMaterializer` - health, platform metadata, and module startup ordering - generic security helpers that are not access-state semantics, such as secret encryption and UTC time helpers -Feature modules should depend on these kernel contracts or the published -`govoplan_access.auth` request dependency API, not on access ORM models or -`govoplan_access.backend.*` implementation internals. +Feature modules should depend on these kernel contracts or the core +`govoplan_core.auth` request dependency facade, not on access ORM models or +`govoplan_access.backend.*` implementation internals. The access package still +exports `govoplan_access.auth` for compatibility, but new routers should use +the core facade so auth can move behind provider-neutral capabilities. + +Access declares tenancy as an optional module integration. It uses the +core-owned `core_scopes` table as the scope table, but it must not import +`govoplan_tenancy` or require the tenancy package to start. + +## Core-Only Startup Contract + +A core-only installation must be able to start far enough to expose process +health, module metadata, and the unauthenticated shell needed for installation +or recovery work. It is not a usable authenticated product installation. + +Authenticated product use requires the `access` module or another module that +provides the same kernel auth capabilities: + +- `auth.apiPrincipalProvider` +- `auth.principalResolver` +- `auth.permissionEvaluator` +- `auth.tenantContextSwitcher` + +Access contributes the default implementations for those capabilities plus the +interactive `/api/v1/auth/*` routes. Product modules should express auth needs +as required capabilities or route permission requirements instead of importing +access internals. Runtime configurations that intentionally omit access should +hide authenticated navigation and return capability errors for authenticated +product routes rather than failing process startup. ## Principal Context Contract @@ -66,21 +102,64 @@ contracts. New module code should pass around `PrincipalRef` or primitive IDs. `PrincipalRef.to_dict()` is the canonical API/WebUI serialization shape: - `account_id`, `membership_id`, and `tenant_id` -- sorted `scopes` and `group_ids` +- optional `identity_id` +- sorted `scopes`, `group_ids`, `role_ids`, `function_assignment_ids`, and + `delegation_ids` - `auth_method` plus optional `session_id`, `api_key_id`, or `service_account_id` +- optional `acting_for_account_id` for acting-in-place flows - optional display fields `email` and `display_name` -`/api/v1/auth/me`, `/api/v1/auth/login`, profile refreshes, and tenant switches -include this payload as `principal` alongside the existing compatibility -fields. Modules that need current user context should prefer -`auth.principal`/`AuthInfo.principal` in the WebUI and +`govoplan_core.auth` is now backed by the `auth.apiPrincipalProvider` +capability. The access module provides that capability; core no longer imports +access auth dependencies directly. `/api/v1/auth/me`, `/api/v1/auth/login`, +profile refreshes, and tenant switches include this payload as `principal` +alongside the existing compatibility fields. Modules that need current user +context should prefer `auth.principal`/`AuthInfo.principal` in the WebUI and `principal.to_platform_principal()` in backend request handlers. +Interactive tenant context switching is exposed through +`auth.tenantContextSwitcher`. The existing `/api/v1/auth/switch-tenant` route +remains for API compatibility; `govoplan-tenancy` also contributes +`/api/v1/tenancy/switch-tenant`. Both delegate to the same access-owned session +switch behavior. Lifecycle code must use the capability instead of importing +`govoplan_access.backend.security.sessions`. + +## Identity And Function Boundary + +The full semantic model is documented in +[IDENTITY_ACCOUNT_FUNCTION_MODEL.md](IDENTITY_ACCOUNT_FUNCTION_MODEL.md). +In short: + +- `govoplan-idm` imports and previews external identity and organization facts + from IDM systems. +- `govoplan-identity` owns canonical identities and identity/account links. +- `govoplan-organizations` owns canonical organization units, functions, and + account-held function assignments. +- `govoplan-access` owns the authorization projection that maps organization + and identity facts to roles, rights, delegation enforcement, and explainable + permission decisions. + +Function assignments are account-held and organization-scoped. They can apply +only to the selected organization unit or to that unit and all subunits. +Delegation and acting-in-place must remain explicit facts with audit +provenance; modules must not infer either from plain group membership. + +The backend foundation exposes these administration routes: + +- `/api/v1/admin/identities` +- `/api/v1/admin/organization-units` +- `/api/v1/admin/functions` +- `/api/v1/admin/function-assignments` +- `/api/v1/admin/function-delegations` + +Dedicated WebUI management panels and explicit acting-in-place context +selection are still follow-up work on top of these routes. + ## Removed Compatibility Paths These legacy imports were removed from core. Use access-owned modules, the -public `govoplan_access.auth` request dependency API, or kernel capabilities +core `govoplan_core.auth` request dependency facade, or kernel capabilities instead: - `govoplan_core.security.api_keys` diff --git a/Repo-docs-IDENTITY-ACCOUNT-FUNCTION-MODEL.md b/Repo-docs-IDENTITY-ACCOUNT-FUNCTION-MODEL.md index 1d58c1b..e194024 100644 --- a/Repo-docs-IDENTITY-ACCOUNT-FUNCTION-MODEL.md +++ b/Repo-docs-IDENTITY-ACCOUNT-FUNCTION-MODEL.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-access/docs/IDENTITY_ACCOUNT_FUNCTION_MODEL.md`. > Origin: `repository`. @@ -7,58 +7,178 @@ --- # Identity, Account, Function, Role, And Right Model -GovOPlaN access should distinguish identity facts from organizational -responsibility and authorization decisions. +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 may authenticate people -and provide membership facts. GovOPlaN access owns the platform projection used -for sessions, tenant membership, groups, functions, roles, delegation, and -permission decisions. +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. -- Account: the login or technical account used to authenticate. -- Tenant membership: the person's participation in a tenant. +- 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. -- Function: a responsibility held in an organization unit, such as case clerk, - intake desk, treasurer, or committee secretary. + 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 should avoid collapsing these layers into one generic group -concept. Directory groups can feed mappings, but they should not silently become -business authority without a governed mapping rule. +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. -## Boundary +## Organizational Function Scope -Access owns: +A function is meaningful only with organizational scope. The stable contract +therefore separates: -- account and tenant membership projection +- `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 -- identity and membership change events -- SCIM/OIDC/SAML/LDAP mapping effects when implemented +- access-owned identity and membership change events +- mapping effects after an IDM import is accepted Access does not own: -- mailboxes, calendars, files, cases, tasks, or postboxes +- 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 should be explainable in concrete terms: +Access decisions must be explainable in concrete terms: -- actor identity/account +- actor identity and account - tenant membership - organization unit - function assignment or group membership - role source -- permission/right checked -- delegation or system-actor context -- policy or lock that changed the result +- permission or right checked +- delegation or acting-in-place context +- policy, lock, or maintenance state that changed the result -This shape is required for postbox role access, workflow actions, service -directory personalization, delegated administration, and audit review. +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.