feat(mail): add governed POP3 legacy import
Module Package Release / publish-packages (push) Successful in 11s

This commit is contained in:
2026-08-22 04:52:25 +02:00
parent 93ecedf607
commit 218fef11f1
27 changed files with 3291 additions and 88 deletions
+75 -17
View File
@@ -23,12 +23,13 @@ See also [Mail protocol roadmap](MAIL_PROTOCOL_ROADMAP.md) and the Campaign
Mail owns:
- reusable SMTP/IMAP profile definitions and scope;
- encrypted SMTP/IMAP credentials and safe credential replacement;
- reusable SMTP/IMAP profile definitions, dedicated legacy POP3 sources, and scope;
- encrypted SMTP/IMAP/POP3 credentials and safe credential replacement;
- effective profile policy and visibility/authorization decisions;
- connection tests and protocol adapters;
- SMTP send and IMAP append operations exposed to consumers;
- read-only mailbox folder/message access and its bounded indexes; and
- read-only mailbox folder/message access, bounded indexes, and encrypted
pending-review records imported from legacy POP3 sources; and
- the transport sanitization boundary and throttling behavior. A general
Mail-owned provider-attempt/diagnostic ledger remains planned.
@@ -65,6 +66,10 @@ profile test and Ops health surfaces. If the receipt says SMTP is unavailable,
is invalid, or is not mounted, import is blocked with an operator-facing
resolution instead of creating a partial profile.
Configuration packages remain SMTP-focused. A POP3 legacy source is a deliberate
operational migration action and is not silently exported, cloned, or enabled by
an SMTP profile package.
## Interface patterns and unavailable actions
Mail uses the platform's shared explorer, connection tree, adaptive form,
@@ -89,9 +94,10 @@ deactivating a profile may scrub Mail-owned credentials as described below.
### Profile
A profile is a reusable, named delivery identity with optional SMTP and IMAP
configuration. It has a stable id, lifecycle state, scope, owner context, and
non-secret connection metadata. Passwords are write-only encrypted values and
are never returned through list/read/capability responses.
configuration. It can additionally own a dedicated POP3 endpoint for an
explicit legacy-import workflow. It has a stable id, lifecycle state, scope,
owner context, and non-secret connection metadata. Passwords are write-only
encrypted values and are never returned through list/read/capability responses.
An IMAP server may map the standard Inbox, Sent, Drafts, Trash, Archive, and
Junk roles to exact provider folder names. These mappings belong to the reusable
@@ -128,6 +134,11 @@ authorization. Mail re-evaluates profile activity, visibility, policy, and
revision immediately before it resolves credentials and performs the
effect.
POP3 imports pin the endpoint/credential transport revision at preview time. A
changed revision or a missing provider UIDL stops import and requires a fresh
preview. POP3 does not participate in the ordinary mailbox folder/message
projection.
### Provider outcomes
SMTP acceptance, partial or complete recipient refusal, temporary/permanent
@@ -202,6 +213,46 @@ not mutate read/unread, delete, move, or reply state. Message responses are
bounded by the deployment response policy; ordinary UI should avoid loading a
whole large mailbox or attachment merely to show a list.
### Import a legacy POP3 mailbox
POP3 is available only for bounded migration from a legacy server that cannot
provide IMAP or JMAP. It is disabled by default and is not a replacement for
the read-only mailbox UI.
1. An actor with profile-write, secret-management, and `mail:pop3:manage`
authority opens **Legacy POP3 import**, selects a Mail profile, and creates a
dedicated source. The UI stages the endpoint disabled, stores its encrypted
username/password credential, and enables it only after both operations
succeed.
2. The administrator explicitly enables legacy import, sets TLS mode, timeout,
maximum message and batch sizes, and preview body lines, and tests connection,
authentication, TLS, and provider message count. Plain transport remains
subject to deployment egress/security policy and should not be used across
an untrusted network.
3. An operator with `mail:profile:use` and `mail:pop3:import` refreshes a live
preview of at most 100 messages. Preview sends no `DELE`, changes no flags,
and exposes only bounded headers/body text. A server without stable UIDL
identifiers is rejected. If `TOP` is unavailable, Mail uses `RETR` only
inside the configured size bound and suppresses an oversized preview.
4. The operator selects messages. Mail downloads within the size gate and
creates encrypted local `pending_review` records. Tenant, profile, endpoint,
and UIDL form the duplicate boundary. Raw content never appears in list,
provider-state, audit, or DSAR output.
5. Source messages remain untouched by default. Delete-after-import requires
the endpoint's separate `allow_delete_after_import` policy, the operator's
`mail:pop3:delete` permission, an explicit per-batch choice, and destructive
confirmation. Mail commits the local import plus `mail.pop3.imported` audit
evidence before sending `DELE`. It separately records
`mail.pop3.source_deletion`; disconnect during `QUIT` is outcome-unknown and
must be reconciled before another destructive attempt.
The supplied **Mail legacy import operator** role can test, preview, and import
without deleting. The **Mail profile administrator** role also contains source
management and destructive-delete permissions; deployments should remove or
split `mail:pop3:delete` when operators must never delete provider messages.
Imported records follow configured Mail/records retention and require manual
review for a data-subject request or deletion decision.
## Profile administration
### Roles
@@ -214,11 +265,16 @@ The supplied templates are:
and manage credentials only for the current account's own user-scoped
profiles, subject to the effective Mail policy.
- **Mail profile administrator:** additionally create/update profiles and
create/replace encrypted credentials across tenant-owned scopes.
create/replace encrypted credentials across tenant-owned scopes, configure
legacy POP3 imports, and—unless the template is narrowed—request source
deletion after import.
- **Mail legacy import operator:** test approved POP3 sources and preview/import
messages without permission to delete them at the provider.
The specific permissions are `mail:profile:read`, `mail:profile:use`,
`mail:profile:test`, `mail:mailbox:read`, `mail:profile:write_own`,
`mail:secret:manage_own`, `mail:profile:write`, and `mail:secret:manage`.
`mail:secret:manage_own`, `mail:profile:write`, `mail:secret:manage`,
`mail:pop3:manage`, `mail:pop3:import`, and `mail:pop3:delete`.
The `_own` permissions are enforced against the authenticated membership id and
never authorize a tenant, group, campaign, system, or another user's profile.
They also do not authorize profile-policy changes. System-scoped definitions
@@ -305,10 +361,10 @@ tenant posture; it does not expose credential material.
Private-network connector access is controlled deployment-wide by
`GOVOPLAN_CONNECTOR_ALLOW_PRIVATE_NETWORKS`. Whether private or public targets
are allowed, SMTP and IMAP resolve, validate, and connect to the exact approved
address records at connection time while retaining the original hostname for
TLS SNI and certificate verification. A DNS change cannot redirect the socket
after validation.
are allowed, SMTP, IMAP, and legacy POP3 resolve, validate, and connect to the
exact approved address records at connection time while retaining the original
hostname for TLS SNI and certificate verification. A DNS change cannot redirect
the socket after validation.
Transports that cannot pin every connection peer or revalidate protocol-managed
redirects/referrals must fail before client construction. Do not weaken this
@@ -383,10 +439,11 @@ state transition or outbound synchronization effect.
### Backup, restore, and retirement
Backups contain encrypted credentials and therefore need the same protection as
the live database and key material. Restoring a Mail database without the
matching encryption key makes credentials unusable; restoring it with keys can
reactivate sensitive historical state and must be controlled.
Backups contain encrypted credentials and encrypted raw POP3 import records and
therefore need the same protection as the live database and key material.
Restoring a Mail database without the matching encryption key makes those
records unusable; restoring it with keys can reactivate sensitive historical
state and must be controlled.
Destructive module retirement first applies the same immediate credential
scrub/audit rule to every remaining profile, then drops Mail-owned tables after
@@ -495,7 +552,8 @@ Before claiming a Mail composition is production-ready:
Campaign business-action contract built on Mail transport operations.
- JMAP mailbox synchronization/search; it is preferred only after the IMAP MVP
is stable.
- POP3 except for a future explicit legacy download/import requirement.
- Expanding POP3 beyond the implemented explicit legacy download/import
workflow; it has no folder, flag, search, or synchronization contract.
- A full mail client with compose/reply/move/delete/read-state mutation.
- Quick Access may launch the operating environment's configured composer via
`mailto:`. That explicit handoff is not a GovOPlaN Mail delivery: it selects
+27 -11
View File
@@ -1,12 +1,15 @@
# Mail Protocol Roadmap
GovOPlaN Mail currently focuses on SMTP sending and IMAP mailbox access. POP3
and JMAP are deferred until the IMAP mailbox MVP is stable.
GovOPlaN Mail focuses on SMTP sending and IMAP mailbox access. It also provides
an explicitly enabled, bounded POP3 legacy-import path. JMAP remains deferred
until the IMAP mailbox MVP and protocol-neutral mailbox contract are stable.
## Current Baseline
- SMTP is the send protocol.
- IMAP is the read/append protocol.
- POP3 is an optional legacy migration source, never a general mailbox
protocol or default profile endpoint.
- Mail profile policy, encrypted credentials, mailbox folder parsing, test
buttons, and read-only mailbox UI are built around SMTP and IMAP.
@@ -56,17 +59,30 @@ JMAP should be added only after:
## POP3
POP3 should remain legacy-only.
POP3 remains legacy-only. The bounded import slice is available when a concrete
deployment must retire a mailbox that cannot offer IMAP or JMAP.
Add it only when a concrete deployment requires mailbox download from a server
that cannot offer IMAP or JMAP. POP3 is a poor fit for the normal GovOPlaN
mailbox UX because it has limited folder, sync, and server-side state semantics.
It is disabled until an administrator creates a dedicated POP3 endpoint and
sets `legacy_import_enabled`. The endpoint has its own encrypted credential,
connection/TLS/authentication diagnostics, maximum message and batch sizes, preview body
limit, and a separate `allow_delete_after_import` policy. Stable UIDL support is
mandatory; Mail refuses import when a provider cannot supply it.
If implemented, POP3 should be scoped to explicit download/import workflows, not
general mailbox browsing.
Preview and ordinary import are non-destructive. Selected messages become
encrypted `pending_review` records with a content digest, pinned transport
revision, source UIDL, and audit evidence. Repeating a UIDL reports a duplicate.
Provider deletion requires both endpoint policy and `mail:pop3:delete`, is
chosen separately per batch, and runs only after the local import and its audit
event commit. A disconnect while POP3 `QUIT` commits deletions becomes
`outcome_unknown` and is never retried blindly.
POP3 does not supply folder, flag, thread, search, or synchronization semantics.
It is therefore excluded from the normal mailbox UI and from the recommended
ongoing Mail profile. Configuration-package export/import remains SMTP-focused;
legacy source rollout is an explicit operational action.
## Decision
Do not add POP3 or JMAP now. Stabilize SMTP/IMAP first, design protocol-neutral
mailbox DTOs, then prefer JMAP for modern servers and reserve POP3 for explicit
legacy download requirements.
Keep the implemented POP3 surface limited to governed legacy import. Do not
expand it into mailbox browsing. Design protocol-neutral mailbox DTOs and
prefer JMAP for future modern synchronization/search support.