MASON-WP-0014-T01: draft MAS TEM SMTP relay construction plan

Kubernetes-auth, namespaced-store lane for platform/workloads/mas/tem-relay,
temporary for MAS-WP-0003. Live survey and CCR pending.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 278674@bnt-lap001
Assistant-Session: 64827407-e196-4ce3-b70c-76e7b537493f
This commit is contained in:
tegwick 2026-10-18 11:26:18 +02:00
parent 9121961444
commit 5f52d2f42f
2 changed files with 185 additions and 0 deletions

121
plans/mas-tem-relay-smtp.md Normal file
View file

@ -0,0 +1,121 @@
---
id: mas-tem-relay-smtp
demand_source: mail-address-semantics/workplans/MAS-WP-0003-T03
consumer_repo: mail-address-semantics
credential_type: openbao-kv-founder-provision
status: draft
approved_by: null
approved_at: null
created: "2026-10-18"
updated: "2026-10-18"
---
# Construction plan: MAS live-test TEM SMTP relay credential
## 1. Demand
`MAS-WP-0003-T03` runs a temporary live-test MX (`mas/mas-mx`) on
railiance01. It sends service replies through Scaleway Transactional Email
at `[smtp.tem.scaleway.com]:587`, because outbound port 25 is blocked on the
node. The MX needs one SMTP credential: `username` (the Scaleway project ID,
which is not secret) and `password` (a Scaleway API secret key). The founder
types the value into the OpenBao UI. ops-mason builds an empty home and a
read path into namespace `mas`, delivered as Secret `mas-relay`, which the MX
mounts optionally at `/etc/mas-relay`. The lane is temporary: it is removed
with the `mas` namespace when MAS-WP-0003 closes.
Requested by hub message `14bdd217` (2026-10-18). The request suggested
`kv/mas/tem-relay`, a ClusterSecretStore `openbao-mas` and an ESO token.
This plan keeps the shape but adapts it to the current conventions (§3).
## 2. Existing-structure survey
Checked 2026-10-18 from repo sources only. **Live survey pending:** no
`ops-mason-survey` grant was active (`bao-session.sh status`: none). Run
before review:
```bash
./scripts/plan-survey.py --kv-path platform/workloads/mas/tem-relay \
--policy workload-kv-read-mas-tem-relay \
--k8s-role external-secrets-mas-tem-relay \
--consumer mail-address-semantics --keyword tem --keyword smtp
```
- **Catalog** (`ops-warden/registry/routing/catalog.yaml`): no entry for
`mas`, TEM or SMTP relay.
- **railiance-platform:** no CCR, policy or store mentions `mas` or
`tem.scaleway`. The latest CCR is `CCR-2026-0050`.
- **Nearest lane:** `openbao-email-connect` (CCR-2026-0010) is a TEM-adjacent
sender for namespace `email-connect`. It is a separate product with its own
Scaleway key. Reusing it would give the throwaway test MX a production
sender's key, so it is not reused.
- **Store pattern:** new lanes use Kubernetes auth bound to one namespace
and one ServiceAccount, with no static ESO token (RPF-WP-0045,
CCR-2026-0050). Older AppRole/token stores, such as
`openbao-backup-object-storage`, are being migrated away from.
- **Does an existing lane already satisfy this?** No (draft; confirm with
the live survey).
## 3. Proposed changes
SEC-DSM §37:
- **Q1** Can the operation use identity directly? No. TEM SMTP
authenticates only with username/password.
- **Q2** Can the target accept federated identity? No. TEM SMTP has no
federation.
- **Q3** Can the target issue an ephemeral credential? Not viably. Scaleway
API keys can carry an expiry, but adding an issuer for a temporary test
lane would be issuance for show (`DSM-TRANS-003`). Instead the founder sets
the key's own Scaleway expiry to the end of MAS-WP-0003.
- **Q4** Can an existing static credential be rotated automatically? No
automated rotation for a lane this short-lived.
- **Q5** Must a persistent static credential exist? Yes, for the life of
MAS-WP-0003 only. This is §5 level "vaulted static secret".
**Credential facts:**
| Field | Value |
|---|---|
| Owner | founder (Scaleway IAM) |
| Consumer | `mas/mas-mx` |
| Authority | Scaleway IAM API key on a dedicated application with only the Transactional Email permission set, on the TEM project |
| Delivery | ESO → Secret `mas/mas-relay` |
| Copies | OpenBao KV, plus one Kubernetes Secret (a delivery copy, not the authority) |
| Rotation | Replace the KV version; ESO refreshes |
| Revocation | Delete the API key in Scaleway, then tear down (rows 6–7 below) |
| Detection | TEM sending logs and the OpenBao audit log for reads of the path |
| What would eliminate it | Removing the MX, or an MTA that relays through `email-connect`'s API instead of SMTP |
| # | Action | Object | Reuse-vs-new rationale |
|---|---|---|---|
| 1 | create | KV v2 `platform/workloads/mas/tem-relay`, fields `username`, `password` (placeholder `xxx`) | No existing home (§2). This follows the `platform/workloads/<consumer>/<name>` convention, not `kv/` |
| 2 | create | policy `workload-kv-read-mas-tem-relay`: `read` on `platform/data/workloads/mas/tem-relay` only | Single-path ESO reader; no metadata read needed |
| 3 | create | Kubernetes auth role `external-secrets-mas-tem-relay`: SA `mas-tem-relay-eso`, ns `mas`, audience `openbao`, ttl/max 15m, `token_no_default_policy` | Current pattern (CCR-2026-0050), with no static ESO token to deliver or expire |
| 4 | create (consumer repo) | ServiceAccount `mas-tem-relay-eso`, **namespaced** SecretStore `openbao-mas-tem-relay`, ExternalSecret `mas-relay` (keys `username`, `password`), all in ns `mas` | Namespaced instead of a ClusterSecretStore, so the store is deleted with the namespace |
| 5 | create (railiance-platform) | CCR-2026-00NN `workload-kv-read` for rows 1–3 | Platform allocates the CCR and applies it through the delegated applier |
| 6 | tear-down (at MAS-WP-0003 close) | auth role, policy, KV path (`metadata delete`) | Cluster-scoped OpenBao objects do not go away with the namespace |
| 7 | tear-down (founder) | Scaleway API key | Revokes the authority itself |
No catalog entry: the lane is temporary and has a single consumer.
## 4. Review notes
- **Naming:** `mas-tem-relay` is used for the path, policy, role, SA and
store, so one grep finds every object to retire. Secret `mas-relay` keeps
the name the consumer asked for.
- **TTL/scoping:** 15m role TTL matches CCR-2026-0050. The policy covers one
data path and no metadata. Binding is to exact SA and namespace claims.
- **Redundancy:** does not reuse the `email-connect` sender key (§2).
- **Deviation from the request:** it asked for a ClusterSecretStore
`openbao-mas` and an ESO token. Both are replaced, by Kubernetes auth
(DSM-K8S-001, projected identity before a broker token) and by a
namespaced store (easier to retire). The consumer applies rows 4 itself.
- **Secret values:** ops-mason neither reads nor writes them. The policy
grants `read` only to the ESO role.
- **Open:** live survey (§2); CCR number from railiance-platform;
`bound_claims_confirmed` after the SA exists.
## 5. Executive summary
*(Generated after review.)*

