ops-mason/plans/reef-storage-scaleway-bootstrap.md

6.2 KiB

id demand_source consumer_repo credential_type status approved_by approved_at created updated
reef-storage-scaleway-bootstrap resource-control/workplans/RESOURCE-WP-0002-T03 reef-storage openbao-kv-founder-provision built Bernd Worsch 2026-08-14 2026-08-14 2026-08-14

Construction plan: Scaleway bootstrap key for reef-storage

1. Demand

We need to create a private Scaleway Multi-AZ bucket in nl-ams for postgres backup (RESOURCE-WP-0002). The founder has a new Scaleway account and an API key in the usual Terraform snippet shape (access_key, secret_key, organization_id, project_id in scaleway.auto.tfvars). Those four values must live in OpenBao, not in git or chat. ops-mason builds the empty lane. The founder pastes the values once (desk or local tfvars ingest). reef-storage then creates the bucket by reading OpenBao and never printing the keys.

2. Existing-structure survey

Checked 2026-08-14:

  • KV path does not exist. platform/metadata/workloads/railiance/scaleway/bootstrap is 404. Same for the later backup path platform/workloads/railiance/backup/object-storage.
  • CCR already reserved the path. railiance-platform CCR-2026-0011 names platform/workloads/railiance/scaleway/bootstrap and the four fields. Reuse that path. Do not invent a second one.
  • CCR-2026-0004 is Nextcloud/age offsite backup (platform/workloads/railiance/backup/offsite-lane). Different provider, different fields. Do not merge.
  • Catalog. No scaleway / s3-backup lane. openbao-api-key is the generic template and must not become this concrete key.
  • Auth. This is an operator-workstation bootstrap key for a one-shot (or rare) scw create, not an in-cluster ESO consumer. No AppRole. Founder paste-once / local tfvars ingest is the right desk. The later scoped Barman key (T04) is a different path and may get a workload CCR then.
  • Does an existing lane already satisfy this? No live secret. The reserved CCR path is the one to build.

Terraform snippet → OpenBao fields (same four facts, scw-native names):

Terraform (scaleway.auto.tfvars) OpenBao field
access_key ACCESS_KEY
secret_key SECRET_KEY
organization_id DEFAULT_ORGANIZATION_ID
project_id DEFAULT_PROJECT_ID

3. Proposed changes

# Action Object Reuse-vs-new rationale
1 reuse CCR-2026-0011 path platform/workloads/railiance/scaleway/bootstrap Already reserved; do not fork
2 create empty KV v2 path (metadata only, no secret data) Structure so paste-once / ingest has a home
3 create policy operator-kv-scaleway-bootstrap (read/write that path only) Founder desk and the bucket-create script; no sibling paths
4 reuse founder paste-once desk + optional local tfvars ingest ops-mason never sees values; four fields, four desk pastes or one founder-run ingest
5 propose catalog scaleway-bootstrap (draft) + playbook Pointer only; warden_executes: false
6 defer AppRole / ESO / scoped backup key T04 / CCR for backup/object-storage; not this plan

No new rail. Scaleway operates S3.

4. Review notes

  • Naming: path follows platform/workloads/railiance/…. Policy operator-kv-scaleway-bootstrap matches “operator workstation, not workload ESO.”
  • TTL/scoping: no AppRole token. The downstream Scaleway key is long-lived until the founder deletes it after the scoped key exists.
  • Redundancy: does not reuse Nextcloud offsite-lane. Does not put org-admin keys in the Barman runtime path.
  • Compaction: none. This is the first Scaleway lane.
  • Secret values: mason does not read, write, or log them. Founder uses warden desk --act paste_once_provision four times, or reef-storage/tools/ingest-scaleway-tfvars.sh on a local 0600 scaleway.auto.tfvars they already have.
  • Founder remaining acts: approve this plan; paste four fields (or run ingest once); say “bootstrap is in OpenBao.”

5. Executive summary

One-line ask: approve an OpenBao home for the four Scaleway Terraform variables so we can create the backup bucket without putting keys in git or chat.

Who gets access: you (founder / operator token) to write the four fields; the bucket-create script, using that same operator token, to read them once. No new AppRole. No cluster workload. Nothing else gains a path.

To what: only platform/workloads/railiance/scaleway/bootstrap (ACCESS_KEY, SECRET_KEY, DEFAULT_ORGANIZATION_ID, DEFAULT_PROJECT_ID). Not the later Barman key path. Not other platform/workloads/railiance/backup/* secrets.

For how long: the KV version stays until you rotate or delete it. This bootstrap key should be revoked at Scaleway after the scoped bucket key works (T04).

Blast radius if the credential leaks: create/list/delete Object Storage (and whatever else that API key can do in the project). Revoke the key in the Scaleway console, delete the KV version, rotate to a scoped bucket-only key.

Cost to reverse: delete the KV path, draft catalog entry, and policy. No other consumer is bound. The bucket, once created, stays until you empty and delete it.

Decision: approve, reject, or send back to phase 1. Approval authorizes structure (empty path, policy, catalog draft) and your paste-once / tfvars ingest. It does not authorize ops-mason to handle the Terraform secret values.

6. Build result

Executed 2026-08-14 after founder asked to bootstrap with example data and replace values in the OpenBao UI.

Created (structure + placeholders only; values are the string xxx):

  • policy operator-kv-scaleway-bootstrap (read/write that one path)
  • KV v2 platform/workloads/railiance/scaleway/bootstrap version 1 fields ACCESS_KEY, SECRET_KEY, DEFAULT_ORGANIZATION_ID, DEFAULT_PROJECT_ID
  • custom_metadata placeholder=true, ccr=CCR-2026-0011, replace_in_ui=true

Catalog draft scaleway-bootstrap already proposed.

Founder next: OpenBao UI → secret platform/workloads/railiance/scaleway/bootstrap → create version 2 with the real Terraform values. Then say “bootstrap is in OpenBao.” The bucket-create script refuses xxx placeholders.