CCR-2026-0009: propose qonto-assistant workload KV read lane
QONTO-WP-0004-T06. Requests a second, workload-scoped access lane into the existing tenants/binky/qonto-api credential (CCR-2026-0008 is human/OIDC admin access only, not usable by a running pod). Mirrors CCR-2026-0003's llm-connect pattern: External Secrets Operator reads the KV path into a namespace-scoped Kubernetes Secret via a ClusterSecretStore restricted to the new qonto-assistant namespace; the pod never touches the OpenBao token directly. Status: proposed, not approved -- requires platform-operator and binky-tenant-owner sign-off before the auth role/policy are applied. Draft ClusterSecretStore manifest included, following the same "deployed separately, not via this kustomization" pattern as the existing activity-core/forgejo/reuse stores. Validated against schemas/credential-change-request.schema.yaml. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
ca24dc6507
commit
63818fe498
2 changed files with 157 additions and 0 deletions
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue