diff --git a/registry/routing/catalog.yaml b/registry/routing/catalog.yaml index 52ce8d2..33edb7f 100644 --- a/registry/routing/catalog.yaml +++ b/registry/routing/catalog.yaml @@ -639,3 +639,39 @@ entries: - "SECRET_KEY: make coulomb-social-env-secret COULOMB_SOCIAL_ENV_SECRET_ARGS='--rotate-secret-key' then rollout restart deploy/coulomb-social." - "USER_ENGINE_PROXY_SECRET: rotate user-engine/user-engine-runtime, re-run make coulomb-social-env-secret, restart app." - "DATABASE_URL: platform rotates apps-pg role password secret; re-run make coulomb-social-env-secret; restart app." + + - id: email-connect-transactional + title: email-connect transactional SMTP and caller ingest token + need_keywords: [email-connect, transactional, smtp, ionos, starttls, ingest, invitation, verification, EMAIL_CONNECT_SMTP_PASSWORD, EMAIL_CONNECT_INGEST_TOKEN] + owner_repo: railiance-platform + subsystem: OpenBao + email-connect + warden_executes: false + wiki_ref: wiki/playbooks/email-connect-transactional.md#worker-checklist + canon_ref: railiance-platform/docs/workload-kv-access-lanes.md + reviewed: "2026-08-12" + status: active + risk: high + # CCR-2026-0010 approved 2026-08-12; applied same day (EMAIL-WP-0004-T03): + # policies external-secrets-email-connect + workload-kv-read-email-connect-transactional, + # KV platform/workloads/email-connect/transactional v1, ESO token Secret, + # ClusterSecretStore openbao-email-connect Ready, ExternalSecret SecretSynced, + # Deployment Ready on railiance01. Positive: user-engine /healthz 200 and + # bearer allow-list checks; negative: non-user-engine Connection refused, + # unauth 401. user-engine must receive ingest token under its own custody + # (not SMTP fields) for production outbox wiring (NK-WP-0024). + auth_method: "caller's own OpenBao token (operator OIDC, or ESO child token openbao-email-connect-eso-token)" + path_template: "platform/workloads/email-connect/transactional" + fetch_command: "bao kv get -field=EMAIL_CONNECT_SMTP_PASSWORD platform/workloads/email-connect/transactional" + policy_ref: "flex-auth check secret.read:email-connect" + exec_capable: true + resolvable: true + lane: secret + rotation: + method: rotate + owner: railiance-platform + automatable: false + steps: + - "At IONOS, mint a new mailbox app password for the transactional identity; keep the old password until ESO refresh and pod Ready." + - "`bao kv put platform/workloads/email-connect/transactional EMAIL_CONNECT_SMTP_PASSWORD=@file` (and USERNAME/INGEST_TOKEN if those rotate); shred mode-0600 files." + - "ESO re-syncs email-connect/email-connect-runtime; roll email-connect. If INGEST_TOKEN changed, update user-engine runtime and roll user-engine." + - "Verify capabilities-safe on platform/data/workloads/email-connect/transactional; confirm /healthz Ready without printing secret values." diff --git a/wiki/playbooks/email-connect-transactional.md b/wiki/playbooks/email-connect-transactional.md new file mode 100644 index 0000000..46fe025 --- /dev/null +++ b/wiki/playbooks/email-connect-transactional.md @@ -0,0 +1,91 @@ +# email-connect transactional SMTP + ingest token + +Date: 2026-08-12 +Workplan: EMAIL-WP-0004-T03 · CCR-2026-0010 +Catalog: `email-connect-transactional` (**active** — OpenBao path live, ESO delivering on railiance01) + +Pointer playbook for the IONOS STARTTLS credentials and shared caller bearer +used by the `email-connect` transactional invitation/verification receiver on +railiance01. ops-warden issues SSH certs only — SMTP passwords and API tokens +are OpenBao → Kubernetes Secret actions owned by `railiance-platform` and the +`email-connect` package. + +--- + +## Owners + +| Concern | Owner repo | Authoritative doc | +| --- | --- | --- | +| OpenBao path, ESO policy/role, ClusterSecretStore | `railiance-platform` | `docs/workload-kv-access-lanes.md` — email-connect section | +| K8s package, NetworkPolicy, probes, rollback | `email-connect` | `deploy/k8s/railiance/README.md` | +| user-engine caller wiring (same ingest token) | `net-kingdom` / user-engine | NK-WP-0024 | + +--- + +## Do not ask ops-warden + +```bash +warden route show openbao-api-key --json +warden route show email-connect-transactional --json +``` + +`EMAIL_CONNECT_SMTP_PASSWORD` and `EMAIL_CONNECT_INGEST_TOKEN` must not appear +in Git, State Hub, workplans, logs, or chat. + +--- + +## Custody shape (proposed) + +```text +platform/workloads/email-connect/transactional +``` + +Properties: + +- `EMAIL_CONNECT_INGEST_TOKEN` +- `EMAIL_CONNECT_SMTP_USERNAME` +- `EMAIL_CONNECT_SMTP_PASSWORD` + +Delivery: ExternalSecret `email-connect/email-connect-runtime` +(ClusterSecretStore `openbao-email-connect`, ESO policy +`external-secrets-email-connect`) → Secret `email-connect-runtime`. + +Non-secret host/port/sender/portal URL: ConfigMap `email-connect-config`. + +--- + +## Worker checklist + +### 1. Confirm need + +- [ ] Consumer is the transactional receiver in namespace `email-connect` +- [ ] Need is SMTP send or shared ingest token — not Binky IMAP mailbox scan + (`binky-company-email-imap` is a different lane) +- [ ] CCR-2026-0010 is approved before live provision + +### 2. Platform path + +- [ ] Path provisioned under `platform/workloads/email-connect/transactional` +- [ ] ESO role `external-secrets-email-connect` applied +- [ ] ClusterSecretStore `openbao-email-connect` namespace-limited + +### 3. Deployment wiring + +- [ ] `kubectl apply -k deploy/k8s/railiance` (email-connect repo) +- [ ] ExternalSecret SecretSynced; Deployment Ready +- [ ] user-engine holds the **same** ingest token; no SMTP fields there + +### 4. Smoke + +- [ ] `/healthz` from a user-engine pod succeeds +- [ ] A pod outside user-engine cannot reach TCP 8080 +- [ ] Record non-secret evidence only (timestamps, request ids, Ready status) + +--- + +## Related lanes + +| Catalog id | Relationship | +| --- | --- | +| `binky-company-email-imap` | Mailbox **read** for evidence scans — not this send path | +| `openbao-api-key` | Generic pointer when no concrete lane exists |