feat: propose CCR-2026-0012 for platform-pg Barman key
Workload KV path and ESO drafts for Secret platform-pg-backup-s3. Founder mints the project-scoped Scaleway application; values stay out of git.
This commit is contained in:
parent
015f0e43a9
commit
2769258631
5 changed files with 219 additions and 1 deletions
|
|
@ -0,0 +1,32 @@
|
|||
# DRAFT — CCR-2026-0012. Do not apply until the CCR is approved and the
|
||||
# KV values are real. Deploy on railiance01 (databases lives there), not
|
||||
# the CoulombCore ArgoCD kustomization.
|
||||
#
|
||||
# Prereq: ESO can authenticate to OpenBao with policy
|
||||
# workload-kv-read-platform-pg-backup-s3. Interim railiance01 identity
|
||||
# may be AppRole or a child token; Kubernetes auth role
|
||||
# external-secrets-platform-pg-backup is the CCR-declared steady state.
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: ClusterSecretStore
|
||||
metadata:
|
||||
name: openbao-platform-pg-backup
|
||||
labels:
|
||||
app.kubernetes.io/part-of: railiance-gitops
|
||||
railiance-platform/component: external-secrets
|
||||
app.kubernetes.io/name: platform-pg-backup
|
||||
spec:
|
||||
provider:
|
||||
vault:
|
||||
server: http://openbao.openbao.svc:8200
|
||||
path: platform
|
||||
version: v2
|
||||
auth:
|
||||
kubernetes:
|
||||
mountPath: kubernetes
|
||||
role: external-secrets-platform-pg-backup
|
||||
serviceAccountRef:
|
||||
name: external-secrets
|
||||
namespace: external-secrets
|
||||
conditions:
|
||||
- namespaces:
|
||||
- databases
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
id: CCR-2026-0012
|
||||
kind: credential-change-request
|
||||
schema_version: 1
|
||||
request_type: workload-kv-read
|
||||
title: Scaleway scoped Barman key for platform-pg backup
|
||||
status: proposed
|
||||
created: '2026-08-14'
|
||||
updated: '2026-08-14'
|
||||
requester:
|
||||
agent: grok
|
||||
reason: >-
|
||||
RESOURCE-WP-0002 T04 needs a renewable, revocable, bucket-and-prefix
|
||||
scoped Scaleway key in OpenBao so railiance-platform can vend Secret
|
||||
platform-pg-backup-s3 into the databases namespace. The bootstrap key
|
||||
(CCR-2026-0011) can create buckets and must not be the runtime key.
|
||||
review:
|
||||
required: true
|
||||
required_approvers:
|
||||
- platform-operator
|
||||
comments: []
|
||||
target:
|
||||
domain: financials
|
||||
tenant: railiance
|
||||
workload: platform-pg-backup
|
||||
rapp: rapp-postgres
|
||||
environment: production
|
||||
purpose: >-
|
||||
CNPG/Barman object-store credentials for platform-pg WAL and base
|
||||
backups. Secret keys ACCESS_KEY_ID and ACCESS_SECRET_KEY only.
|
||||
Endpoint, bucket, prefix, and region stay on reef-storage.
|
||||
openbao:
|
||||
mount: platform
|
||||
kv_path: platform/workloads/railiance/backup/platform-pg-backup-s3
|
||||
fields:
|
||||
- ACCESS_KEY_ID
|
||||
- ACCESS_SECRET_KEY
|
||||
- APPLICATION_ID
|
||||
policy_name: workload-kv-read-platform-pg-backup-s3
|
||||
policy_file: openbao/policies/workload-kv-read-platform-pg-backup-s3.hcl
|
||||
auth:
|
||||
method: kubernetes
|
||||
mount: kubernetes
|
||||
role: external-secrets-platform-pg-backup
|
||||
bound_claims:
|
||||
service_account_names:
|
||||
- external-secrets
|
||||
service_account_namespaces:
|
||||
- external-secrets
|
||||
bound_claims_confirmed: false
|
||||
policies:
|
||||
- workload-kv-read-platform-pg-backup-s3
|
||||
ttl: 15m
|
||||
access_frontdoor:
|
||||
type: ops-warden
|
||||
catalog_id: platform-pg-backup-s3
|
||||
selector: platform-pg Barman Scaleway key
|
||||
command: warden access platform-pg-backup-s3 --fetch ACCESS_KEY_ID
|
||||
resolvable: false
|
||||
readiness: pending-review
|
||||
delivery:
|
||||
surface: external-secrets
|
||||
target: >-
|
||||
ClusterSecretStore openbao-platform-pg-backup (namespace condition
|
||||
databases) → ExternalSecret databases/platform-pg-backup-s3 → Secret
|
||||
platform-pg-backup-s3 with keys ACCESS_KEY_ID and ACCESS_SECRET_KEY.
|
||||
Drafts live under railiance-platform/argocd/platform-addons/openbao-secretstore/
|
||||
and rapp-postgres/helm/platform-pg-backup-s3.externalsecret.yaml.
|
||||
Do not apply until this CCR is approved and the KV values are real.
|
||||
risk:
|
||||
classification: high
|
||||
notes:
|
||||
- The runtime key can write and delete objects under the backup prefix.
|
||||
Compromise can destroy recovery points or fill the bucket.
|
||||
- The bootstrap key (CCR-2026-0011) must be revoked after this key works.
|
||||
- Do not enable continuous WAL archiving until the empty-archive preflight
|
||||
passes (RESOURCE-WP-0002 T05).
|
||||
- Values must not appear in Git, State Hub, logs, or chat.
|
||||
verification:
|
||||
positive:
|
||||
- Field names present on the KV path; values not printed.
|
||||
- An approved databases-namespace ExternalSecret can sync ACCESS_KEY_ID
|
||||
and ACCESS_SECRET_KEY to Secret platform-pg-backup-s3.
|
||||
- The scoped key can list/put/delete only under prefix platform-pg/.
|
||||
negative:
|
||||
- A token without this policy cannot read the KV path.
|
||||
- A namespace outside the ClusterSecretStore condition cannot use the store.
|
||||
- A second, unused key (or revoked key) cannot access the bucket.
|
||||
- The scoped key cannot list sibling buckets or create compute resources.
|
||||
activation_conditions:
|
||||
- Platform-operator approves this CCR.
|
||||
- Founder creates the Scaleway IAM application and project-scoped
|
||||
Object Storage key, then replaces OpenBao placeholders.
|
||||
- ESO store and ExternalSecret applied only after values are real.
|
||||
lifecycle:
|
||||
deactivate: Disable the catalog entry, delete the ExternalSecret, revoke
|
||||
the Scaleway API key, delete the IAM application.
|
||||
rotate: Overlap-first. Put a new key in OpenBao, wait for ESO refresh,
|
||||
revoke the old Scaleway key.
|
||||
compromised: Revoke both the Barman key and the bootstrap key at Scaleway,
|
||||
rotate this path, review bucket contents, open incident follow-up.
|
||||
state_hub:
|
||||
workplan_id: RESOURCE-WP-0002
|
||||
task_id: RESOURCE-WP-0002-T04
|
||||
72
docs/put-platform-pg-backup-s3.md
Normal file
72
docs/put-platform-pg-backup-s3.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Put the scoped Barman key (founder, local only)
|
||||
|
||||
Do this on a trusted terminal. **Do not paste ACCESS_KEY_ID or
|
||||
ACCESS_SECRET_KEY into chat, Git, or State Hub.**
|
||||
|
||||
CCR: `credential-change-requests/CCR-2026-0012-platform-pg-backup-s3.yaml`
|
||||
Path: `platform/workloads/railiance/backup/platform-pg-backup-s3`
|
||||
|
||||
This is **not** the bootstrap key (`…/scaleway/bootstrap`). That key
|
||||
created the bucket. This key is the CNPG/Barman runtime identity.
|
||||
|
||||
## 1. Create a dedicated IAM application
|
||||
|
||||
In [console.scaleway.com](https://console.scaleway.com) → IAM → Applications:
|
||||
|
||||
1. Create application `railiance-barman-platform-pg`.
|
||||
2. Create an API key **on that application** (not on your user):
|
||||
- Description: `platform-pg Barman runtime`
|
||||
- **Preferred Project for Object Storage:** the project that owns
|
||||
bucket `railiance-platform-pg-backup`
|
||||
3. Copy the access key and secret key into a local scratch file
|
||||
(`chmod 600`). The secret is shown once.
|
||||
|
||||
## 2. Attach a project-scoped Object Storage policy
|
||||
|
||||
IAM → Policies → create `railiance-barman-platform-pg-objects`:
|
||||
|
||||
- Principal: the application from step 1
|
||||
- Scope: **that one project**, not the whole Organization
|
||||
- Permission sets, if the console lists them:
|
||||
- `ObjectStorageBucketsRead`
|
||||
- `ObjectStorageObjectsRead`
|
||||
- `ObjectStorageObjectsWrite`
|
||||
- `ObjectStorageObjectsDelete`
|
||||
- If those sets are not listed, `ObjectStorageFullAccess` **on this
|
||||
project only** is acceptable because the project should contain only
|
||||
this backup bucket.
|
||||
|
||||
Do **not** attach `IAM*` or compute permission sets.
|
||||
|
||||
## 3. Put the values in OpenBao
|
||||
|
||||
On this host, with a token that can write the `platform` mount:
|
||||
|
||||
```bash
|
||||
bao kv put platform/workloads/railiance/backup/platform-pg-backup-s3 \
|
||||
ACCESS_KEY_ID='SCWxxxxxxxx' \
|
||||
ACCESS_SECRET_KEY='xxxxxxxx' \
|
||||
APPLICATION_ID='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
||||
```
|
||||
|
||||
Or replace the `xxx` placeholders in the OpenBao UI on that same path.
|
||||
|
||||
`APPLICATION_ID` is the IAM application UUID (not a secret). It is needed
|
||||
later for the bucket policy.
|
||||
|
||||
## 4. Confirm without printing values
|
||||
|
||||
```bash
|
||||
bao kv metadata get platform/workloads/railiance/backup/platform-pg-backup-s3
|
||||
```
|
||||
|
||||
You should see a current version greater than any placeholder version.
|
||||
Then tell the agent: **“the Barman key is in bao.”** Also say the
|
||||
application name if `APPLICATION_ID` is in bao.
|
||||
|
||||
Do not enable WAL archiving yourself. T04 still has to prove a negative
|
||||
key cannot access the bucket and to vend Secret `platform-pg-backup-s3`.
|
||||
T05 enables continuous archiving.
|
||||
|
||||
After the scoped key works, delete or lock down the bootstrap key from
|
||||
CCR-2026-0011.
|
||||
|
|
@ -180,7 +180,7 @@ shape unless it *is* a secrets engine.
|
|||
| --- | --- | --- | --- |
|
||||
| `rapp-openbao` | none | none — package is the store | correct |
|
||||
| `rapp-postgres` | `consumer_contract` + `openbao-database-secrets-engine` | `rapp-postgres/audit-core-runtime`, `rapp-postgres/audit-core-migration` | bound |
|
||||
| `rapp-postgres` | `s3-backup-target` | no lane yet; Secret `platform-pg-backup-s3` is S3 custody after RESOURCE-WP-0002 | fail-closed on purpose |
|
||||
| `rapp-postgres` | `s3-backup-target` / `secret_references: platform/workloads/railiance/backup/platform-pg-backup-s3` | `CCR-2026-0012` | pointer set; CCR `proposed`; Secret not vended |
|
||||
| `rapp-qonto` | `secret_references: tenants/binky/qonto-api` | `CCR-2026-0009` | pointer set; CCR itself is still `proposed` |
|
||||
|
||||
Live CCRs without `target.rapp` are un-rapped workloads. They stay on
|
||||
|
|
|
|||
11
openbao/policies/workload-kv-read-platform-pg-backup-s3.hcl
Normal file
11
openbao/policies/workload-kv-read-platform-pg-backup-s3.hcl
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Least-privilege read of the Barman runtime key for platform-pg.
|
||||
# ESO (or the later Kubernetes auth role) is the only in-cluster reader.
|
||||
# Values never belong in Git.
|
||||
|
||||
path "platform/data/workloads/railiance/backup/platform-pg-backup-s3" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "platform/metadata/workloads/railiance/backup/platform-pg-backup-s3" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue