email-connect/deploy/closure/prepare.py
tegwick f77e2333af
Some checks failed
Transactional mail acceptance / mail (push) Failing after 46s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Retain independent ledger recovery custody and activate verified backups
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a11fd9-caf6-7a63-b578-9daaaa134ff2
2026-10-10 13:39:49 +02:00

143 lines
8.2 KiB
Python

"""Render public closure artifacts. No credentials, network calls or activation."""
import hashlib
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
OUT = Path(__file__).resolve().parent
def save(name, value):
(OUT / name).write_text(json.dumps(value, indent=2) + "\n")
policy = json.loads((ROOT / "config/callers.user-engine.draft.json").read_text())
readers = [
dict(namespace="email-connect", service_account="email-connect-scoped-caller-eso",
role="email-connect-scoped-caller-eso", store="openbao-email-connect-scoped-caller",
secret="email-connect-caller-user-engine", secret_key="token"),
dict(namespace="user-engine", service_account="user-engine-scoped-mail-eso",
role="user-engine-scoped-mail-eso", store="openbao-user-engine-scoped-mail",
secret="user-engine-scoped-mail", secret_key="token"),
]
plan = {
"schema": "email-connect.closure-plan.v1", "status": "prepared",
"existing_backup_publisher": {
"application": "email-connect-backup-primary",
"application_id": "0eb0f958-77a4-4c70-9aa7-14ba46411415",
"bucket": "railiance-platform-pg-backup",
"prefix": "platform-pg/application-archives/email-connect/",
"retain_for_routine_backups": True,
"escrow_or_administration_grant_inferred": False,
},
"receiver_image": "forgejo.coulomb.social/coulomb/email-connect@sha256:5d79fd1fec15d3a279383820f170d263de3a55f5308df01a0a34732ebaea6d3d",
"user_engine_image": "forgejo.coulomb.social/coulomb/user-engine@sha256:312dcb062b237c518148e1b4f09798a4e6ad08bc60d4add6834aab3f246f2002",
"user_engine_live_baseline": "0d0751d",
"user_engine_patch_sha256": hashlib.sha256((ROOT / "deploy/caller-rollout/user-engine-mail-bindings.patch").read_bytes()).hexdigest(),
"caller_policy": policy,
"caller_custody": {
"kv_path": "platform/workloads/email-connect/callers/user-engine", "field": "TOKEN",
"initial_cas": 0, "writer_policy": "email-connect-scoped-caller-writer",
"reader_policy": "email-connect-scoped-caller-reader", "readers": readers,
},
"backup": {
"recovery_mirror": {
"project_id": "1d37ea63-8c8f-44e1-80e1-2de862579ba7",
"bucket": "railiance-email-connect-archives", "prefix": "archives/",
"verified_copy_required_before_success": True,
"versioned_recovery_receipt_required": True, "retention_days": 30,
},
"schedule_utc": "04:15", "jitter_seconds": 300, "rpo_target_hours": 24,
"stale_threshold_hours": 26, "attended_rto_target_minutes": 60,
"minimum_node_free_bytes": 8 * 1024**3, "local_budget_bytes": 8 * 1024**3,
"daily_generations": 14, "weekly_generations": 4, "provider_archive_retention_days": 30,
"retained_recovery_point_copied_to_escrow_kit": True,
"automatic_retained_object_deletion": False, "failure_recipient": "platform-root",
"retention_operator": "platform-root", "retention_review_interval": "weekly",
"retention_execution": "Separate owner-operated expiry; publisher never deletes retained objects",
"incident_restore_requires_fencing_and_post_capture_reconciliation": True,
},
"scaleway_recovery": {
"region": "nl-ams", "secret_manager_name": "email-connect-ledger-age-recovery",
"secret_manager_protected": True,
"secret_manager_ephemeral_policy": None, "kit_bucket": "railiance-email-connect-recovery",
"kit_prefix": "kits/", "kit_lifecycle": None, "kit_versioning": "Enabled",
"kit_contents": ["age-encrypted-ledger", "public-transfer-and-recovery-receipts",
"pinned-receiver-image", "recovery-tools", "SHA256SUMS"],
"private_age_identity_in_kit": False, "scheduled_worker_escrow_access": False,
"recovery_caller": "Separate read-only IAM application; effective prefix/bucket denial proofs required",
"independent_entry": "platform-root Scaleway account; credentials held only on railiance01 do not qualify",
},
"activation_order": [
"Approve exact plan and perform attended caller custody and Scaleway admission",
"Deliver two bounded ESO projections and privately verify matching caller credentials",
"Freeze user-engine dispatch, capture current ledger and resume receiver",
"Apply coordinated immutable receiver/user-engine images and scoped policy",
"Verify health, denial, limits, accepted/unknown continuity and original handles without mail",
"Repin capture/rehearsal together; refresh and independently read back recovery kit",
"Enable daily backup/hourly freshness after independent custody and retention proofs",
"Finish workplans only after all admitted custody and operating proofs are present",
],
}
save("plan.json", plan)
reader = '''path "platform/data/workloads/email-connect/callers/user-engine" {
capabilities = ["read"]
}
path "auth/token/lookup-self" { capabilities = ["read"] }
path "auth/token/revoke-self" { capabilities = ["update"] }
'''
writer = reader.replace('capabilities = ["read"]', 'capabilities = ["create", "read", "update"]', 1)
writer += '''
path "platform/metadata/workloads/email-connect/callers/user-engine" {
capabilities = ["read"]
}
'''
(OUT / "caller-reader.hcl").write_text(reader)
(OUT / "caller-writer.hcl").write_text(writer)
items = []
for row in readers:
ns, sa = row["namespace"], row["service_account"]
items.append({"apiVersion": "v1", "kind": "ServiceAccount",
"metadata": {"name": sa, "namespace": ns}, "automountServiceAccountToken": False})
vault = {
"server": "http://openbao.openbao.svc:8200", "path": "platform", "version": "v2",
"auth": {"kubernetes": {"mountPath": "kubernetes", "role": row["role"],
"serviceAccountRef": {"name": sa, "namespace": ns, "audiences": ["openbao"]}}},
}
items.append({"apiVersion": "external-secrets.io/v1", "kind": "ClusterSecretStore",
"metadata": {"name": row["store"]},
"spec": {"conditions": [{"namespaces": [ns]}], "provider": {"vault": vault}}})
items.append({
"apiVersion": "external-secrets.io/v1", "kind": "ExternalSecret",
"metadata": {"name": row["secret"], "namespace": ns},
"spec": {
"refreshInterval": "5m", "secretStoreRef": {"kind": "ClusterSecretStore", "name": row["store"]},
"target": {"name": row["secret"], "creationPolicy": "Owner", "deletionPolicy": "Retain",
"template": {"metadata": {"labels": {"email-connect.io/caller": "user-engine"}, "annotations": {}}}},
"data": [{"secretKey": row["secret_key"],
"remoteRef": {"key": plan["caller_custody"]["kv_path"], "property": "TOKEN"}}],
},
})
save("caller-delivery.json", {"apiVersion": "v1", "kind": "List", "items": items})
user = {"name": "portal", "image": plan["user_engine_image"], "env": [
{"name": "USER_ENGINE_MAIL_CLIENT_BINDINGS", "value": json.dumps(json.loads((ROOT / "config/mail-client-bindings.user-engine.draft.json").read_text()), separators=(",", ":"))},
*[{"name": name, "valueFrom": {"secretKeyRef": {"name": "user-engine-scoped-mail", "key": "token"}}}
for name in ("USER_ENGINE_MAIL_TOKEN", "USER_ENGINE_REGISTRATION_VERIFICATION_TOKEN")],
]}
save("user-engine.patch.json", {"spec": {"template": {"spec": {"containers": [user]}}}})
receiver = json.loads((ROOT / "deploy/caller-rollout/receiver-policy.patch.json").read_text())
receiver["spec"]["template"]["spec"]["containers"][0]["image"] = plan["receiver_image"]
save("receiver.patch.json", receiver)
artifacts = [
"deploy/closure/caller-reader.hcl", "deploy/closure/caller-writer.hcl",
"deploy/closure/caller-delivery.json", "deploy/closure/receiver.patch.json",
"deploy/closure/user-engine.patch.json", "scripts/admit-scoped-caller.py",
"scripts/scaleway-recovery-custody.py", "scripts/publish-ledger-recovery-kit.py",
"scripts/prepare-ledger-recovery-kit.py", "scripts/rehearse-ledger.py",
"scripts/backup-ledger.py", "scripts/mirror-ledger.py",
"scripts/capture-ledger.py",
]
plan["artifacts"] = {name: hashlib.sha256((ROOT / name).read_bytes()).hexdigest() for name in artifacts}
save("plan.json", plan)