id: CCR-2026-0010 kind: credential-change-request schema_version: 1 request_type: workload-kv-read title: email-connect transactional SMTP and ingest token lane status: active created: '2026-08-12' updated: '2026-08-21' requester: agent: grok reason: >- EMAIL-WP-0004-T03 requires OpenBao custody for IONOS SMTP STARTTLS credentials and the shared caller ingest token so user-engine can call the cluster-local transactional receiver without possessing SMTP material. Package manifests live in email-connect/deploy/k8s/railiance; this CCR covers the OpenBao path, ESO policy/role, and ops-warden catalog front door. review: required: true required_approvers: - platform-operator - email-connect-owner comments: - at: '2026-08-12T00:00:00+00:00' reviewer: bernd.worsch decision: approved comment: >- Approved in chat (Grok session, EMAIL-WP-0004-T03) acting as platform-operator and email-connect-owner. Daily send-quota privilege tiers explicitly deferred (DECISIONS.md); proceed with lane apply and deploy package. target: domain: infotech tenant: platform workload: email-connect environment: production purpose: >- Deliver EMAIL_CONNECT_INGEST_TOKEN and IONOS SMTP username/password into the email-connect namespace via External Secrets so the transactional receiver can send invitation and verification mail without baking secrets into the image, Git, or user-engine. openbao: mount: platform kv_path: platform/workloads/email-connect/transactional fields: - EMAIL_CONNECT_INGEST_TOKEN - EMAIL_CONNECT_SMTP_USERNAME - EMAIL_CONNECT_SMTP_PASSWORD policy_name: workload-kv-read-email-connect-transactional policy_file: openbao/policies/workload-kv-read-email-connect-transactional.hcl eso_policy_name: external-secrets-email-connect eso_policy_file: openbao/policies/external-secrets-email-connect.hcl auth: # Interim railiance01 pattern (matches openbao-activity-core / openbao-reuse): # policy-limited orphan child token stored as K8s Secret, not Kubernetes auth. # Kubernetes auth role external-secrets-email-connect remains the preferred # follow-up once the cluster auth mount is wired for this namespace. method: token token_secret: external-secrets/openbao-email-connect-eso-token bootstrap_script: email-connect/deploy/k8s/railiance/openbao-eso-token-apply.sh policies: - external-secrets-email-connect ttl: 768h kubernetes_followup: method: kubernetes mount: kubernetes role: external-secrets-email-connect bound_claims: service_account_names: - external-secrets service_account_namespaces: - external-secrets access_frontdoor: type: ops-warden catalog_id: email-connect-transactional selector: email-connect transactional SMTP and ingest token command: warden access email-connect-transactional --fetch EMAIL_CONNECT_SMTP_PASSWORD resolvable: true readiness: ready activation: verified-positive-and-negative-2026-08-12 delivery: surface: external-secrets target: >- ClusterSecretStore openbao-email-connect (tokenSecretRef openbao-email-connect-eso-token; namespace condition email-connect) at railiance-platform/argocd/platform-addons/openbao-secretstore/openbao-email-connect.clustersecretstore.yaml → ExternalSecret email-connect/email-connect-runtime → Secret email-connect-runtime. Package manifests in email-connect/deploy/k8s/railiance/ (not applied until this CCR is approved and the KV secret is provisioned). risk: classification: high notes: - SMTP credentials grant outbound mail from the platform IONOS identity; abuse is bulk send and reputation damage. - The ingest token is a shared bearer between user-engine and email-connect; compromise lets a holder submit invitation/verification sends within the fixed template allow-list (not arbitrary content). - NetworkPolicy restricts ingress to user-engine and egress to DNS + TCP 587; credentials are a second gate, not the only one. - Interim ESO delivery uses a renewable orphan child token (same pattern as activity-core/reuse); ops-warden must proxy operator reads as the caller and must not retain values. verification: positive: - An approved email-connect-namespace ExternalSecret can sync the three fields to Secret email-connect-runtime without printing values. - The email-connect Deployment reaches Ready and /healthz without SMTP fields present in user-engine secrets. negative: - A namespace outside the ClusterSecretStore condition cannot use the store to read the path. - A token without external-secrets-email-connect cannot read the KV path. - Pods outside user-engine cannot reach TCP 8080 on the receiver. activation_conditions: - Policy applied with platform-admin/operator authority. - ESO child token Secret and ClusterSecretStore openbao-email-connect live on railiance01, namespace-scoped to email-connect. - Secret value provisioned directly in OpenBao through approved operator custody. - Positive and negative verification recorded with non-secret audit ids or timestamps. evidence: - at: '2026-08-20T22:56:00+00:00' actor: codex kind: auth_path_reconciliation result: passed details: - Live ClusterSecretStore openbao-email-connect uses tokenSecretRef external-secrets/openbao-email-connect-eso-token, is namespace-limited to email-connect, and reports Valid. - ExternalSecret email-connect-runtime reports SecretSynced. No Secret value was read. lifecycle: deactivate: Disable ops-warden catalog entry and detach ESO role policy. rotate: >- Overlap-first: put new SMTP password and/or ingest token in OpenBao; wait for ESO refresh (or force sync); roll email-connect and user-engine as needed; revoke old provider password / retire old bearer. compromised: Immediately deactivate front door, rotate SMTP and ingest token, record blast-radius notes, and open incident follow-up. state_hub: workplan_id: EMAIL-WP-0004 task_id: EMAIL-WP-0004-T03