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