verify / verify (push) Successful in 4m29s
Reviewed source export adds verified TLS mail, encrypted outbox, mailbox verification and password reset protocols. Preserve public ancestry; omit local development history and operational queue. Consumer deployment and inbox delivery proof remain separate.
48 lines
2.8 KiB
Markdown
48 lines
2.8 KiB
Markdown
<!-- SPDX-License-Identifier: MPL-2.0 -->
|
|
|
|
# Encrypted transactional outbox
|
|
|
|
`mailsqlite.Queue` stores a single-recipient `mail.Message` as authenticated
|
|
AES-256-GCM ciphertext. Use a separate 32-byte application-managed secret, kept
|
|
out of source control and logs; back it up separately. It may be wrapped in SQLite
|
|
only if the wrapping key stays outside the database and is backed up separately.
|
|
Identity and expiry
|
|
are bound to the ciphertext. Key-derived HMACs support idempotency without storing
|
|
plaintext message hashes. Losing the key loses pending message contents.
|
|
|
|
Call `CreateSchema` inside the application's explicit, versioned migration.
|
|
`EnqueueTx` joins a caller-owned transaction, allowing account changes, audit and
|
|
mail intent to commit or roll back together. `Enqueue` is a convenience for a
|
|
standalone transaction. A message ID belongs to exactly one message/expiry, even
|
|
after its payload is cleared. Do not use the queue to authorize recipients.
|
|
|
|
`ProcessOne` commits a one-minute claim before calling the transport; it never
|
|
holds a database writer lock over SMTP. Transports must honor the supplied
|
|
deadline (at most 30 seconds). A stale worker cannot acknowledge a newer lease.
|
|
Retryable failures back off for 1, 2, 4 and 8 minutes, up to five attempts, only
|
|
while the message is valid. Application workers own scheduling and shutdown.
|
|
|
|
An incorrect key or corrupt payload never reaches SMTP. Such work retains its
|
|
ciphertext and retries decoding after five minutes without consuming a delivery
|
|
attempt. Restoring the correct key before expiry can recover pending messages.
|
|
This is not transparent key rotation: drain the old queue or provide an explicit
|
|
migration before changing keys.
|
|
|
|
Payloads expire within 24 hours and are cleared after terminal delivery results
|
|
or expiry. Run `Sweep` periodically even when sending is disabled; each call is
|
|
bounded to 100 records. Pending capacity defaults to 1,000 (maximum 10,000).
|
|
Safe metadata/deduplication tombstones remain; applications own any later bounded
|
|
retention policy and must not reuse purged IDs. Never expose `Recent` publicly.
|
|
|
|
SMTP acceptance is not inbox delivery. A crash or lost acknowledgement can cause
|
|
a retry after the remote server accepted DATA. Stable Message-ID helps diagnose
|
|
duplicates but cannot make SMTP exactly-once. Do not use this queue for payments
|
|
or another external operation requiring an exactly-once commitment.
|
|
|
|
Local Go/race/vet tests cover encryption and identity binding, domain rollback,
|
|
idempotency, concurrent capacity/claims, lock-free network waits, stale workers,
|
|
cancelled acknowledgements, retry bounds, safe diagnostics, expiry and wrong-key
|
|
recovery. No real SMTP credential, provider delivery or consumer deployment is
|
|
claimed here. [Account verification/reset protocols](../authmail/README.md) are a
|
|
separate optional layer, not behavior inferred by the queue.
|