View file

@ -0,0 +1,64 @@
---
id: MASON-WP-0014
type: workplan
title: "Build the temporary MAS live-test TEM SMTP relay lane"
domain: infotech
repo: ops-mason
status: proposed
owner: claude
topic_slug: netkingdom-security-architecture
created: "2026-10-18"
updated: "2026-10-18"
flavor: implementation
depends_on: []
---
# MAS TEM SMTP relay lane
Demand: hub message `14bdd217` from mail-address-semantics (MAS-WP-0003-T03).
Plan: `plans/mas-tem-relay-smtp.md`. Temporary; retires with namespace `mas`.
## Draft the construction plan
```task
id: MASON-WP-0014-T01
status: done
priority: high
```
Drafted `plans/mas-tem-relay-smtp.md` (status `draft`) and replied to the
requester with the proposed path, role and store names.
## Live survey and self-review
```task
id: MASON-WP-0014-T02
status: wait
priority: high
```
Needs an `ops-mason-survey` grant (`bao-session.sh grant MASON-WP-0014-T02`).
Run `plan-survey.py` as given in plan §2, then set the plan to `reviewed`.
## CCR and founder approval
```task
id: MASON-WP-0014-T03
status: wait
priority: high
```
railiance-platform allocates the CCR for plan rows 1–3. The founder approves
the plan and the CCR, applies them through the delegated applier, and fills
`password` in the OpenBao UI.
## Verify delivery and record teardown
```task
id: MASON-WP-0014-T04
status: wait
priority: medium
```
Confirm KV metadata exists and that Secret `mas/mas-relay` syncs (names only).
Record the teardown steps (plan rows 6–7) as a residual against MAS-WP-0003 close.