Prepare empty OpenBao slots for the two backup publisher pairs.
Version 1 names both AWS fields and holds a placeholder. The founder enters the real keys as the next version. Assistant: grok Assistant-Session: 01a11cdb-f9fe-7011-947c-936e72007e54
This commit is contained in:
parent
9b658e3f19
commit
31c679f212
2 changed files with 106 additions and 2 deletions
102
scripts/prepare-backup-pair-slots.py
Normal file
102
scripts/prepare-backup-pair-slots.py
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Create the two empty backup-primary KV slots.
|
||||
|
||||
One CAS=0 write per path stores both field names with the placeholder
|
||||
PENDING. The founder replaces that version in the OpenBao UI. No provider
|
||||
key is read or written.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
STAGE = Path("/home/worsch/.local/state/railiance/receipts/backup-pair-slots.stage")
|
||||
RECEIPT = Path("/home/worsch/.local/state/railiance/receipts/backup-pair-slots.json")
|
||||
PATHS = (
|
||||
"platform/workloads/coulomb-social/backup-primary",
|
||||
"platform/workloads/email-connect/backup-primary",
|
||||
)
|
||||
|
||||
|
||||
def stage(text):
|
||||
STAGE.parent.mkdir(mode=0o700, exist_ok=True)
|
||||
STAGE.write_text(text + "\n")
|
||||
STAGE.chmod(0o600)
|
||||
|
||||
|
||||
def run(args, token=None):
|
||||
env = os.environ.copy()
|
||||
if token is None:
|
||||
env.pop("BAO_TOKEN", None)
|
||||
env.pop("VAULT_TOKEN", None)
|
||||
else:
|
||||
env["BAO_TOKEN"] = token
|
||||
env["VAULT_TOKEN"] = token
|
||||
return subprocess.run(args, capture_output=True, env=env)
|
||||
|
||||
|
||||
def main():
|
||||
created = run(
|
||||
[
|
||||
"bao", "token", "create",
|
||||
"-policy=backup-pair-writer",
|
||||
"-ttl=5m",
|
||||
"-use-limit=3",
|
||||
"-orphan",
|
||||
"-format=json",
|
||||
]
|
||||
)
|
||||
if created.returncode:
|
||||
stage(f"token_create_failed {created.returncode}")
|
||||
raise SystemExit(51)
|
||||
token = json.loads(created.stdout)["auth"]["client_token"]
|
||||
body = Path(os.environ["HOME"]) / "backup-pair-slot.json"
|
||||
body.write_text(json.dumps({
|
||||
"AWS_ACCESS_KEY_ID": "PENDING",
|
||||
"AWS_SECRET_ACCESS_KEY": "PENDING",
|
||||
}))
|
||||
body.chmod(0o600)
|
||||
puts = []
|
||||
try:
|
||||
for path in PATHS:
|
||||
meta = run(["bao", "kv", "metadata", "get", "-format=json", path])
|
||||
if meta.returncode == 0:
|
||||
stage(f"already_present {path}")
|
||||
raise SystemExit(52)
|
||||
put = run(["bao", "kv", "put", "-cas=0", path, f"@{body}"], token=token)
|
||||
puts.append({"path": path, "put_returncode": put.returncode})
|
||||
if put.returncode:
|
||||
stage(f"put_failed {path} {put.returncode}")
|
||||
raise SystemExit(53)
|
||||
finally:
|
||||
body.unlink(missing_ok=True)
|
||||
run(["bao", "token", "revoke", "-self"], token=token)
|
||||
slots = []
|
||||
for path in PATHS:
|
||||
meta = run(["bao", "kv", "metadata", "get", "-format=json", path])
|
||||
if meta.returncode:
|
||||
slots.append({"path": path, "metadata_returncode": meta.returncode})
|
||||
continue
|
||||
data = json.loads(meta.stdout)["data"]
|
||||
slots.append({
|
||||
"path": path,
|
||||
"current_version": data.get("current_version"),
|
||||
"version_count": len(data.get("versions") or {}),
|
||||
})
|
||||
RECEIPT.parent.mkdir(mode=0o700, exist_ok=True)
|
||||
RECEIPT.write_text(json.dumps({"slots": slots, "puts": puts}, indent=2) + "\n")
|
||||
RECEIPT.chmod(0o600)
|
||||
stage("ok")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except SystemExit:
|
||||
raise
|
||||
except Exception as exc:
|
||||
stage("failed " + type(exc).__name__)
|
||||
raise SystemExit(54) from None
|
||||
|
|
@ -230,8 +230,10 @@ remain open; no credentials delivered, productive capture/upload or timer enable
|
|||
intended writer policy is `backup-pair-writer` and The founder admitted this writer on 2026-10-08, using the words
|
||||
"bucket-pair-writer". The policy name remains `backup-pair-writer`
|
||||
(`openbao/policies/backup-pair-writer.hcl`). The installed policy matches
|
||||
that file, and `WRITER_ADMITTED` is true. Both backup-primary KV paths are
|
||||
absent. The bootstrap key cannot list IAM applications (403). The live bucket
|
||||
that file, and `WRITER_ADMITTED` is true. Both backup-primary KV paths were absent. Version 1 now exists on each
|
||||
path, with both field names set to a non-credential placeholder. The founder
|
||||
will write the real pairs as a new UI version. The bootstrap key cannot list
|
||||
IAM applications (403). The live bucket
|
||||
policy still names only application ee80333e-5bab-4a04-85a9-5bdb46b7b3c1 on
|
||||
`platform-pg/*`. No publisher key was created. T05 stays wait for the two
|
||||
console-created applications and their CAS=0 pairs. An admitted writer, covered
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue