Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a11fd9-caf6-7a63-b578-9daaaa134ff2
143 lines
8.2 KiB
Python
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)
|