Files
govoplan-postbox/docs/POSTBOX_CONCEPT.md
2026-07-14 13:22:12 +02:00

197 lines
9.1 KiB
Markdown

# Postbox Concept
## Purpose
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 strategic target is an encrypted administrative postbox. The first
implementation may start with ordinary persisted messages, but the model must
not prevent later end-to-end encryption, role/function key epochs, signed
manifests, external-recipient tokens, or honest retraction semantics. The
cross-module target architecture is recorded in
`govoplan-core/docs/POSTBOX_E2EE_ARCHITECTURE.md`.
## Function/Role-Organization-Bound Access
The special access pattern is a postbox linked to an organizational unit and
one or more roles or functions. A person can access that postbox while their
account has an effective matching function assignment in that organizational
unit, or while a matching function maps to one of the required roles.
Example:
- Organizational unit: `District Office North`
- Required role: `Case Clerk`
- Postbox: `District Office North / Case Clerk Intake`
Any identity/account currently holding the `Case Clerk` function or a mapped
role for `District Office North` can see the postbox. When the function,
delegation, or role mapping is removed or expires, access disappears without
moving messages or reassigning a mailbox.
This makes postboxes useful for responsibilities that outlive individuals:
- intake desks
- role-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
## Authorization Model
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.
The minimum authorization inputs are:
- postbox id
- tenant id
- organizational unit id
- required function id, role id, or role key
- actor identity id
- current effective function assignments, delegations, and roles from the
access module
- optional explicit administrative grants for postbox administration
The expected result is a narrow access decision:
- can discover
- can read
- can send or reply
- 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.
Runtime integration must use the access kernel capabilities:
- `access.semanticDirectory` to inspect identity/account/function facts.
- `access.explanation` to attach identity/account/function/role/right
provenance to access decisions.
Postbox must not import access ORM models or duplicate function/role
resolution. Acting-in-place access should require an explicit selected acting
context once Access exposes that runtime selector.
## Domain Objects
The initial domain model should stay small:
- `Postbox`: the addressable container.
- `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.
- `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.
## Capability Boundaries
Postbox should expose narrow capabilities through core:
- `postbox.directory`: find postboxes visible to an actor.
- `postbox.access`: answer access decisions for a postbox/action pair.
- `postbox.messages`: create, list, and read postbox messages through DTOs.
- `postbox.delivery`: accept messages or delivery artifacts from other modules.
- `postbox.evidence`: link durable evidence references without owning the evidence store.
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.
- 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.
- 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.
- Expiry, withdrawal, and retraction UI must distinguish future access control
from already fetched or decrypted plaintext.
- Message metadata should preserve room for ciphertext manifests, wrapped keys,
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 role 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.
The WebUI should start as an administration and inbox surface:
- postbox directory
- role-bound access explanation
- message list and message detail
- binding editor for organization and role links
- audit-visible administrative actions
Campaign, files, portal, and mail behavior should arrive as optional integrations after the core postbox model is stable.
## E2EE Readiness Checklist
Before the data model is considered stable, verify that it can represent:
- message or attachment ciphertext references
- signed manifest references
- recipient, role, or function key wrapping records
- key epoch and device-key references
- key-fetch/access audit events
- external recipient token state
- expiry and withdrawal state separate from deletion
- retention state that can operate without decrypting content