diff --git a/argocd/platform-addons/openbao-secretstore/openbao-qonto-assistant.clustersecretstore.yaml b/argocd/platform-addons/openbao-secretstore/openbao-qonto-assistant.clustersecretstore.yaml new file mode 100644 index 0000000..c556fba --- /dev/null +++ b/argocd/platform-addons/openbao-secretstore/openbao-qonto-assistant.clustersecretstore.yaml @@ -0,0 +1,36 @@ +# DRAFT -- proposed alongside CCR-2026-0009 (status: proposed, not yet +# approved). Do not apply until CCR-2026-0009 is approved and the underlying +# OpenBao policy + Kubernetes auth role exist. +# +# Mirrors openbao-activity-core.clustersecretstore.yaml's interim pattern: +# reads from coulombcore OpenBao (https://bao.coulomb.social) via a +# policy-limited token until railiance01 OpenBao is bootstrapped and a real +# Kubernetes auth role (external-secrets-qonto-assistant, CCR-2026-0009) is +# live. Scoped to the tenants mount (matches CCR-2026-0008's mount, not +# CCR-2026-0003's platform mount) and restricted to the qonto-assistant +# namespace only via `conditions`. +# +# Prereq: Secret external-secrets/openbao-qonto-assistant-eso-token (key: +# token) with a policy-limited OpenBao token that can read +# tenants/binky/qonto-api (API_KEY, API_USER) -- see CCR-2026-0009. +apiVersion: external-secrets.io/v1beta1 +kind: ClusterSecretStore +metadata: + name: openbao-qonto-assistant + labels: + app.kubernetes.io/part-of: railiance-gitops + railiance-platform/component: external-secrets +spec: + provider: + vault: + server: https://bao.coulomb.social + path: tenants + version: v2 + auth: + tokenSecretRef: + name: openbao-qonto-assistant-eso-token + namespace: external-secrets + key: token + conditions: + - namespaces: + - qonto-assistant diff --git a/credential-change-requests/CCR-2026-0009-qonto-assistant-workload-kv-read.yaml b/credential-change-requests/CCR-2026-0009-qonto-assistant-workload-kv-read.yaml new file mode 100644 index 0000000..9c2aa50 --- /dev/null +++ b/credential-change-requests/CCR-2026-0009-qonto-assistant-workload-kv-read.yaml @@ -0,0 +1,121 @@ +id: CCR-2026-0009 +kind: credential-change-request +schema_version: 1 +request_type: workload-kv-read +title: qonto-assistant workload access to tenants/binky/qonto-api +status: proposed +created: '2026-07-24' +updated: '2026-07-24' +requester: + agent: claude + reason: >- + qonto-assistant (QONTO-WP-0004, docs/SecurityPractice.md) needs its own + running pod to fetch tenants/binky/qonto-api at cold-start, without + reusing the existing human/OIDC admin lane from CCR-2026-0008 (which is + scoped to net-kingdom-admins operators, not a workload identity). Mirrors + CCR-2026-0003's llm-connect pattern: External Secrets Operator reads the + KV path into a namespace-scoped Kubernetes Secret; qonto-assistant's pod + consumes the resulting Secret, never the OpenBao token itself. +review: + required: true + required_approvers: + - platform-operator + - binky-tenant-owner + comments: [] +target: + domain: financials + tenant: binky + workload: qonto-assistant + environment: production + purpose: >- + Workload (not human/admin) read access to the existing + tenants/binky/qonto-api credential so qonto-assistant's own pod can fetch + it via External Secrets, matching the isolation profile requested in + qonto-assistant/docs/SecurityPractice.md #7 (I1 Reinforced minimum). +openbao: + mount: tenants + kv_path: tenants/binky/qonto-api + fields: + - API_KEY + - API_USER + policy_name: workload-kv-read-qonto-assistant + policy_file: openbao/policies/workload-kv-read-qonto-assistant.hcl + auth: + method: kubernetes + mount: kubernetes + role: external-secrets-qonto-assistant + bound_claims: + service_account_names: + - external-secrets + service_account_namespaces: + - external-secrets + bound_claims_confirmed: false + policies: + - workload-kv-read-qonto-assistant + ttl: 15m +access_frontdoor: + type: ops-warden + catalog_id: qonto-assistant-workload-kv + selector: qonto-assistant workload Qonto API key + command: warden access qonto-assistant-workload-kv --fetch API_KEY,API_USER + resolvable: false + readiness: proposed +delivery: + surface: external-secrets + target: >- + ExternalSecret to Secret qonto-assistant-qonto-api in the (new, dedicated) + qonto-assistant namespace -- see + qonto-assistant/deploy/k8s/qonto-assistant/externalsecret.yaml (draft, + not yet applied). +risk: + classification: high + notes: + - Same underlying bank credential as CCR-2026-0008; this CCR does not + request a new secret value, only a second, workload-scoped access lane + into the existing tenants/binky/qonto-api path. + - The Kubernetes auth subject is the External Secrets Operator service + account external-secrets/external-secrets, with ClusterSecretStore usage + limited to the new qonto-assistant namespace (mirrors CCR-2026-0003's + activity-core scoping) -- no other namespace can use this store to read + this path. + - qonto-assistant's own policy kernel (default-deny, no spend/volume-cost + tools) is the downstream control on what the fetched credential is used + for; this CCR only governs whether the pod can fetch it at all. + - qonto-assistant's deployment isolation profile (namespace, NetworkPolicy, + resource limits) should land before or alongside this CCR's approval, not + after -- see qonto-assistant/deploy/k8s/qonto-assistant/. +verification: + positive: + - An approved qonto-assistant-namespace ExternalSecret can sync fields + API_KEY/API_USER to Secret qonto-assistant-qonto-api without printing + values. + - The qonto-assistant runtime can consume the resulting Kubernetes Secret + without exposing values (existing credentials.py env-injection path, + unchanged). + negative: + - A namespace outside the approved ClusterSecretStore condition cannot use + this store to read the path. + - A service account outside external-secrets/external-secrets cannot + authenticate through this OpenBao role. + activation_conditions: + - qonto-assistant namespace exists (see deploy/k8s/qonto-assistant/namespace.yaml, + draft). + - Policy and Kubernetes auth role applied with platform-admin/operator + authority. + - ClusterSecretStore openbao-qonto-assistant applied, scoped to the + qonto-assistant namespace only (draft manifest alongside this CCR). + - Positive and negative verification recorded with non-secret audit ids or + timestamps. + evidence: [] +lifecycle: + deactivate: Disable ops-warden catalog entry and remove or detach the + external-secrets-qonto-assistant auth role policy. Does not affect + CCR-2026-0008's separate human/OIDC admin lane. + rotate: Shared with CCR-2026-0008 -- rotating the underlying API key in + Qonto's dashboard and OpenBao rotates both access lanes simultaneously; + no independent rotation exists for this lane alone. + compromised: Immediately deactivate this access front door; the underlying + key compromise/rotation procedure is CCR-2026-0008's, since both lanes + share the same secret value. +state_hub: + workplan_id: QONTO-WP-0004