railiance-platform/docs/email-connect-smtp-foundation-review-2026-10-31.md
codex e77f3989b4
Some checks failed
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
CCR intake gate / gate (push) Has been cancelled
Prepare supervised email-connect SMTP foundation and projection
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
2026-10-31 12:00:57 +01:00

7 KiB

Email-connect platform SMTP foundation review

Prepared for CCR-2026-0056 and RPF-WP-0068, supporting CSOC-WP-0015-T02. This is a concrete review packet, not evidence of live installation.

Decision scope

Admit email-connect as a third reader of the existing platform SMTP mailbox, alongside telemetry and Authelia. Create exactly one service account, namespace SecretStore and ExternalSecret in email-connect. The scoped Kubernetes role reads the whole exact OpenBao KV record at platform/data/workloads/railiance-telemetry/smtp; ESO projects only SMTP_PASSWORD into the new Secret's password key. OpenBao does not enforce field-level access. The role has no default policy, a maximum 15-minute lifetime and only the exact service-account/namespace binding with audience openbao.

This does not change the email-connect deployment or sender, create a caller, send email, scan a mailbox, activate backup monitoring, rotate the shared password, or grant suppression authority. Those live obligations remain in CSOC-WP-0015. The user already selected platform-root, with Bernd as human operator, for replies and bounces. This new reader requires its own admission review.

The source-backed foundation proposal is:

sha256:f8da6c831160e1c6354ce54f936809d2d4fb48eb45eb23484dc0bcdfe0bb52f0

Reproduce it without credentials or network operations:

python3 /home/worsch/railiance-platform/scripts/email_connect_smtp_foundation.py

The digest binds the controller, all three resources including server defaults, cluster/namespace/application identities, fixed kubeconfig path and admission digest. The latter binds the CCR's functional scope, policy and seven dependency files. Changes to execution code or scope require a new proposal. Approval and native binding evidence do not change functional scope.

Preconditions and approval boundary

CCR-2026-0056 remains proposed, with native binding unconfirmed. The credential workflow states: “Only approved requests may be applied.” Its shared-reader lane requires platform review; automatic single-reader approval does not apply. Its client workflow also states: “The founder resolves the State Hub decision” and “Clients do not run sync-decision on their own CCRs.” No review, approval or sync is impersonated here.

The completed packet is ready for that platform/consumer review and founder decision. After the owner workflow has made the exact CCR approved, the founder can run the attended command below. The controller creates and verifies the dedicated service account, then uses canonical confirm-binding itself before admitting the OpenBao role. The operator need not falsely confirm an absent SA.

Attended command after approval

Run in the founder's terminal; this is not an agent execution instruction. The OpenBao relay must be available at port18200 and the fixed primary kubeconfig must be present. warden plan resolves this operation to openbao-platform-admin-login with one interactive OIDC/MFA login.

mkdir -m 700 /home/worsch/email-connect-smtp-admission-20261031
BAO_ADDR=http://127.0.0.1:18200 VAULT_ADDR=http://127.0.0.1:18200 \
warden access openbao-platform-admin-login --exec -- \
  python3 /home/worsch/railiance-platform/scripts/email_connect_smtp_foundation.py \
  --execute \
  --expect-digest sha256:f8da6c831160e1c6354ce54f936809d2d4fb48eb45eb23484dc0bcdfe0bb52f0 \
  --receipt /home/worsch/email-connect-smtp-admission-20261031/receipt.jsonl

The directory creation is intentionally exclusive. If it already exists, inspect its contents and prior receipts before proceeding; do not remove or overwrite evidence. Do not run the second command if the first failed. The helper separately requires a private caller-owned directory and a new receipt path.

The child must be silent because Warden rejects child output. It records a private mode0600 append-only JSON Lines journal, fsynced before changes. Share only the last complete receipt and Warden outcome; never login tokens or provider values. The expected final child status is foundation_admitted_projection_ready. Warden must also report successful session revocation and cleanup.

What execution verifies

Before mutation, pinned OpenBao and Kubernetes cluster/namespace identities, platform-admin without root, current deployment identity/generation and absence of all three new objects and the target Secret are required. Objects are created exclusively; none is applied over an existing object. No automatic rollback or retry follows a partial result.

The new service account disables automount. Its new short-lived JWT passes native TokenReview for its UID, full service-account name and openbao audience. Only then does canonical confirm-binding run. Guarded admission preserves the shared mailbox, telemetry/Authelia roles and policies, and existing agent denial. It authenticates to SMTP using certificate-verified STARTTLS without submitting mail.

Actual workload OpenBao login must have only the dedicated policy and bounded TTL, read its exact record, and deny metadata, siblings and mutation capabilities. Wrong service account and wrong audience must fail. The workload token is revoked and lookup must fail afterward. This does not claim an independently exercised same-name/wrong-namespace fixture; exact namespace binding is checked in role metadata and the positive namespace identity is pinned.

Both store and projection must report Ready with exact reviewed specs; the new Secret must name the new ExternalSecret as controller owner. Secret checks use PartialObjectMetadata content negotiation through a private Unix-socket proxy, with no full-object fallback. Secret values are neither requested nor journaled. Existing application/configuration/old projection fingerprints must remain equal.

If execution fails, retain the journal and inspect its last phase and native state. There may be a created SA, admitted role or projection even if no final success was written. Do not rerun blindly, revoke unrelated readers, rotate the mailbox or roll out the application while outcome is uncertain.

Validation and remaining work

41 synthetic SMTP tests pass, including12 controller cases and15 admission cases. They exercise ordering, drift refusal, target collisions, binding refusal, partial creation, privacy/exclusive journals, interruption, native token capability and revocation checks, and metadata-only response enforcement/proxy cleanup. All three resources passed a fresh native server dry-run. A read-only native metadata query confirmed the target Secret absent. No credential was fetched by the agent and no production resource was installed.

Evidence: docs/evidence/email-connect-smtp-foundation-preparation-2026-10-31.json. After the attended return, verify receipt and native state, record CCR verification and rotation inventory, and hand the custody result to CSOC-WP-0015-T02. The sender rollout, actual delivered-message authentication, inbox access, authoritative return handling, suppression admission and retention remain separate unfinished work.