From 16702d5f5afd99f75cba0ace8842279223d11515 Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Tue, 28 Jul 2026 19:06:51 +0200 Subject: [PATCH] Sync wiki from project files --- Repo-README.md | 48 ++++++- Repo-docs-POSTBOX-CONCEPT.md | 254 ++++++++++++++++++++++++++++++++--- 2 files changed, 275 insertions(+), 27 deletions(-) diff --git a/Repo-README.md b/Repo-README.md index 3259ae2..71d8db4 100644 --- a/Repo-README.md +++ b/Repo-README.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-postbox/README.md`. > Origin: `repository`. @@ -7,7 +7,12 @@ --- # govoplan-postbox -GovOPlaN Postbox provides platform-owned postboxes for internal work, portals, campaign flows, and role-bound organizational communication. + +**Repository type:** module (domain). + + +GovOPlaN Postbox provides platform-owned postboxes for internal work, portals, +campaign flows, and function-bound organizational communication. ## Ownership @@ -16,18 +21,47 @@ This repository owns: - backend module manifest `postbox` - postbox permissions and policy checks - postbox, binding, message, participant, attachment-reference, and audit-facing data models -- role-organization-bound access resolution for postboxes +- function-organization-bound access resolution for postboxes through + normalized Identity, IDM, Organizations, and Core/Access contracts - API routes for postbox directory, messages, access checks, and administration - optional integration capabilities for campaign, files, portal, notification, and mail-facing workflows - future WebUI package `@govoplan/postbox-webui` -Core owns auth, tenants, RBAC evaluation, database/session primitives, module discovery, migrations, CSRF/API helpers, and shell layout. Access owns identities, users, groups, roles, memberships, and administrative RBAC surfaces. +Core owns auth, tenants, RBAC evaluation, database/session primitives, module +discovery, migrations, CSRF/API helpers, and shell layout. Identity owns +identities and account links. Organizations owns units, structures, function +types, and concrete functions. IDM owns effective identity-to-function +assignments, delegation, and acting-for facts. Access owns generic application +roles, permissions, and administrative RBAC surfaces. -## Role-bound postboxes +## Function-bound postboxes -A role-bound postbox is linked to an organizational unit and one or more roles. A person can access that postbox while their identity has an effective matching role in that organizational unit. Access is not tied to a login mailbox, personal email address, or static user assignment. +A function-bound postbox has a stable institutional address linked to an +organizational unit and one or more functions. It can exist with zero, one, or +several current incumbents. A person can access it only while their identity +has an effective assignment or time-bounded delegation in that organizational +context and their account may perform the relevant Postbox action. Access is +not tied to a login mailbox, personal email address, static user assignment, or +function-to-RBAC-role mapping. -When the role assignment changes, postbox access changes with it. The postbox keeps durable message and evidence history, while authorization remains derived from current platform role state. +When the assignment changes, postbox access and encrypted key grants change +with it. The postbox keeps durable content and evidence history through +vacancy, hand-over, and delegation; multiple incumbents receive independently +auditable access. Revocation prevents future platform key access but cannot +erase plaintext already fetched or exported. + +Reusable Postbox templates may target a function type and organization scope. +Unit-specific addresses are resolved lazily and remain stable through vacancy +and reassignment. Exact postboxes remain available for exceptional +responsibilities or case/service contexts. + +Users holding several functions may group selected postboxes into unified +inbox views. These are query projections only: messages, address, read state, +retention, and evidence remain attached to their source postboxes. + +Hierarchy propagation is off by default. Explicit copy, attention/escalation, +and shared-visibility rules are distinct, bounded, classification-aware, and +snapshotted when a message is delivered. ## Module integration diff --git a/Repo-docs-POSTBOX-CONCEPT.md b/Repo-docs-POSTBOX-CONCEPT.md index 5b94c6a..04d0694 100644 --- a/Repo-docs-POSTBOX-CONCEPT.md +++ b/Repo-docs-POSTBOX-CONCEPT.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-postbox/docs/POSTBOX_CONCEPT.md`. > Origin: `repository`. @@ -11,7 +11,13 @@ GovOPlaN Postbox provides in-platform postboxes that are addressable containers for messages, files, workflow evidence, and operational handoff. They can be used internally, exposed through portals, and connected to campaign workflows. -The key distinction from a mailbox is ownership. A mailbox is usually bound to a login, user credential, or external mail account. A GovOPlaN postbox is bound to platform context: organization, role, process, portal, campaign, or service responsibility. +The key distinction from a mailbox is ownership. A mailbox is usually bound to +a login, user credential, or external mail account. A GovOPlaN postbox is a +durable communication and content-access container bound to institutional +context: primarily a function in an organizational unit, and where explicitly +needed a role, process, portal, campaign, or service responsibility. It may look +like an inbox for a message task or like a vault for content shared with the +current holders of that responsibility; neither form is owned by one account. The strategic target is an encrypted administrative postbox. The first implementation may start with ordinary persisted messages, but the model must @@ -20,38 +26,87 @@ manifests, external-recipient tokens, or honest retraction semantics. The cross-module target architecture is recorded in `govoplan-core/docs/POSTBOX_E2EE_ARCHITECTURE.md`. -## Role-Organization-Bound Access +## Function-Organization-Bound Access -The special access pattern is a postbox linked to an organizational unit and one or more roles. A person can access that postbox while their identity has an effective matching role in that organizational unit. +The primary access pattern is a postbox linked to an organizational unit and +one or more institutional functions. A person can access that postbox while +their identity/account has an effective matching function assignment in that +organizational unit and their account may perform the requested Postbox action. +Opening a function postbox does not require mapping the function to an RBAC +role. Example: - Organizational unit: `District Office North` -- Required role: `Case Clerk` +- Required function: `Case Clerk` - Postbox: `District Office North / Case Clerk Intake` -Any identity currently holding the `Case Clerk` role for `District Office North` can see the postbox. When the role is removed or expires, access disappears without moving messages or reassigning a mailbox. +Any identity/account currently holding the `Case Clerk` function for `District +Office North` can see the postbox if it also satisfies the generic Postbox +permission and applicable policy. When the function assignment or delegation +is removed or expires, access disappears without moving messages or +reassigning a mailbox. + +The postbox exists independently of its holders. It remains addressable while +the function is vacant and may accept durable deliveries according to policy; +the UI must then show that no current human holder can open or act on the +content. Assigning one or several incumbents grants access in their explicit +function context. It does not transfer ownership of the container or rewrite +its history. This makes postboxes useful for responsibilities that outlive individuals: - intake desks -- role-based service queues +- function-based service queues - campaign sender or response desks - portal message inboxes for organizational responsibilities -- file or evidence drops linked to a role in an organization +- file or evidence drops linked to a function in an organization -## Authorization Model +### Incumbency, hand-over, and delegation -Postbox authorization should be derived from access-owned identity and role data through core/access contracts. The postbox module stores postbox bindings and postbox-specific permissions, but it should not duplicate membership, group, or role resolution. +- Zero, one, or several people may hold a function at the same time. +- A postbox can remain vacant without being deleted, redirected to a personal + account, or losing content. +- A new assignment can grant access to the function's permitted history through + a current key epoch. Which historical epochs a new incumbent receives is an + explicit postbox policy, not an accidental consequence of account creation. +- A delegation is a time-bounded access grant in the represented function + context. Expiry removes future platform key access and action authority; it + cannot destroy plaintext or exports already obtained. +- Hand-over and revocation rotate the function/postbox key epoch. Per-content + data keys should normally be rewrapped; policy may require content + re-encryption for a stronger rotation event. +- Stored content is not silently substituted or overwritten. A correction, + replacement, or new version is a new linked object with provenance while the + previous signed/ciphertext manifest remains governed by retention policy. + +## Directory And Authorization Model + +The normalized ownership boundary is: + +- Organizations owns units, structures, function types, and concrete + functions. +- Identity owns identities and account links. +- IDM owns effective identity-to-function assignments, validity, delegation, + acting-for context, and assignment lifecycle facts. +- Core/Access authorizes generic Postbox actions. +- Postbox owns templates, stable addresses, containers, messages, routing, + visibility decisions, grouping preferences, and retention. + +The Postbox module stores postbox bindings and postbox-specific decisions, but +it must not duplicate identity, organization, assignment, hierarchy, or RBAC +resolution. The minimum authorization inputs are: - postbox id - tenant id - organizational unit id -- required role id or role key +- required function id or function type id - actor identity id -- current effective role assignments from the access module +- current effective function assignments, delegations, and acting context from + IDM +- generic Postbox permissions from Core/Access - optional explicit administrative grants for postbox administration The expected result is a narrow access decision: @@ -62,17 +117,100 @@ The expected result is a narrow access decision: - can attach or link files - can administer bindings -Access changes must be auditable because a person can gain or lose postbox visibility through role assignment changes rather than direct postbox membership edits. +Access changes must be auditable because a person can gain or lose postbox +visibility through function-assignment changes rather than direct postbox +membership edits. + +Runtime integration must use the kernel capabilities: + +- `identity.directory` to resolve identities and account links. +- `idm.directory` to resolve effective function assignments. +- `organizations.directory` to resolve function, function-type, unit, and + hierarchy facts. +- the Core/Access permission evaluator for generic Postbox actions. +- access explanation/audit contracts to attach permission and acting-context + provenance where available. + +Postbox must not import Identity, IDM, Organizations, or Access ORM models. +Acting-in-place access requires an explicit selected acting context. A function +assignment is an organizational responsibility fact; it does not grant +unrelated application permissions. + +## Templates And Stable Addresses + +A reusable Postbox template can target a function type and an organization +scope, such as a unit type, structure, or subtree. Postbox resolves a stable +unit-specific address from the tenant, template revision, concrete unit, +concrete function, and optional case/service context. + +Addresses should be resolved lazily and idempotently rather than eagerly +creating empty containers for every unit. They remain durable through vacancy +and reassignment. A delivery snapshots the template revision and normalized +organization/function references so later hierarchy changes do not rewrite +history. + +Exact postboxes remain useful for exceptional responsibilities that do not +belong to a reusable function type. + +## Unified Inbox Projections + +A user with several functions can group selected visible postboxes into named +unified inbox views and keep other responsibilities separate. Grouping is a +query projection only. It never merges source containers, messages, read or +acknowledgement state, retention, encryption keys, or audit evidence. + +Every item and action continues to show the source function, unit, postbox, +assignment/delegation context, and classification. Policy may require some +postboxes to remain separate. + +## Hierarchy Routing + +Hierarchy behavior is disabled by default. The system distinguishes: + +- a linked copy delivered to a parent function postbox +- attention or escalation metadata sent to a parent responsibility +- shared visibility over the original message + +These have different privacy, retention, acknowledgement, and audit effects +and must not be treated as synonyms. + +The first production slice should implement explicit linked-copy routing with +a selected structure, target function mapping, maximum depth, stop condition, +classification gate, loop protection, and delivery-time route snapshot. +Organization changes do not retroactively expose old messages. + +Vacancy is a visible delivery/attention state rather than an automatic grant +to an unrelated personal account. Policy may trigger a bounded escalation +after a delay. + +## Campaign Distribution + +Campaign can use Postbox as an explicit delivery channel through +`postbox.delivery`. A campaign may select Mail, Postbox, both, or a configured +fallback order for a target. It must never switch channels silently. + +Validation and build preview stable function/unit/context destinations, +vacancies, hierarchy-copy effects, classifications, and duplicates. Delivery +uses idempotency keys and returns per-target evidence. Postbox owns acceptance, +routing, message state, read/acknowledgement state, and postbox ids; Campaign +owns campaign preparation, jobs, recipient reports, and channel-attempt +evidence. ## Domain Objects The initial domain model should stay small: -- `Postbox`: the addressable container. +- `PostboxTemplate` and immutable revisions: reusable function/scope + configuration. +- `PostboxAddress`: the stable tenant/function/unit/context destination. +- `Postbox`: the addressable container, materialized when needed. - `PostboxBinding`: the binding to organization, role, portal, campaign, service, or explicit context. - `PostboxMessage`: a platform-native message or message reference. - `PostboxParticipant`: normalized sender, recipient, author, or actor reference. - `PostboxAttachmentRef`: reference to a file, evidence item, generated campaign artifact, or external attachment. +- `PostboxDelivery` and `PostboxRoute`: idempotent producer acceptance and + linked copy/escalation provenance. +- `PostboxGrouping`: a per-user source-preserving inbox projection. - `PostboxAccessEvent`: auditable record of access-affecting changes and sensitive actions. Messages and files should be linked by stable ids and typed references. The postbox module should not import file, mail, or campaign internals. @@ -89,15 +227,23 @@ Postbox should expose narrow capabilities through core: Optional consumers: -- Campaign can use postboxes for campaign sender context, reply intake, review queues, and role-bound access to campaign artifacts. -- Files can expose file references to a postbox when the actor's role grants access. +- Campaign can use postboxes for function-targeted delivery, sender context, + reply intake, review queues, and access to campaign artifacts. +- Files can expose file references to a postbox when the actor has effective + source-postbox access. - Portal can show portal-facing postboxes without owning the postbox access model. - Mail can bridge external mailbox delivery into postboxes when configured, without making postboxes mailbox-bound. ## Operational Rules -- Current role state controls current access. -- Historical message records remain durable even when no current person holds the role. +- Current function assignment and delegation state controls current access. +- Historical message records remain durable even when no current person holds + the function; vacancy is a visible attention/access state, not a missing + postbox. +- Multiple incumbents receive independent device-bound key grants and remain + distinguishable in access and action evidence. +- Delegation start, expiry, withdrawal, key grant, and key-epoch rotation are + separate auditable events. - Administration of bindings should require explicit postbox administration permission plus access/RBAC authority for the target organization. - Sensitive access decisions and binding changes should emit audit events. - Retention rules should be postbox-owned but able to reference campaign, file, and portal provenance. @@ -107,6 +253,58 @@ Optional consumers: key epochs, recipient device references, and external capability tokens even before full E2EE ships. +### Retention, Audit, And Privacy + +Postbox retention is owned by the postbox module because postbox messages are +platform-native communication records, not mailbox folders and not ordinary file +shares. Retention policies may reference provenance from campaign, file, portal, +mail, or workflow modules, but those modules should pass stable ids and typed +evidence references through capabilities instead of giving postbox direct access +to their internals. + +The postbox module should emit audit events for: + +- postbox creation, archival, and destructive retirement +- binding creation, changes, expiry, and removal +- sensitive access checks when an actor gains or loses visibility +- message creation, read/download of sensitive content, attachment linking, and + delivery handoff +- retention holds, retention expiry, export, and destruction decisions + +Privacy behavior must separate current access from historical evidence. Losing +a function assignment or generic Postbox permission removes future visibility, +but it does not rewrite the fact that a person previously accessed a message or +that a message existed. Deletion and destructive retention actions must +preserve legally required audit/evidence records while removing or redacting +content according to the effective policy. + +When E2EE is enabled later, retention and audit metadata must remain operable +without decrypting message content. UI copy should be honest: expiry, +withdrawal, or revocation can prevent future platform access, but it cannot +guarantee removal of plaintext already fetched, exported, printed, or delivered +outside the platform. + +### Migration And Compatibility Ownership + +Postbox-owned tables, DTOs, migrations, and capability names belong in +`govoplan-postbox`. Core may temporarily contain compatibility imports or +legacy migration references only when needed to keep existing installations +upgradable while code is being extracted. + +Compatibility code must be narrow and documented: + +- new postbox behavior is implemented in `govoplan-postbox` +- old import paths may re-export postbox DTOs or helpers during a transition, + but must not become active owners of postbox logic +- migrations that move tables to postbox ownership must preserve existing data + and have explicit downgrade/retirement notes +- optional integrations with campaign, files, portal, or mail remain capability + contracts, not direct imports + +Once supported release migrations have crossed the compatibility window, legacy +core import aliases and old table ownership comments should be removed through +a normal cleanup issue. + ## First Implementation Shape The first implementation should define the backend manifest, permissions, DTOs, and migrations before building rich UI. A minimal API can then support directory lookup, access checks, message creation, message listing, and binding administration. @@ -114,9 +312,9 @@ The first implementation should define the backend manifest, permissions, DTOs, The WebUI should start as an administration and inbox surface: - postbox directory -- role-bound access explanation +- function-bound access explanation - message list and message detail -- binding editor for organization and role links +- template and binding editor for organization/function links - audit-visible administrative actions Campaign, files, portal, and mail behavior should arrive as optional integrations after the core postbox model is stable. @@ -133,3 +331,19 @@ Before the data model is considered stable, verify that it can represent: - external recipient token state - expiry and withdrawal state separate from deletion - retention state that can operate without decrypting content + +## E2EE decisions still to settle before implementation + +The product direction above is selected, but the first trusted profile still +needs bounded decisions on: + +- whether a new incumbent receives all retained history, history from a + policy-defined date, or only content delivered during the assignment; +- organizational recovery/escrow and the authority required when every holder + loses all registered device keys; +- whether ordinary rotation only rewraps per-content keys or also re-encrypts + ciphertext, and which events require the stronger path; +- assurance and quorum requirements for delegation, hand-over, emergency + access, export, and destructive retention; and +- how attention/escalation works during a vacancy without granting plaintext + access to an unrelated personal account.