retarget: CCR-2026-0012 is the general backup object-store lane

Use IAM application resource-control and policy Scoped backup access.
OpenBao path is platform/workloads/railiance/backup/object-storage.
rapp-postgres keeps Secret platform-pg-backup-s3 as the first projection.
This commit is contained in:
codex 2026-08-14 19:19:56 +02:00
parent 2769258631
commit 94b2f7cc9c
8 changed files with 160 additions and 143 deletions

View file

@ -1,31 +1,38 @@
# Put the scoped Barman key (founder, local only)
# Put the scoped backup object-store 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`
CCR: `credential-change-requests/CCR-2026-0012-backup-object-storage.yaml`
Path: `platform/workloads/railiance/backup/object-storage`
This is **not** the bootstrap key (`…/scaleway/bootstrap`). That key
created the bucket. This key is the CNPG/Barman runtime identity.
created the bucket. This key is the general **backup** runtime identity
for application `resource-control`. First consumer is `rapp-postgres`
(Secret `platform-pg-backup-s3`).
## 1. Create a dedicated IAM application
## 1. Use IAM application `resource-control`
In [console.scaleway.com](https://console.scaleway.com) → IAM → Applications:
1. Create application `railiance-barman-platform-pg`.
1. Create application `resource-control` if it does not exist. Do **not**
create a Barman- or postgres-specific application.
2. Create an API key **on that application** (not on your user):
- Description: `platform-pg Barman runtime`
- Description / name: `Scoped backup access`
- **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
Put **only** backup-scoped keys on this application. Scaleway attaches
policies to the application, not to one key. The bootstrap key must stay
off `resource-control`.
IAM → Policies → create `railiance-barman-platform-pg-objects`:
## 2. Bind policy `Scoped backup access`
- Principal: the application from step 1
IAM → Policies → create (or reuse) `Scoped backup access`:
- Principal: application `resource-control`
- Scope: **that one project**, not the whole Organization
- Permission sets, if the console lists them:
- `ObjectStorageBucketsRead`
@ -34,7 +41,7 @@ IAM → Policies → create `railiance-barman-platform-pg-objects`:
- `ObjectStorageObjectsDelete`
- If those sets are not listed, `ObjectStorageFullAccess` **on this
project only** is acceptable because the project should contain only
this backup bucket.
backup buckets.
Do **not** attach `IAM*` or compute permission sets.
@ -43,7 +50,7 @@ Do **not** attach `IAM*` or compute permission sets.
On this host, with a token that can write the `platform` mount:
```bash
bao kv put platform/workloads/railiance/backup/platform-pg-backup-s3 \
bao kv put platform/workloads/railiance/backup/object-storage \
ACCESS_KEY_ID='SCWxxxxxxxx' \
ACCESS_SECRET_KEY='xxxxxxxx' \
APPLICATION_ID='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
@ -51,21 +58,20 @@ bao kv put platform/workloads/railiance/backup/platform-pg-backup-s3 \
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.
`APPLICATION_ID` is the `resource-control` 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
bao kv metadata get platform/workloads/railiance/backup/object-storage
```
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.
Then tell the agent: **“the backup key 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`.
key cannot access the bucket and to vend the first consumer Secret.
T05 enables continuous archiving.
After the scoped key works, delete or lock down the bootstrap key from

View file

@ -47,7 +47,8 @@ the list does not say who provisions the thing that satisfies a name.
`openbao-database-secrets-engine` and `s3-backup-target` are capabilities.
The database engine is configured by S3 from statements the package
owns; the backup bucket is a `resource-control` resource and the
provider credential is S3 custody (`Secret platform-pg-backup-s3`).
provider credential is S3 custody (`secret:railiance-platform/backup`,
first projection Secret `platform-pg-backup-s3`).
Fail-closed until that handoff lands is correct, not a hole in the
package.
@ -180,7 +181,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` / `secret_references: platform/workloads/railiance/backup/platform-pg-backup-s3` | `CCR-2026-0012` | pointer set; CCR `proposed`; Secret not vended |
| `rapp-postgres` | `s3-backup-target` / `secret_references: platform/workloads/railiance/backup/object-storage` | `CCR-2026-0012` | pointer set; CCR `proposed`; first consumer of the general backup key; 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