From 72f3a6769ff6ba24700ab9fcd8ca195385e0b24f Mon Sep 17 00:00:00 2001 From: codex Date: Sun, 1 Nov 2026 22:36:38 +0100 Subject: [PATCH] docs: preserve reviewed NetKingdom session artifacts --- .../apps-r1/review/apps-owner-review-r1.md | 104 +++ .../apps-r1/review/local-verification-r1.json | 94 +++ .../review/owner-review-receipt-r1.json | 27 + .../review/private-reader-values.r1.yaml | 5 + ...use-surface-runtime-externalsecret.r1.yaml | 46 ++ .../runtime-auth-source-allowlist-r1.json | 18 + .../review/supervision-preparation-r1.json | 10 + .../apps-r1/review/verify_preparation.py | 68 ++ .../reuse-surface/templates/_helpers.tpl | 56 ++ .../reuse-surface/templates/deployment.yaml | 87 +++ .../charts/reuse-surface/values.schema.json | 30 + .../files/charts/reuse-surface/values.yaml | 106 +++ .../apps-owner-review-r2.md | 119 +++ .../local-verification-r2.json | 96 +++ .../private-reader-values.r1.yaml | 5 + ...use-surface-runtime-externalsecret.r1.yaml | 46 ++ .../runtime-auth-source-allowlist-r1.json | 18 + .../supervision-preparation-r1.json | 10 + .../verify_preparation.py | 94 +++ .../reuse_authenticated_source_inventory.py | 62 ++ ...PS-WP-0017-reuse-private-reader-release.md | 57 ++ .../owner-assembly/apps-r2/owner.patch | 659 +++++++++++++++++ .../cust81-auth-url-shape-observation-r1.json | 27 + ...t81-firefox-loopback-probe-r1-receipt.json | 10 + ...t81-firefox-loopback-probe-r2-receipt.json | 13 + ...1-oidc-callback-transport-findings-r1.json | 53 ++ ...ttended-runner-publication-receipt-r3.json | 24 + ...ust81-warden-baseline-firstfailure-r1.json | 17 + ...st81-warden-fullsuite-firstfailure-r1.json | 9 + .../cust81-windows-go-loopback-matrix-r1.json | 32 + .../forge-attended-review-publication-r1.json | 19 + .../owner-assembly/forge-final-r2/owner.patch | 583 +++++++++++++++ .../review/forge-owner-review-r1.json | 58 ++ ...forge-owner-review-r2-before-recovery.json | 54 ++ ...er-review-r2-recovery-refresh-receipt.json | 11 + ...orge-owner-review-r2-recovery-refresh.diff | 57 ++ .../review/forge-owner-review-r2.json | 57 ++ ...agination-independent-fixture-results.json | 22 + .../review/target-api-contract-r1.json | 122 ++++ .../target-contract-verification-plan.md | 69 ++ ...forge-owner-attended-runner-review-r2.json | 35 + ...forge-owner-attended-runner-review-r3.json | 52 ++ .../forge-source-publication-r1.json | 35 + ...-historical-identity-investigation-r1.json | 73 ++ .../owner-assembly/mason-r1/checks.json | 22 + .../owner-assembly/mason-r1/owner.patch | 684 ++++++++++++++++++ .../owner-assembly/mason-r2/checks.json | 44 ++ .../auth-source-allowlist.json | 1 + .../candidate-spec.sha256 | 1 + .../construction-inputs.json | 278 +++++++ 50 files changed, 4279 insertions(+) create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/apps-owner-review-r1.md create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/local-verification-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/owner-review-receipt-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/private-reader-values.r1.yaml create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/reuse-surface-runtime-externalsecret.r1.yaml create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/runtime-auth-source-allowlist-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/supervision-preparation-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/verify_preparation.py create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/templates/_helpers.tpl create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/templates/deployment.yaml create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/values.schema.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/values.yaml create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/apps-owner-review-r2.md create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/local-verification-r2.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/reuse-surface-runtime-externalsecret.r1.yaml create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/supervision-preparation-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/verify_preparation.py create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/scripts/reuse_authenticated_source_inventory.py create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/workplans/RAPPS-WP-0017-reuse-private-reader-release.md create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/owner.patch create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-auth-url-shape-observation-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-firefox-loopback-probe-r1-receipt.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-firefox-loopback-probe-r2-receipt.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-oidc-callback-transport-findings-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-platform-attended-runner-publication-receipt-r3.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-warden-baseline-firstfailure-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-warden-fullsuite-firstfailure-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-windows-go-loopback-matrix-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-attended-review-publication-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/owner.patch create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-before-recovery.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-recovery-refresh-receipt.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-recovery-refresh.diff create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/pagination-independent-fixture-results.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/target-api-contract-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/target-contract-verification-plan.md create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-owner-attended-runner-review-r2.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-owner-attended-runner-review-r3.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-source-publication-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-historical-identity-investigation-r1.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r1/checks.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r1/owner.patch create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/checks.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/auth-source-allowlist.json create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/candidate-spec.sha256 create mode 100644 docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/construction-inputs.json diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/apps-owner-review-r1.md b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/apps-owner-review-r1.md new file mode 100644 index 00000000..9a510503 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/apps-owner-review-r1.md @@ -0,0 +1,104 @@ +# Railiance apps preparation review — CUST81 private metadata reader R1 + +Reviewer: delegated railiance-apps preparation worker, supervised local preparation +assignment. No promotion evidence or existing own-scope supervision record was +found; the descriptive preparation record grants no runtime authority. This is +an S5 release-contract review grounded in INTENT principles 1–5 (workloads, +release contracts, repeatable operations, explicit S3 handoff, verified health). +It is not a founder decision, independent platform credential review or reuse +application source review. No live changes, commits, pushes, hub writes, image +publishes, login or credential retrieval occurred. + +Disposition: **approved for integration as local preparation only; live promotion blocked**. +Canonical review disposition: `approved`. This accepts the bounded S5 proposal +and its explicit runtime gates, not live execution or another owner’s review. + +## Proposed changes and owner boundaries + +The chart accepts an optional immutable image digest, adds a non-secret exact +`REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST` environment binding, and fails rendering +when a nonempty allowlist lacks an immutable digest. Schema checks enforce +HTTPS allowlist entries and valid digest syntax. Production values continue +using their existing `main-6cbc862` tag; production ExternalSecret is unchanged. +The preparation override contains exactly 14 reviewed pinned metadata URLs and +an empty digest deliberately preventing deployment. A synthetic all-zero digest +in local tests is not an image and must never be promoted. + +The proposed phase-B ExternalSecret preserves existing two keys, target metadata +and existing `openbao-reuse` ClusterSecretStore, adding only +`REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN` from +`workloads/reuse/reuse-surface/forgejo-source-read:FORGEJO_SOURCE_TOKEN`. +Platform owns the dedicated KV path/policy/store read scope, CCR-2026-0046 and +credential issuance; apps neither provisions nor consumes an admin credential. + +Digest presence cannot prove the hardened application is included. The reuse +owner must provide published build digest, source revision, tests and review +binding *both* authenticated redirect rejection and exact environment-name/URL +credential routing. A reader must not reach the existing vulnerable runtime. + +## Ordered promotion gates — not executed + +1. Confirm own-scope supervision and founder change approval, reviewed CCR, + exact seven-source owner consent packet and scoped Forgejo read-only issuer + receipt. Integrate provisional RAPPS-WP-0017 through root owner coordination. +2. Run metadata inventory helper with an explicitly verified railiance01 + kubeconfig; compare existing authenticated registrations with newly + fail-closed image behavior. The helper reads only SQLite registration + metadata, never env/Secrets, captures command errors and refuses unsafe + URLs. If it refuses, resolve via the source owner without emitting raw + objects. Any existing authenticated source requires separately reviewed + exact URL bindings including capability entry URLs before promotion; do not + silently orphan sources or broaden the 14-URL map. Missing inventory blocks + phase A. Store only safe names, counts and validated metadata URLs. +3. Read live release image/revision, replica state, PVC storage/access modes and + readiness. Confirm node external IP `92.205.62.239`, not retired coulombcore. + Record requested CPU/memory headroom and pending pods before rollout. Existing + API requests 100m CPU/256Mi, surge1 requires that much additional allocatable + capacity; landing unchanged. Confirm the existing PVC supports simultaneous + pod scheduling/mount on this single node; stop if RWO/RWOP or mount conflicts + prevent it. No rollout strategy/resource/PVC changes are proposed. Do not + change other workloads merely to obtain capacity. +4. Once a real reviewed digest exists, fill the preparation values; render + exact chart with production values plus proposal overrides. Server dry-run + and client diff must cover every rendered chart object and the phase-B ESO + manifest. Preserve stderr in memory and emit sanitized status only; never + print live Secrets, Helm secret values, annotations or raw API failures. + Existing release owner and any Argo adoption must be verified before choosing + owner Helm upgrade versus GitOps sync; neither is executed here. +5. Phase A: approved release of hardened digest plus approved allowlist, with + existing ESO fields only. Owner Helm path must use atomic upgrade, timeout + and wait; verify actual running imageID matches digest, API health/probes, + public federation baseline63 and credential-routing refusal/redirect tests. + Deployment failure blocks phase B. Database/PVC remains unchanged. Collect a + separately approved safe backup/recovery receipt before any risky live release. +6. Phase B: after verified phase A, execute reviewed platform credential action + and ESO reader mapping. Verify only ESO condition/status and key-presence + booleans via approved suppressing helpers, then restart/sync the hardened + workload so envFrom obtains the reader. Never dump Secret or process env. +7. Reuse owner runs native exact-byte authenticated proof for all14 URLs and + seven capability entries using pinned consent hashes. Only then register + seven sources through the scoped write route and verify hosted70/70, + no duplicates/conflicting IDs and public federation preserves all63. + +## Rollback contract + +Before execution capture previous approved release revision, digest/tag and +safe configuration, public discovery baseline and database recovery receipt. +If phase A fails before credential delivery, atomic restore of previous release +is safe because no reader has been supplied. After phase B, **never downgrade to +vulnerable runtime with reader still available**: revoke the dedicated reader +at Forgejo/OpenBao via credential owner, remove phase-B ESO mapping and materialized +reader key through reviewed silent maintenance, restart current hardened pods, +verify absence/revocation, then restore prior approved chart/image only if needed. +Metadata registrations may remain inaccessible until re-established; record the +regression explicitly. Do not roll back the PVC or use stale tokens as recovery. + +## Local evidence and limitations + +`helm lint charts/reuse-surface -f helm/reuse-surface-values.yaml` passed. +`python3 docs/assessments/cust81-private-reader/verify_preparation.py` passed eight +checks, including exact14 roundtrip, digest/schema refusal, retention of current +strategy/resources/PVC, correct isolated ESO mapping, metadata URL sanitization +and subprocess error suppression. `local-verification-r1.json` contains command +statuses without raw output. No cluster inventory, resource headroom, +server dry-run/diff, image publish, live approval or native fetch has been proven. diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/local-verification-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/local-verification-r1.json new file mode 100644 index 00000000..531488b0 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/local-verification-r1.json @@ -0,0 +1,94 @@ +{ + "status": "passed", + "local_only": true, + "real_image_digest": null, + "synthetic_digest_used_only_to_check_rendering": true, + "checks": [ + "production rendering unchanged except empty fail-closed allowlist", + "unknown/malformed digest fails", + "HTTP allowlist fails schema", + "exact14 URLs roundtrip", + "strategy resources PVC retained", + "dedicated ESO mapping preserves current fields/store", + "metadata sanitizer excludes userinfo/query secrets/fragments", + "kubectl failure output discarded" + ], + "helm_calls": [ + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml" + ], + "exit_code": 0, + "expected_success": true + }, + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", + "-f", + "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml" + ], + "exit_code": 1, + "expected_success": false + }, + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", + "-f", + "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml", + "--set", + "image.digest=sha256:bad" + ], + "exit_code": 1, + "expected_success": false + }, + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", + "-f", + "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml", + "--set-json", + "authSourceAllowlist={\"BAD\":[\"http://attacker.invalid\"]}", + "--set", + "image.digest=sha256:0000000000000000000000000000000000000000000000000000000000000000" + ], + "exit_code": 1, + "expected_success": false + }, + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", + "-f", + "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml", + "--set", + "image.digest=sha256:0000000000000000000000000000000000000000000000000000000000000000" + ], + "exit_code": 0, + "expected_success": true + } + ] +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/owner-review-receipt-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/owner-review-receipt-r1.json new file mode 100644 index 00000000..2b074c61 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/owner-review-receipt-r1.json @@ -0,0 +1,27 @@ +{ + "reviewer_owner": "railiance-apps", + "reviewer_assignment": "delegated-railiance-apps-cust81-preparation", + "disposition": "approved", + "approved_scope": "isolated S5 chart/ESO preparation integration only", + "live_execution_approval": false, + "workitem": "RAPPS-WP-0017", + "intent_basis": [ + "Release Contracts over Source Internals", + "Repeatable Operations", + "Clear Lower-Layer Handoffs", + "Evidence Before Confidence" + ], + "review_artifact_sha256": "33d8d4fa5e213fee59f51175b3819200796d4bee03ed2e5533aa38e6bbec1fd5", + "reviewed_manifest_sha256": "9ee69ac22f5ace155a222cdad4b6e73e86da2d789acaea8cb3cc48e00d0a92ce", + "reviewed_patch_sha256": "9cbec88d38237e6560b163f4175186ee67f2f4dd747ef3427cfcef061704a637", + "gates": [ + "unknown reviewed hardened image digest", + "metadata-only existing authenticated source inventory/migration", + "live node headroom/PVC/readiness survey", + "server dry-run and client diff", + "release-specific EUR estimates and founder live-change approval", + "phase A verified before phase B credential delivery", + "approved executed platform credential CCR", + "native14 URL/7 metadata hash proof then70/70 hosted" + ] +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/private-reader-values.r1.yaml b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/private-reader-values.r1.yaml new file mode 100644 index 00000000..70dc9325 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/private-reader-values.r1.yaml @@ -0,0 +1,5 @@ +# PREPARATION ONLY: empty digest deliberately prevents rendering/deployment. +# Fill only after reuse-surface publishes and reviews the fully hardened image. +image: + digest: "" +authSourceAllowlist: {"REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN": ["https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/capabilities/capability.railiance.openbao-package.md?ref=35672be138036c8433a5ac5de91e068c03c2b124", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/capabilities/capability.railiance.policy-publication-package.md?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/capabilities/capability.railiance.postgres-isolation-recovery.md?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/capabilities/capability.railiance.sbom-runtime-package.md?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/capabilities/capability.railiance.telemetry-package.md?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/capabilities/capability.railiance.tenant-engine-package.md?ref=9bdc86572728783a5ed94266f04f7b12d414c557", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/capabilities/capability.railiance.user-engine-package.md?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738"]} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/reuse-surface-runtime-externalsecret.r1.yaml b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/reuse-surface-runtime-externalsecret.r1.yaml new file mode 100644 index 00000000..38227993 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/reuse-surface-runtime-externalsecret.r1.yaml @@ -0,0 +1,46 @@ +# PROPOSAL ONLY: phase B, after hardened runtime verified and CCR approved. +# reuse-surface hub runtime secrets from OpenBao (RAILIANCE-WP-0011 / CCR-2026-0005). +# +# OpenBao path (platform KV v2): workloads/reuse/reuse-surface/runtime-secrets +# Fields: REUSE_SURFACE_TOKEN, REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET +# +# Prereqs on railiance01: +# - External Secrets Operator (make eso-deploy) +# - ClusterSecretStore openbao-reuse (railiance-platform openbao-secretstore) +# - OpenBao policy workload-kv-read-reuse-surface-runtime + ESO token +# (make reuse-openbao-eso-token-apply) +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: reuse-surface-runtime + namespace: reuse + labels: + app.kubernetes.io/name: reuse-surface + app.kubernetes.io/part-of: railiance-apps +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: openbao-reuse + target: + # Explicit target metadata prevents ESO copying source last-applied annotations. + template: + metadata: + labels: + app.kubernetes.io/name: reuse-surface + app.kubernetes.io/part-of: railiance-apps + name: reuse-surface-env + creationPolicy: Owner + data: + - secretKey: REUSE_SURFACE_TOKEN + remoteRef: + key: workloads/reuse/reuse-surface/runtime-secrets + property: REUSE_SURFACE_TOKEN + - secretKey: REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET + remoteRef: + key: workloads/reuse/reuse-surface/runtime-secrets + property: REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET + - secretKey: REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN + remoteRef: + key: workloads/reuse/reuse-surface/forgejo-source-read + property: FORGEJO_SOURCE_TOKEN diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/runtime-auth-source-allowlist-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/runtime-auth-source-allowlist-r1.json new file mode 100644 index 00000000..edb5f744 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/runtime-auth-source-allowlist-r1.json @@ -0,0 +1,18 @@ +{ + "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN": [ + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/capabilities/capability.railiance.openbao-package.md?ref=35672be138036c8433a5ac5de91e068c03c2b124", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/capabilities/capability.railiance.policy-publication-package.md?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/capabilities/capability.railiance.postgres-isolation-recovery.md?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/capabilities/capability.railiance.sbom-runtime-package.md?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/capabilities/capability.railiance.telemetry-package.md?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/capabilities/capability.railiance.tenant-engine-package.md?ref=9bdc86572728783a5ed94266f04f7b12d414c557", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/capabilities/capability.railiance.user-engine-package.md?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738" + ] +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/supervision-preparation-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/supervision-preparation-r1.json new file mode 100644 index 00000000..722694be --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/supervision-preparation-r1.json @@ -0,0 +1,10 @@ +{ + "agent": "delegated-railiance-apps-cust81-preparation", + "mode": "supervised", + "scope": "isolated local chart/config/ESO proposal preparation, local verification only", + "supervisor": "root custodian coordinating founder-authorized work", + "promotion_evidence": null, + "runtime_enforcement_verified": false, + "authority_granted": false, + "live_execution_authorized": false +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/verify_preparation.py b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/verify_preparation.py new file mode 100644 index 00000000..8523b6b3 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r1/review/verify_preparation.py @@ -0,0 +1,68 @@ +"""Local chart and non-disclosure checks only; never contacts a cluster.""" +import hashlib +import importlib.util +import json +from pathlib import Path +import subprocess +import yaml + +ROOT = Path(__file__).resolve().parents[3] +ARTIFACT = Path(__file__).resolve().parent +calls = [] + +def render(extra, success=True): + command = ['helm', 'template', 'reuse', str(ROOT / 'charts/reuse-surface'), '-f', str(ROOT / 'helm/reuse-surface-values.yaml'), *extra] + proc = subprocess.run(command, capture_output=True, text=True) + calls.append({'command': command, 'exit_code': proc.returncode, 'expected_success': success}) + assert (proc.returncode == 0) == success + return list(yaml.safe_load_all(proc.stdout)) if success else [] + +def api(docs): + return next(d for d in docs if d and d.get('kind') == 'Deployment' and d['metadata']['name'] == 'reuse-surface') + +current = api(render([])) +assert current['spec']['template']['spec']['containers'][0]['image'].endswith(':main-6cbc862') +assert next(e['value'] for e in current['spec']['template']['spec']['containers'][0]['env'] if e['name']=='REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST') == '{}' +proposal = ['-f', str(ARTIFACT / 'private-reader-values.r1.yaml')] +render(proposal, False) # unknown real digest is a hard gate +# Synthetic digest is render-only, and expressly not promotion/build evidence. +render(proposal+['--set', 'image.digest=sha256:bad'], False) +render(proposal+['--set-json', 'authSourceAllowlist={"BAD":["http://attacker.invalid"]}', '--set', 'image.digest=sha256:'+'0'*64], False) +docs = render(proposal+['--set', 'image.digest=sha256:'+'0'*64]) +deployment = api(docs) +container = deployment['spec']['template']['spec']['containers'][0] +assert container['image'].endswith('@sha256:'+'0'*64) +allowlist=json.loads(next(e['value'] for e in container['env'] if e['name']=='REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST')) +expected = json.loads((ARTIFACT/'runtime-auth-source-allowlist-r1.json').read_text()) +assert allowlist==expected and len(next(iter(allowlist.values())))==14 +assert deployment['spec']['strategy'] == current['spec']['strategy'] +assert container['resources']==current['spec']['template']['spec']['containers'][0]['resources'] +assert deployment['spec']['template']['spec']['volumes']==current['spec']['template']['spec']['volumes'] +assert container['volumeMounts']==current['spec']['template']['spec']['containers'][0]['volumeMounts'] +secret=yaml.safe_load((ARTIFACT/'reuse-surface-runtime-externalsecret.r1.yaml').read_text()) +baseline=yaml.safe_load((ROOT/'manifests/reuse-surface-runtime-externalsecret.yaml').read_text()) +assert secret['spec']['data'][:-1]==baseline['spec']['data'] +assert secret['spec']['secretStoreRef']==baseline['spec']['secretStoreRef'] +assert secret['spec']['data'][-1]=={'secretKey':'REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN','remoteRef':{'key':'workloads/reuse/reuse-surface/forgejo-source-read','property':'FORGEJO_SOURCE_TOKEN'}} +spec=importlib.util.spec_from_file_location('inventory',ROOT/'scripts/reuse_authenticated_source_inventory.py') +mod=importlib.util.module_from_spec(spec);spec.loader.exec_module(mod) +url=expected['REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN'][1] +assert len(mod.sanitize([['rapp-openbao','FIXTURE_READ_TOKEN',url]]))==1 +for bad in ['https://token@forgejo.coulomb.social/x', url+'&token=fixture-secret','http://attacker.invalid',url+'#fixture-secret']: + try: mod.sanitize([['rapp-openbao','FIXTURE_READ_TOKEN',bad]]) + except ValueError: pass + else: raise AssertionError('unsafe URL accepted') +# Errors from kubectl are discarded before output; no subprocess invoked in test. +original=mod.subprocess.run +class Failure: + returncode=1;stdout=b'fixture-secret';stderr=b'fixture-secret' +mod.subprocess.run=lambda *args,**kwargs: Failure() +import sys,io,contextlib +argv=sys.argv;sys.argv=['inventory','--kubeconfig','fixture-path'] +buf=io.StringIO() +with contextlib.redirect_stdout(buf): assert mod.main()==1 +sys.argv=argv;mod.subprocess.run=original +assert 'fixture-secret' not in buf.getvalue() +result={'status':'passed','local_only':True,'real_image_digest':None,'synthetic_digest_used_only_to_check_rendering':True,'checks':['production rendering unchanged except empty fail-closed allowlist','unknown/malformed digest fails','HTTP allowlist fails schema','exact14 URLs roundtrip','strategy resources PVC retained','dedicated ESO mapping preserves current fields/store','metadata sanitizer excludes userinfo/query secrets/fragments','kubectl failure output discarded'],'helm_calls':calls} +(ARTIFACT/'local-verification-r1.json').write_text(json.dumps(result,indent=2)+'\n') +print(json.dumps({'status':'passed','checks':len(result['checks'])})) diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/templates/_helpers.tpl b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/templates/_helpers.tpl new file mode 100644 index 00000000..cdcae935 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/templates/_helpers.tpl @@ -0,0 +1,56 @@ +{{- define "reuse.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s" $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "reuse.labels" -}} +app.kubernetes.io/name: {{ include "reuse.fullname" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +app.kubernetes.io/part-of: railiance-apps +helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }} +{{- end -}} + +{{- define "reuse.selectorLabels" -}} +app.kubernetes.io/name: {{ include "reuse.fullname" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{- define "reuse.landingFullname" -}} +{{- printf "%s-landing" (include "reuse.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "reuse.redirectMiddlewareName" -}} +{{- printf "%s-redirect-https" (include "reuse.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "reuse.landingSelectorLabels" -}} +app.kubernetes.io/name: {{ include "reuse.fullname" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/component: landing +{{- end -}} + +{{- define "reuse.image" -}} +{{- if and .Values.authSourceAllowlist (not .Values.image.digest) -}} +{{- fail "authenticated source allowlist requires reviewed hardened image.digest" -}} +{{- end -}} +{{- if .Values.image.digest -}} +{{- if not (regexMatch "^sha256:[a-f0-9]{64}$" .Values.image.digest) -}} +{{- fail "image.digest must be sha256 plus 64 lowercase hex characters" -}} +{{- end -}} +{{- printf "%s@%s" .Values.image.repository .Values.image.digest -}} +{{- else -}} +{{- if not .Values.image.tag -}} +{{- fail "image.tag is required - pin it in helm/reuse-surface-values.yaml" -}} +{{- end -}} +{{- printf "%s:%s" .Values.image.repository .Values.image.tag -}} +{{- end -}} +{{- end -}} + +{{- define "reuse.landingImage" -}} +{{- if not .Values.landing.image.tag -}} +{{- fail "landing.image.tag is required when landing.enabled=true" -}} +{{- end -}} +{{- printf "%s:%s" .Values.landing.image.repository .Values.landing.image.tag -}} +{{- end -}} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/templates/deployment.yaml b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/templates/deployment.yaml new file mode 100644 index 00000000..06b815d6 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/templates/deployment.yaml @@ -0,0 +1,87 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "reuse.fullname" . }} + labels: + {{- include "reuse.labels" . | nindent 4 }} + app.kubernetes.io/component: api +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: {{- include "reuse.selectorLabels" . | nindent 6 }} + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + template: + metadata: + labels: + {{- include "reuse.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: api + spec: + enableServiceLinks: false + securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: reuse-surface + image: {{ include "reuse.image" . | quote }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["reuse-surface", "serve"] + securityContext: {{- toYaml .Values.securityContext | nindent 12 }} + ports: + - name: http + containerPort: {{ .Values.service.targetPort }} + protocol: TCP + envFrom: + - secretRef: + name: {{ .Values.envSecretName | quote }} + env: + - name: REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST + value: {{ .Values.authSourceAllowlist | toJson | quote }} + - name: REUSE_SURFACE_LISTEN_HOST + value: "0.0.0.0" + - name: REUSE_SURFACE_LISTEN_PORT + value: {{ .Values.service.targetPort | quote }} + - name: REUSE_SURFACE_DB + value: {{ printf "%s/reuse.db" .Values.persistence.mountPath | quote }} + - name: REUSE_SURFACE_CACHE_DIR + value: {{ printf "%s/cache" .Values.persistence.mountPath | quote }} + {{- if .Values.persistence.enabled }} + volumeMounts: + - name: data + mountPath: {{ .Values.persistence.mountPath }} + {{- end }} + {{- if .Values.probes.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.probes.path }} + port: {{ .Values.probes.port }} + initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.readiness.periodSeconds }} + timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds }} + failureThreshold: {{ .Values.probes.readiness.failureThreshold }} + livenessProbe: + httpGet: + path: {{ .Values.probes.path }} + port: {{ .Values.probes.port }} + initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.liveness.periodSeconds }} + timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds }} + failureThreshold: {{ .Values.probes.liveness.failureThreshold }} + {{- end }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- if .Values.persistence.enabled }} + volumes: + - name: data + persistentVolumeClaim: + claimName: {{ include "reuse.fullname" . }}-data + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/values.schema.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/values.schema.json new file mode 100644 index 00000000..7367c10a --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/values.schema.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "digest": { + "type": "string", + "pattern": "^(|sha256:[a-f0-9]{64})$" + } + } + }, + "authSourceAllowlist": { + "type": "object", + "propertyNames": { + "pattern": "^[A-Z][A-Z0-9_]*$" + }, + "additionalProperties": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "pattern": "^https://[^\\s]+$" + }, + "minItems": 1 + } + } + } +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/values.yaml b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/values.yaml new file mode 100644 index 00000000..0e520d26 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/charts/reuse-surface/values.yaml @@ -0,0 +1,106 @@ +image: + repository: forgejo.coulomb.social/coulomb/reuse-surface + tag: "" + digest: "" + pullPolicy: IfNotPresent + +replicaCount: 1 + +service: + type: ClusterIP + port: 8000 + targetPort: 8000 + +persistence: + enabled: true + size: 1Gi + mountPath: /data + storageClassName: "" + +resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + +envSecretName: reuse-surface-env + +# Non-secret exact URL bindings for authenticated remote metadata fetches. +# Nonempty bindings require an immutable digest; use only a reviewed hardened image. +authSourceAllowlist: {} + +landing: + enabled: false + image: + repository: nginxinc/nginx-unprivileged + tag: "1.27-alpine" + pullPolicy: IfNotPresent + service: + port: 8080 + targetPort: 8080 + ingress: + # Explicit Traefik router priority for the landing catch-all. Traefik + # otherwise derives priority from rule-string length, where PathPrefix(`/`) + # ties with Path(`/health`) and can win. Keep this below every API route. + priority: 1 + noindex: true + title: "Railiance service endpoint" + eyebrow: "Railiance S5" + body: "This endpoint is available for automated clients and operators." + buttonLabel: "Continue" + primaryUrl: "" + redirect: + enabled: false + target: "" + delaySeconds: 5 + links: [] + html: "" + resources: + requests: + cpu: 10m + memory: 32Mi + limits: + cpu: 50m + memory: 64Mi + +ingress: + enabled: true + className: traefik + host: reuse.coulomb.social + tls: true + redirectHttp: + enabled: false + permanent: true + apiPaths: + - path: /health + pathType: Exact + - path: /v1 + pathType: Prefix + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-prod + +probes: + enabled: true + path: /health + port: 8000 + liveness: + initialDelaySeconds: 15 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 + readiness: + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + +podSecurityContext: {} +securityContext: {} + +nodeSelector: {} +tolerations: [] +affinity: {} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/apps-owner-review-r2.md b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/apps-owner-review-r2.md new file mode 100644 index 00000000..a7f7b1b9 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/apps-owner-review-r2.md @@ -0,0 +1,119 @@ +# Railiance apps preparation review — CUST81 private metadata reader R2 + +Reviewer: delegated railiance-apps preparation worker, supervised local preparation +assignment. No promotion evidence or existing own-scope supervision record was +found; the descriptive preparation record grants no runtime authority. This is +an S5 release-contract review grounded in INTENT principles 1–5 (workloads, +release contracts, repeatable operations, explicit S3 handoff, verified health). +It is not a founder decision, independent platform credential review or reuse +application source review. No live changes, commits, pushes, hub writes, image +publishes, login or credential retrieval occurred. + +Disposition: **approved for integration as local preparation only; live promotion blocked**. +Canonical review disposition: `approved`. This accepts the bounded S5 proposal +and its explicit runtime gates, not live execution or another owner’s review. + +## Proposed changes and owner boundaries + +The chart accepts an optional immutable image digest, adds a non-secret exact +`REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST` environment binding, and fails rendering +when a nonempty allowlist lacks an immutable digest. Schema checks enforce +HTTPS allowlist entries and valid digest syntax. Production values continue +using their existing `main-6cbc862` tag; production ExternalSecret is unchanged. +The preparation override contains exactly 14 reviewed pinned metadata URLs and +an empty digest deliberately preventing deployment. A synthetic all-zero digest +in local tests is not an image and must never be promoted. + +The proposed phase-B ExternalSecret preserves existing two keys, target metadata +and existing `openbao-reuse` ClusterSecretStore, adding only +`REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN` from +`workloads/reuse/reuse-surface/forgejo-source-read:FORGEJO_SOURCE_TOKEN`. +Platform owns the dedicated KV path/policy/store read scope, CCR-2026-0046 and +credential issuance; apps neither provisions nor consumes an admin credential. + +Digest presence cannot prove the hardened application is included. The reuse +owner must provide published build digest, source revision, tests and review +binding *both* authenticated redirect rejection and exact environment-name/URL +credential routing. A reader must not reach the existing vulnerable runtime. + +## Ordered promotion gates — not executed + +1. Confirm own-scope supervision and founder change approval, reviewed CCR, + exact seven-source owner consent packet and scoped Forgejo read-only issuer + receipt. Integrate provisional RAPPS-WP-0017 through root owner coordination. +2. Run metadata inventory helper with an explicitly verified railiance01 + kubeconfig; compare existing authenticated registrations with newly + fail-closed image behavior. The helper reads only SQLite registration + metadata, never env/Secrets, captures command errors and refuses unsafe + URLs. If it refuses, resolve via the source owner without emitting raw + objects. Any existing authenticated source requires separately reviewed + exact URL bindings including capability entry URLs before promotion; do not + silently orphan sources or broaden the 14-URL map. Missing inventory blocks + phase A. Store only safe names, counts and validated metadata URLs. +3. Read live release image/revision, replica state, PVC storage/access modes and + readiness. Confirm node external IP `92.205.62.239`, not retired coulombcore. + Record requested CPU/memory headroom and pending pods before rollout. Existing + API requests 100m CPU/256Mi, surge1 requires that much additional allocatable + capacity; landing unchanged. Confirm the existing PVC supports simultaneous + pod scheduling/mount on this single node; stop if RWO/RWOP or mount conflicts + prevent it. No rollout strategy/resource/PVC changes are proposed. Do not + change other workloads merely to obtain capacity. +4. Once a real reviewed digest exists, fill the preparation values; render + exact chart with production values plus proposal overrides. Server dry-run + and client diff must cover every rendered chart object and the phase-B ESO + manifest. Preserve stderr in memory and emit sanitized status only; never + print live Secrets, Helm secret values, annotations or raw API failures. + Existing release owner and any Argo adoption must be verified before choosing + owner Helm upgrade versus GitOps sync; neither is executed here. +5. Phase A: approved release of hardened digest plus approved allowlist, with + existing ESO fields only. Owner Helm path must use atomic upgrade, timeout + and wait; verify actual running imageID matches digest, API health/probes, + public federation baseline63 and credential-routing refusal/redirect tests. + Deployment failure blocks phase B. Database/PVC remains unchanged. Collect a + separately approved safe backup/recovery receipt before any risky live release. +6. Phase B: after verified phase A, execute reviewed platform credential action + and ESO reader mapping. Verify only ESO condition/status and key-presence + booleans via approved suppressing helpers, then restart/sync the hardened + workload so envFrom obtains the reader. Never dump Secret or process env. +7. Reuse owner runs native exact-byte authenticated proof for all14 URLs and + seven capability entries using pinned consent hashes. Only then register + seven sources through the scoped write route and verify hosted70/70, + no duplicates/conflicting IDs and public federation preserves all63. + +## Rollback contract + +Before execution capture previous approved release revision, digest/tag and +safe configuration, public discovery baseline and database recovery receipt. +If phase A fails before credential delivery, atomic restore of previous release +is safe because no reader has been supplied. After phase B, **never downgrade to +vulnerable runtime with reader still available**: revoke the dedicated reader +at Forgejo/OpenBao via credential owner, remove phase-B ESO mapping and materialized +reader key through reviewed silent maintenance, restart current hardened pods, +verify absence/revocation, then restore prior approved chart/image only if needed. +Metadata registrations may remain inaccessible until re-established; record the +regression explicitly. Do not roll back the PVC or use stale tokens as recovery. + +## Local evidence and limitations + +`helm lint charts/reuse-surface -f helm/reuse-surface-values.yaml` passed. +`python3 docs/assessments/cust81-private-reader/verify_preparation.py` passed ten +checks, including exact14 roundtrip, digest/schema refusal, retention of current +strategy/resources/PVC, correct isolated ESO mapping, metadata URL sanitization +and subprocess error suppression. `local-verification-r2.json` contains command +statuses without raw output. No cluster inventory, resource headroom, +server dry-run/diff, image publish, live approval or native fetch has been proven. + +## Revision history — same proposal, no second trial + +R1 root review found the inventory SQL incorrectly selected `$.index_url` rather +than the native HubStore registration field `$.url`. R1's local checks did not +exercise the pod SQL and therefore missed this defect. R1 must not be executed; +it remains preserved in the root assembly archive. R2 selects `$.url` and tests +the exact read-only pod SQL against a real SQLite registration payload containing +`repo`, `url`, `auth_env`, timestamps and an unrelated sentinel description, plus +an anonymous registration. Only expected names/URL emerge; rows remain unchanged. +R2 also accepts canonical Forgejo raw branch/commit/tag index routes while still +refusing userinfo, non-HTTPS, credentials in queries and fragments. Untrusted +successful subprocess output is refused without raw echo, as are failures. +No live inventory command has run. This corrective refinement is the same +CUST81-APPS-PRIVATE-READER-RELEASE proposal revision2, not an unchanged success. diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/local-verification-r2.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/local-verification-r2.json new file mode 100644 index 00000000..dbd13662 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/local-verification-r2.json @@ -0,0 +1,96 @@ +{ + "status": "passed", + "local_only": true, + "real_image_digest": null, + "synthetic_digest_used_only_to_check_rendering": true, + "checks": [ + "production rendering unchanged except empty fail-closed allowlist", + "unknown/malformed digest fails", + "HTTP allowlist fails schema", + "exact14 URLs roundtrip", + "strategy resources PVC retained", + "dedicated ESO mapping preserves current fields/store", + "metadata sanitizer excludes userinfo/query secrets/fragments", + "kubectl failure output discarded", + "exact pod SQL real payload URL keys readonly fixture and anonymous filtering", + "legacy Forgejo branch URL accepted without weakening credential query refusal" + ], + "helm_calls": [ + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml" + ], + "exit_code": 0, + "expected_success": true + }, + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", + "-f", + "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml" + ], + "exit_code": 1, + "expected_success": false + }, + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", + "-f", + "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml", + "--set", + "image.digest=sha256:bad" + ], + "exit_code": 1, + "expected_success": false + }, + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", + "-f", + "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml", + "--set-json", + "authSourceAllowlist={\"BAD\":[\"http://attacker.invalid\"]}", + "--set", + "image.digest=sha256:0000000000000000000000000000000000000000000000000000000000000000" + ], + "exit_code": 1, + "expected_success": false + }, + { + "command": [ + "helm", + "template", + "reuse", + "/tmp/cust81-apps-reader-owner/charts/reuse-surface", + "-f", + "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", + "-f", + "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml", + "--set", + "image.digest=sha256:0000000000000000000000000000000000000000000000000000000000000000" + ], + "exit_code": 0, + "expected_success": true + } + ] +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml new file mode 100644 index 00000000..70dc9325 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml @@ -0,0 +1,5 @@ +# PREPARATION ONLY: empty digest deliberately prevents rendering/deployment. +# Fill only after reuse-surface publishes and reviews the fully hardened image. +image: + digest: "" +authSourceAllowlist: {"REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN": ["https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/capabilities/capability.railiance.openbao-package.md?ref=35672be138036c8433a5ac5de91e068c03c2b124", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/capabilities/capability.railiance.policy-publication-package.md?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/capabilities/capability.railiance.postgres-isolation-recovery.md?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/capabilities/capability.railiance.sbom-runtime-package.md?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/capabilities/capability.railiance.telemetry-package.md?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/capabilities/capability.railiance.tenant-engine-package.md?ref=9bdc86572728783a5ed94266f04f7b12d414c557", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/capabilities/capability.railiance.user-engine-package.md?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738"]} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/reuse-surface-runtime-externalsecret.r1.yaml b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/reuse-surface-runtime-externalsecret.r1.yaml new file mode 100644 index 00000000..38227993 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/reuse-surface-runtime-externalsecret.r1.yaml @@ -0,0 +1,46 @@ +# PROPOSAL ONLY: phase B, after hardened runtime verified and CCR approved. +# reuse-surface hub runtime secrets from OpenBao (RAILIANCE-WP-0011 / CCR-2026-0005). +# +# OpenBao path (platform KV v2): workloads/reuse/reuse-surface/runtime-secrets +# Fields: REUSE_SURFACE_TOKEN, REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET +# +# Prereqs on railiance01: +# - External Secrets Operator (make eso-deploy) +# - ClusterSecretStore openbao-reuse (railiance-platform openbao-secretstore) +# - OpenBao policy workload-kv-read-reuse-surface-runtime + ESO token +# (make reuse-openbao-eso-token-apply) +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: reuse-surface-runtime + namespace: reuse + labels: + app.kubernetes.io/name: reuse-surface + app.kubernetes.io/part-of: railiance-apps +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: openbao-reuse + target: + # Explicit target metadata prevents ESO copying source last-applied annotations. + template: + metadata: + labels: + app.kubernetes.io/name: reuse-surface + app.kubernetes.io/part-of: railiance-apps + name: reuse-surface-env + creationPolicy: Owner + data: + - secretKey: REUSE_SURFACE_TOKEN + remoteRef: + key: workloads/reuse/reuse-surface/runtime-secrets + property: REUSE_SURFACE_TOKEN + - secretKey: REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET + remoteRef: + key: workloads/reuse/reuse-surface/runtime-secrets + property: REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET + - secretKey: REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN + remoteRef: + key: workloads/reuse/reuse-surface/forgejo-source-read + property: FORGEJO_SOURCE_TOKEN diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json new file mode 100644 index 00000000..edb5f744 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json @@ -0,0 +1,18 @@ +{ + "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN": [ + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/capabilities/capability.railiance.openbao-package.md?ref=35672be138036c8433a5ac5de91e068c03c2b124", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/capabilities/capability.railiance.policy-publication-package.md?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/capabilities/capability.railiance.postgres-isolation-recovery.md?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/capabilities/capability.railiance.sbom-runtime-package.md?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/capabilities/capability.railiance.telemetry-package.md?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/capabilities/capability.railiance.tenant-engine-package.md?ref=9bdc86572728783a5ed94266f04f7b12d414c557", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/capabilities/capability.railiance.user-engine-package.md?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738", + "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738" + ] +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/supervision-preparation-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/supervision-preparation-r1.json new file mode 100644 index 00000000..722694be --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/supervision-preparation-r1.json @@ -0,0 +1,10 @@ +{ + "agent": "delegated-railiance-apps-cust81-preparation", + "mode": "supervised", + "scope": "isolated local chart/config/ESO proposal preparation, local verification only", + "supervisor": "root custodian coordinating founder-authorized work", + "promotion_evidence": null, + "runtime_enforcement_verified": false, + "authority_granted": false, + "live_execution_authorized": false +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/verify_preparation.py b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/verify_preparation.py new file mode 100644 index 00000000..df571999 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/docs/assessments/cust81-private-reader/verify_preparation.py @@ -0,0 +1,94 @@ +"""Local chart and non-disclosure checks only; never contacts a cluster.""" +import hashlib +import importlib.util +import json +from pathlib import Path +import subprocess +import yaml + +ROOT = Path(__file__).resolve().parents[3] +ARTIFACT = Path(__file__).resolve().parent +calls = [] + +def render(extra, success=True): + command = ['helm', 'template', 'reuse', str(ROOT / 'charts/reuse-surface'), '-f', str(ROOT / 'helm/reuse-surface-values.yaml'), *extra] + proc = subprocess.run(command, capture_output=True, text=True) + calls.append({'command': command, 'exit_code': proc.returncode, 'expected_success': success}) + assert (proc.returncode == 0) == success + return list(yaml.safe_load_all(proc.stdout)) if success else [] + +def api(docs): + return next(d for d in docs if d and d.get('kind') == 'Deployment' and d['metadata']['name'] == 'reuse-surface') + +current = api(render([])) +assert current['spec']['template']['spec']['containers'][0]['image'].endswith(':main-6cbc862') +assert next(e['value'] for e in current['spec']['template']['spec']['containers'][0]['env'] if e['name']=='REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST') == '{}' +proposal = ['-f', str(ARTIFACT / 'private-reader-values.r1.yaml')] +render(proposal, False) # unknown real digest is a hard gate +# Synthetic digest is render-only, and expressly not promotion/build evidence. +render(proposal+['--set', 'image.digest=sha256:bad'], False) +render(proposal+['--set-json', 'authSourceAllowlist={"BAD":["http://attacker.invalid"]}', '--set', 'image.digest=sha256:'+'0'*64], False) +docs = render(proposal+['--set', 'image.digest=sha256:'+'0'*64]) +deployment = api(docs) +container = deployment['spec']['template']['spec']['containers'][0] +assert container['image'].endswith('@sha256:'+'0'*64) +allowlist=json.loads(next(e['value'] for e in container['env'] if e['name']=='REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST')) +expected = json.loads((ARTIFACT/'runtime-auth-source-allowlist-r1.json').read_text()) +assert allowlist==expected and len(next(iter(allowlist.values())))==14 +assert deployment['spec']['strategy'] == current['spec']['strategy'] +assert container['resources']==current['spec']['template']['spec']['containers'][0]['resources'] +assert deployment['spec']['template']['spec']['volumes']==current['spec']['template']['spec']['volumes'] +assert container['volumeMounts']==current['spec']['template']['spec']['containers'][0]['volumeMounts'] +secret=yaml.safe_load((ARTIFACT/'reuse-surface-runtime-externalsecret.r1.yaml').read_text()) +baseline=yaml.safe_load((ROOT/'manifests/reuse-surface-runtime-externalsecret.yaml').read_text()) +assert secret['spec']['data'][:-1]==baseline['spec']['data'] +assert secret['spec']['secretStoreRef']==baseline['spec']['secretStoreRef'] +assert secret['spec']['data'][-1]=={'secretKey':'REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN','remoteRef':{'key':'workloads/reuse/reuse-surface/forgejo-source-read','property':'FORGEJO_SOURCE_TOKEN'}} +spec=importlib.util.spec_from_file_location('inventory',ROOT/'scripts/reuse_authenticated_source_inventory.py') +mod=importlib.util.module_from_spec(spec);spec.loader.exec_module(mod) +url=expected['REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN'][1] +assert len(mod.sanitize([['rapp-openbao','FIXTURE_READ_TOKEN',url]]))==1 +legacy='https://forgejo.coulomb.social/coulomb/rapp-openbao/raw/branch/main/registry/indexes/capabilities.yaml' +assert len(mod.sanitize([['rapp-openbao','FIXTURE_READ_TOKEN',legacy]]))==1 +# Exercise the EXACT pod code against actual native registration keys in SQLite. +# Replacing only the fixture DB path leaves the metadata SELECT/read-only mode intact. +import sqlite3,tempfile +with tempfile.TemporaryDirectory(prefix='apps-reader-fixture-') as temp: + fixture=Path(temp)/'reuse.db' + with sqlite3.connect(fixture) as db: + db.execute('CREATE TABLE registrations(repo TEXT PRIMARY KEY, payload TEXT NOT NULL, registered_at TEXT, updated_at TEXT)') + db.execute('INSERT INTO registrations VALUES(?,?,?,?)', ('rapp-openbao',json.dumps({'repo':'rapp-openbao','url':url,'auth_env':'FIXTURE_READ_TOKEN','description':'fixture-secret-never-emit'}),'fixture','fixture')) + db.execute('INSERT INTO registrations VALUES(?,?,?,?)', ('anonymous',json.dumps({'repo':'anonymous','url':legacy}),'fixture','fixture')) + pod_code=mod.POD_CODE.replace('/data/reuse.db',str(fixture)) + proc=subprocess.run(['python3','-c',pod_code],capture_output=True,text=True,check=True) + assert json.loads(proc.stdout)==[['rapp-openbao','FIXTURE_READ_TOKEN',url]] + assert 'fixture-secret' not in proc.stdout + assert len(mod.sanitize(json.loads(proc.stdout)))==1 + with sqlite3.connect(fixture) as db: assert db.execute('SELECT count(*) FROM registrations').fetchone()==(2,) + assert 'mode=ro' in pod_code and '$.index_url' not in pod_code + assert 'os.environ' not in pod_code and 'getenv' not in pod_code and 'kubectl' not in pod_code + +for bad in ['https://token@forgejo.coulomb.social/x', url+'&token=fixture-secret','http://attacker.invalid',url+'#fixture-secret',legacy+'?token=fixture-secret',legacy+'/../credentials',legacy+'%3Ftoken=fixture-secret']: + try: mod.sanitize([['rapp-openbao','FIXTURE_READ_TOKEN',bad]]) + except ValueError: pass + else: raise AssertionError('unsafe URL accepted') +# Errors from kubectl are discarded before output; no subprocess invoked in test. +original=mod.subprocess.run +class Failure: + returncode=1;stdout=b'fixture-secret';stderr=b'fixture-secret' +mod.subprocess.run=lambda *args,**kwargs: Failure() +import sys,io,contextlib +argv=sys.argv;sys.argv=['inventory','--kubeconfig','fixture-path'] +buf=io.StringIO() +with contextlib.redirect_stdout(buf): assert mod.main()==1 +assert 'fixture-secret' not in buf.getvalue() +class UnsafeSuccess: + returncode=0;stdout=json.dumps([['rapp-openbao','FIXTURE_READ_TOKEN',url+'&token=fixture-secret']]).encode();stderr=b'' +mod.subprocess.run=lambda *args,**kwargs: UnsafeSuccess() +buf=io.StringIO() +with contextlib.redirect_stdout(buf): assert mod.main()==1 +assert 'fixture-secret' not in buf.getvalue() +sys.argv=argv;mod.subprocess.run=original +result={'status':'passed','local_only':True,'real_image_digest':None,'synthetic_digest_used_only_to_check_rendering':True,'checks':['production rendering unchanged except empty fail-closed allowlist','unknown/malformed digest fails','HTTP allowlist fails schema','exact14 URLs roundtrip','strategy resources PVC retained','dedicated ESO mapping preserves current fields/store','metadata sanitizer excludes userinfo/query secrets/fragments','kubectl failure output discarded','exact pod SQL real payload URL keys readonly fixture and anonymous filtering','legacy Forgejo branch URL accepted without weakening credential query refusal'],'helm_calls':calls} +(ARTIFACT/'local-verification-r2.json').write_text(json.dumps(result,indent=2)+'\n') +print(json.dumps({'status':'passed','checks':len(result['checks'])})) diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/scripts/reuse_authenticated_source_inventory.py b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/scripts/reuse_authenticated_source_inventory.py new file mode 100644 index 00000000..aea33a5a --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/scripts/reuse_authenticated_source_inventory.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +"""Read-only authenticated source metadata; never read env or Kubernetes Secrets. + +Caller must first confirm the kubeconfig targets railiance01. Raw command +stdout/stderr and exception text are never emitted. No credentials are needed +beyond the caller's separately approved Kubernetes observation/exec lane. +""" +import argparse +import json +import re +import subprocess +from urllib.parse import urlsplit, parse_qs + +# SQL projects metadata only; the registration payload itself is never printed. +POD_CODE = '''import json, sqlite3 +with sqlite3.connect("file:/data/reuse.db?mode=ro", uri=True) as db: + rows=db.execute("SELECT repo, json_extract(payload, '$.auth_env'), json_extract(payload, '$.url') FROM registrations WHERE json_extract(payload, '$.auth_env') IS NOT NULL AND json_extract(payload, '$.auth_env') != ''").fetchall() + print(json.dumps(rows)) +''' + + +def sanitize(rows): + result = [] + for repo, name, url in rows: + if not isinstance(repo, str) or not re.fullmatch(r'[a-zA-Z0-9_.-]{1,128}', repo): + raise ValueError('invalid metadata') + if not isinstance(name, str) or not re.fullmatch(r'[A-Z][A-Z0-9_]{0,127}', name): + raise ValueError('invalid metadata') + parts = urlsplit(url) + # URLs are untrusted stored data; refuse userinfo/fragments and arbitrary + # query fields (which could contain credentials). Never echo invalid rows. + query = parse_qs(parts.query, keep_blank_values=True) + if (parts.scheme != 'https' or parts.username or parts.password or parts.fragment + or parts.hostname != 'forgejo.coulomb.social' or parts.port not in (None, 443) + or not (re.fullmatch(r'/api/v1/repos/coulomb/[a-zA-Z0-9_.-]+/raw/registry/indexes/[a-zA-Z0-9_.-]+', parts.path) + or re.fullmatch(r'/coulomb/[a-zA-Z0-9_.-]+/raw/(?:branch|commit|tag)/[a-zA-Z0-9_.-]+/registry/indexes/[a-zA-Z0-9_.-]+', parts.path)) + or any(k != 'ref' for k in query) + or ('ref' in query and (len(query['ref']) != 1 or not re.fullmatch(r'[a-zA-Z0-9_.-]{1,128}', query['ref'][0])))): + raise ValueError('unsafe metadata') + result.append({'repo': repo, 'auth_env': name, 'index_url': url}) + return sorted(result, key=lambda row: row['repo']) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--kubeconfig', required=True) + args = parser.parse_args() + try: + proc = subprocess.run(['kubectl', '--kubeconfig', args.kubeconfig, '-n', 'reuse', + 'exec', 'deployment/reuse-surface', '-c', 'reuse-surface', '--', 'python3', '-c', POD_CODE], + capture_output=True, timeout=30) + if proc.returncode: + raise RuntimeError('inventory unavailable') + rows = sanitize(json.loads(proc.stdout)) + except Exception: + print(json.dumps({'status': 'refused_or_unavailable', 'raw_output_discarded': True})) + return 1 + print(json.dumps({'status': 'verified', 'authenticated_source_count': len(rows), 'sources': rows}, indent=2)) + return 0 + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/workplans/RAPPS-WP-0017-reuse-private-reader-release.md b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/workplans/RAPPS-WP-0017-reuse-private-reader-release.md new file mode 100644 index 00000000..0363d08b --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/files/workplans/RAPPS-WP-0017-reuse-private-reader-release.md @@ -0,0 +1,57 @@ +--- +id: RAPPS-WP-0017 +type: workplan +title: "Release hardened reuse federation with seven-source metadata reader" +domain: financials +repo: railiance-apps +status: proposed +owner: codex +created: "2026-10-15" +updated: "2026-10-15" +flavor: implementation +depends_on: [RPF-WP-0058, REUSE-WP-0025] +--- + +Provisional id in isolated preparation checkout; root integration must confirm +availability. No hub registration, fix-consistency or push until integration. +Source owners approved metadata disclosure under CUST81 R1; that is not approval +for live credential issuance or workload rollout. Apps owns only S5 release. + +## Prepare bounded release contract + +```task +id: RAPPS-WP-0017-T01 +status: done +priority: high +``` + +Prepare chart allowlist/digest support, exact14 URL override and separate phase-B +ESO manifest, own preparation review and meaningful local validation. +Evidence: docs/assessments/cust81-private-reader/apps-owner-review-r1.md. + +## Verify and promote hardened runtime before reader delivery + +```task +id: RAPPS-WP-0017-T02 +status: wait +priority: high +``` + +Wait for published fully hardened image digest/source/tests plus owner reviews +and change authorization. Obtain metadata-only existing auth-source migration +inventory, live headroom/PVC evidence, exact server dry-run/diff, baseline health +and rollback receipt. Phase A deploy excludes reader ESO mapping. + +## Deliver reviewed reader and prove complete hosted discovery + +```task +id: RAPPS-WP-0017-T03 +status: wait +priority: high +``` + +After verified phase A and approved/executed platform CCR, apply phase-B ESO +mapping and restart hardened runtime through reviewed owner lane. Require +sanitized ESO/key-presence proof and reuse native14 fetch/7 entry hashes before +registration. Final CUST81 owner verifies70/70 hosted; rollback revokes/removes +reader before any vulnerable image restoration. diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/owner.patch b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/owner.patch new file mode 100644 index 00000000..c48be3f4 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/apps-r2/owner.patch @@ -0,0 +1,659 @@ +diff --git a/charts/reuse-surface/templates/_helpers.tpl b/charts/reuse-surface/templates/_helpers.tpl +index 1c46bdb..cdcae93 100644 +--- a/charts/reuse-surface/templates/_helpers.tpl ++++ b/charts/reuse-surface/templates/_helpers.tpl +@@ -32,11 +32,21 @@ app.kubernetes.io/component: landing + {{- end -}} + + {{- define "reuse.image" -}} ++{{- if and .Values.authSourceAllowlist (not .Values.image.digest) -}} ++{{- fail "authenticated source allowlist requires reviewed hardened image.digest" -}} ++{{- end -}} ++{{- if .Values.image.digest -}} ++{{- if not (regexMatch "^sha256:[a-f0-9]{64}$" .Values.image.digest) -}} ++{{- fail "image.digest must be sha256 plus 64 lowercase hex characters" -}} ++{{- end -}} ++{{- printf "%s@%s" .Values.image.repository .Values.image.digest -}} ++{{- else -}} + {{- if not .Values.image.tag -}} + {{- fail "image.tag is required - pin it in helm/reuse-surface-values.yaml" -}} + {{- end -}} + {{- printf "%s:%s" .Values.image.repository .Values.image.tag -}} + {{- end -}} ++{{- end -}} + + {{- define "reuse.landingImage" -}} + {{- if not .Values.landing.image.tag -}} +diff --git a/charts/reuse-surface/templates/deployment.yaml b/charts/reuse-surface/templates/deployment.yaml +index b1c47e7..06b815d 100644 +--- a/charts/reuse-surface/templates/deployment.yaml ++++ b/charts/reuse-surface/templates/deployment.yaml +@@ -36,6 +36,8 @@ spec: + - secretRef: + name: {{ .Values.envSecretName | quote }} + env: ++ - name: REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST ++ value: {{ .Values.authSourceAllowlist | toJson | quote }} + - name: REUSE_SURFACE_LISTEN_HOST + value: "0.0.0.0" + - name: REUSE_SURFACE_LISTEN_PORT +diff --git a/charts/reuse-surface/values.yaml b/charts/reuse-surface/values.yaml +index fb54e76..0e520d2 100644 +--- a/charts/reuse-surface/values.yaml ++++ b/charts/reuse-surface/values.yaml +@@ -1,6 +1,7 @@ + image: + repository: forgejo.coulomb.social/coulomb/reuse-surface + tag: "" ++ digest: "" + pullPolicy: IfNotPresent + + replicaCount: 1 +@@ -26,6 +27,10 @@ resources: + + envSecretName: reuse-surface-env + ++# Non-secret exact URL bindings for authenticated remote metadata fetches. ++# Nonempty bindings require an immutable digest; use only a reviewed hardened image. ++authSourceAllowlist: {} ++ + landing: + enabled: false + image: +diff --git a/charts/reuse-surface/values.schema.json b/charts/reuse-surface/values.schema.json +new file mode 100644 +index 0000000..7367c10 +--- /dev/null ++++ b/charts/reuse-surface/values.schema.json +@@ -0,0 +1,30 @@ ++{ ++ "$schema": "https://json-schema.org/draft-07/schema#", ++ "type": "object", ++ "properties": { ++ "image": { ++ "type": "object", ++ "properties": { ++ "digest": { ++ "type": "string", ++ "pattern": "^(|sha256:[a-f0-9]{64})$" ++ } ++ } ++ }, ++ "authSourceAllowlist": { ++ "type": "object", ++ "propertyNames": { ++ "pattern": "^[A-Z][A-Z0-9_]*$" ++ }, ++ "additionalProperties": { ++ "type": "array", ++ "uniqueItems": true, ++ "items": { ++ "type": "string", ++ "pattern": "^https://[^\\s]+$" ++ }, ++ "minItems": 1 ++ } ++ } ++ } ++} +diff --git a/scripts/reuse_authenticated_source_inventory.py b/scripts/reuse_authenticated_source_inventory.py +new file mode 100644 +index 0000000..aea33a5 +--- /dev/null ++++ b/scripts/reuse_authenticated_source_inventory.py +@@ -0,0 +1,62 @@ ++#!/usr/bin/env python3 ++"""Read-only authenticated source metadata; never read env or Kubernetes Secrets. ++ ++Caller must first confirm the kubeconfig targets railiance01. Raw command ++stdout/stderr and exception text are never emitted. No credentials are needed ++beyond the caller's separately approved Kubernetes observation/exec lane. ++""" ++import argparse ++import json ++import re ++import subprocess ++from urllib.parse import urlsplit, parse_qs ++ ++# SQL projects metadata only; the registration payload itself is never printed. ++POD_CODE = '''import json, sqlite3 ++with sqlite3.connect("file:/data/reuse.db?mode=ro", uri=True) as db: ++ rows=db.execute("SELECT repo, json_extract(payload, '$.auth_env'), json_extract(payload, '$.url') FROM registrations WHERE json_extract(payload, '$.auth_env') IS NOT NULL AND json_extract(payload, '$.auth_env') != ''").fetchall() ++ print(json.dumps(rows)) ++''' ++ ++ ++def sanitize(rows): ++ result = [] ++ for repo, name, url in rows: ++ if not isinstance(repo, str) or not re.fullmatch(r'[a-zA-Z0-9_.-]{1,128}', repo): ++ raise ValueError('invalid metadata') ++ if not isinstance(name, str) or not re.fullmatch(r'[A-Z][A-Z0-9_]{0,127}', name): ++ raise ValueError('invalid metadata') ++ parts = urlsplit(url) ++ # URLs are untrusted stored data; refuse userinfo/fragments and arbitrary ++ # query fields (which could contain credentials). Never echo invalid rows. ++ query = parse_qs(parts.query, keep_blank_values=True) ++ if (parts.scheme != 'https' or parts.username or parts.password or parts.fragment ++ or parts.hostname != 'forgejo.coulomb.social' or parts.port not in (None, 443) ++ or not (re.fullmatch(r'/api/v1/repos/coulomb/[a-zA-Z0-9_.-]+/raw/registry/indexes/[a-zA-Z0-9_.-]+', parts.path) ++ or re.fullmatch(r'/coulomb/[a-zA-Z0-9_.-]+/raw/(?:branch|commit|tag)/[a-zA-Z0-9_.-]+/registry/indexes/[a-zA-Z0-9_.-]+', parts.path)) ++ or any(k != 'ref' for k in query) ++ or ('ref' in query and (len(query['ref']) != 1 or not re.fullmatch(r'[a-zA-Z0-9_.-]{1,128}', query['ref'][0])))): ++ raise ValueError('unsafe metadata') ++ result.append({'repo': repo, 'auth_env': name, 'index_url': url}) ++ return sorted(result, key=lambda row: row['repo']) ++ ++ ++def main(): ++ parser = argparse.ArgumentParser(description=__doc__) ++ parser.add_argument('--kubeconfig', required=True) ++ args = parser.parse_args() ++ try: ++ proc = subprocess.run(['kubectl', '--kubeconfig', args.kubeconfig, '-n', 'reuse', ++ 'exec', 'deployment/reuse-surface', '-c', 'reuse-surface', '--', 'python3', '-c', POD_CODE], ++ capture_output=True, timeout=30) ++ if proc.returncode: ++ raise RuntimeError('inventory unavailable') ++ rows = sanitize(json.loads(proc.stdout)) ++ except Exception: ++ print(json.dumps({'status': 'refused_or_unavailable', 'raw_output_discarded': True})) ++ return 1 ++ print(json.dumps({'status': 'verified', 'authenticated_source_count': len(rows), 'sources': rows}, indent=2)) ++ return 0 ++ ++if __name__ == '__main__': ++ raise SystemExit(main()) +diff --git a/workplans/RAPPS-WP-0017-reuse-private-reader-release.md b/workplans/RAPPS-WP-0017-reuse-private-reader-release.md +new file mode 100644 +index 0000000..0363d08 +--- /dev/null ++++ b/workplans/RAPPS-WP-0017-reuse-private-reader-release.md +@@ -0,0 +1,57 @@ ++--- ++id: RAPPS-WP-0017 ++type: workplan ++title: "Release hardened reuse federation with seven-source metadata reader" ++domain: financials ++repo: railiance-apps ++status: proposed ++owner: codex ++created: "2026-10-15" ++updated: "2026-10-15" ++flavor: implementation ++depends_on: [RPF-WP-0058, REUSE-WP-0025] ++--- ++ ++Provisional id in isolated preparation checkout; root integration must confirm ++availability. No hub registration, fix-consistency or push until integration. ++Source owners approved metadata disclosure under CUST81 R1; that is not approval ++for live credential issuance or workload rollout. Apps owns only S5 release. ++ ++## Prepare bounded release contract ++ ++```task ++id: RAPPS-WP-0017-T01 ++status: done ++priority: high ++``` ++ ++Prepare chart allowlist/digest support, exact14 URL override and separate phase-B ++ESO manifest, own preparation review and meaningful local validation. ++Evidence: docs/assessments/cust81-private-reader/apps-owner-review-r1.md. ++ ++## Verify and promote hardened runtime before reader delivery ++ ++```task ++id: RAPPS-WP-0017-T02 ++status: wait ++priority: high ++``` ++ ++Wait for published fully hardened image digest/source/tests plus owner reviews ++and change authorization. Obtain metadata-only existing auth-source migration ++inventory, live headroom/PVC evidence, exact server dry-run/diff, baseline health ++and rollback receipt. Phase A deploy excludes reader ESO mapping. ++ ++## Deliver reviewed reader and prove complete hosted discovery ++ ++```task ++id: RAPPS-WP-0017-T03 ++status: wait ++priority: high ++``` ++ ++After verified phase A and approved/executed platform CCR, apply phase-B ESO ++mapping and restart hardened runtime through reviewed owner lane. Require ++sanitized ESO/key-presence proof and reuse native14 fetch/7 entry hashes before ++registration. Final CUST81 owner verifies70/70 hosted; rollback revokes/removes ++reader before any vulnerable image restoration. +diff --git a/docs/assessments/cust81-private-reader/apps-owner-review-r2.md b/docs/assessments/cust81-private-reader/apps-owner-review-r2.md +new file mode 100644 +index 0000000..a7f7b1b +--- /dev/null ++++ b/docs/assessments/cust81-private-reader/apps-owner-review-r2.md +@@ -0,0 +1,119 @@ ++# Railiance apps preparation review — CUST81 private metadata reader R2 ++ ++Reviewer: delegated railiance-apps preparation worker, supervised local preparation ++assignment. No promotion evidence or existing own-scope supervision record was ++found; the descriptive preparation record grants no runtime authority. This is ++an S5 release-contract review grounded in INTENT principles 1–5 (workloads, ++release contracts, repeatable operations, explicit S3 handoff, verified health). ++It is not a founder decision, independent platform credential review or reuse ++application source review. No live changes, commits, pushes, hub writes, image ++publishes, login or credential retrieval occurred. ++ ++Disposition: **approved for integration as local preparation only; live promotion blocked**. ++Canonical review disposition: `approved`. This accepts the bounded S5 proposal ++and its explicit runtime gates, not live execution or another owner’s review. ++ ++## Proposed changes and owner boundaries ++ ++The chart accepts an optional immutable image digest, adds a non-secret exact ++`REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST` environment binding, and fails rendering ++when a nonempty allowlist lacks an immutable digest. Schema checks enforce ++HTTPS allowlist entries and valid digest syntax. Production values continue ++using their existing `main-6cbc862` tag; production ExternalSecret is unchanged. ++The preparation override contains exactly 14 reviewed pinned metadata URLs and ++an empty digest deliberately preventing deployment. A synthetic all-zero digest ++in local tests is not an image and must never be promoted. ++ ++The proposed phase-B ExternalSecret preserves existing two keys, target metadata ++and existing `openbao-reuse` ClusterSecretStore, adding only ++`REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN` from ++`workloads/reuse/reuse-surface/forgejo-source-read:FORGEJO_SOURCE_TOKEN`. ++Platform owns the dedicated KV path/policy/store read scope, CCR-2026-0046 and ++credential issuance; apps neither provisions nor consumes an admin credential. ++ ++Digest presence cannot prove the hardened application is included. The reuse ++owner must provide published build digest, source revision, tests and review ++binding *both* authenticated redirect rejection and exact environment-name/URL ++credential routing. A reader must not reach the existing vulnerable runtime. ++ ++## Ordered promotion gates — not executed ++ ++1. Confirm own-scope supervision and founder change approval, reviewed CCR, ++ exact seven-source owner consent packet and scoped Forgejo read-only issuer ++ receipt. Integrate provisional RAPPS-WP-0017 through root owner coordination. ++2. Run metadata inventory helper with an explicitly verified railiance01 ++ kubeconfig; compare existing authenticated registrations with newly ++ fail-closed image behavior. The helper reads only SQLite registration ++ metadata, never env/Secrets, captures command errors and refuses unsafe ++ URLs. If it refuses, resolve via the source owner without emitting raw ++ objects. Any existing authenticated source requires separately reviewed ++ exact URL bindings including capability entry URLs before promotion; do not ++ silently orphan sources or broaden the 14-URL map. Missing inventory blocks ++ phase A. Store only safe names, counts and validated metadata URLs. ++3. Read live release image/revision, replica state, PVC storage/access modes and ++ readiness. Confirm node external IP `92.205.62.239`, not retired coulombcore. ++ Record requested CPU/memory headroom and pending pods before rollout. Existing ++ API requests 100m CPU/256Mi, surge1 requires that much additional allocatable ++ capacity; landing unchanged. Confirm the existing PVC supports simultaneous ++ pod scheduling/mount on this single node; stop if RWO/RWOP or mount conflicts ++ prevent it. No rollout strategy/resource/PVC changes are proposed. Do not ++ change other workloads merely to obtain capacity. ++4. Once a real reviewed digest exists, fill the preparation values; render ++ exact chart with production values plus proposal overrides. Server dry-run ++ and client diff must cover every rendered chart object and the phase-B ESO ++ manifest. Preserve stderr in memory and emit sanitized status only; never ++ print live Secrets, Helm secret values, annotations or raw API failures. ++ Existing release owner and any Argo adoption must be verified before choosing ++ owner Helm upgrade versus GitOps sync; neither is executed here. ++5. Phase A: approved release of hardened digest plus approved allowlist, with ++ existing ESO fields only. Owner Helm path must use atomic upgrade, timeout ++ and wait; verify actual running imageID matches digest, API health/probes, ++ public federation baseline63 and credential-routing refusal/redirect tests. ++ Deployment failure blocks phase B. Database/PVC remains unchanged. Collect a ++ separately approved safe backup/recovery receipt before any risky live release. ++6. Phase B: after verified phase A, execute reviewed platform credential action ++ and ESO reader mapping. Verify only ESO condition/status and key-presence ++ booleans via approved suppressing helpers, then restart/sync the hardened ++ workload so envFrom obtains the reader. Never dump Secret or process env. ++7. Reuse owner runs native exact-byte authenticated proof for all14 URLs and ++ seven capability entries using pinned consent hashes. Only then register ++ seven sources through the scoped write route and verify hosted70/70, ++ no duplicates/conflicting IDs and public federation preserves all63. ++ ++## Rollback contract ++ ++Before execution capture previous approved release revision, digest/tag and ++safe configuration, public discovery baseline and database recovery receipt. ++If phase A fails before credential delivery, atomic restore of previous release ++is safe because no reader has been supplied. After phase B, **never downgrade to ++vulnerable runtime with reader still available**: revoke the dedicated reader ++at Forgejo/OpenBao via credential owner, remove phase-B ESO mapping and materialized ++reader key through reviewed silent maintenance, restart current hardened pods, ++verify absence/revocation, then restore prior approved chart/image only if needed. ++Metadata registrations may remain inaccessible until re-established; record the ++regression explicitly. Do not roll back the PVC or use stale tokens as recovery. ++ ++## Local evidence and limitations ++ ++`helm lint charts/reuse-surface -f helm/reuse-surface-values.yaml` passed. ++`python3 docs/assessments/cust81-private-reader/verify_preparation.py` passed ten ++checks, including exact14 roundtrip, digest/schema refusal, retention of current ++strategy/resources/PVC, correct isolated ESO mapping, metadata URL sanitization ++and subprocess error suppression. `local-verification-r2.json` contains command ++statuses without raw output. No cluster inventory, resource headroom, ++server dry-run/diff, image publish, live approval or native fetch has been proven. ++ ++## Revision history — same proposal, no second trial ++ ++R1 root review found the inventory SQL incorrectly selected `$.index_url` rather ++than the native HubStore registration field `$.url`. R1's local checks did not ++exercise the pod SQL and therefore missed this defect. R1 must not be executed; ++it remains preserved in the root assembly archive. R2 selects `$.url` and tests ++the exact read-only pod SQL against a real SQLite registration payload containing ++`repo`, `url`, `auth_env`, timestamps and an unrelated sentinel description, plus ++an anonymous registration. Only expected names/URL emerge; rows remain unchanged. ++R2 also accepts canonical Forgejo raw branch/commit/tag index routes while still ++refusing userinfo, non-HTTPS, credentials in queries and fragments. Untrusted ++successful subprocess output is refused without raw echo, as are failures. ++No live inventory command has run. This corrective refinement is the same ++CUST81-APPS-PRIVATE-READER-RELEASE proposal revision2, not an unchanged success. +diff --git a/docs/assessments/cust81-private-reader/local-verification-r2.json b/docs/assessments/cust81-private-reader/local-verification-r2.json +new file mode 100644 +index 0000000..dbd1366 +--- /dev/null ++++ b/docs/assessments/cust81-private-reader/local-verification-r2.json +@@ -0,0 +1,96 @@ ++{ ++ "status": "passed", ++ "local_only": true, ++ "real_image_digest": null, ++ "synthetic_digest_used_only_to_check_rendering": true, ++ "checks": [ ++ "production rendering unchanged except empty fail-closed allowlist", ++ "unknown/malformed digest fails", ++ "HTTP allowlist fails schema", ++ "exact14 URLs roundtrip", ++ "strategy resources PVC retained", ++ "dedicated ESO mapping preserves current fields/store", ++ "metadata sanitizer excludes userinfo/query secrets/fragments", ++ "kubectl failure output discarded", ++ "exact pod SQL real payload URL keys readonly fixture and anonymous filtering", ++ "legacy Forgejo branch URL accepted without weakening credential query refusal" ++ ], ++ "helm_calls": [ ++ { ++ "command": [ ++ "helm", ++ "template", ++ "reuse", ++ "/tmp/cust81-apps-reader-owner/charts/reuse-surface", ++ "-f", ++ "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml" ++ ], ++ "exit_code": 0, ++ "expected_success": true ++ }, ++ { ++ "command": [ ++ "helm", ++ "template", ++ "reuse", ++ "/tmp/cust81-apps-reader-owner/charts/reuse-surface", ++ "-f", ++ "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", ++ "-f", ++ "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml" ++ ], ++ "exit_code": 1, ++ "expected_success": false ++ }, ++ { ++ "command": [ ++ "helm", ++ "template", ++ "reuse", ++ "/tmp/cust81-apps-reader-owner/charts/reuse-surface", ++ "-f", ++ "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", ++ "-f", ++ "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml", ++ "--set", ++ "image.digest=sha256:bad" ++ ], ++ "exit_code": 1, ++ "expected_success": false ++ }, ++ { ++ "command": [ ++ "helm", ++ "template", ++ "reuse", ++ "/tmp/cust81-apps-reader-owner/charts/reuse-surface", ++ "-f", ++ "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", ++ "-f", ++ "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml", ++ "--set-json", ++ "authSourceAllowlist={\"BAD\":[\"http://attacker.invalid\"]}", ++ "--set", ++ "image.digest=sha256:0000000000000000000000000000000000000000000000000000000000000000" ++ ], ++ "exit_code": 1, ++ "expected_success": false ++ }, ++ { ++ "command": [ ++ "helm", ++ "template", ++ "reuse", ++ "/tmp/cust81-apps-reader-owner/charts/reuse-surface", ++ "-f", ++ "/tmp/cust81-apps-reader-owner/helm/reuse-surface-values.yaml", ++ "-f", ++ "/tmp/cust81-apps-reader-owner/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml", ++ "--set", ++ "image.digest=sha256:0000000000000000000000000000000000000000000000000000000000000000" ++ ], ++ "exit_code": 0, ++ "expected_success": true ++ } ++ ] ++} +diff --git a/docs/assessments/cust81-private-reader/verify_preparation.py b/docs/assessments/cust81-private-reader/verify_preparation.py +new file mode 100644 +index 0000000..df57199 +--- /dev/null ++++ b/docs/assessments/cust81-private-reader/verify_preparation.py +@@ -0,0 +1,94 @@ ++"""Local chart and non-disclosure checks only; never contacts a cluster.""" ++import hashlib ++import importlib.util ++import json ++from pathlib import Path ++import subprocess ++import yaml ++ ++ROOT = Path(__file__).resolve().parents[3] ++ARTIFACT = Path(__file__).resolve().parent ++calls = [] ++ ++def render(extra, success=True): ++ command = ['helm', 'template', 'reuse', str(ROOT / 'charts/reuse-surface'), '-f', str(ROOT / 'helm/reuse-surface-values.yaml'), *extra] ++ proc = subprocess.run(command, capture_output=True, text=True) ++ calls.append({'command': command, 'exit_code': proc.returncode, 'expected_success': success}) ++ assert (proc.returncode == 0) == success ++ return list(yaml.safe_load_all(proc.stdout)) if success else [] ++ ++def api(docs): ++ return next(d for d in docs if d and d.get('kind') == 'Deployment' and d['metadata']['name'] == 'reuse-surface') ++ ++current = api(render([])) ++assert current['spec']['template']['spec']['containers'][0]['image'].endswith(':main-6cbc862') ++assert next(e['value'] for e in current['spec']['template']['spec']['containers'][0]['env'] if e['name']=='REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST') == '{}' ++proposal = ['-f', str(ARTIFACT / 'private-reader-values.r1.yaml')] ++render(proposal, False) # unknown real digest is a hard gate ++# Synthetic digest is render-only, and expressly not promotion/build evidence. ++render(proposal+['--set', 'image.digest=sha256:bad'], False) ++render(proposal+['--set-json', 'authSourceAllowlist={"BAD":["http://attacker.invalid"]}', '--set', 'image.digest=sha256:'+'0'*64], False) ++docs = render(proposal+['--set', 'image.digest=sha256:'+'0'*64]) ++deployment = api(docs) ++container = deployment['spec']['template']['spec']['containers'][0] ++assert container['image'].endswith('@sha256:'+'0'*64) ++allowlist=json.loads(next(e['value'] for e in container['env'] if e['name']=='REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST')) ++expected = json.loads((ARTIFACT/'runtime-auth-source-allowlist-r1.json').read_text()) ++assert allowlist==expected and len(next(iter(allowlist.values())))==14 ++assert deployment['spec']['strategy'] == current['spec']['strategy'] ++assert container['resources']==current['spec']['template']['spec']['containers'][0]['resources'] ++assert deployment['spec']['template']['spec']['volumes']==current['spec']['template']['spec']['volumes'] ++assert container['volumeMounts']==current['spec']['template']['spec']['containers'][0]['volumeMounts'] ++secret=yaml.safe_load((ARTIFACT/'reuse-surface-runtime-externalsecret.r1.yaml').read_text()) ++baseline=yaml.safe_load((ROOT/'manifests/reuse-surface-runtime-externalsecret.yaml').read_text()) ++assert secret['spec']['data'][:-1]==baseline['spec']['data'] ++assert secret['spec']['secretStoreRef']==baseline['spec']['secretStoreRef'] ++assert secret['spec']['data'][-1]=={'secretKey':'REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN','remoteRef':{'key':'workloads/reuse/reuse-surface/forgejo-source-read','property':'FORGEJO_SOURCE_TOKEN'}} ++spec=importlib.util.spec_from_file_location('inventory',ROOT/'scripts/reuse_authenticated_source_inventory.py') ++mod=importlib.util.module_from_spec(spec);spec.loader.exec_module(mod) ++url=expected['REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN'][1] ++assert len(mod.sanitize([['rapp-openbao','FIXTURE_READ_TOKEN',url]]))==1 ++legacy='https://forgejo.coulomb.social/coulomb/rapp-openbao/raw/branch/main/registry/indexes/capabilities.yaml' ++assert len(mod.sanitize([['rapp-openbao','FIXTURE_READ_TOKEN',legacy]]))==1 ++# Exercise the EXACT pod code against actual native registration keys in SQLite. ++# Replacing only the fixture DB path leaves the metadata SELECT/read-only mode intact. ++import sqlite3,tempfile ++with tempfile.TemporaryDirectory(prefix='apps-reader-fixture-') as temp: ++ fixture=Path(temp)/'reuse.db' ++ with sqlite3.connect(fixture) as db: ++ db.execute('CREATE TABLE registrations(repo TEXT PRIMARY KEY, payload TEXT NOT NULL, registered_at TEXT, updated_at TEXT)') ++ db.execute('INSERT INTO registrations VALUES(?,?,?,?)', ('rapp-openbao',json.dumps({'repo':'rapp-openbao','url':url,'auth_env':'FIXTURE_READ_TOKEN','description':'fixture-secret-never-emit'}),'fixture','fixture')) ++ db.execute('INSERT INTO registrations VALUES(?,?,?,?)', ('anonymous',json.dumps({'repo':'anonymous','url':legacy}),'fixture','fixture')) ++ pod_code=mod.POD_CODE.replace('/data/reuse.db',str(fixture)) ++ proc=subprocess.run(['python3','-c',pod_code],capture_output=True,text=True,check=True) ++ assert json.loads(proc.stdout)==[['rapp-openbao','FIXTURE_READ_TOKEN',url]] ++ assert 'fixture-secret' not in proc.stdout ++ assert len(mod.sanitize(json.loads(proc.stdout)))==1 ++ with sqlite3.connect(fixture) as db: assert db.execute('SELECT count(*) FROM registrations').fetchone()==(2,) ++ assert 'mode=ro' in pod_code and '$.index_url' not in pod_code ++ assert 'os.environ' not in pod_code and 'getenv' not in pod_code and 'kubectl' not in pod_code ++ ++for bad in ['https://token@forgejo.coulomb.social/x', url+'&token=fixture-secret','http://attacker.invalid',url+'#fixture-secret',legacy+'?token=fixture-secret',legacy+'/../credentials',legacy+'%3Ftoken=fixture-secret']: ++ try: mod.sanitize([['rapp-openbao','FIXTURE_READ_TOKEN',bad]]) ++ except ValueError: pass ++ else: raise AssertionError('unsafe URL accepted') ++# Errors from kubectl are discarded before output; no subprocess invoked in test. ++original=mod.subprocess.run ++class Failure: ++ returncode=1;stdout=b'fixture-secret';stderr=b'fixture-secret' ++mod.subprocess.run=lambda *args,**kwargs: Failure() ++import sys,io,contextlib ++argv=sys.argv;sys.argv=['inventory','--kubeconfig','fixture-path'] ++buf=io.StringIO() ++with contextlib.redirect_stdout(buf): assert mod.main()==1 ++assert 'fixture-secret' not in buf.getvalue() ++class UnsafeSuccess: ++ returncode=0;stdout=json.dumps([['rapp-openbao','FIXTURE_READ_TOKEN',url+'&token=fixture-secret']]).encode();stderr=b'' ++mod.subprocess.run=lambda *args,**kwargs: UnsafeSuccess() ++buf=io.StringIO() ++with contextlib.redirect_stdout(buf): assert mod.main()==1 ++assert 'fixture-secret' not in buf.getvalue() ++sys.argv=argv;mod.subprocess.run=original ++result={'status':'passed','local_only':True,'real_image_digest':None,'synthetic_digest_used_only_to_check_rendering':True,'checks':['production rendering unchanged except empty fail-closed allowlist','unknown/malformed digest fails','HTTP allowlist fails schema','exact14 URLs roundtrip','strategy resources PVC retained','dedicated ESO mapping preserves current fields/store','metadata sanitizer excludes userinfo/query secrets/fragments','kubectl failure output discarded','exact pod SQL real payload URL keys readonly fixture and anonymous filtering','legacy Forgejo branch URL accepted without weakening credential query refusal'],'helm_calls':calls} ++(ARTIFACT/'local-verification-r2.json').write_text(json.dumps(result,indent=2)+'\n') ++print(json.dumps({'status':'passed','checks':len(result['checks'])})) +diff --git a/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml b/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml +new file mode 100644 +index 0000000..70dc932 +--- /dev/null ++++ b/docs/assessments/cust81-private-reader/private-reader-values.r1.yaml +@@ -0,0 +1,5 @@ ++# PREPARATION ONLY: empty digest deliberately prevents rendering/deployment. ++# Fill only after reuse-surface publishes and reviews the fully hardened image. ++image: ++ digest: "" ++authSourceAllowlist: {"REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN": ["https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/capabilities/capability.railiance.openbao-package.md?ref=35672be138036c8433a5ac5de91e068c03c2b124", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/capabilities/capability.railiance.policy-publication-package.md?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/capabilities/capability.railiance.postgres-isolation-recovery.md?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/capabilities/capability.railiance.sbom-runtime-package.md?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/capabilities/capability.railiance.telemetry-package.md?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/capabilities/capability.railiance.tenant-engine-package.md?ref=9bdc86572728783a5ed94266f04f7b12d414c557", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/capabilities/capability.railiance.user-engine-package.md?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738", "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738"]} +diff --git a/docs/assessments/cust81-private-reader/reuse-surface-runtime-externalsecret.r1.yaml b/docs/assessments/cust81-private-reader/reuse-surface-runtime-externalsecret.r1.yaml +new file mode 100644 +index 0000000..3822799 +--- /dev/null ++++ b/docs/assessments/cust81-private-reader/reuse-surface-runtime-externalsecret.r1.yaml +@@ -0,0 +1,46 @@ ++# PROPOSAL ONLY: phase B, after hardened runtime verified and CCR approved. ++# reuse-surface hub runtime secrets from OpenBao (RAILIANCE-WP-0011 / CCR-2026-0005). ++# ++# OpenBao path (platform KV v2): workloads/reuse/reuse-surface/runtime-secrets ++# Fields: REUSE_SURFACE_TOKEN, REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET ++# ++# Prereqs on railiance01: ++# - External Secrets Operator (make eso-deploy) ++# - ClusterSecretStore openbao-reuse (railiance-platform openbao-secretstore) ++# - OpenBao policy workload-kv-read-reuse-surface-runtime + ESO token ++# (make reuse-openbao-eso-token-apply) ++apiVersion: external-secrets.io/v1beta1 ++kind: ExternalSecret ++metadata: ++ name: reuse-surface-runtime ++ namespace: reuse ++ labels: ++ app.kubernetes.io/name: reuse-surface ++ app.kubernetes.io/part-of: railiance-apps ++spec: ++ refreshInterval: 1h ++ secretStoreRef: ++ kind: ClusterSecretStore ++ name: openbao-reuse ++ target: ++ # Explicit target metadata prevents ESO copying source last-applied annotations. ++ template: ++ metadata: ++ labels: ++ app.kubernetes.io/name: reuse-surface ++ app.kubernetes.io/part-of: railiance-apps ++ name: reuse-surface-env ++ creationPolicy: Owner ++ data: ++ - secretKey: REUSE_SURFACE_TOKEN ++ remoteRef: ++ key: workloads/reuse/reuse-surface/runtime-secrets ++ property: REUSE_SURFACE_TOKEN ++ - secretKey: REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET ++ remoteRef: ++ key: workloads/reuse/reuse-surface/runtime-secrets ++ property: REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET ++ - secretKey: REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN ++ remoteRef: ++ key: workloads/reuse/reuse-surface/forgejo-source-read ++ property: FORGEJO_SOURCE_TOKEN +diff --git a/docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json b/docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json +new file mode 100644 +index 0000000..edb5f74 +--- /dev/null ++++ b/docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json +@@ -0,0 +1,18 @@ ++{ ++ "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN": [ ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/capabilities/capability.railiance.openbao-package.md?ref=35672be138036c8433a5ac5de91e068c03c2b124", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/capabilities/capability.railiance.policy-publication-package.md?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/capabilities/capability.railiance.postgres-isolation-recovery.md?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/capabilities/capability.railiance.sbom-runtime-package.md?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/capabilities/capability.railiance.telemetry-package.md?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/capabilities/capability.railiance.tenant-engine-package.md?ref=9bdc86572728783a5ed94266f04f7b12d414c557", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/capabilities/capability.railiance.user-engine-package.md?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738", ++ "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738" ++ ] ++} +diff --git a/docs/assessments/cust81-private-reader/supervision-preparation-r1.json b/docs/assessments/cust81-private-reader/supervision-preparation-r1.json +new file mode 100644 +index 0000000..722694b +--- /dev/null ++++ b/docs/assessments/cust81-private-reader/supervision-preparation-r1.json +@@ -0,0 +1,10 @@ ++{ ++ "agent": "delegated-railiance-apps-cust81-preparation", ++ "mode": "supervised", ++ "scope": "isolated local chart/config/ESO proposal preparation, local verification only", ++ "supervisor": "root custodian coordinating founder-authorized work", ++ "promotion_evidence": null, ++ "runtime_enforcement_verified": false, ++ "authority_granted": false, ++ "live_execution_authorized": false ++} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-auth-url-shape-observation-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-auth-url-shape-observation-r1.json new file mode 100644 index 00000000..454f491c --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-auth-url-shape-observation-r1.json @@ -0,0 +1,27 @@ +{ + "observed_at": "2026-10-15T03:00:22.518402+00:00", + "component": "openbao_pending_authorization_url", + "category": "authorization_url_shape_observed", + "browser_opened": false, + "credential_or_ambient_helper_read": false, + "pending_request_only_no_authenticated_login": true, + "scheme_class": "https", + "hostname_matches_source_expected": true, + "username_present": false, + "password_present": false, + "fragment_present": false, + "control_character_present": false, + "known_parameter_names": [ + "client_id", + "code_challenge", + "code_challenge_method", + "nonce", + "redirect_uri", + "response_type", + "scope", + "state" + ], + "unknown_parameter_count": 0, + "url_length_bucket": "under512", + "adapter_parse_accepted": true +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-firefox-loopback-probe-r1-receipt.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-firefox-loopback-probe-r1-receipt.json new file mode 100644 index 00000000..3ac9a738 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-firefox-loopback-probe-r1-receipt.json @@ -0,0 +1,10 @@ +{ + "id": "CUST81-FIREFOX-LOOPBACK-PROBE-R1", + "started_at": "2026-10-15T02:55:02.796020+00:00", + "listener_sha256": "83b9bb69e988a8817b9c799eae31ed545a9ecfe2c573ba5363d9278ac984bc5f", + "adapter_sha256": "4b91a4dc635e464143bfe1f484eccb2456ccd992326ac7a126b53d0a9a3c7f96", + "status": "probe_unavailable", + "firefox_launch_returned": false, + "no_oidc_or_credentials": true, + "finished_at": "2026-10-15T02:55:02.803765+00:00" +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-firefox-loopback-probe-r2-receipt.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-firefox-loopback-probe-r2-receipt.json new file mode 100644 index 00000000..acbea795 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-firefox-loopback-probe-r2-receipt.json @@ -0,0 +1,13 @@ +{ + "id": "CUST81-FIREFOX-LOOPBACK-PROBE-R2", + "started_at": "2026-10-15T02:55:40.991792+00:00", + "listener_sha256": "83b9bb69e988a8817b9c799eae31ed545a9ecfe2c573ba5363d9278ac984bc5f", + "adapter_sha256": "4b91a4dc635e464143bfe1f484eccb2456ccd992326ac7a126b53d0a9a3c7f96", + "status": "browser_reached_listener", + "firefox_launch_returned": true, + "no_oidc_or_credentials": true, + "requested_address": "localhost:8250", + "actual_address": "127.0.0.1:8250", + "expected_request_count": 1, + "finished_at": "2026-10-15T02:56:28.932552+00:00" +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-oidc-callback-transport-findings-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-oidc-callback-transport-findings-r1.json new file mode 100644 index 00000000..09db1b6d --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-oidc-callback-transport-findings-r1.json @@ -0,0 +1,53 @@ +{ + "id": "CUST81-OIDC-CALLBACK-TRANSPORT-FINDINGS-R1", + "observed_at": "2026-10-15T02:56:43.204951+00:00", + "mode": "no_oidc_or_credentials_workstation_transport_probe", + "matrix_receipt": "/tmp/cust81-windows-go-loopback-matrix-r1.json", + "matrix_sha256": "277fcda4c02edbb805d47bde686c25bef2b83aa86f4896673c42eaec6ffc4236", + "observed_listener_requested": "localhost:8250", + "observed_listener_actual": "127.0.0.1:8250", + "windows_os_no_proxy_http_results": [ + { + "component": "windows_http_client", + "address_kind": "localhost", + "http_status": 204, + "fixed_probe_header": true, + "category": "response_observed" + }, + { + "component": "windows_http_client", + "address_kind": "127.0.0.1", + "http_status": 204, + "fixed_probe_header": true, + "category": "response_observed" + }, + { + "component": "windows_http_client", + "address_kind": "[::1]", + "category": "connection_observation_failed" + } + ], + "owned_listener_stopped": true, + "go_helper_source_sha256": "bd09e7c0aba0933c1c86c1c7476a2684e4204bc52a2df0b2da4adb6e7d9a922c", + "interpretation": "Windows-to-WSL default-Go-localhost IPv4 transport works in this no-proxy HTTP client probe. Does not prove Firefox proxy/DNS/redirect behavior or the real OIDC callback. IPv6 refusal matches IPv4-only listener and does not justify widening the listener.", + "source_configuration": { + "platform_admin_role_callback_declarations": [ + "CLI localhost8250 present", + "CLI127loopback8250 present" + ], + "keycape_openbao_admin_callback_declarations": [ + "CLI localhost8250 present", + "CLI127loopback8250 present" + ], + "installed_role": "Not read using credentials; unauthenticated exactrole metadata denied in prior bounded correlation.", + "bao_2_5_5_cli": "Default client callbackmode, localhost host/listener,8250. Handler supports both query GET and form_post POST. Two-minute wait requires callbackhandler completion; upstream callback request blocking remains possible.", + "bao_primary_source": "https://raw.githubusercontent.com/openbao/openbao/v2.5.5/builtin/credential/jwt/cli.go" + }, + "preserved_failed_observations": [ + "First sandbox Windows invocation exited1 with raw errors suppressed and old Go helper finished45s zero requests; not a reachability failure proof.", + "Root independent Firefox probe collided with newly approved matrix listener at02:55:02, failed closed before GUI; root owns next Firefox probe." + ], + "remaining": "Root actual Firefox probe/founder final page determines browser-specific behavior. No production role/client/listener config change recommended from current evidence.", + "no_admin_login_ambient_credentials_or_mutations": true, + "progress_id": "1fe1a332-6538-432b-8939-2217132caa0a" +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-platform-attended-runner-publication-receipt-r3.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-platform-attended-runner-publication-receipt-r3.json new file mode 100644 index 00000000..fc25177b --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-platform-attended-runner-publication-receipt-r3.json @@ -0,0 +1,24 @@ +{ + "checked_at": "2026-10-14T23:58:37.768485+00:00", + "repo": "railiance-platform", + "commit": "635daec6b4265ccbd066b96b53228919ac4cbd79", + "publication": "remote origin/main verified exact commit", + "projection": "applied exact primary/railiance01", + "raw_receipt_path": "/tmp/cust81-platform-attended-runner-publication-raw-r3.json", + "raw_receipt_sha256": "dddc0695ca20832c697ef456bcd593789527396f6de7389ab2ed86435c5d8614", + "artifact_hashes": { + "scripts/apply-reuse-surface-reader-custody.py": "934b421c357e154f6508ab4b7c30f1aadfea2bf9a2f187d83968928d5eecad42", + "tests/test_reuse_surface_reader_custody_apply.py": "cb2c4b5f8a96cfb71015d94c5d51de0e1bbf5c8e3d90e866b207a070c1a7a266", + "docs/proposals/2026-10-15-reuse-private-reader/conditional-approved-ccr-state-candidate-r1.json": "178dd2aeddf3544438d584fa16e3ceb1a541a357d4dff5b8b4b0e95db2f357ac", + "docs/proposals/2026-10-15-reuse-private-reader/attended-custody-handoff-r1.json": "1247ad5aa73289a26a48e999b870ce2d60abb409132783e14456ea318689acff", + "docs/proposals/2026-10-15-reuse-private-reader/platform-attended-runner-review-r1.json": "2406b70ed5a0fe755fe967d3568fabffc84396bb5509c55417aa6900dbb9a4d9" + }, + "source_ccr_sha256": "90522912fb78fed72e625382fb7114a0e9aafe76d59e36bffecab83c5bb7d643", + "ccr_status": "proposed", + "claims_confirmed": false, + "unrelated_changes_preserved": [ + "WORK-RECORDS.md" + ], + "progress_id": "b288122a-e140-4a1e-bcab-e3f4974b840f", + "no_live_identity_credentials_mutation": true +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-warden-baseline-firstfailure-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-warden-baseline-firstfailure-r1.json new file mode 100644 index 00000000..1b80a2a7 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-warden-baseline-firstfailure-r1.json @@ -0,0 +1,17 @@ +{ + "baseline_commit": "1baeb0821cb6304464fab78932d8c6501f8c4cc6", + "changed_module_restored_from_base": true, + "test_node": "tests/test_access.py::test_access_advisory_output", + "exit": 1, + "same_failure": true, + "trace_test_lines": [ + "124" + ], + "cause_categories": { + "AssertionError": true, + "PermissionError": false, + "Read-only file system": true, + "OperationalError": false + }, + "raw_output_discarded": true +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-warden-fullsuite-firstfailure-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-warden-fullsuite-firstfailure-r1.json new file mode 100644 index 00000000..f798cffc --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-warden-fullsuite-firstfailure-r1.json @@ -0,0 +1,9 @@ +{ + "status": "terminal", + "exit": 1, + "failed_test_nodes": [ + "tests/test_access.py::test_access_advisory_output" + ], + "raw_output_discarded": true, + "checked_at": "2026-10-15T02:26:14.392407+00:00" +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-windows-go-loopback-matrix-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-windows-go-loopback-matrix-r1.json new file mode 100644 index 00000000..9d8dd296 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/cust81-windows-go-loopback-matrix-r1.json @@ -0,0 +1,32 @@ +{ + "observed_at": "2026-10-15T02:55:00.719576+00:00", + "category": "matrix_observed", + "no_oidc_login_credentials": true, + "listener": { + "actual_address": "127.0.0.1:8250", + "requested_address": "localhost:8250", + "status": "ready" + }, + "rows": [ + { + "component": "windows_http_client", + "address_kind": "localhost", + "http_status": 204, + "fixed_probe_header": true, + "category": "response_observed" + }, + { + "component": "windows_http_client", + "address_kind": "127.0.0.1", + "http_status": 204, + "fixed_probe_header": true, + "category": "response_observed" + }, + { + "component": "windows_http_client", + "address_kind": "[::1]", + "category": "connection_observation_failed" + } + ], + "probe_listener_stopped": true +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-attended-review-publication-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-attended-review-publication-r1.json new file mode 100644 index 00000000..95ef1534 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-attended-review-publication-r1.json @@ -0,0 +1,19 @@ +{ + "id": "CUST81-FORGE-ATTENDED-REVIEW-PUBLICATION-R1", + "checked_at": "2026-10-14T23:59:58.187068+00:00", + "source_commit": "93eab10", + "published_commit": "d322b9c9e8a1caa2b3479b270fff8a0e9f6c1f59", + "remote_verified": true, + "primary_projection_expected_commit": "d322b9c9e8a1caa2b3479b270fff8a0e9f6c1f59", + "primary_projection_derived_commit": "d322b9c9e8a1caa2b3479b270fff8a0e9f6c1f59", + "primary_instance": "railiance01", + "normal_sync_status": "applied", + "task_id": "646fd838-7ecb-5ca5-b856-a1d2e7fe569a", + "reviews": { + "r2": "changes_requested", + "r3": "approved_preparation_only" + }, + "unrelated_WORK_RECORDS_preserved": true, + "no_live_privilege_execution": true, + "task_status_verified": "done" +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/owner.patch b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/owner.patch new file mode 100644 index 00000000..a66c6d4c --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/owner.patch @@ -0,0 +1,583 @@ +diff --git a/.kaizen/agents/forge-reader-owner/supervision.json b/.kaizen/agents/forge-reader-owner/supervision.json +new file mode 100644 +index 0000000..4a7dce6 +--- /dev/null ++++ b/.kaizen/agents/forge-reader-owner/supervision.json +@@ -0,0 +1,13 @@ ++{ ++ "agent_id": "forge-reader-owner", ++ "repo": "railiance-forge", ++ "mode": "supervised", ++ "scope": "FORGE-WP-0007 independent CCR-2026-0046 preparation/review only", ++ "supervisor": "founder via root coordinating agent; no live grant delegated", ++ "runtime_enforcement": { ++ "verified": false, ++ "autopilot_granted": false ++ }, ++ "authority": "No custodian agent scope inherited; no admin credentials, live changes or approval recording authorized.", ++ "proposals": [] ++} +diff --git a/docs/proposals/cust81-private-reader/forge-owner-review-r1.json b/docs/proposals/cust81-private-reader/forge-owner-review-r1.json +new file mode 100644 +index 0000000..d6d9061 +--- /dev/null ++++ b/docs/proposals/cust81-private-reader/forge-owner-review-r1.json +@@ -0,0 +1,58 @@ ++{ ++ "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", ++ "decision": "changes_requested", ++ "comment": "INTENT Core Principles 1/4/6 and Stable Handoffs require reliable exact grants and revocation evidence; FORGE-WP-0007-T01. Reviewed exact artifacts below. Public API version/schema supports identity/team/PAT contracts, but current pagination silently truncates server-capped lists; live grants/lifecycle remain unverified. No founder approval or target admission is recorded.", ++ "work_item": "FORGE-WP-0007-T01", ++ "reviewed_artifacts": { ++ "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "438f384215c7a1719c1e069dfa9723d5ddab4cfa9ceb64236acdb1cae4854f02", ++ "scripts/provision-reuse-surface-forgejo-source.py": "f7b4f2c7a0a85315d1229a1c96f8f0b255b9c17d77426d47f9b14df9a83787ae", ++ "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "1ca0192a5c066a1756f4d11a2fb840784c4a49088f77f575a6b2170f3a5ca47e", ++ "openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl": "6320f6c2d262d924ea16291d301d5f9eeb7efdb6ce7ea141c1a41d277d86b01b" ++ }, ++ "metadata_contract": "docs/proposals/cust81-private-reader/target-api-contract-r1.json", ++ "findings": [ ++ { ++ "id": "FORGE-CUST81-F01", ++ "severity": "blocking", ++ "status": "confirmed", ++ "summary": "Client.pages returns after first capped page because len(batch)<100; target default cap50. Extra private grant/otherteam/token on page2 escapes scope checks.", ++ "trace": "Client.pages -> limit=100 -> utils.GetListOptions -> convert.ToCorrectPageSize -> MaxResponseItems(default50).", ++ "fixture": { ++ "server_cap": 50, ++ "page1_items": 50, ++ "page2_items": 1, ++ "observed_items": 50, ++ "expected_items": 51, ++ "result": "confirmed_incomplete_inventory" ++ }, ++ "required_change": "Enumerate to authoritative empty page or reconcile X-Total-Count, bound pages/items, reject duplicate IDs/repeated pages, fail closed incomplete totals. Test 50+1 excluded grant and cap7 exact-repo case." ++ }, ++ { ++ "id": "FORGE-CUST81-F02", ++ "severity": "blocking", ++ "status": "contract_unverified_execution", ++ "summary": "Recovery/90day manual rotation has no exact executable revocation/CAS-update plan or dated operational record. PAT deletion requires Basic/reverse-proxy auth, not adminPAT alone.", ++ "trace": "api.go /users/{username}/tokens/{id} DELETE middleware reqBasicOrRevProxyAuth; user/app.go DeleteAccessToken binds ContextUser.ID.", ++ "required_change": "Prepare bounded exact-token recovery/revocation fixture and explicit rotation/due-date inventory. Keep manual90days as stated policy, not runtime expiry/enforcement." ++ }, ++ { ++ "id": "FORGE-CUST81-F03", ++ "severity": "blocking", ++ "status": "proof_missing", ++ "summary": "Source-contract evidence cannot prove existing target identities/grants or KeyCape federation/ephemeral machine issuer configuration.", ++ "required_change": "Before approval/execution, bind public expected targetversion and recheck; at approved attended execution use sanitized complete effective-grant proof incl sudo identity and token_last_eight; retain Q1\u2013Q3 confirmation gates." ++ } ++ ], ++ "rejected_preliminary_hypothesis": { ++ "summary": "Swagger /user/repos says owned, initially suspected missing collaborator grants.", ++ "resolution": "Not confirmed: ListMyRepos defaults Collaborate=None; model SearchRepositoryCondition unions ownership with UserAccessRepoCond and UserOrgTeamRepoCond. Keep /user/repos with source-proven semantics and complete pagination." ++ }, ++ "live_proof": { ++ "credentials_used": false, ++ "mutations": false, ++ "grants": null, ++ "token_issued": false, ++ "native_fetch": null ++ }, ++ "binding_correction": "Historical reviewed artifacts rebound to retained platform-r1 baseline and independent fixture rerun. Earlier temporary artifact hashing raced R2 script replacement; no approval relied on those interim bytes." ++} +diff --git a/docs/proposals/cust81-private-reader/forge-owner-review-r2-before-recovery.json b/docs/proposals/cust81-private-reader/forge-owner-review-r2-before-recovery.json +new file mode 100644 +index 0000000..18c8380 +--- /dev/null ++++ b/docs/proposals/cust81-private-reader/forge-owner-review-r2-before-recovery.json +@@ -0,0 +1,54 @@ ++{ ++ "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", ++ "decision": "approved", ++ "comment": "FORGE-WP-0007-T02; INTENT Core Principles 1/4/6: provider owns target grant contract, dependable stable handoffs, and evidence reflecting current Forgejo runtime. Approve CCR-2026-0046 revision2 bounded design/preparation on exact artifact hashes below. Complete pagination defect is corrected and the versioned model proves effective /user/repos semantics. This is an owner review, not founder authorization or live target proof. Retain all declared pre-activation gates, especially bounded Basic-auth recovery helper/due-date task and separately reviewed consumer image+allowlist+apps rollout; no execution approval is inferred.", ++ "reviewed_revision": 2, ++ "reviewed_at": "2026-10-14T22:53:44.918962+00:00", ++ "work_item": "FORGE-WP-0007-T02", ++ "reviewed_artifacts": { ++ "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "1488d4c5928bf0af2735792855194c8c0d68cc738f1ae5c8a0fba947cd176a1d", ++ "scripts/provision-reuse-surface-forgejo-source.py": "abf60a754596baa1610d23b1fd367385b0222ac8aeaebba0f2cfb7ec4c62055b", ++ "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "bd235d93cdb1b4f432ae4b2755e0cb80da93a21f7feab115b2a61ea931d656f9", ++ "openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl": "6320f6c2d262d924ea16291d301d5f9eeb7efdb6ce7ea141c1a41d277d86b01b", ++ "tests/test_reuse_surface_forgejo_source_provision.py": "0d06fd22596a0f17ecd8dd5ff6a12bb1b1782258d00126ad468661099d7d298b" ++ }, ++ "validation": { ++ "targeted_unittest": "23 passed, independently rerun", ++ "independent_capped_page_fixture": "R1 50/51, R2 51/51 and page2 excluded-private grant visible", ++ "fixture_receipt": "pagination-independent-fixture-results.json", ++ "static_target_contract": "target-api-contract-r1.json", ++ "live_credentials_used": false, ++ "live_mutations": false, ++ "live_effective_grants_verified": false, ++ "live_native_fetch_verified": false ++ }, ++ "r1_disposition_preserved": "forge-owner-review-r1.json changes_requested; same CCR trial refined, not unchanged success", ++ "contract_findings_resolved": [ ++ { ++ "id": "FORGE-CUST81-F01", ++ "resolution": "Bounded page-until-empty; duplicate/missingID and optional stable-total reconciliation; independent capped50 fixture includes excluded page2 grant; late-collaborator test rejects before mutation." ++ }, ++ { ++ "id": "FORGE-CUST81-F02", ++ "resolution": "CCR explicitly states manual quarterly policy lacks expiry enforcement and requires due-date owner task/receipt plus executable Basic recovery helper before activation. Deactivation now states exact-token reset+Basic deletion compatible with API; helper/approval remains gate, not claimed complete." ++ }, ++ { ++ "id": "FORGE-CUST81-F03", ++ "resolution": "Public deployed version/schema inspected; matching version source establishes contract support. Installed target grants, Sudoidentity, machinefederation/ephemeral issuance, and native consumer route behavior remain explicit attended verification gates." ++ } ++ ], ++ "sec_dsm_order": { ++ "Q1": "No direct Kubernetes identity accepted by current raw HTTP route is demonstrated.", ++ "Q2": "KeyCape human login does not establish machine API federation; no installed workload JWT trust demonstrated.", ++ "Q3": "Upstream Forgejo OAuth can issue expiring access tokens, but supports authorization_code/refresh_token only; no viable workload client_credentials/token_exchange demonstrated. Therefore static fallback is conditional, not universal target incapability claim.", ++ "Q4": "No automatic rotation demonstrated; manual90day policy and target owner due-date record required before activation.", ++ "Q5": "Dedicated read:repository PAT vault custody conditional fallback, exact7private grants; ESO15minute token is delivery authentication, not PATexpiry." ++ }, ++ "execution_boundary": [ ++ "Founder exact revision disposition and independent otherowner reviews remain required.", ++ "Before any mutation revalidate public expected version/schema; quiet attended Sudo /user identity and complete grant inventory must prove restricted targetreader rather than administrator.", ++ "Executable exact-token Basic recovery helper plus due-date task/receipt required before activation; separately reviewed rotationCAS update before rotation.", ++ "No credential delivery until verified consumer redirect/HTTPS/exact14URL allowlist image and appsowner rollout.", ++ "Target token inventory IDs/token_last_eight and actual grants are only claimed after authenticated sanitized receipts; final nativefetch and hosted70/70 remain unproven." ++ ] ++} +diff --git a/docs/proposals/cust81-private-reader/forge-owner-review-r2-recovery-refresh-receipt.json b/docs/proposals/cust81-private-reader/forge-owner-review-r2-recovery-refresh-receipt.json +new file mode 100644 +index 0000000..a265a1c +--- /dev/null ++++ b/docs/proposals/cust81-private-reader/forge-owner-review-r2-recovery-refresh-receipt.json +@@ -0,0 +1,11 @@ ++{ ++ "proposal": "CCR-2026-0046", ++ "revision": 2, ++ "work_item": "FORGE-WP-0007-T02", ++ "old_review_sha256": "ad4ca9e794d202af447a47d3e895afcfdec4c91f021d919fd205f882d7886292", ++ "new_review_sha256": "30d9233f9e0514f5f2b1ff4ca9c4fc0a7c1aa56679d3fcc9b452bc1f4ad007a1", ++ "refresh_diff_sha256": "21bad3a4e07984115680f7877610a8889af863ab4b5c0476c696f303063310fa", ++ "reason": "Platform added executable exact-PAT Basic-auth rollback after original R2 owner review; same revision refinement retained, original review bytes preserved.", ++ "decision": "approved", ++ "live_mutation": false ++} +diff --git a/docs/proposals/cust81-private-reader/forge-owner-review-r2-recovery-refresh.diff b/docs/proposals/cust81-private-reader/forge-owner-review-r2-recovery-refresh.diff +new file mode 100644 +index 0000000..c427355 +--- /dev/null ++++ b/docs/proposals/cust81-private-reader/forge-owner-review-r2-recovery-refresh.diff +@@ -0,0 +1,57 @@ ++--- forge-owner-review-r2-before-recovery.json +++++ forge-owner-review-r2.json ++@@ -1,26 +1,29 @@ ++ { ++ "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", ++ "decision": "approved", ++- "comment": "FORGE-WP-0007-T02; INTENT Core Principles 1/4/6: provider owns target grant contract, dependable stable handoffs, and evidence reflecting current Forgejo runtime. Approve CCR-2026-0046 revision2 bounded design/preparation on exact artifact hashes below. Complete pagination defect is corrected and the versioned model proves effective /user/repos semantics. This is an owner review, not founder authorization or live target proof. Retain all declared pre-activation gates, especially bounded Basic-auth recovery helper/due-date task and separately reviewed consumer image+allowlist+apps rollout; no execution approval is inferred.", +++ "comment": "FORGE-WP-0007-T02; INTENT Core Principles 1/4/6: dependable provider-owned target grants and stable handoffs. Approve CCR-2026-0046 revision2 bounded design/preparation, refreshed against final exact artifacts including executable rollback. Page-completeness correction remains verified; recovery resets only dedicated user password, Basic-revokes exactly approved PAT ID/name after single-token inventory, read-only reconciles ambiguity, and never remints or changes KV/delivery. This owner review is not founder authorization or authenticated live proof. Preserve separate exact-token recovery authorization, manual due-date task/receipt and independently reviewed image/allowlist/apps rollout gates before activation. Same proposal/review workitem, not a new successful trial.", ++ "reviewed_revision": 2, ++- "reviewed_at": "2026-10-14T22:53:44.918962+00:00", +++ "reviewed_at": "2026-10-14T23:08:34.771501+00:00", ++ "work_item": "FORGE-WP-0007-T02", ++ "reviewed_artifacts": { ++- "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "1488d4c5928bf0af2735792855194c8c0d68cc738f1ae5c8a0fba947cd176a1d", +++ "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "90522912fb78fed72e625382fb7114a0e9aafe76d59e36bffecab83c5bb7d643", ++ "scripts/provision-reuse-surface-forgejo-source.py": "abf60a754596baa1610d23b1fd367385b0222ac8aeaebba0f2cfb7ec4c62055b", ++- "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "bd235d93cdb1b4f432ae4b2755e0cb80da93a21f7feab115b2a61ea931d656f9", +++ "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "2bb72671e0a5f230497ab8ef2967a20ee68d1f2cf081f07c84f6db3442e18d8b", ++ "openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl": "6320f6c2d262d924ea16291d301d5f9eeb7efdb6ce7ea141c1a41d277d86b01b", ++- "tests/test_reuse_surface_forgejo_source_provision.py": "0d06fd22596a0f17ecd8dd5ff6a12bb1b1782258d00126ad468661099d7d298b" +++ "tests/test_reuse_surface_forgejo_source_provision.py": "0d06fd22596a0f17ecd8dd5ff6a12bb1b1782258d00126ad468661099d7d298b", +++ "scripts/revoke-reuse-surface-forgejo-source.py": "f78d1b26fbff93c6cc481a896d9fb9b9ce93049b8b3267fa41a64bc57dadb162", +++ "tests/test_reuse_surface_forgejo_source_recovery.py": "08247129b220c198d8f7d1322ce63956203b9ffcaa0342e52990bb6520fd138d" ++ }, ++ "validation": { ++- "targeted_unittest": "23 passed, independently rerun", +++ "targeted_unittest": "28 passed independently rerun (23 provisioning + 5 recovery)", ++ "independent_capped_page_fixture": "R1 50/51, R2 51/51 and page2 excluded-private grant visible", ++ "fixture_receipt": "pagination-independent-fixture-results.json", ++ "static_target_contract": "target-api-contract-r1.json", ++ "live_credentials_used": false, ++ "live_mutations": false, ++ "live_effective_grants_verified": false, ++- "live_native_fetch_verified": false +++ "live_native_fetch_verified": false, +++ "recovery_contract": "Observed version-tag API requires Basic/reverse-proxy for DELETE. Recovery PATCH uses admin API then reader Basic DELETE exactly approved ID; current inventory checks matching name/scopes and fails on any additional token." ++ }, ++ "r1_disposition_preserved": "forge-owner-review-r1.json changes_requested; same CCR trial refined, not unchanged success", ++ "contract_findings_resolved": [ ++@@ -30,7 +33,7 @@ ++ }, ++ { ++ "id": "FORGE-CUST81-F02", ++- "resolution": "CCR explicitly states manual quarterly policy lacks expiry enforcement and requires due-date owner task/receipt plus executable Basic recovery helper before activation. Deactivation now states exact-token reset+Basic deletion compatible with API; helper/approval remains gate, not claimed complete." +++ "resolution": "Executable separately approved recovery helper now supplied and reviewed: exact bounded single PAT inventory then dedicated password reset and Basic delete; ambiguous DELETE read-only reconciliation with no repeat; absent-token noop no mutations; no KV/delete/remint. CCR still requires manual due-date task/receipt and separate exact-token recovery approval before activation." ++ }, ++ { ++ "id": "FORGE-CUST81-F03", ++@@ -47,7 +50,7 @@ ++ "execution_boundary": [ ++ "Founder exact revision disposition and independent otherowner reviews remain required.", ++ "Before any mutation revalidate public expected version/schema; quiet attended Sudo /user identity and complete grant inventory must prove restricted targetreader rather than administrator.", ++- "Executable exact-token Basic recovery helper plus due-date task/receipt required before activation; separately reviewed rotationCAS update before rotation.", +++ "Manual due-date task/receipt and separate exact-token recovery approval remain required before activation; executable recovery helper is prepared, not live-tested. Separately reviewed scoped CAS update before rotation.", ++ "No credential delivery until verified consumer redirect/HTTPS/exact14URL allowlist image and appsowner rollout.", ++ "Target token inventory IDs/token_last_eight and actual grants are only claimed after authenticated sanitized receipts; final nativefetch and hosted70/70 remain unproven." ++ ] +diff --git a/docs/proposals/cust81-private-reader/forge-owner-review-r2.json b/docs/proposals/cust81-private-reader/forge-owner-review-r2.json +new file mode 100644 +index 0000000..5490bdf +--- /dev/null ++++ b/docs/proposals/cust81-private-reader/forge-owner-review-r2.json +@@ -0,0 +1,57 @@ ++{ ++ "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", ++ "decision": "approved", ++ "comment": "FORGE-WP-0007-T02; INTENT Core Principles 1/4/6: dependable provider-owned target grants and stable handoffs. Approve CCR-2026-0046 revision2 bounded design/preparation, refreshed against final exact artifacts including executable rollback. Page-completeness correction remains verified; recovery resets only dedicated user password, Basic-revokes exactly approved PAT ID/name after single-token inventory, read-only reconciles ambiguity, and never remints or changes KV/delivery. This owner review is not founder authorization or authenticated live proof. Preserve separate exact-token recovery authorization, manual due-date task/receipt and independently reviewed image/allowlist/apps rollout gates before activation. Same proposal/review workitem, not a new successful trial.", ++ "reviewed_revision": 2, ++ "reviewed_at": "2026-10-14T23:08:34.771501+00:00", ++ "work_item": "FORGE-WP-0007-T02", ++ "reviewed_artifacts": { ++ "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "90522912fb78fed72e625382fb7114a0e9aafe76d59e36bffecab83c5bb7d643", ++ "scripts/provision-reuse-surface-forgejo-source.py": "abf60a754596baa1610d23b1fd367385b0222ac8aeaebba0f2cfb7ec4c62055b", ++ "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "2bb72671e0a5f230497ab8ef2967a20ee68d1f2cf081f07c84f6db3442e18d8b", ++ "openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl": "6320f6c2d262d924ea16291d301d5f9eeb7efdb6ce7ea141c1a41d277d86b01b", ++ "tests/test_reuse_surface_forgejo_source_provision.py": "0d06fd22596a0f17ecd8dd5ff6a12bb1b1782258d00126ad468661099d7d298b", ++ "scripts/revoke-reuse-surface-forgejo-source.py": "f78d1b26fbff93c6cc481a896d9fb9b9ce93049b8b3267fa41a64bc57dadb162", ++ "tests/test_reuse_surface_forgejo_source_recovery.py": "08247129b220c198d8f7d1322ce63956203b9ffcaa0342e52990bb6520fd138d" ++ }, ++ "validation": { ++ "targeted_unittest": "28 passed independently rerun (23 provisioning + 5 recovery)", ++ "independent_capped_page_fixture": "R1 50/51, R2 51/51 and page2 excluded-private grant visible", ++ "fixture_receipt": "pagination-independent-fixture-results.json", ++ "static_target_contract": "target-api-contract-r1.json", ++ "live_credentials_used": false, ++ "live_mutations": false, ++ "live_effective_grants_verified": false, ++ "live_native_fetch_verified": false, ++ "recovery_contract": "Observed version-tag API requires Basic/reverse-proxy for DELETE. Recovery PATCH uses admin API then reader Basic DELETE exactly approved ID; current inventory checks matching name/scopes and fails on any additional token." ++ }, ++ "r1_disposition_preserved": "forge-owner-review-r1.json changes_requested; same CCR trial refined, not unchanged success", ++ "contract_findings_resolved": [ ++ { ++ "id": "FORGE-CUST81-F01", ++ "resolution": "Bounded page-until-empty; duplicate/missingID and optional stable-total reconciliation; independent capped50 fixture includes excluded page2 grant; late-collaborator test rejects before mutation." ++ }, ++ { ++ "id": "FORGE-CUST81-F02", ++ "resolution": "Executable separately approved recovery helper now supplied and reviewed: exact bounded single PAT inventory then dedicated password reset and Basic delete; ambiguous DELETE read-only reconciliation with no repeat; absent-token noop no mutations; no KV/delete/remint. CCR still requires manual due-date task/receipt and separate exact-token recovery approval before activation." ++ }, ++ { ++ "id": "FORGE-CUST81-F03", ++ "resolution": "Public deployed version/schema inspected; matching version source establishes contract support. Installed target grants, Sudoidentity, machinefederation/ephemeral issuance, and native consumer route behavior remain explicit attended verification gates." ++ } ++ ], ++ "sec_dsm_order": { ++ "Q1": "No direct Kubernetes identity accepted by current raw HTTP route is demonstrated.", ++ "Q2": "KeyCape human login does not establish machine API federation; no installed workload JWT trust demonstrated.", ++ "Q3": "Upstream Forgejo OAuth can issue expiring access tokens, but supports authorization_code/refresh_token only; no viable workload client_credentials/token_exchange demonstrated. Therefore static fallback is conditional, not universal target incapability claim.", ++ "Q4": "No automatic rotation demonstrated; manual90day policy and target owner due-date record required before activation.", ++ "Q5": "Dedicated read:repository PAT vault custody conditional fallback, exact7private grants; ESO15minute token is delivery authentication, not PATexpiry." ++ }, ++ "execution_boundary": [ ++ "Founder exact revision disposition and independent otherowner reviews remain required.", ++ "Before any mutation revalidate public expected version/schema; quiet attended Sudo /user identity and complete grant inventory must prove restricted targetreader rather than administrator.", ++ "Manual due-date task/receipt and separate exact-token recovery approval remain required before activation; executable recovery helper is prepared, not live-tested. Separately reviewed scoped CAS update before rotation.", ++ "No credential delivery until verified consumer redirect/HTTPS/exact14URL allowlist image and appsowner rollout.", ++ "Target token inventory IDs/token_last_eight and actual grants are only claimed after authenticated sanitized receipts; final nativefetch and hosted70/70 remain unproven." ++ ] ++} +diff --git a/docs/proposals/cust81-private-reader/pagination-independent-fixture-results.json b/docs/proposals/cust81-private-reader/pagination-independent-fixture-results.json +new file mode 100644 +index 0000000..88998d2 +--- /dev/null ++++ b/docs/proposals/cust81-private-reader/pagination-independent-fixture-results.json +@@ -0,0 +1,22 @@ ++{ ++ "r1": { ++ "script_sha256": "f7b4f2c7a0a85315d1229a1c96f8f0b255b9c17d77426d47f9b14df9a83787ae", ++ "observed_items": 50, ++ "expected_items": 51, ++ "later_private_grant_seen": false, ++ "calls": [ ++ "/user/repos?limit=100&page=1" ++ ] ++ }, ++ "r2": { ++ "script_sha256": "abf60a754596baa1610d23b1fd367385b0222ac8aeaebba0f2cfb7ec4c62055b", ++ "observed_items": 51, ++ "expected_items": 51, ++ "later_private_grant_seen": true, ++ "calls": [ ++ "/user/repos?limit=100&page=1", ++ "/user/repos?limit=100&page=2", ++ "/user/repos?limit=100&page=3" ++ ] ++ } ++} +diff --git a/docs/proposals/cust81-private-reader/target-api-contract-r1.json b/docs/proposals/cust81-private-reader/target-api-contract-r1.json +new file mode 100644 +index 0000000..b03d615 +--- /dev/null ++++ b/docs/proposals/cust81-private-reader/target-api-contract-r1.json +@@ -0,0 +1,122 @@ ++{ ++ "observed_at": "2026-10-14T22:51:05.088367+00:00", ++ "authenticated": false, ++ "mutations": false, ++ "endpoint": "https://forgejo.coulomb.social", ++ "version_response": "11.0.3+gitea-1.22.0", ++ "swagger_version": "11.0.3+gitea-1.22.0", ++ "swagger_sha256": "fe7b5f952d860dfe2b0d423b66762d5d6df1ea06655c34228316c485a0ce999e", ++ "swagger_routes": 291, ++ "source_tag": "v11.0.3", ++ "source_caveat": "Upstream tag matching reported version is contract evidence, not proof deployed binary/config identity or authenticated grants.", ++ "source_files": [ ++ { ++ "upstream_path": "services/auth/oauth2.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/services/auth/oauth2.go", ++ "sha256": "cea158f620221a706643e7e3d3ae070d695c2eba9d51f886ed0aefa0f23a9bd0", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-services_auth_oauth2.go" ++ }, ++ { ++ "upstream_path": "models/unit/unit.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/models/unit/unit.go", ++ "sha256": "338b7b84e24ddca589b1b4f2c0f5d55ee3c7d58b83c6119153e27ed275f0a404", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-models_unit_unit.go" ++ }, ++ { ++ "upstream_path": "modules/structs/repo.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/modules/structs/repo.go", ++ "sha256": "15a68b0af0f6bd97bf0631f2e7e9d92ccef673cf0cf04c04ae890e9307cec27f", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-modules_structs_repo.go" ++ }, ++ { ++ "upstream_path": "routers/api/v1/repo/repo.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/repo/repo.go", ++ "sha256": "9a173231b982140e5d1794cacb9589ce7be71635e4f7e7f2b4a1a826250b7015", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_repo_repo.go" ++ }, ++ { ++ "upstream_path": "services/convert/convert.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/services/convert/convert.go", ++ "sha256": "921c52da59223e563f1f372536b0187aa01d149b4f8bb245adacdb2d2f5fc206", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-services_convert_convert.go" ++ }, ++ { ++ "upstream_path": "models/user/user.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/models/user/user.go", ++ "sha256": "ca81982afdf8775a3d1ab8965368da69a48f515daaf39e60212440dbf090447d", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-models_user_user.go" ++ }, ++ { ++ "upstream_path": "services/context/api.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/services/context/api.go", ++ "sha256": "c1acaf81c7df31d17fdcc9b4ab504dec1d32b52ef9558ffe19237d38b468e78f", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-services_context_api.go" ++ }, ++ { ++ "upstream_path": "models/auth/access_token.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/models/auth/access_token.go", ++ "sha256": "c3131e03c24356fb09fdd600efd17d8054063534355a4c5a3b769f840a58c8ac", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-models_auth_access_token.go" ++ }, ++ { ++ "upstream_path": "models/repo/repo_list.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/models/repo/repo_list.go", ++ "sha256": "bb7833badf0fe7f6a2c800c2f301cb846b5968ce3f9e9bd29c3f1677db42acd9", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-models_repo_repo_list.go" ++ }, ++ { ++ "upstream_path": "routers/api/v1/utils/page.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/utils/page.go", ++ "sha256": "1d286f60b5571513fb5a26a9243c22eae65f05d7be32dfe5d0f0b15d20550954", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_utils_page.go" ++ }, ++ { ++ "upstream_path": "services/convert/utils.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/services/convert/utils.go", ++ "sha256": "2689ffc579ea1df69457fbe84410fef101ae4a9580f0e56dcc3113a2988626b3", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-services_convert_utils.go" ++ }, ++ { ++ "upstream_path": "routers/api/v1/user/app.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/user/app.go", ++ "sha256": "14f5788e3b990b166004bd734c425f6da14d02b609a0034072455d9e6f6688b7", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_user_app.go" ++ }, ++ { ++ "upstream_path": "routers/api/v1/org/team.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/org/team.go", ++ "sha256": "14a2e9781185d852676cbf49ee27e9ddc4430d5482e41f37197d72c47d1480a2", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_org_team.go" ++ }, ++ { ++ "upstream_path": "routers/api/v1/api.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/api.go", ++ "sha256": "82d04743f1a5f80f6e818f5a45cdd789963e4b73f235d50cc3043dd8d8e090ef", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_api.go" ++ }, ++ { ++ "upstream_path": "modules/setting/api.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/modules/setting/api.go", ++ "sha256": "1f640ed884afaa6454c4bf427eccd2d6bb9a092fe37ac1aedfdc5eb85de4f7ba", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-modules_setting_api.go" ++ }, ++ { ++ "upstream_path": "routers/api/v1/user/repo.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/user/repo.go", ++ "sha256": "adee62e6671aadd95b5013a64dbb690f2d81a0b9b4de0350c70b4153074ca6ec", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_user_repo.go" ++ }, ++ { ++ "upstream_path": "routers/api/v1/admin/user.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/admin/user.go", ++ "sha256": "b0b0453ac4f09da7a95f4b3fc369d2c8fe4b2c10c67796a65bf90af5287a9b6f", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_admin_user.go" ++ }, ++ { ++ "upstream_path": "routers/web/auth/oauth.go", ++ "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/web/auth/oauth.go", ++ "sha256": "6f454b3550b150178a8597a9437adb0c626556f34c15a13778c15d675b05659b", ++ "local_cache": "/tmp/cust81-forge-contract-source/source-routers_web_auth_oauth.go" ++ } ++ ] ++} +diff --git a/docs/proposals/cust81-private-reader/target-contract-verification-plan.md b/docs/proposals/cust81-private-reader/target-contract-verification-plan.md +new file mode 100644 +index 0000000..cb19583 +--- /dev/null ++++ b/docs/proposals/cust81-private-reader/target-contract-verification-plan.md +@@ -0,0 +1,69 @@ ++# Forge owner contract and execution evidence boundary ++ ++Public metadata was read without credentials or mutations at ++`https://forgejo.coulomb.social/api/v1/version` and `/swagger.v1.json`. ++Both report `11.0.3+gitea-1.22.0`. The matching upstream tag is contractual ++support; it does not establish deployed image bytes/configuration or grants. ++The exact public schema/source hashes are in `target-api-contract-r1.json`. ++ ++The current `/user/repos` endpoint is usable for effective grants: upstream ++`routers/api/v1/user/repo.go` defaults `Collaborate=None`, and ++`models/repo/repo_list.go` SearchRepositoryCondition combines ownership, ++UserAccessRepoCond and UserOrgTeamRepoCond. Swagger's "owns" description alone ++is insufficient. This corrects the initial owned-only hypothesis. ++ ++Every organization/team/member/repository/PAT list must be read completely. ++Upstream `routers/api/v1/utils/page.go` calls ++`services/convert/utils.go` ToCorrectPageSize; `modules/setting/api.go` defaults ++MaxResponseItems to 50. A request for limit100 can return50 with further pages. ++Read bounded pages until an empty terminal result or reconcile a valid stable ++X-Total-Count. Never infer completion from a short page relative to requested ++limit; reject duplicate identities/repeated pages, cap exhaustion and changing ++or invalid totals. Test page2 excluded private grant, unrelated team/token, ++server-cap7 and repeated/incomplete pages with synthetic fixtures. ++ ++GET token inventory supports administrator context: API router self-or-admin ++gate; ListAccessTokens reads ContextUser.ID and returns token_last_eight without ++the token. Create and DELETE additionally require Basic or reverse-proxy auth. ++Exact token revocation therefore needs a reviewed method compatible with that ++auth contract (e.g. attended admin resets only dedicated user's random memory-only ++password, then user Basic deletes exact reviewed tokenID). An admin PAT alone ++cannot satisfy the Basic-only DELETE gate. The original tokenID and ambiguity ++must remain durable; an observation timeout never authorizes a remint. ++ ++The intended team code-read flags and restricted private non-admin user fields ++exist in the observed API schema. Non-code units none are valid; upstream ++MinUnitAccessMode deliberately ignores none while finding a positive minimum. ++Bearer PAT headers are accepted by services/auth/oauth2.go parseToken. Still, ++only actual native fetch after approved provisioning can prove installed route ++behavior and consented index/entry hashes. ++ ++SEC-DSM §37 is evaluated in order: ++ ++1. Q1: Current native HTTP interface does not demonstrate direct projected SA ++ identity at the forge; changing visibility or transport is outside scope. ++2. Q2: Human KeyCape OIDC login is not machine-token exchange. Matching upstream ++ authentication validates Forgejo-owned OAuth tokens; no installed trust of ++ arbitrary KeyCape workload JWTs is established. ++3. Q3: Forgejo supports expiring OAuth access tokens, so do not state it cannot ++ issue ephemeral credentials. Matching token grant handler accepts only ++ authorization_code and refresh_token, not client_credentials/token_exchange. ++ Unattended refresh requires persistent authority; no viable installed ++ workload-native ephemeral path is demonstrated. Keep target-owner execution ++ confirmation gate and prefer a viable higher mechanism if surfaced. ++4. Q4: Proposed bootstrap can mint a dedicated reader but is not an automatic ++ rotation controller. No automatic90day enforcement is demonstrated. ++5. Q5: A dedicated centrally vaulted PAT is a conditional static fallback with ++ restricted target grants and owned manual rotation/revocation. ESO15minute ++ Bao tokens expire delivery authority, not the PAT. ++ ++Approved attended verification must quietly prove `/user` under Sudo is the ++exact restricted reader; complete identities/organizations/teams/repos/PATs; ++exact seven private repos, no extra private effective grants, read permission; ++one PAT read:repository and token_last_eight binding to custody; native Bearer ++fetch matching consented hashes; excluded private repo/admin/actions denial. ++Only booleans/counts/IDs/hashes survive. No private source/error/token output. ++Record GENERATED_AT, rotation due_at<=90days, target tokenID, owner/recovery task ++and observed custody version; retain manual policy as manual. Revalidate public ++version/schema before mutation and halt drift until reviewed. No such attended ++proof or credential approval exists in this preparation. +diff --git a/workplans/FORGE-WP-0007-reuse-private-reader-contract-review.md b/workplans/FORGE-WP-0007-reuse-private-reader-contract-review.md +new file mode 100644 +index 0000000..d5b79a4 +--- /dev/null ++++ b/workplans/FORGE-WP-0007-reuse-private-reader-contract-review.md +@@ -0,0 +1,60 @@ ++--- ++id: FORGE-WP-0007 ++type: workplan ++title: "Review exact seven-source Reuse Surface Forgejo reader contract" ++domain: financials ++repo: railiance-forge ++status: active ++owner: codex ++created: "2026-10-15" ++updated: "2026-10-15" ++flavor: planning ++depends_on: [] ++--- ++ ++Review CCR-2026-0046 independently under railiance-forge INTENT Core Principles ++1, 4 and 6 (forge operation, stable handoffs, current/future forge contract). ++Preparation only; source disclosure consent does not grant credential issuance. ++This isolated checkout has its own supervised record and no autopilot or live ++credential authority. No hub task writes or integration commits occur here. ++ ++## Independently review target API and exact grant/lifecycle contract ++ ++```task ++id: FORGE-WP-0007-T01 ++status: done ++priority: high ++``` ++ ++Public unauthenticated target metadata reports Forgejo 11.0.3+gitea-1.22.0. ++Matched Swagger and versioned upstream source were inspected. Initial suspicion ++that /user/repos omitted collaborators was disproven by the downstream model ++union; retain that correction in the owner review. Confirmed capped-pagination ++fixture truncates 51 effective grants to 50. Exact artifact-bound owner review is ++`docs/proposals/cust81-private-reader/forge-owner-review-r1.json`, disposition ++changes_requested. No authenticated target-state proof is claimed. ++ ++## Review platform correction and hand off final owner entry ++ ++```task ++id: FORGE-WP-0007-T02 ++status: done ++priority: high ++``` ++ ++Review complete pagination and exact lifecycle recovery changes when platform ++worker delivers the revised bytes. Required deployment/credential evidence stays ++explicit as execution gates; approval of preparation does not assert target state ++or authorize runtime changes. Parent integrates file-bound owner entries. ++ ++Independent R2 owner design review is approved, exact artifact-bound in ++`forge-owner-review-r2.json`. Targeted23tests pass; independent cap50 fixture ++now observes51/51. Historical R1 changes_requested and artifact timing correction ++remain preserved. Preparation review is finished; approved attended activation ++proof/recovery/helper and rollout gates remain with owner execution work. ++ ++Final R2 refresh includes executable Basic-auth exact-PAT recovery; independently ++rerun28tests pass. Original R2 review preserved verbatim in ++`forge-owner-review-r2-before-recovery.json` with exact refresh diff/receipt. ++Recovery approval, manual due-date record and authenticated execution proof stay ++pending owner execution; no KV removal or remint is part of recovery. diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r1.json new file mode 100644 index 00000000..d6d9061a --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r1.json @@ -0,0 +1,58 @@ +{ + "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", + "decision": "changes_requested", + "comment": "INTENT Core Principles 1/4/6 and Stable Handoffs require reliable exact grants and revocation evidence; FORGE-WP-0007-T01. Reviewed exact artifacts below. Public API version/schema supports identity/team/PAT contracts, but current pagination silently truncates server-capped lists; live grants/lifecycle remain unverified. No founder approval or target admission is recorded.", + "work_item": "FORGE-WP-0007-T01", + "reviewed_artifacts": { + "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "438f384215c7a1719c1e069dfa9723d5ddab4cfa9ceb64236acdb1cae4854f02", + "scripts/provision-reuse-surface-forgejo-source.py": "f7b4f2c7a0a85315d1229a1c96f8f0b255b9c17d77426d47f9b14df9a83787ae", + "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "1ca0192a5c066a1756f4d11a2fb840784c4a49088f77f575a6b2170f3a5ca47e", + "openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl": "6320f6c2d262d924ea16291d301d5f9eeb7efdb6ce7ea141c1a41d277d86b01b" + }, + "metadata_contract": "docs/proposals/cust81-private-reader/target-api-contract-r1.json", + "findings": [ + { + "id": "FORGE-CUST81-F01", + "severity": "blocking", + "status": "confirmed", + "summary": "Client.pages returns after first capped page because len(batch)<100; target default cap50. Extra private grant/otherteam/token on page2 escapes scope checks.", + "trace": "Client.pages -> limit=100 -> utils.GetListOptions -> convert.ToCorrectPageSize -> MaxResponseItems(default50).", + "fixture": { + "server_cap": 50, + "page1_items": 50, + "page2_items": 1, + "observed_items": 50, + "expected_items": 51, + "result": "confirmed_incomplete_inventory" + }, + "required_change": "Enumerate to authoritative empty page or reconcile X-Total-Count, bound pages/items, reject duplicate IDs/repeated pages, fail closed incomplete totals. Test 50+1 excluded grant and cap7 exact-repo case." + }, + { + "id": "FORGE-CUST81-F02", + "severity": "blocking", + "status": "contract_unverified_execution", + "summary": "Recovery/90day manual rotation has no exact executable revocation/CAS-update plan or dated operational record. PAT deletion requires Basic/reverse-proxy auth, not adminPAT alone.", + "trace": "api.go /users/{username}/tokens/{id} DELETE middleware reqBasicOrRevProxyAuth; user/app.go DeleteAccessToken binds ContextUser.ID.", + "required_change": "Prepare bounded exact-token recovery/revocation fixture and explicit rotation/due-date inventory. Keep manual90days as stated policy, not runtime expiry/enforcement." + }, + { + "id": "FORGE-CUST81-F03", + "severity": "blocking", + "status": "proof_missing", + "summary": "Source-contract evidence cannot prove existing target identities/grants or KeyCape federation/ephemeral machine issuer configuration.", + "required_change": "Before approval/execution, bind public expected targetversion and recheck; at approved attended execution use sanitized complete effective-grant proof incl sudo identity and token_last_eight; retain Q1\u2013Q3 confirmation gates." + } + ], + "rejected_preliminary_hypothesis": { + "summary": "Swagger /user/repos says owned, initially suspected missing collaborator grants.", + "resolution": "Not confirmed: ListMyRepos defaults Collaborate=None; model SearchRepositoryCondition unions ownership with UserAccessRepoCond and UserOrgTeamRepoCond. Keep /user/repos with source-proven semantics and complete pagination." + }, + "live_proof": { + "credentials_used": false, + "mutations": false, + "grants": null, + "token_issued": false, + "native_fetch": null + }, + "binding_correction": "Historical reviewed artifacts rebound to retained platform-r1 baseline and independent fixture rerun. Earlier temporary artifact hashing raced R2 script replacement; no approval relied on those interim bytes." +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-before-recovery.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-before-recovery.json new file mode 100644 index 00000000..18c8380f --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-before-recovery.json @@ -0,0 +1,54 @@ +{ + "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", + "decision": "approved", + "comment": "FORGE-WP-0007-T02; INTENT Core Principles 1/4/6: provider owns target grant contract, dependable stable handoffs, and evidence reflecting current Forgejo runtime. Approve CCR-2026-0046 revision2 bounded design/preparation on exact artifact hashes below. Complete pagination defect is corrected and the versioned model proves effective /user/repos semantics. This is an owner review, not founder authorization or live target proof. Retain all declared pre-activation gates, especially bounded Basic-auth recovery helper/due-date task and separately reviewed consumer image+allowlist+apps rollout; no execution approval is inferred.", + "reviewed_revision": 2, + "reviewed_at": "2026-10-14T22:53:44.918962+00:00", + "work_item": "FORGE-WP-0007-T02", + "reviewed_artifacts": { + "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "1488d4c5928bf0af2735792855194c8c0d68cc738f1ae5c8a0fba947cd176a1d", + "scripts/provision-reuse-surface-forgejo-source.py": "abf60a754596baa1610d23b1fd367385b0222ac8aeaebba0f2cfb7ec4c62055b", + "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "bd235d93cdb1b4f432ae4b2755e0cb80da93a21f7feab115b2a61ea931d656f9", + "openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl": "6320f6c2d262d924ea16291d301d5f9eeb7efdb6ce7ea141c1a41d277d86b01b", + "tests/test_reuse_surface_forgejo_source_provision.py": "0d06fd22596a0f17ecd8dd5ff6a12bb1b1782258d00126ad468661099d7d298b" + }, + "validation": { + "targeted_unittest": "23 passed, independently rerun", + "independent_capped_page_fixture": "R1 50/51, R2 51/51 and page2 excluded-private grant visible", + "fixture_receipt": "pagination-independent-fixture-results.json", + "static_target_contract": "target-api-contract-r1.json", + "live_credentials_used": false, + "live_mutations": false, + "live_effective_grants_verified": false, + "live_native_fetch_verified": false + }, + "r1_disposition_preserved": "forge-owner-review-r1.json changes_requested; same CCR trial refined, not unchanged success", + "contract_findings_resolved": [ + { + "id": "FORGE-CUST81-F01", + "resolution": "Bounded page-until-empty; duplicate/missingID and optional stable-total reconciliation; independent capped50 fixture includes excluded page2 grant; late-collaborator test rejects before mutation." + }, + { + "id": "FORGE-CUST81-F02", + "resolution": "CCR explicitly states manual quarterly policy lacks expiry enforcement and requires due-date owner task/receipt plus executable Basic recovery helper before activation. Deactivation now states exact-token reset+Basic deletion compatible with API; helper/approval remains gate, not claimed complete." + }, + { + "id": "FORGE-CUST81-F03", + "resolution": "Public deployed version/schema inspected; matching version source establishes contract support. Installed target grants, Sudoidentity, machinefederation/ephemeral issuance, and native consumer route behavior remain explicit attended verification gates." + } + ], + "sec_dsm_order": { + "Q1": "No direct Kubernetes identity accepted by current raw HTTP route is demonstrated.", + "Q2": "KeyCape human login does not establish machine API federation; no installed workload JWT trust demonstrated.", + "Q3": "Upstream Forgejo OAuth can issue expiring access tokens, but supports authorization_code/refresh_token only; no viable workload client_credentials/token_exchange demonstrated. Therefore static fallback is conditional, not universal target incapability claim.", + "Q4": "No automatic rotation demonstrated; manual90day policy and target owner due-date record required before activation.", + "Q5": "Dedicated read:repository PAT vault custody conditional fallback, exact7private grants; ESO15minute token is delivery authentication, not PATexpiry." + }, + "execution_boundary": [ + "Founder exact revision disposition and independent otherowner reviews remain required.", + "Before any mutation revalidate public expected version/schema; quiet attended Sudo /user identity and complete grant inventory must prove restricted targetreader rather than administrator.", + "Executable exact-token Basic recovery helper plus due-date task/receipt required before activation; separately reviewed rotationCAS update before rotation.", + "No credential delivery until verified consumer redirect/HTTPS/exact14URL allowlist image and appsowner rollout.", + "Target token inventory IDs/token_last_eight and actual grants are only claimed after authenticated sanitized receipts; final nativefetch and hosted70/70 remain unproven." + ] +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-recovery-refresh-receipt.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-recovery-refresh-receipt.json new file mode 100644 index 00000000..a265a1c3 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-recovery-refresh-receipt.json @@ -0,0 +1,11 @@ +{ + "proposal": "CCR-2026-0046", + "revision": 2, + "work_item": "FORGE-WP-0007-T02", + "old_review_sha256": "ad4ca9e794d202af447a47d3e895afcfdec4c91f021d919fd205f882d7886292", + "new_review_sha256": "30d9233f9e0514f5f2b1ff4ca9c4fc0a7c1aa56679d3fcc9b452bc1f4ad007a1", + "refresh_diff_sha256": "21bad3a4e07984115680f7877610a8889af863ab4b5c0476c696f303063310fa", + "reason": "Platform added executable exact-PAT Basic-auth rollback after original R2 owner review; same revision refinement retained, original review bytes preserved.", + "decision": "approved", + "live_mutation": false +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-recovery-refresh.diff b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-recovery-refresh.diff new file mode 100644 index 00000000..c427355e --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2-recovery-refresh.diff @@ -0,0 +1,57 @@ +--- forge-owner-review-r2-before-recovery.json ++++ forge-owner-review-r2.json +@@ -1,26 +1,29 @@ + { + "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", + "decision": "approved", +- "comment": "FORGE-WP-0007-T02; INTENT Core Principles 1/4/6: provider owns target grant contract, dependable stable handoffs, and evidence reflecting current Forgejo runtime. Approve CCR-2026-0046 revision2 bounded design/preparation on exact artifact hashes below. Complete pagination defect is corrected and the versioned model proves effective /user/repos semantics. This is an owner review, not founder authorization or live target proof. Retain all declared pre-activation gates, especially bounded Basic-auth recovery helper/due-date task and separately reviewed consumer image+allowlist+apps rollout; no execution approval is inferred.", ++ "comment": "FORGE-WP-0007-T02; INTENT Core Principles 1/4/6: dependable provider-owned target grants and stable handoffs. Approve CCR-2026-0046 revision2 bounded design/preparation, refreshed against final exact artifacts including executable rollback. Page-completeness correction remains verified; recovery resets only dedicated user password, Basic-revokes exactly approved PAT ID/name after single-token inventory, read-only reconciles ambiguity, and never remints or changes KV/delivery. This owner review is not founder authorization or authenticated live proof. Preserve separate exact-token recovery authorization, manual due-date task/receipt and independently reviewed image/allowlist/apps rollout gates before activation. Same proposal/review workitem, not a new successful trial.", + "reviewed_revision": 2, +- "reviewed_at": "2026-10-14T22:53:44.918962+00:00", ++ "reviewed_at": "2026-10-14T23:08:34.771501+00:00", + "work_item": "FORGE-WP-0007-T02", + "reviewed_artifacts": { +- "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "1488d4c5928bf0af2735792855194c8c0d68cc738f1ae5c8a0fba947cd176a1d", ++ "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "90522912fb78fed72e625382fb7114a0e9aafe76d59e36bffecab83c5bb7d643", + "scripts/provision-reuse-surface-forgejo-source.py": "abf60a754596baa1610d23b1fd367385b0222ac8aeaebba0f2cfb7ec4c62055b", +- "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "bd235d93cdb1b4f432ae4b2755e0cb80da93a21f7feab115b2a61ea931d656f9", ++ "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "2bb72671e0a5f230497ab8ef2967a20ee68d1f2cf081f07c84f6db3442e18d8b", + "openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl": "6320f6c2d262d924ea16291d301d5f9eeb7efdb6ce7ea141c1a41d277d86b01b", +- "tests/test_reuse_surface_forgejo_source_provision.py": "0d06fd22596a0f17ecd8dd5ff6a12bb1b1782258d00126ad468661099d7d298b" ++ "tests/test_reuse_surface_forgejo_source_provision.py": "0d06fd22596a0f17ecd8dd5ff6a12bb1b1782258d00126ad468661099d7d298b", ++ "scripts/revoke-reuse-surface-forgejo-source.py": "f78d1b26fbff93c6cc481a896d9fb9b9ce93049b8b3267fa41a64bc57dadb162", ++ "tests/test_reuse_surface_forgejo_source_recovery.py": "08247129b220c198d8f7d1322ce63956203b9ffcaa0342e52990bb6520fd138d" + }, + "validation": { +- "targeted_unittest": "23 passed, independently rerun", ++ "targeted_unittest": "28 passed independently rerun (23 provisioning + 5 recovery)", + "independent_capped_page_fixture": "R1 50/51, R2 51/51 and page2 excluded-private grant visible", + "fixture_receipt": "pagination-independent-fixture-results.json", + "static_target_contract": "target-api-contract-r1.json", + "live_credentials_used": false, + "live_mutations": false, + "live_effective_grants_verified": false, +- "live_native_fetch_verified": false ++ "live_native_fetch_verified": false, ++ "recovery_contract": "Observed version-tag API requires Basic/reverse-proxy for DELETE. Recovery PATCH uses admin API then reader Basic DELETE exactly approved ID; current inventory checks matching name/scopes and fails on any additional token." + }, + "r1_disposition_preserved": "forge-owner-review-r1.json changes_requested; same CCR trial refined, not unchanged success", + "contract_findings_resolved": [ +@@ -30,7 +33,7 @@ + }, + { + "id": "FORGE-CUST81-F02", +- "resolution": "CCR explicitly states manual quarterly policy lacks expiry enforcement and requires due-date owner task/receipt plus executable Basic recovery helper before activation. Deactivation now states exact-token reset+Basic deletion compatible with API; helper/approval remains gate, not claimed complete." ++ "resolution": "Executable separately approved recovery helper now supplied and reviewed: exact bounded single PAT inventory then dedicated password reset and Basic delete; ambiguous DELETE read-only reconciliation with no repeat; absent-token noop no mutations; no KV/delete/remint. CCR still requires manual due-date task/receipt and separate exact-token recovery approval before activation." + }, + { + "id": "FORGE-CUST81-F03", +@@ -47,7 +50,7 @@ + "execution_boundary": [ + "Founder exact revision disposition and independent otherowner reviews remain required.", + "Before any mutation revalidate public expected version/schema; quiet attended Sudo /user identity and complete grant inventory must prove restricted targetreader rather than administrator.", +- "Executable exact-token Basic recovery helper plus due-date task/receipt required before activation; separately reviewed rotationCAS update before rotation.", ++ "Manual due-date task/receipt and separate exact-token recovery approval remain required before activation; executable recovery helper is prepared, not live-tested. Separately reviewed scoped CAS update before rotation.", + "No credential delivery until verified consumer redirect/HTTPS/exact14URL allowlist image and appsowner rollout.", + "Target token inventory IDs/token_last_eight and actual grants are only claimed after authenticated sanitized receipts; final nativefetch and hosted70/70 remain unproven." + ] diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2.json new file mode 100644 index 00000000..5490bdfd --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/forge-owner-review-r2.json @@ -0,0 +1,57 @@ +{ + "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", + "decision": "approved", + "comment": "FORGE-WP-0007-T02; INTENT Core Principles 1/4/6: dependable provider-owned target grants and stable handoffs. Approve CCR-2026-0046 revision2 bounded design/preparation, refreshed against final exact artifacts including executable rollback. Page-completeness correction remains verified; recovery resets only dedicated user password, Basic-revokes exactly approved PAT ID/name after single-token inventory, read-only reconciles ambiguity, and never remints or changes KV/delivery. This owner review is not founder authorization or authenticated live proof. Preserve separate exact-token recovery authorization, manual due-date task/receipt and independently reviewed image/allowlist/apps rollout gates before activation. Same proposal/review workitem, not a new successful trial.", + "reviewed_revision": 2, + "reviewed_at": "2026-10-14T23:08:34.771501+00:00", + "work_item": "FORGE-WP-0007-T02", + "reviewed_artifacts": { + "credential-change-requests/CCR-2026-0046-reuse-surface-forgejo-source-read.yaml": "90522912fb78fed72e625382fb7114a0e9aafe76d59e36bffecab83c5bb7d643", + "scripts/provision-reuse-surface-forgejo-source.py": "abf60a754596baa1610d23b1fd367385b0222ac8aeaebba0f2cfb7ec4c62055b", + "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "2bb72671e0a5f230497ab8ef2967a20ee68d1f2cf081f07c84f6db3442e18d8b", + "openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl": "6320f6c2d262d924ea16291d301d5f9eeb7efdb6ce7ea141c1a41d277d86b01b", + "tests/test_reuse_surface_forgejo_source_provision.py": "0d06fd22596a0f17ecd8dd5ff6a12bb1b1782258d00126ad468661099d7d298b", + "scripts/revoke-reuse-surface-forgejo-source.py": "f78d1b26fbff93c6cc481a896d9fb9b9ce93049b8b3267fa41a64bc57dadb162", + "tests/test_reuse_surface_forgejo_source_recovery.py": "08247129b220c198d8f7d1322ce63956203b9ffcaa0342e52990bb6520fd138d" + }, + "validation": { + "targeted_unittest": "28 passed independently rerun (23 provisioning + 5 recovery)", + "independent_capped_page_fixture": "R1 50/51, R2 51/51 and page2 excluded-private grant visible", + "fixture_receipt": "pagination-independent-fixture-results.json", + "static_target_contract": "target-api-contract-r1.json", + "live_credentials_used": false, + "live_mutations": false, + "live_effective_grants_verified": false, + "live_native_fetch_verified": false, + "recovery_contract": "Observed version-tag API requires Basic/reverse-proxy for DELETE. Recovery PATCH uses admin API then reader Basic DELETE exactly approved ID; current inventory checks matching name/scopes and fails on any additional token." + }, + "r1_disposition_preserved": "forge-owner-review-r1.json changes_requested; same CCR trial refined, not unchanged success", + "contract_findings_resolved": [ + { + "id": "FORGE-CUST81-F01", + "resolution": "Bounded page-until-empty; duplicate/missingID and optional stable-total reconciliation; independent capped50 fixture includes excluded page2 grant; late-collaborator test rejects before mutation." + }, + { + "id": "FORGE-CUST81-F02", + "resolution": "Executable separately approved recovery helper now supplied and reviewed: exact bounded single PAT inventory then dedicated password reset and Basic delete; ambiguous DELETE read-only reconciliation with no repeat; absent-token noop no mutations; no KV/delete/remint. CCR still requires manual due-date task/receipt and separate exact-token recovery approval before activation." + }, + { + "id": "FORGE-CUST81-F03", + "resolution": "Public deployed version/schema inspected; matching version source establishes contract support. Installed target grants, Sudoidentity, machinefederation/ephemeral issuance, and native consumer route behavior remain explicit attended verification gates." + } + ], + "sec_dsm_order": { + "Q1": "No direct Kubernetes identity accepted by current raw HTTP route is demonstrated.", + "Q2": "KeyCape human login does not establish machine API federation; no installed workload JWT trust demonstrated.", + "Q3": "Upstream Forgejo OAuth can issue expiring access tokens, but supports authorization_code/refresh_token only; no viable workload client_credentials/token_exchange demonstrated. Therefore static fallback is conditional, not universal target incapability claim.", + "Q4": "No automatic rotation demonstrated; manual90day policy and target owner due-date record required before activation.", + "Q5": "Dedicated read:repository PAT vault custody conditional fallback, exact7private grants; ESO15minute token is delivery authentication, not PATexpiry." + }, + "execution_boundary": [ + "Founder exact revision disposition and independent otherowner reviews remain required.", + "Before any mutation revalidate public expected version/schema; quiet attended Sudo /user identity and complete grant inventory must prove restricted targetreader rather than administrator.", + "Manual due-date task/receipt and separate exact-token recovery approval remain required before activation; executable recovery helper is prepared, not live-tested. Separately reviewed scoped CAS update before rotation.", + "No credential delivery until verified consumer redirect/HTTPS/exact14URL allowlist image and appsowner rollout.", + "Target token inventory IDs/token_last_eight and actual grants are only claimed after authenticated sanitized receipts; final nativefetch and hosted70/70 remain unproven." + ] +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/pagination-independent-fixture-results.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/pagination-independent-fixture-results.json new file mode 100644 index 00000000..88998d24 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/pagination-independent-fixture-results.json @@ -0,0 +1,22 @@ +{ + "r1": { + "script_sha256": "f7b4f2c7a0a85315d1229a1c96f8f0b255b9c17d77426d47f9b14df9a83787ae", + "observed_items": 50, + "expected_items": 51, + "later_private_grant_seen": false, + "calls": [ + "/user/repos?limit=100&page=1" + ] + }, + "r2": { + "script_sha256": "abf60a754596baa1610d23b1fd367385b0222ac8aeaebba0f2cfb7ec4c62055b", + "observed_items": 51, + "expected_items": 51, + "later_private_grant_seen": true, + "calls": [ + "/user/repos?limit=100&page=1", + "/user/repos?limit=100&page=2", + "/user/repos?limit=100&page=3" + ] + } +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/target-api-contract-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/target-api-contract-r1.json new file mode 100644 index 00000000..b03d6157 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/target-api-contract-r1.json @@ -0,0 +1,122 @@ +{ + "observed_at": "2026-10-14T22:51:05.088367+00:00", + "authenticated": false, + "mutations": false, + "endpoint": "https://forgejo.coulomb.social", + "version_response": "11.0.3+gitea-1.22.0", + "swagger_version": "11.0.3+gitea-1.22.0", + "swagger_sha256": "fe7b5f952d860dfe2b0d423b66762d5d6df1ea06655c34228316c485a0ce999e", + "swagger_routes": 291, + "source_tag": "v11.0.3", + "source_caveat": "Upstream tag matching reported version is contract evidence, not proof deployed binary/config identity or authenticated grants.", + "source_files": [ + { + "upstream_path": "services/auth/oauth2.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/services/auth/oauth2.go", + "sha256": "cea158f620221a706643e7e3d3ae070d695c2eba9d51f886ed0aefa0f23a9bd0", + "local_cache": "/tmp/cust81-forge-contract-source/source-services_auth_oauth2.go" + }, + { + "upstream_path": "models/unit/unit.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/models/unit/unit.go", + "sha256": "338b7b84e24ddca589b1b4f2c0f5d55ee3c7d58b83c6119153e27ed275f0a404", + "local_cache": "/tmp/cust81-forge-contract-source/source-models_unit_unit.go" + }, + { + "upstream_path": "modules/structs/repo.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/modules/structs/repo.go", + "sha256": "15a68b0af0f6bd97bf0631f2e7e9d92ccef673cf0cf04c04ae890e9307cec27f", + "local_cache": "/tmp/cust81-forge-contract-source/source-modules_structs_repo.go" + }, + { + "upstream_path": "routers/api/v1/repo/repo.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/repo/repo.go", + "sha256": "9a173231b982140e5d1794cacb9589ce7be71635e4f7e7f2b4a1a826250b7015", + "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_repo_repo.go" + }, + { + "upstream_path": "services/convert/convert.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/services/convert/convert.go", + "sha256": "921c52da59223e563f1f372536b0187aa01d149b4f8bb245adacdb2d2f5fc206", + "local_cache": "/tmp/cust81-forge-contract-source/source-services_convert_convert.go" + }, + { + "upstream_path": "models/user/user.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/models/user/user.go", + "sha256": "ca81982afdf8775a3d1ab8965368da69a48f515daaf39e60212440dbf090447d", + "local_cache": "/tmp/cust81-forge-contract-source/source-models_user_user.go" + }, + { + "upstream_path": "services/context/api.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/services/context/api.go", + "sha256": "c1acaf81c7df31d17fdcc9b4ab504dec1d32b52ef9558ffe19237d38b468e78f", + "local_cache": "/tmp/cust81-forge-contract-source/source-services_context_api.go" + }, + { + "upstream_path": "models/auth/access_token.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/models/auth/access_token.go", + "sha256": "c3131e03c24356fb09fdd600efd17d8054063534355a4c5a3b769f840a58c8ac", + "local_cache": "/tmp/cust81-forge-contract-source/source-models_auth_access_token.go" + }, + { + "upstream_path": "models/repo/repo_list.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/models/repo/repo_list.go", + "sha256": "bb7833badf0fe7f6a2c800c2f301cb846b5968ce3f9e9bd29c3f1677db42acd9", + "local_cache": "/tmp/cust81-forge-contract-source/source-models_repo_repo_list.go" + }, + { + "upstream_path": "routers/api/v1/utils/page.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/utils/page.go", + "sha256": "1d286f60b5571513fb5a26a9243c22eae65f05d7be32dfe5d0f0b15d20550954", + "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_utils_page.go" + }, + { + "upstream_path": "services/convert/utils.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/services/convert/utils.go", + "sha256": "2689ffc579ea1df69457fbe84410fef101ae4a9580f0e56dcc3113a2988626b3", + "local_cache": "/tmp/cust81-forge-contract-source/source-services_convert_utils.go" + }, + { + "upstream_path": "routers/api/v1/user/app.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/user/app.go", + "sha256": "14f5788e3b990b166004bd734c425f6da14d02b609a0034072455d9e6f6688b7", + "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_user_app.go" + }, + { + "upstream_path": "routers/api/v1/org/team.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/org/team.go", + "sha256": "14a2e9781185d852676cbf49ee27e9ddc4430d5482e41f37197d72c47d1480a2", + "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_org_team.go" + }, + { + "upstream_path": "routers/api/v1/api.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/api.go", + "sha256": "82d04743f1a5f80f6e818f5a45cdd789963e4b73f235d50cc3043dd8d8e090ef", + "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_api.go" + }, + { + "upstream_path": "modules/setting/api.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/modules/setting/api.go", + "sha256": "1f640ed884afaa6454c4bf427eccd2d6bb9a092fe37ac1aedfdc5eb85de4f7ba", + "local_cache": "/tmp/cust81-forge-contract-source/source-modules_setting_api.go" + }, + { + "upstream_path": "routers/api/v1/user/repo.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/user/repo.go", + "sha256": "adee62e6671aadd95b5013a64dbb690f2d81a0b9b4de0350c70b4153074ca6ec", + "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_user_repo.go" + }, + { + "upstream_path": "routers/api/v1/admin/user.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/api/v1/admin/user.go", + "sha256": "b0b0453ac4f09da7a95f4b3fc369d2c8fe4b2c10c67796a65bf90af5287a9b6f", + "local_cache": "/tmp/cust81-forge-contract-source/source-routers_api_v1_admin_user.go" + }, + { + "upstream_path": "routers/web/auth/oauth.go", + "url": "https://codeberg.org/forgejo/forgejo/src/tag/v11.0.3/routers/web/auth/oauth.go", + "sha256": "6f454b3550b150178a8597a9437adb0c626556f34c15a13778c15d675b05659b", + "local_cache": "/tmp/cust81-forge-contract-source/source-routers_web_auth_oauth.go" + } + ] +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/target-contract-verification-plan.md b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/target-contract-verification-plan.md new file mode 100644 index 00000000..cb19583d --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-final-r2/review/target-contract-verification-plan.md @@ -0,0 +1,69 @@ +# Forge owner contract and execution evidence boundary + +Public metadata was read without credentials or mutations at +`https://forgejo.coulomb.social/api/v1/version` and `/swagger.v1.json`. +Both report `11.0.3+gitea-1.22.0`. The matching upstream tag is contractual +support; it does not establish deployed image bytes/configuration or grants. +The exact public schema/source hashes are in `target-api-contract-r1.json`. + +The current `/user/repos` endpoint is usable for effective grants: upstream +`routers/api/v1/user/repo.go` defaults `Collaborate=None`, and +`models/repo/repo_list.go` SearchRepositoryCondition combines ownership, +UserAccessRepoCond and UserOrgTeamRepoCond. Swagger's "owns" description alone +is insufficient. This corrects the initial owned-only hypothesis. + +Every organization/team/member/repository/PAT list must be read completely. +Upstream `routers/api/v1/utils/page.go` calls +`services/convert/utils.go` ToCorrectPageSize; `modules/setting/api.go` defaults +MaxResponseItems to 50. A request for limit100 can return50 with further pages. +Read bounded pages until an empty terminal result or reconcile a valid stable +X-Total-Count. Never infer completion from a short page relative to requested +limit; reject duplicate identities/repeated pages, cap exhaustion and changing +or invalid totals. Test page2 excluded private grant, unrelated team/token, +server-cap7 and repeated/incomplete pages with synthetic fixtures. + +GET token inventory supports administrator context: API router self-or-admin +gate; ListAccessTokens reads ContextUser.ID and returns token_last_eight without +the token. Create and DELETE additionally require Basic or reverse-proxy auth. +Exact token revocation therefore needs a reviewed method compatible with that +auth contract (e.g. attended admin resets only dedicated user's random memory-only +password, then user Basic deletes exact reviewed tokenID). An admin PAT alone +cannot satisfy the Basic-only DELETE gate. The original tokenID and ambiguity +must remain durable; an observation timeout never authorizes a remint. + +The intended team code-read flags and restricted private non-admin user fields +exist in the observed API schema. Non-code units none are valid; upstream +MinUnitAccessMode deliberately ignores none while finding a positive minimum. +Bearer PAT headers are accepted by services/auth/oauth2.go parseToken. Still, +only actual native fetch after approved provisioning can prove installed route +behavior and consented index/entry hashes. + +SEC-DSM §37 is evaluated in order: + +1. Q1: Current native HTTP interface does not demonstrate direct projected SA + identity at the forge; changing visibility or transport is outside scope. +2. Q2: Human KeyCape OIDC login is not machine-token exchange. Matching upstream + authentication validates Forgejo-owned OAuth tokens; no installed trust of + arbitrary KeyCape workload JWTs is established. +3. Q3: Forgejo supports expiring OAuth access tokens, so do not state it cannot + issue ephemeral credentials. Matching token grant handler accepts only + authorization_code and refresh_token, not client_credentials/token_exchange. + Unattended refresh requires persistent authority; no viable installed + workload-native ephemeral path is demonstrated. Keep target-owner execution + confirmation gate and prefer a viable higher mechanism if surfaced. +4. Q4: Proposed bootstrap can mint a dedicated reader but is not an automatic + rotation controller. No automatic90day enforcement is demonstrated. +5. Q5: A dedicated centrally vaulted PAT is a conditional static fallback with + restricted target grants and owned manual rotation/revocation. ESO15minute + Bao tokens expire delivery authority, not the PAT. + +Approved attended verification must quietly prove `/user` under Sudo is the +exact restricted reader; complete identities/organizations/teams/repos/PATs; +exact seven private repos, no extra private effective grants, read permission; +one PAT read:repository and token_last_eight binding to custody; native Bearer +fetch matching consented hashes; excluded private repo/admin/actions denial. +Only booleans/counts/IDs/hashes survive. No private source/error/token output. +Record GENERATED_AT, rotation due_at<=90days, target tokenID, owner/recovery task +and observed custody version; retain manual policy as manual. Revalidate public +version/schema before mutation and halt drift until reviewed. No such attended +proof or credential approval exists in this preparation. diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-owner-attended-runner-review-r2.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-owner-attended-runner-review-r2.json new file mode 100644 index 00000000..c82397c9 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-owner-attended-runner-review-r2.json @@ -0,0 +1,35 @@ +{ + "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", + "decision": "changes_requested", + "comment": "FORGE-WP-0007-T03; INTENT Core Principle4 Stable Handoffs and provider contract require exact approved policy bytes and truthful verified custody result. Quietcapture, unchanged ESO900second role, exact conditional twofield CCR transition and approvalbeforeprivilegedreads are supported by12tests; mutablepolicyfilepath and idempotent skipped policyrecheck need correction before approved owner review. Preparation only, no founder/live authorization.", + "reviewed_artifacts": { + "scripts/apply-reuse-surface-reader-custody.py": "179bd66fc53b99f293ff8dc1fc5f9de004391e2e71705b468ca743c0cfb46600", + "tests/test_reuse_surface_reader_custody_apply.py": "6b272b8c8be488594e43607f99a413595ec37e09900e60119f8f168c57e0c253", + "docs/proposals/2026-10-15-reuse-private-reader/conditional-approved-ccr-state-candidate-r1.json": "178dd2aeddf3544438d584fa16e3ceb1a541a357d4dff5b8b4b0e95db2f357ac", + "docs/proposals/2026-10-15-reuse-private-reader/attended-custody-handoff-r1.json": "35962e2c39e92897fe479f2194dee2c832275978d435f9147498c9d6882b8fec", + "docs/proposals/2026-10-15-reuse-private-reader/platform-attended-runner-review-r1.json": "02e7d947dc14e1ab3f20258b2e882e9253fef5e9c5685097a047a88f97442729" + }, + "tests": "12 passed independently; additional adversarial no-recheck fixture demonstrates gap", + "findings": [ + { + "id": "FORGE-CUST81-RUNNER-F01", + "summary": "Policywrite rereads mutable repo filepath after approval hash; approved policy bytes are not the executed snapshot.", + "required_change": "After envelope/bootstrap approvals verify exact policybyte snapshot hash then pass snapshot via stdin to bao policy write POLICY -, not mutable filepath. Test changing repository file after verifiedsnapshot leaves executedbytes exact." + }, + { + "id": "FORGE-CUST81-RUNNER-F02", + "summary": "When current==desired, execute never rereads policy before terminal; concurrent drift can report verified despite no final check.", + "fixture": { + "preflight_current": "desired", + "preflight_desired": "desired", + "later_policy": "concurrently_drifted", + "policy_recheck_calls": 0, + "terminal_outcome": "policy_and_custody_verified_delivery_pending" + }, + "required_change": "Check installedACL matches intendedold/exact state before credentialroute in allbranches, and final exactACL+unchangedrole before terminal. Stopon drift without implicitrewrite/retry. Preserve noCAS attendedserialization limitation." + } + ], + "live_credentials": false, + "live_mutations": false, + "approval_recorded": false +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-owner-attended-runner-review-r3.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-owner-attended-runner-review-r3.json new file mode 100644 index 00000000..e76133c3 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-owner-attended-runner-review-r3.json @@ -0,0 +1,52 @@ +{ + "reviewer": "railiance-forge-owner (agent railiance-forge, codex)", + "decision": "approved", + "comment": "FORGE-WP-0007-T03; INTENT Stable Handoffs and dependable forge operational contracts. Independently approve attended custody runner R3 bounded preparation: exact hash-verified immutable policy snapshot is passed through stdin; before and after retained Forgejo bootstrap all branches verify desired ACL and unchanged900second ESO claims; no rolewrite, delivery or consumer rollout. Exact two-field CCR transition remains conditional on real supervisor disposition and installed claim proof. This owner review is not founder approval or live proof.", + "reviewed_revision": 3, + "reviewed_at": "2026-10-14T23:56:07.949483+00:00", + "work_item": "FORGE-WP-0007-T03", + "reviewed_artifacts": { + "scripts/apply-reuse-surface-reader-custody.py": "934b421c357e154f6508ab4b7c30f1aadfea2bf9a2f187d83968928d5eecad42", + "tests/test_reuse_surface_reader_custody_apply.py": "cb2c4b5f8a96cfb71015d94c5d51de0e1bbf5c8e3d90e866b207a070c1a7a266", + "docs/proposals/2026-10-15-reuse-private-reader/conditional-approved-ccr-state-candidate-r1.json": "178dd2aeddf3544438d584fa16e3ceb1a541a357d4dff5b8b4b0e95db2f357ac", + "docs/proposals/2026-10-15-reuse-private-reader/attended-custody-handoff-r1.json": "1247ad5aa73289a26a48e999b870ce2d60abb409132783e14456ea318689acff", + "docs/proposals/2026-10-15-reuse-private-reader/platform-attended-runner-review-r1.json": "2406b70ed5a0fe755fe967d3568fabffc84396bb5509c55417aa6900dbb9a4d9" + }, + "retained_bootstrap_artifacts": { + "scripts/provision-reuse-surface-forgejo-source.py": "abf60a754596baa1610d23b1fd367385b0222ac8aeaebba0f2cfb7ec4c62055b", + "scripts/revoke-reuse-surface-forgejo-source.py": "f78d1b26fbff93c6cc481a896d9fb9b9ce93049b8b3267fa41a64bc57dadb162", + "docs/proposals/2026-10-15-reuse-private-reader/bootstrap-contract.json": "2bb72671e0a5f230497ab8ef2967a20ee68d1f2cf081f07c84f6db3442e18d8b", + "openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl": "6320f6c2d262d924ea16291d301d5f9eeb7efdb6ce7ea141c1a41d277d86b01b" + }, + "validation": { + "runner_tests": 17, + "all_reader_tests": 45, + "result": "passed independently rerun", + "manifest_hashes": "all5match", + "actual_current_ccr_sha256": "90522912fb78fed72e625382fb7114a0e9aafe76d59e36bffecab83c5bb7d643", + "conditional_future_ccr_sha256": "23039fae6137e7bdd71de0ed3278596b1ed60ae636018eb4bfcc83e53c4ada02", + "candidate_not_installed": true + }, + "resolved_findings": [ + { + "id": "FORGE-CUST81-RUNNER-F01", + "resolution": "approval_envelope retains approvedpolicyhash; execute after baseapproval reads snapshot and checks hash; Bao policywrite consumes stdin snapshot only. Replacement after snapshot cannot affect executedbytes; replacement before snapshot fails beforewrite." + }, + { + "id": "FORGE-CUST81-RUNNER-F02", + "resolution": "verify_ready desiredsnapshot ACL+immutable role runs before and after bootstrap including idempotent paths. Tests deny beforebootstrap ACLdrift and prevent verifiedterminal after ACL/roledrift." + } + ], + "r2_changes_requested_receipt": "forge-owner-attended-runner-review-r2.json", + "r2_receipt_sha256": "c4e61cd185bfc738fe8e2f7e89b71408ed35d441dfa38183cd83bad9c0832445", + "scope_limits": [ + "OpenBao ACL lacks atomicCAS; immediate predecessor recheck and successor verification are bounded attendedguards. Concurrent otheractor writes remain owner serialization constraint, not claimed atomictransaction.", + "Conditional local CCR candidate is unapplied; no statusapproval or boundclaims proof inferred from preparation.", + "Sanctioned attended Warden lane owns browser/login/revocation; nested retained Forgejo route outputcaptured; no defaultadmin/rootfallback.", + "Real founder approval, attended installedrole/ACL proof, scoped target grant/custody receipts and separately approved apps delivery/rollout remain pending." + ], + "live_credentials": false, + "live_mutations": false, + "founder_approval_recorded": false, + "same_trial": "CCR-2026-0046 reviewed refinement under sameFORGE-WP-0007-T03; R2 failures retained, not unchanged-success promotion." +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-source-publication-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-source-publication-r1.json new file mode 100644 index 00000000..a8d460d3 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/forge-source-publication-r1.json @@ -0,0 +1,35 @@ +{ + "repo": "railiance-forge", + "source_commit": "35d966d", + "projection_commit": "62fdc8b1721c0845181818649375cef2a0057f20", + "primary_receipt": { + "instance_role": "primary", + "instance_label": "railiance01", + "expected_commit": "62fdc8b1721c0845181818649375cef2a0057f20", + "derived_commit": "62fdc8b1721c0845181818649375cef2a0057f20", + "status": "applied", + "refused": 0, + "unresolved_edges": 0 + }, + "git": { + "ahead": 0, + "behind": 0 + }, + "records": { + "FORGE-WP-0007": "4d26f0d3-8504-5a38-96d8-590efa0ae5dc", + "FORGE-WP-0007-T01": "0af25c12-5acf-56d2-ba2a-f2af70c2ab1d", + "FORGE-WP-0007-T02": "ef53dca7-17d8-5354-b11b-c287ea87cb71" + }, + "verified_hub_status": { + "FORGE-WP-0007": "active", + "FORGE-WP-0007-T01": "done", + "FORGE-WP-0007-T02": "done" + }, + "progress_id": "a690f38e-aecd-4102-8302-ed7a53b3aea4", + "workflow_inspection": "Forgejo push smoke host/container probes only; Gitea pathfiltered runner probes only; no deployment on reviewedpaths.", + "source_commit_scope": "Exactly10 reviewed ownerfiles; existing stagedbrief preserved through explicit --only commit.", + "manager_commit_scope": "Normal rmgr identifier commit automatically included previouslystaged generated .custodian-brief.md plus generated3UUID fields in ownworkplan; did not manuallyalterbrief.", + "remaining_dirty": "WORK-RECORDS.md untouched", + "live_credentials": false, + "runtime_mutations": false +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-historical-identity-investigation-r1.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-historical-identity-investigation-r1.json new file mode 100644 index 00000000..b40a6bf2 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-historical-identity-investigation-r1.json @@ -0,0 +1,73 @@ +{ + "checked_at": "2026-10-14T23:44:48.018797+00:00", + "status": "Read-only investigation; no mutation", + "repo": "ops-mason", + "task_record_id": "ADHOC-2026-10-11-T03", + "parent_workplan_uuid": "e3854bfd-2bc8-5411-8c96-44ed22d878a7", + "current_source_sha256": "7fadf4475ff765999b71659495b786737a9641c8ad875afc97bd264a8c9f0aec", + "history": [ + { + "commit": "a36b6100fcfa022e35cdcfaa7bb833dbdfed4e5f", + "source_sha256": "9d637bb9fd9d5fc73cfcc24fb2615e65e0849d54c385db4129501469c214d346", + "t03_uuid_present": false + }, + { + "commit": "969fe218df408d83bd493f9f0a2051d61ed11ad8", + "source_sha256": "7fadf4475ff765999b71659495b786737a9641c8ad875afc97bd264a8c9f0aec", + "t03_uuid_present": false + } + ], + "primary_instance": { + "status": "ok", + "db": "connected", + "instance_role": "primary", + "instance_label": "railiance01", + "schema": { + "status": "ok", + "applied": "b3c4d5e6f7a8", + "expected": "b3c4d5e6f7a8" + } + }, + "authoritative_parent_task_rows": [ + { + "id": "d7b760f2-fb8b-542a-a42e-d2846dd03cc9", + "title": "Review the frozen consumer-reader source refinement", + "status": "done" + }, + { + "id": "ff180859-f3d0-5aee-9e09-73e99fee0ad8", + "title": "Review revised workload and token recovery generation", + "status": "done" + } + ], + "fleet_task_search": { + "tasks_inspected": 8504, + "exact_record_or_title_matches": 0 + }, + "contract": "/home/worsch/repo-manager/docs/work-record-uuid-derivation_v1.md", + "contract_sha256": "600f5c16a0f9325df56dd698311d0151571742782664a2d2bc791b8f5d964157", + "findings": [ + "T03 was never UUID-bound in the available Git history.", + "The primary parent projection contains only T01 and T02.", + "No preserved UUID was found in the current primary task inventory.", + "Ordinary rmgr allocation explicitly refuses the unbound grandfathered source; bulk migration covers live unfinished work and does not cover this history." + ], + "bounded_remedy": { + "preferred": "An explicit repo-manager owner identity disposition preserves this closed, unbound history. An exact source fingerprint and receipt can permit canonical new-work projection without inventing a UUID.", + "alternative": "A separately approved single historical binding allocation records the exact record ID, parent and source hash. This would be allocation, not restoration, because no existing UUID was found.", + "must_preserve": [ + "ADHOC-2026-10-11-T03 record ID, referenced by two historical reviews", + "done task status", + "finished parent status", + "original review body and refinement", + "existing T01, T02 and parent UUIDs" + ], + "not_authorized": [ + "mutating the historical task", + "bypassing the sync identity guard", + "renaming the historical ID", + "reusing another task UUID", + "minting a UUID under ordinary sync authorization" + ] + } +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r1/checks.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r1/checks.json new file mode 100644 index 00000000..26810ae7 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r1/checks.json @@ -0,0 +1,22 @@ +{ + "status": "local-preparation-checked-only", + "canonical_spec_sha256": "0d1f604c76e086c82675dc535004cf4da51ef5dc247959fab50295a673407980", + "policy_sha256": "788bb9c49ab571e522beeecf7a5e29d1c79c842a84fe6d801978655facd3b5bd", + "files": [ + "plans/reuse-surface-private-source-reader.md", + "workplans/MASON-WP-0013-reuse-surface-private-source-reader.md", + "builds/reuse-surface-private-source-reader/candidate-spec.sha256", + "builds/reuse-surface-private-source-reader/construction-inputs.json", + "builds/reuse-surface-private-source-reader/externalsecret-data-item.json", + "builds/reuse-surface-private-source-reader/workload-kv-read-reuse-surface-runtime-eso.hcl" + ], + "checks": [ + "draft/no approval", + "proposed workplan", + "exact-seven identity/source equality", + "ESO retains old bytes plus one literal read stanza", + "fixed image mandatory before PAT projection" + ], + "live_checks_performed": false, + "patch_sha256": "dbbfa74a54cfe510d33300256a4729a231b4f21be1516a951bfe681a915db184" +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r1/owner.patch b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r1/owner.patch new file mode 100644 index 00000000..a9167726 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r1/owner.patch @@ -0,0 +1,684 @@ +diff --git a/plans/reuse-surface-private-source-reader.md b/plans/reuse-surface-private-source-reader.md +new file mode 100644 +index 0000000..5d9770d +--- /dev/null ++++ b/plans/reuse-surface-private-source-reader.md +@@ -0,0 +1,311 @@ ++--- ++id: reuse-surface-private-source-reader ++demand_source: the-custodian/workplans/CUST-WP-0081-netkingdom-architecture-review-and-reuse.md ++consumer_repo: reuse-surface ++credential_type: forgejo-restricted-source-read-with-existing-kubernetes-eso ++status: draft ++approved_by: null ++approved_at: null ++created: "2026-10-15" ++updated: "2026-10-15" ++construction_inputs: builds/reuse-surface-private-source-reader/construction-inputs.json ++candidate_spec_sha256: 0d1f604c76e086c82675dc535004cf4da51ef5dc247959fab50295a673407980 ++approved_spec_sha256: null ++filed_as: null ++--- ++ ++# Construction plan: seven-repository hosted capability reader ++ ++## 1. Demand ++ ++The reuse-surface hub has established 63 of the 70 reviewed security capabilities. ++It needs authenticated reads of the seven remaining private repository indexes. ++The founder explicitly approved only public disclosure of the exact capability ++metadata in CUST81-PRIVATE-METADATA-DISCLOSURE-R1; repository source remains ++private. This plan proposes a dedicated repository reader for the hosted process ++and delivery through its existing namespace-bound ESO identity. Credential access ++and live changes require their own reviewed exact-revision approval. ++ ++Preparation source is CUST81-PRIVATE-READER-PROVISIONING-PREPARATION-R1, SHA256 ++`7819eb51d249f5c7aff4df9fb520afcfb76603b05a4104439499102b6c20af99`. ++Consent receipt SHA256 is ++`4a4602ad926e3af855d6ddba4731430d33e4a7432c507ba0a5193b9f43056b52`; ++disclosure packet SHA256 is ++`46ac4fe49a08054cc215aade2fbaf3b36ee334520997857ed84f530b52da9d35`. ++The bundled construction-inputs retain all seven consented commits, index hashes ++and native raw API URLs. These references contain no credential values. ++ ++The delegated ops-mason preparation worker has no own supervision record or ++survey token. It is supervised for preparation only and borrows no custodian ++agent authority. No live OpenBao, Forgejo, Kubernetes or credential read was ++performed. This plan is deliberately **draft**, not reviewed or executable. ++ ++## 2. Existing-structure survey ++ ++### Local evidence; live survey incomplete ++ ++A live `scripts/plan-survey.py` result does not exist: no scoped ops-mason-survey ++grant was supplied. Do not treat source files as installed state. Before review, ++obtain an owner-scoped metadata survey with exact path/policy and Kubernetes-role ++arguments, or a platform-owned sanitized equivalent. Refused queries stay ++incomplete rather than being described as absence. No operator/admin session may ++be substituted for the ops-mason survey grant. ++ ++Local source observations from the pinned preparation and checked files: ++ ++- `railiance-platform/openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl` ++ SHA256 `fab29572fe82fc6674837e430f616409070f97a3867a411b7e21b5141dfaba20` ++ grants the existing runtime-secrets data path and lookup/revoke-self endpoints. ++- The caller policy `workload-kv-read-reuse-surface-runtime`, SHA256 ++ `53dd5eecc94fd8d7fc281a858f5d9fc27c8c895fd79161fd113cd3a1387a1257`, ++ grants the existing runtime-secrets entry plus self-lifecycle/capability checks; ++ it does not grant the proposed new source-reader path. ++- ClusterSecretStore `openbao-reuse` uses Kubernetes role ++ `reuse-surface-runtime-eso`, SA `reuse/reuse-surface-eso`, audience `openbao`, ++ conditions limited to namespace `reuse`. No new static ESO token is proposed. ++- `railiance-apps/manifests/reuse-surface-runtime-externalsecret.yaml` already maps ++ writer/webhook fields to `reuse/reuse-surface-env`; Deployment uses envFrom. ++ Its comments still describe a retired static ESO token; those comments must not ++ be taken as a procedure or used to mint one. Apps owns correction on integration. ++- CCR-2026-0031 and `provision-core-hub-forgejo-source.py` demonstrate dedicated ++ `read:repository` PAT custody. That script explicitly sets all-repository team ++ membership and must **not** be executed unchanged for this demand. ++- Catalog `reuse-surface-hub-write-token` describes the caller writer lane; ++ `forgejo-admin-api-token` is privileged bootstrap authority. Neither is the ++ private-index consumer credential. The preparation found no dedicated private ++ reader lane; installed absence has not been surveyed. ++ ++**Does an existing lane satisfy this demand?** Existing workload identity and ++ESO delivery can be reused. Existing writer credentials and all-repository ++source readers cannot satisfy the exact-seven grant. Propose a dedicated target ++identity and new exact KV entry, with one stanza added to the existing ESO policy. ++A differing existing user/team/path/policy must halt for reconciliation before ++any mutation. Matching names alone do not establish matching effective scope. ++ ++## 3. Proposed changes ++ ++### SEC-DSM §37 decision procedure, in order ++ ++1. **Q1 — native identity:** the current native raw HTTP fetch uses an ++ Authorization credential; Kubernetes SA identity alone is not demonstrated ++ as accepted by this Forgejo route. Candidate answer: no for the current ++ consumer interface, subject to Forgejo/reuse owner confirmation. Anonymous ++ access would require private visibility change and does not satisfy demand. ++2. **Q2 — federation:** human KeyCape OIDC login does not prove a machine-token ++ exchange for these raw API requests. No workload federation exchange for this ++ target is evidenced by the local source review. Candidate answer: no viable ++ installed interface demonstrated; Forgejo owner must confirm or supply a ++ higher mechanism. If supported reliably, revise to federation before approval. ++3. **Q3 — ephemeral target credential:** the local CCR-0031 precedent states PATs ++ have no server-side expiry. No usable ephemeral Forgejo issuance/revocation ++ service is evidenced. Candidate answer: no mechanism demonstrated, pending ++ target-owner confirmation. Do not add a broker just to label a static PAT ++ dynamic (DSM-TRANS-003). ESO's 15-minute Bao token does not expire the PAT. ++4. **Q4 — automatic rotation:** do not reuse an existing broader PAT. No automated ++ rotation job for this proposed dedicated identity is evidenced. Provisioning ++ capability is not automatic lifecycle enforcement. Answer: not demonstrated; ++ proposed attended rotation is explicitly manual, owned and dated. ++5. **Q5 — residual static credential:** conditional on Q1–Q3 owner confirmation, ++ use a centrally governed dedicated PAT, OpenBao as custody authority, Forgejo ++ as grant/revocation authority, ESO/Kubernetes/env as delivery copies. Level 5 ++ in §5, **centrally managed static secret**, not level 3 or 4. No AppRole is ++ needed: the existing ESO projected workload identity authenticates to Bao. ++ ++These answers follow DSM-ARCH-001–004, DSM-TRANS-002/003, DSM-K8S-001–004 and ++§35/36: use existing projected SA identity for delivery, avoid adding a static ++ESO token or broker, and distinguish central custody from delivery copies. ++Unconfirmed Q1–Q3 are explicit review gates, not asserted facts. ++ ++### Exact object changes and boundaries ++ ++- **create** restricted private non-admin Forgejo user `reuse-surface-source`; ++ **create** org team `coulomb/reuse-surface-source-readers`. Dedicated target ++ identity replaces unsuitable broad readers identified in §2. Team permission ++ `read`, `includes_all_repositories=false`, `can_create_org_repo=false`, only ++ `repo.code=read`; all non-code units `none`. Team members exactly this user. ++- **create** team membership for exactly `coulomb/rapp-openbao`, ++ `coulomb/rapp-policy-nexus`, `coulomb/rapp-postgres`, `coulomb/rapp-sbom-nexus`, ++ `coulomb/rapp-telemetry`, `coulomb/rapp-tenant-engine`, `coulomb/rapp-user-engine`. ++ Follow all API pages and inspect effective user grants, other teams, direct ++ collaborator access, organisation membership and repository ownership. Adding ++ seven repositories without checking extra effective grants is insufficient. ++ Existing identity/team with differing configuration is a conflict, not permission ++ to remove unrelated access silently. Reconciliation needs a revised plan. ++- **create** dedicated PAT named `reuse-surface-source-read-` with ++ scopes exactly `[read:repository]`. Platform-owned attended helper holds values ++ in memory, suppresses every raw response/error and returns token IDs only. ++ Password used for service bootstrap is random memory-only, never persisted ++ in evidence or reused as workload authentication. Prevent unattended password ++ login and recovery escalation according to Forgejo owner review. ++- **create** KV-v2 entry `platform/workloads/reuse/reuse-surface/forgejo-source-read`, ++ field `FORGEJO_SOURCE_TOKEN`. Platform alone provisions value through its ++ reviewed silent custody route from stdin; ops-mason does not handle the value. ++ It must retain accessor/token ID and custody version in sanitized lifecycle ++ inventory. A new path separates private reader from attended writer callers. ++- **modify** only existing policy `workload-kv-read-reuse-surface-runtime-eso` by ++ adding `read` on exact ++ `platform/data/workloads/reuse/reuse-surface/forgejo-source-read`. ++ Candidate full file is bundled, SHA256 ++ `788bb9c49ab571e522beeecf7a5e29d1c79c842a84fe6d801978655facd3b5bd`. ++ No glob, metadata grant, other sibling, caller writer policy, OIDC binding, ++ AppRole or Kubernetes auth role change. Verify role/token is still 15m and ++ bound to exact SA/namespace/audience; source configuration is not live proof. ++- **modify** existing `reuse/reuse-surface-runtime` ExternalSecret by one data ++ item: secretKey `REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN`, remoteRef key ++ `workloads/reuse/reuse-surface/forgejo-source-read`, property ++ `FORGEJO_SOURCE_TOKEN`. Bundled JSON item is a proposal for apps integration, ++ not a standalone apply object. Preserve existing writer and webhook fields. ++- **modify** native fetch code/image through reuse and apps review: reuse owner ++ identified Authorization header forwarding on redirects in the current urllib ++ implementation. Do not project the PAT into the running hub until a reviewed ++ fixed image is digest-pinned and runtime redirect credential isolation verified. ++ Then deliver through existing envFrom and an apps-approved controlled rollout. ++ Image change is explicit; preserve resource bounds unless separately reviewed. ++ Rollout must account for SQLite/PVC and single-node headroom before approval. ++- **create** proposed ops-warden pointer `reuse-surface-forgejo-source-read` in ++ draft status after construction, owner `railiance-platform`, non-SSH route ++ only (`warden_executes:false`). Runtime reader is the hub, not warden. ++ Activation remains ops-warden's independent verified catalog review. ++ ++### Residual-secret lifecycle and elimination ++ ++Credential owner is railiance-platform; Forgejo owns target grants; reuse-surface ++is the only workload consumer. Authority exposes **entire source code of the ++seven repositories**, not just registry files. Metadata disclosure approval ++alone does not authorize this larger repository-read grant. ++ ++Known intended copies: OpenBao KV current version and retained versions/backups; ++Kubernetes Secret in `reuse` and etcd backups; hub process environment; transient ++minting/delivery memory. Every namespace actor allowed to attach the ESO store or ++reference the materialized Secret is an indirect consumer/exposure path and must ++be reviewed; namespace conditions are not per-pod isolation. No CI/chat/local ++credential file copy is allowed. Avoid Secret last-applied annotation copies. ++ ++Proposed lifetime policy is attended rotation **every 90 days**, and immediately ++on compromise, owner change, consumer retirement or scope drift. This is a ++recommended stricter policy than CCR-0031's 180-day precedent; it is not a claim ++of automated enforcement or PAT native expiry. Record issuance and next-due UTC ++in platform inventory, with an assigned owner reminder before activation. ++Rotation: mint one replacement with the same checked grant; compare scopes and ++all effective grants; write it as a new KV version without changing other fields; ++wait for ESO, roll the reviewed fixed image, verify all seven native fetches, then revoke old ++PAT by recorded ID. Replacement overlap must end within 24 hours. Failed or ++ambiguous replacement issuance is reconciled by token-name/ID inventory before ++retry; no blind minting. Review retained KV versions/backups under platform's ++retention policy; obsolete token copies are harmless only after target revocation. ++ ++Immediate revocation deletes the dedicated PAT by ID, then removes/disables only ++this identity's team grants as approved. Compromise response reviews Forgejo ++access/audit metadata and scans owned repositories and approved logs for leaks ++without placing tokens in prompts. Use secret scanners/redactors and suppressed ++negative probes. Availability strategy fails private refresh closed and marks ++consented cache stale; public discovery continues. Never substitute privileged ++personal/admin/core-hub credentials during issuer outage. ++ ++Elimination depends on Forgejo/native federation or an operationally viable ++short-lived service credential, plus native consumer support. Revisit at rotation ++and at target upgrades; retain a live owner record for that engineering debt. ++ ++## 4. Review notes (ops-mason phase 2, incomplete) ++ ++Reuse existing delivery identity and stores rather than introduce AppRole/static ++ESO authority. The new PAT is isolated; caller writer policy stays byte-identical. ++The proposed full ESO policy preserves every original byte before one added exact ++read stanza; integration must compare current live and source digests. If policy ++changed, rebase, review and pin a fresh digest rather than overwrite it. ++ ++Existing `ops_mason.executor` engines do not express Forgejo user/team/PAT and ++shared-policy extension. Do not mislabel this JSON as a supported build_spec or ++pass it to a single-KV builder: that could replace existing policy. Candidate ++spec digest is SHA256 of UTF-8 sorted compact JSON with allow_nan=false. It ++binds scope; it is neither approval nor an executable adapter. Platform must ++allocate CCR, own a silent idempotent provisioner and pin all execution/artifact ++inputs before phase 3. Approval of a construction plan does not supply a token. ++ ++This draft is not yet phase-3 ready. Gaps: scoped live structure survey, target ++Q1–Q3 confirmation, effective-access enumeration design, reviewed platform CCR ++and script, consumer raw-route/Bearer behavior and redirect-fixed image proof plan, apps exact deployment ++and headroom/PVC rollback plan, independent owner reviews. No owner review is ++written on another repo's behalf. Only ops-mason's own preparation findings are ++recorded here. No own autopilot grant or monetary risk limit is claimed. ++ ++## 5. Executive summary (candidate; not yet ready for approval) ++ ++1. **One-line ask.** Give the hosted capability hub a dedicated read-only account ++ for the seven private repositories whose capability metadata you consented ++ to publish, delivered using the existing workload-identity path. ++2. **Who/what gets access.** Forgejo user `reuse-surface-source` obtains the ++ seven-repository read grant; the existing `reuse-surface-runtime-eso` identity ++ reads one additional exact custody entry for the hub. Namespace actors able ++ to reuse the delivery store/Secret remain an exposure consideration to review. ++3. **To what.** Read-only source access across the seven named private repositories, ++ with no write/admin/non-code-unit grants. The hub publishes only the pinned ++ consented capability metadata; repository visibility stays private. ++4. **For how long.** Bao delivery tokens remain 15 minutes, but the Forgejo PAT ++ has no expiry demonstrated. Proposed attended rotation is every 90 days with ++ immediate revocation on compromise; this distinction must be accepted explicitly. ++5. **Blast radius if the credential leaks.** Entire private source of those seven ++ repositories can be read. The token must have no additional private-repository ++ access and cannot write. Metadata disclosure consent is narrower than that read ++ grant. Availability impact of controlled rollout remains owner-reviewed. ++6. **Cost to reverse.** Revoke one PAT, remove only its dedicated grants, remove ++ one new ESO data item and one new policy stanza, and roll the reviewed fixed image. ++ Reconcile private registrations from the exact attempt; preserve the existing ++ public capabilities and writer/webhook keys. No additional paid infrastructure ++ is proposed (incremental estimate EUR 0); labor and credible loss remain unpriced, ++ so this stays supervised. ++ ++After the missing reviews and executable inputs are attached, the founder can ++**approve**, **reject**, or **send back to phase 1**. No founder disposition is ++recorded for this credential proposal. Existing metadata consent is retained as ++separate evidence and does not set status approved. ++ ++## 6. Proposed verification and rollback contract ++ ++This section describes future acceptance, **not a build result**. Phase 4 has not ++run and no success evidence or active catalog entry exists. ++ ++Before changes: exact CCR/plan/script/manifest digests, owner reviews and founder ++approved revision must match; metadata survey proves current path/policy/role; ++source/consent pins match; all existing user/team conflicts resolved; previous ++policy and deployment revision retained; apps runs dry-run and client diff, ++confirms target node and headroom/PVC strategy. Never read or print Secret objects. ++ ++Before projecting any PAT into the hub: reuse owner patch must close native ++redirect Authorization forwarding, tests must exercise the boundary, and apps ++must pin and verify the exact fixed image. The earlier same-image preparation ++assumption is superseded; fixed image/source/patch digests remain pending. ++ ++After target issuance, scope metadata must be exactly read:repository, team repo ++set exactly seven and complete effective grants enumerated. Choose a known private ++outside repo by target-owner metadata and prove denial without body retention. ++Use safe read-only negative admin/non-code routes; never try writes as a negative ++probe because unexpected privilege could make them succeed. Verify absence of ++write authority through scope and effective permissions. Missing auth/anonymous ++private raw reads fail closed, never cached as fresh successes. ++ ++Bao positive receipt proves ESO role exact path read; negative receipts prove ++default identity and dedicated caller writer cannot read the new path, ESO cannot ++read an unrelated sibling, and wrong SA/namespace/audience cannot authenticate. ++These are effective token-specific checks, not a test on an admin session. ++Owner suppressing helper checks ESO Ready and materialized key presence only. ++ ++In the actual running hub, native `fetch_remote_index_text` must fetch all seven ++pinned URLs using `REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN` and native header code; ++validate schema, exact index hashes, exact expected IDs and relative entry handling ++without printing private bodies. Local curl success is insufficient for native ++runtime verification. Then register seven pinned sources with the approved writer ++lane and force fresh composition; prove all 70 reviewed IDs exactly once, no stale ++private fallback and matching metadata. Public URLs/entries and source bytes must ++stay inside disclosure consent; new commits need renewed metadata review. ++ ++Rollback order: immediately revoke dedicated PAT; disable only new private ++registrations after reconciling ambiguous requests; remove/revert exact new ++ESO data item and policy stanza through owner paths; remove only the new ++materialized token key with a suppressing helper, preserve writer/webhook keys; ++controlled approved-image rollout. A previously vulnerable image must never ++receive the new reader key; verify key removal before restoring such an image. ++Restore previous pinned policy/deployment revision ++when applicable. Retain partial, failed and unverified outcomes and token IDs. ++Do not delete the shared Secret/store/role, overwrite unrelated policy changes, ++or remove all public registrations. No transactional rollback is claimed. +diff --git a/workplans/MASON-WP-0013-reuse-surface-private-source-reader.md b/workplans/MASON-WP-0013-reuse-surface-private-source-reader.md +new file mode 100644 +index 0000000..d5120ba +--- /dev/null ++++ b/workplans/MASON-WP-0013-reuse-surface-private-source-reader.md +@@ -0,0 +1,77 @@ ++--- ++id: MASON-WP-0013 ++type: workplan ++title: "Construct the seven-repository reuse-surface source reader" ++domain: infotech ++repo: ops-mason ++status: proposed ++owner: codex ++topic_slug: netkingdom-security-architecture ++created: "2026-10-15" ++updated: "2026-10-15" ++flavor: implementation ++depends_on: [] ++--- ++ ++# Seven-repository hosted reader ++ ++Demand: CUST-WP-0081; metadata disclosure consent is recorded separately. This ++workplan is prepared in an isolated owner checkout and is not yet integrated, ++synced, approved or executed. No production or credential authority is inferred. ++ ++## Prepare the construction bundle ++ ++```task ++id: MASON-WP-0013-T01 ++status: done ++priority: high ++``` ++ ++Prepared `plans/reuse-surface-private-source-reader.md` and ++`builds/reuse-surface-private-source-reader/` with exact-seven scope, candidate ++ESO policy, data item, canonical candidate specification digest and SEC-DSM ++hierarchy/lifecycle analysis. Plan remains draft because required live survey ++and independent mechanism/owner reviews are missing. ++ ++## Complete scoped survey and construction review ++ ++```task ++id: MASON-WP-0013-T02 ++status: wait ++priority: high ++``` ++ ++Requires legitimate own metadata-only survey grant or sanitized platform-owned ++survey. Confirm current exact path/policy/role and matching-existing identity ++handling; Forgejo owner confirms Q1–Q3 hierarchy choices. Review effective grants ++across all API pages, secret lifecycle, negative tests and caller/ESO separation. ++Do not use operator tokens or another agent supervision record. ++ ++## Bind owner CCR and executable inputs to founder decision ++ ++```task ++id: MASON-WP-0013-T03 ++status: wait ++priority: high ++``` ++ ++Platform allocates CCR and reviewed silent adapter; apps owns concrete rollout ++and rollback artifacts; reuse owns native fetch/public metadata validation; ++warden owns pointer review. Obtain separate founder decision on exact credential ++and live-change revision/digests. Existing disclosure consent cannot approve ++repository-wide credential grant. Requires T02. ++ ++## Verify the authorized owner build and routing handoff ++ ++```task ++id: MASON-WP-0013-T04 ++status: wait ++priority: high ++``` ++ ++After T03, founder/platform privileged path executes, ops-mason observes only ++through scoped permitted metadata. Preserve outcome/rollback receipts, complete ++native seven-index positive and least-privilege negative checks, propose draft ++catalog route and hand 70-ID fresh audit evidence to CUST-WP-0081. Never publish ++success before actual receipt or finish while unresolved lifecycle work is only ++in prose. +diff --git a/builds/reuse-surface-private-source-reader/candidate-spec.sha256 b/builds/reuse-surface-private-source-reader/candidate-spec.sha256 +new file mode 100644 +index 0000000..4e1cdb8 +--- /dev/null ++++ b/builds/reuse-surface-private-source-reader/candidate-spec.sha256 +@@ -0,0 +1 @@ ++0d1f604c76e086c82675dc535004cf4da51ef5dc247959fab50295a673407980 canonical-sorted-compact-json(construction-inputs.json) +diff --git a/builds/reuse-surface-private-source-reader/construction-inputs.json b/builds/reuse-surface-private-source-reader/construction-inputs.json +new file mode 100644 +index 0000000..6c21368 +--- /dev/null ++++ b/builds/reuse-surface-private-source-reader/construction-inputs.json +@@ -0,0 +1,237 @@ ++{ ++ "id": "MASON-CUST81-PRIVATE-READER-R1", ++ "revision": 1, ++ "status": "draft-not-executable", ++ "engine": "platform-owned-forgejo-restricted-reader-and-existing-eso-delta", ++ "execution_support": "requires platform reviewed adapter; not an ops_mason.executor supported build_spec", ++ "preparation_sha256": "7819eb51d249f5c7aff4df9fb520afcfb76603b05a4104439499102b6c20af99", ++ "metadata_consent_sha256": "4a4602ad926e3af855d6ddba4731430d33e4a7432c507ba0a5193b9f43056b52", ++ "disclosure_packet_sha256": "46ac4fe49a08054cc215aade2fbaf3b36ee334520997857ed84f530b52da9d35", ++ "identity": { ++ "forgejo_user": "reuse-surface-source", ++ "forgejo_org": "coulomb", ++ "forgejo_team": "reuse-surface-source-readers", ++ "restricted": true, ++ "is_admin": false, ++ "visibility": "private", ++ "password": "random value retained only in attended process memory; never stored in evidence", ++ "team_permission": "read", ++ "includes_all_repositories": false, ++ "can_create_org_repo": false, ++ "units_map": { ++ "repo.code": "read", ++ "repo.actions": "none", ++ "repo.packages": "none", ++ "repo.issues": "none", ++ "repo.ext_issues": "none", ++ "repo.wiki": "none", ++ "repo.pulls": "none", ++ "repo.releases": "none", ++ "repo.projects": "none", ++ "repo.ext_wiki": "none" ++ }, ++ "team_repositories": [ ++ "coulomb/rapp-openbao", ++ "coulomb/rapp-policy-nexus", ++ "coulomb/rapp-postgres", ++ "coulomb/rapp-sbom-nexus", ++ "coulomb/rapp-telemetry", ++ "coulomb/rapp-tenant-engine", ++ "coulomb/rapp-user-engine" ++ ], ++ "token_scopes": [ ++ "read:repository" ++ ], ++ "token_name_prefix": "reuse-surface-source-read-", ++ "reuse_other_workload_token": false, ++ "fail_on_differing_existing_identity_or_team": true, ++ "enforcement": "Verify complete team membership and all effective user repository grants; no other team, collaborator or organisation grants may provide extra private read access." ++ }, ++ "delivery": { ++ "kv_mount": "platform", ++ "kv_path": "platform/workloads/reuse/reuse-surface/forgejo-source-read", ++ "field": "FORGEJO_SOURCE_TOKEN", ++ "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN", ++ "eso_role": "reuse-surface-runtime-eso", ++ "eso_identity": "reuse/reuse-surface-eso", ++ "audience": "openbao", ++ "ttl": "15m", ++ "cluster_secret_store": "openbao-reuse", ++ "store_namespace_condition": [ ++ "reuse" ++ ], ++ "external_secret": "reuse/reuse-surface-runtime", ++ "target_secret": "reuse/reuse-surface-env", ++ "existing_consumption": "Existing Deployment envFrom interface is reusable, but PAT delivery must wait for a reviewed, digest-pinned fixed image that prevents Authorization header forwarding on native HTTP redirects.", ++ "policy_delta": { ++ "file": "railiance-platform/openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl", ++ "add_exact_stanza": "path \"platform/data/workloads/reuse/reuse-surface/forgejo-source-read\" { capabilities = [\"read\"] }", ++ "retain_existing_paths": true, ++ "do_not_change": "Caller-facing workload-kv-read-reuse-surface-runtime policy or writer OIDC role; those remain unable to read this new path." ++ }, ++ "external_secret_data_delta": { ++ "secretKey": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN", ++ "remoteRef": { ++ "key": "workloads/reuse/reuse-surface/forgejo-source-read", ++ "property": "FORGEJO_SOURCE_TOKEN" ++ } ++ }, ++ "delivery_design_reason": "Uses the existing namespace-limited ESO store and identity plus the existing envFrom interface. Separate new KV path keeps scoped writer callers from also acquiring private-source access. No new static ESO token or new store is needed.", ++ "native_source_auth": { ++ "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN", ++ "auth_header": "Authorization", ++ "header_behavior": "Native federation _auth_headers prefixes a bare token with Bearer; owner must verify accepted Forgejo raw API route with this actual native implementation." ++ }, ++ "fixed_image_gate": { ++ "status": "pending owner patch and reviewed image", ++ "reason": "Reuse owner identified urllib Authorization forwarding on redirects in current native fetch implementation.", ++ "required": [ ++ "reuse owner redirect patch and tests", ++ "exact source/patch digest", ++ "approved image digest built from fixed source", ++ "runtime proof credentials cannot reach redirected destination", ++ "apps reviewed rollout with image change explicit" ++ ], ++ "current_image_accepts_new_pat": false ++ } ++ }, ++ "sources": [ ++ { ++ "repo": "rapp-openbao", ++ "capability_ids": [ ++ "capability.railiance.openbao-package" ++ ], ++ "consented_commit": "35672be138036c8433a5ac5de91e068c03c2b124", ++ "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124", ++ "index_sha256": "044efa3d02b90e1872f2516c581159d388a8080a689f76fcd78bb4d048d6ee64", ++ "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" ++ }, ++ { ++ "repo": "rapp-policy-nexus", ++ "capability_ids": [ ++ "capability.railiance.policy-publication-package" ++ ], ++ "consented_commit": "088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", ++ "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", ++ "index_sha256": "e68bdedf61eee9ca2026f46a2434ce384c26234616e74f7a5d08a06c75b3bb00", ++ "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" ++ }, ++ { ++ "repo": "rapp-postgres", ++ "capability_ids": [ ++ "capability.railiance.postgres-isolation-recovery" ++ ], ++ "consented_commit": "a9f569c96d74aa384ac8d3ac4aa960e4061550b5", ++ "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", ++ "index_sha256": "d939333eed9d85172e006f526c445fbe2602a721d53f7c0d14bc68286ae08776", ++ "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" ++ }, ++ { ++ "repo": "rapp-sbom-nexus", ++ "capability_ids": [ ++ "capability.railiance.sbom-runtime-package" ++ ], ++ "consented_commit": "adbedd349e8df97be43a1f57db7095af45ff29d1", ++ "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", ++ "index_sha256": "d2ee0f193d2198bf8f16ce64c90ae7664e59a2bc307ad711426af3fd47deb057", ++ "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" ++ }, ++ { ++ "repo": "rapp-telemetry", ++ "capability_ids": [ ++ "capability.railiance.telemetry-package" ++ ], ++ "consented_commit": "f158307e24b86bab88a1af4830ff6b4f85afdeb5", ++ "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", ++ "index_sha256": "ee8801f143ed5cf064205710a61c2bb24efc6ea8585d5786d6b679426ec4c1d4", ++ "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" ++ }, ++ { ++ "repo": "rapp-tenant-engine", ++ "capability_ids": [ ++ "capability.railiance.tenant-engine-package" ++ ], ++ "consented_commit": "9bdc86572728783a5ed94266f04f7b12d414c557", ++ "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557", ++ "index_sha256": "d8e9c1282350b5d2fd4f4d69712aa7a5fbcd2367bb1a7fad1b6eb16a97e5d732", ++ "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" ++ }, ++ { ++ "repo": "rapp-user-engine", ++ "capability_ids": [ ++ "capability.railiance.user-engine-package" ++ ], ++ "consented_commit": "f35108f9e1b8702fb6c526fe42b2fec5ca032738", ++ "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738", ++ "index_sha256": "95b4ed2d0b189f6847b1c0899f740d1da46933a8f40491e1a02f2d4e57c819fc", ++ "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" ++ } ++ ], ++ "policy_before_sha256": "fab29572fe82fc6674837e430f616409070f97a3867a411b7e21b5141dfaba20", ++ "policy_candidate_sha256": "788bb9c49ab571e522beeecf7a5e29d1c79c842a84fe6d801978655facd3b5bd", ++ "caller_writer_policy_sha256": "53dd5eecc94fd8d7fc281a858f5d9fc27c8c895fd79161fd113cd3a1387a1257", ++ "lifecycle": { ++ "owner": "railiance-platform", ++ "target_owner": "railiance-forge", ++ "consumer": "reuse-surface hosted process only", ++ "rotation_days": 90, ++ "expiry": "No PAT native expiry demonstrated; 90-day attended rotation is proposed owner policy, not implemented expiry enforcement.", ++ "automatic_rotation": false, ++ "revoke_on": [ ++ "compromise", ++ "scope drift", ++ "owner or consumer change", ++ "90-day rotation after replacement verifies" ++ ], ++ "replacement_overlap_max_hours": 24, ++ "outage": "Private refresh fails closed; prior consented cache visibly stale, public sources continue. Never substitute admin/personal/core-hub PAT." ++ }, ++ "approval": { ++ "supervisor": "Bernd Worsch, GOVERN @ estate", ++ "approved_by": null, ++ "approved_at": null, ++ "approved_digest": null, ++ "metadata_disclosure_is_not_credential_approval": true ++ }, ++ "pre_execution_gates": [ ++ "own scoped metadata survey or platform sanitized equivalent", ++ "Forgejo owner Q1-Q3 mechanism confirmation", ++ "platform CCR allocation and reviewed silent provisioner", ++ "effective exact-seven authorization proof design", ++ "own owner reviews including reuse native fetch and apps rollout", ++ "founder exact revision approval", ++ "headroom/PVC/rollout preflight", ++ "reuse owner redirect patch reviewed and fixed image approved", ++ "verify fixed image before projecting reader PAT into hub process" ++ ], ++ "verification": { ++ "pre_apply": [ ++ "Pin exact CCR and plan revision/digest, owner reviews, founder disposition and rollout artifacts. Resolve existing identity/team/path conflicts before any mutation.", ++ "Confirm live namespace/Deployment and its image digest, current ESO identity/binding and secret field presence through safe suppressing helper; no Secret dump.", ++ "Check CPU headroom and rollout strategy/PVC constraints; retain exact prior source manifest/image and server dry-run/client diff.", ++ "Current native fetch redirect forwarding hazard must be fixed in the reviewed image before PAT delivery to the hub. An unchanged vulnerable image is not acceptable." ++ ], ++ "positive": [ ++ "PAT metadata scope exactly read:repository; exact seven team repos with no other private grants.", ++ "Actual native fetch_remote_index_text from hub process with the approved auth_env fetches all seven pinned raw index URLs; validate schema, one expected capability each and exact index SHA256. No token or fetched private source output.", ++ "ESO Ready and materialized key present checked without values; Deployment Ready on reviewed fixed-image digest after controlled rollout; redirect credential isolation verified.", ++ "Register private sources only after credential and native fetch receipts; fresh hosted federation then proves all70 reviewed IDs exactly once and matching metadata." ++ ], ++ "negative": [ ++ "Reader cannot fetch a known private repository outside the seven (preselected by platform using metadata, no unauthorized body retention).", ++ "Forgejo writes, admin/user operations and non-code unit access denied; probe design must avoid creating writes if an unexpected permission exists.", ++ "Default identity and scoped writer OIDC caller cannot read new KV path; ESO role cannot read any other sibling path, and wrong SA/namespace/audience cannot authenticate.", ++ "Native missing-auth and anonymous private-index fetch fail closed; no fallback to admin/personal/core-hub credentials." ++ ], ++ "receipts": "Sanitized IDs, repo names, scopes, hashes, status booleans and timestamps only; no credentials, raw errors, private index bodies or Secret objects." ++ }, ++ "rollback": { ++ "immediate": "Revoke this dedicated PAT and remove exact new team/user grants. Disable only private registrations created by the associated attempt after reconciling ambiguous requests; preserve all public registrations.", ++ "delivery": "Remove only new ES data item and exact new ESO policy stanza, restore prior source revision through owner path, delete only new materialized token key if needed using suppressed owner helper, then roll the reviewed fixed image or restore a prior image only after credential removal is verified. Do not delete reuse-surface-env or rotate existing writer/webhook fields.", ++ "preserve_evidence": "Retain failed/partial outcomes, reconcile any ambiguous identity or token creation; never blindly remint after an observation timeout." ++ }, ++ "cost_estimate_eur": 0, ++ "cost_assumptions": "Incremental cloud infrastructure only; existing service/resources. Build and rollout of reviewed fixed image is required. Human labor/compute changes not priced; re-estimate if owner rollout changes resources.", ++ "credible_loss_estimate_eur": null, ++ "risk_unpriced_reason": "Repository-wide private source exposure and availability impact cannot be bounded from local evidence; supervised execution required." ++} +diff --git a/builds/reuse-surface-private-source-reader/externalsecret-data-item.json b/builds/reuse-surface-private-source-reader/externalsecret-data-item.json +new file mode 100644 +index 0000000..bbfa8ab +--- /dev/null ++++ b/builds/reuse-surface-private-source-reader/externalsecret-data-item.json +@@ -0,0 +1,7 @@ ++{ ++ "secretKey": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN", ++ "remoteRef": { ++ "key": "workloads/reuse/reuse-surface/forgejo-source-read", ++ "property": "FORGEJO_SOURCE_TOKEN" ++ } ++} +diff --git a/builds/reuse-surface-private-source-reader/workload-kv-read-reuse-surface-runtime-eso.hcl b/builds/reuse-surface-private-source-reader/workload-kv-read-reuse-surface-runtime-eso.hcl +new file mode 100644 +index 0000000..a878399 +--- /dev/null ++++ b/builds/reuse-surface-private-source-reader/workload-kv-read-reuse-surface-runtime-eso.hcl +@@ -0,0 +1,15 @@ ++path "platform/data/workloads/reuse/reuse-surface/runtime-secrets" { ++ capabilities = ["read"] ++} ++ ++path "auth/token/lookup-self" { ++ capabilities = ["read"] ++} ++ ++path "auth/token/revoke-self" { ++ capabilities = ["update"] ++} ++ ++path "platform/data/workloads/reuse/reuse-surface/forgejo-source-read" { ++ capabilities = ["read"] ++} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/checks.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/checks.json new file mode 100644 index 00000000..0c148d66 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/checks.json @@ -0,0 +1,44 @@ +{ + "status": "local-preparation-checked-only", + "proposal_id": "MASON-CUST81-PRIVATE-READER-R1", + "revision": 2, + "prior_revision": 1, + "original_r1_spec_sha256": "0d1f604c76e086c82675dc535004cf4da51ef5dc247959fab50295a673407980", + "canonical_spec_sha256": "59a7334eb58135790547fab0a8c8e8debb94cc7acaae88d30654c9ae887d6732", + "policy_sha256": "788bb9c49ab571e522beeecf7a5e29d1c79c842a84fe6d801978655facd3b5bd", + "allowlist_sha256": "9a5d5a1ffb6ff1fa9e0cba7fb77779fd832c5bff413718d63c6f6e314ac653fc", + "url_count": 14, + "files": [ + "plans/reuse-surface-private-source-reader.md", + "workplans/MASON-WP-0013-reuse-surface-private-source-reader.md", + "builds/reuse-surface-private-source-reader/auth-source-allowlist.json", + "builds/reuse-surface-private-source-reader/candidate-spec.sha256", + "builds/reuse-surface-private-source-reader/construction-inputs.json", + "builds/reuse-surface-private-source-reader/externalsecret-data-item.json", + "builds/reuse-surface-private-source-reader/workload-kv-read-reuse-surface-runtime-eso.hcl" + ], + "checks": [ + "same proposal revision2; R1 preserved", + "draft/no approval", + "exact-seven identity/source equality", + "exact14 pinned index+entry destinations; newreader mapping only", + "fullconsumer sourceauthorization and redirect fix gate", + "existing authenticated-source safe migration gate" + ], + "live_checks_performed": false, + "patch_sha256": "c412d12ade1ed2d8eac235dda7eec222c66ee7f0ce512feaf47f7b13d63a6884", + "revision_diff_sha256": "215b512cd3af0c8d5a2980885c89ee19d4535242e2cb6a2e92e87b177897c61e", + "consumer_owner_crosscheck": { + "consumer_owner_allowlist_artifact": "/tmp/cust81-reuse-reader-owner/docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json", + "consumer_owner_allowlist_sha256": "e1948c537e206b30fc72b9e4732a3f600d92e131813e6f7ecfd4bfbb18c27286", + "consumer_patch_artifact": "/tmp/cust81-reuse-reader-owner/docs/assessments/cust81-private-reader/reuse-owner-preparation-r1.patch", + "consumer_patch_sha256": "f707ddfd36d5d470c176530671bb30ff6a3af2dfff86937aa8a5618bcb79768e", + "fixed_federation_source_sha256": "dbaa40f25cc0f090143578cd1c7068cb2cb00960fafd17d5239bf8a5bac514dd", + "allowlist_semantic_crosscheck": "pass exact same env and exact14 URL sets; serialization ordering differs", + "image_digest": null, + "owner_review_status": "baseline changes_requested; full candidate must integrate and obtain runtime proof", + "test_report": "owner reports focused30pass; whole226pass1isolatedrelativepath failure; no live runtime proof", + "native_verification_helper_sha256": "c67a284091cc4dd62dca56658a14b8ea1357e2b3df1518120da4c51e0ee8d85c", + "native_verification_helper_artifact": "/tmp/cust81-reuse-reader-owner/reuse_surface/private_source_verify.py" + } +} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/auth-source-allowlist.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/auth-source-allowlist.json new file mode 100644 index 00000000..e6155275 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/auth-source-allowlist.json @@ -0,0 +1 @@ +{"REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN":["https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/capabilities/capability.railiance.openbao-package.md?ref=35672be138036c8433a5ac5de91e068c03c2b124","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/capabilities/capability.railiance.policy-publication-package.md?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/capabilities/capability.railiance.postgres-isolation-recovery.md?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/capabilities/capability.railiance.sbom-runtime-package.md?ref=adbedd349e8df97be43a1f57db7095af45ff29d1","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/capabilities/capability.railiance.telemetry-package.md?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/capabilities/capability.railiance.tenant-engine-package.md?ref=9bdc86572728783a5ed94266f04f7b12d414c557","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738","https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/capabilities/capability.railiance.user-engine-package.md?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738"]} diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/candidate-spec.sha256 b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/candidate-spec.sha256 new file mode 100644 index 00000000..d60e48da --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/candidate-spec.sha256 @@ -0,0 +1 @@ +59a7334eb58135790547fab0a8c8e8debb94cc7acaae88d30654c9ae887d6732 canonical-sorted-compact-json(construction-inputs.json) diff --git a/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/construction-inputs.json b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/construction-inputs.json new file mode 100644 index 00000000..47311da5 --- /dev/null +++ b/docs/assessments/netkingdom-2026-10-14/owner-assembly/mason-r2/files/builds/reuse-surface-private-source-reader/construction-inputs.json @@ -0,0 +1,278 @@ +{ + "id": "MASON-CUST81-PRIVATE-READER-R1", + "revision": 2, + "status": "draft-not-executable", + "engine": "platform-owned-forgejo-restricted-reader-and-existing-eso-delta", + "execution_support": "requires platform reviewed adapter; not an ops_mason.executor supported build_spec", + "preparation_sha256": "7819eb51d249f5c7aff4df9fb520afcfb76603b05a4104439499102b6c20af99", + "metadata_consent_sha256": "4a4602ad926e3af855d6ddba4731430d33e4a7432c507ba0a5193b9f43056b52", + "disclosure_packet_sha256": "46ac4fe49a08054cc215aade2fbaf3b36ee334520997857ed84f530b52da9d35", + "identity": { + "forgejo_user": "reuse-surface-source", + "forgejo_org": "coulomb", + "forgejo_team": "reuse-surface-source-readers", + "restricted": true, + "is_admin": false, + "visibility": "private", + "password": "random value retained only in attended process memory; never stored in evidence", + "team_permission": "read", + "includes_all_repositories": false, + "can_create_org_repo": false, + "units_map": { + "repo.code": "read", + "repo.actions": "none", + "repo.packages": "none", + "repo.issues": "none", + "repo.ext_issues": "none", + "repo.wiki": "none", + "repo.pulls": "none", + "repo.releases": "none", + "repo.projects": "none", + "repo.ext_wiki": "none" + }, + "team_repositories": [ + "coulomb/rapp-openbao", + "coulomb/rapp-policy-nexus", + "coulomb/rapp-postgres", + "coulomb/rapp-sbom-nexus", + "coulomb/rapp-telemetry", + "coulomb/rapp-tenant-engine", + "coulomb/rapp-user-engine" + ], + "token_scopes": [ + "read:repository" + ], + "token_name_prefix": "reuse-surface-source-read-", + "reuse_other_workload_token": false, + "fail_on_differing_existing_identity_or_team": true, + "enforcement": "Verify complete team membership and all effective user repository grants; no other team, collaborator or organisation grants may provide extra private read access." + }, + "delivery": { + "kv_mount": "platform", + "kv_path": "platform/workloads/reuse/reuse-surface/forgejo-source-read", + "field": "FORGEJO_SOURCE_TOKEN", + "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN", + "eso_role": "reuse-surface-runtime-eso", + "eso_identity": "reuse/reuse-surface-eso", + "audience": "openbao", + "ttl": "15m", + "cluster_secret_store": "openbao-reuse", + "store_namespace_condition": [ + "reuse" + ], + "external_secret": "reuse/reuse-surface-runtime", + "target_secret": "reuse/reuse-surface-env", + "existing_consumption": "Existing envFrom interface is reusable only after approved full fixed image plus runtime-owned exact14 URL/auth-env allowlist is active. Existing authenticated sources need separately reviewed safe inventory and migration before fail-closed rollout.", + "policy_delta": { + "file": "railiance-platform/openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl", + "add_exact_stanza": "path \"platform/data/workloads/reuse/reuse-surface/forgejo-source-read\" { capabilities = [\"read\"] }", + "retain_existing_paths": true, + "do_not_change": "Caller-facing workload-kv-read-reuse-surface-runtime policy or writer OIDC role; those remain unable to read this new path." + }, + "external_secret_data_delta": { + "secretKey": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN", + "remoteRef": { + "key": "workloads/reuse/reuse-surface/forgejo-source-read", + "property": "FORGEJO_SOURCE_TOKEN" + } + }, + "delivery_design_reason": "Uses the existing namespace-limited ESO store and identity plus the existing envFrom interface. Separate new KV path keeps scoped writer callers from also acquiring private-source access. No new static ESO token or new store is needed.", + "native_source_auth": { + "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN", + "auth_header": "Authorization", + "header_behavior": "Native federation _auth_headers prefixes a bare token with Bearer; owner must verify accepted Forgejo raw API route with this actual native implementation." + }, + "fixed_image_gate": { + "status": "pending owner patch and reviewed image", + "reason": "Current native fetch permits registration-selected auth_env plus arbitrary URL and forwards Authorization on redirect. Both must be fixed before credential delivery.", + "required": [ + "reuse owner full redirect and auth_env/URL patch and meaningful boundary tests", + "exact full source/patch digest", + "approved image digest built from fixed source", + "runtime controlled exact14 auth allowlist config digest", + "safe owner inventory and reviewed migration of existing authenticated sources", + "runtime proof denied URLs are checked before credential lookup and authenticated redirects never forward credential", + "apps reviewed rollout and rollback with image/config changes explicit" + ], + "current_image_accepts_new_pat": false, + "reviewed_candidate_inputs": { + "consumer_owner_allowlist_artifact": "/tmp/cust81-reuse-reader-owner/docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json", + "consumer_owner_allowlist_sha256": "e1948c537e206b30fc72b9e4732a3f600d92e131813e6f7ecfd4bfbb18c27286", + "consumer_patch_artifact": "/tmp/cust81-reuse-reader-owner/docs/assessments/cust81-private-reader/reuse-owner-preparation-r1.patch", + "consumer_patch_sha256": "f707ddfd36d5d470c176530671bb30ff6a3af2dfff86937aa8a5618bcb79768e", + "fixed_federation_source_sha256": "dbaa40f25cc0f090143578cd1c7068cb2cb00960fafd17d5239bf8a5bac514dd", + "allowlist_semantic_crosscheck": "pass exact same env and exact14 URL sets; serialization ordering differs", + "image_digest": null, + "owner_review_status": "baseline changes_requested; full candidate must integrate and obtain runtime proof", + "test_report": "owner reports focused30pass; whole226pass1isolatedrelativepath failure; no live runtime proof", + "native_verification_helper_sha256": "c67a284091cc4dd62dca56658a14b8ea1357e2b3df1518120da4c51e0ee8d85c", + "native_verification_helper_artifact": "/tmp/cust81-reuse-reader-owner/reuse_surface/private_source_verify.py" + } + }, + "runtime_auth_source_allowlist": { + "env": "REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST", + "candidate_value": "{\"REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN\":[\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/capabilities/capability.railiance.openbao-package.md?ref=35672be138036c8433a5ac5de91e068c03c2b124\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/capabilities/capability.railiance.policy-publication-package.md?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/capabilities/capability.railiance.postgres-isolation-recovery.md?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/capabilities/capability.railiance.sbom-runtime-package.md?ref=adbedd349e8df97be43a1f57db7095af45ff29d1\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/capabilities/capability.railiance.telemetry-package.md?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/capabilities/capability.railiance.tenant-engine-package.md?ref=9bdc86572728783a5ed94266f04f7b12d414c557\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738\",\"https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/capabilities/capability.railiance.user-engine-package.md?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738\"]}", + "candidate_artifact": "builds/reuse-surface-private-source-reader/auth-source-allowlist.json", + "artifact_sha256": "9a5d5a1ffb6ff1fa9e0cba7fb77779fd832c5bff413718d63c6f6e314ac653fc", + "semantic_value_sha256": "30c823e0ccd4cd5bcccacfa731bcf0674b63ba6d5ec79f2c012ec650201f81f5", + "policy": "Only runtime owner may configure; untrusted registration cannot grant itself authorization. Exact equality checked before any credential env lookup. Exact14 pinned index and entry API URLs only.", + "existing_authenticated_sources": "Owner must safely inventory all authenticated sources using sanitized auth_env/URL metadata and migrate valid existing mappings before fail-closed rollout; do not expose secrets or blindly authorize inventory." + } + }, + "sources": [ + { + "repo": "rapp-openbao", + "capability_ids": [ + "capability.railiance.openbao-package" + ], + "consented_commit": "35672be138036c8433a5ac5de91e068c03c2b124", + "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-openbao/raw/registry/indexes/capabilities.yaml?ref=35672be138036c8433a5ac5de91e068c03c2b124", + "index_sha256": "044efa3d02b90e1872f2516c581159d388a8080a689f76fcd78bb4d048d6ee64", + "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" + }, + { + "repo": "rapp-policy-nexus", + "capability_ids": [ + "capability.railiance.policy-publication-package" + ], + "consented_commit": "088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", + "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-policy-nexus/raw/registry/indexes/capabilities.yaml?ref=088b78ac03b0cebeec34a69aae3569eb7ec2f9c3", + "index_sha256": "e68bdedf61eee9ca2026f46a2434ce384c26234616e74f7a5d08a06c75b3bb00", + "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" + }, + { + "repo": "rapp-postgres", + "capability_ids": [ + "capability.railiance.postgres-isolation-recovery" + ], + "consented_commit": "a9f569c96d74aa384ac8d3ac4aa960e4061550b5", + "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-postgres/raw/registry/indexes/capabilities.yaml?ref=a9f569c96d74aa384ac8d3ac4aa960e4061550b5", + "index_sha256": "d939333eed9d85172e006f526c445fbe2602a721d53f7c0d14bc68286ae08776", + "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" + }, + { + "repo": "rapp-sbom-nexus", + "capability_ids": [ + "capability.railiance.sbom-runtime-package" + ], + "consented_commit": "adbedd349e8df97be43a1f57db7095af45ff29d1", + "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-sbom-nexus/raw/registry/indexes/capabilities.yaml?ref=adbedd349e8df97be43a1f57db7095af45ff29d1", + "index_sha256": "d2ee0f193d2198bf8f16ce64c90ae7664e59a2bc307ad711426af3fd47deb057", + "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" + }, + { + "repo": "rapp-telemetry", + "capability_ids": [ + "capability.railiance.telemetry-package" + ], + "consented_commit": "f158307e24b86bab88a1af4830ff6b4f85afdeb5", + "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-telemetry/raw/registry/indexes/capabilities.yaml?ref=f158307e24b86bab88a1af4830ff6b4f85afdeb5", + "index_sha256": "ee8801f143ed5cf064205710a61c2bb24efc6ea8585d5786d6b679426ec4c1d4", + "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" + }, + { + "repo": "rapp-tenant-engine", + "capability_ids": [ + "capability.railiance.tenant-engine-package" + ], + "consented_commit": "9bdc86572728783a5ed94266f04f7b12d414c557", + "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-tenant-engine/raw/registry/indexes/capabilities.yaml?ref=9bdc86572728783a5ed94266f04f7b12d414c557", + "index_sha256": "d8e9c1282350b5d2fd4f4d69712aa7a5fbcd2367bb1a7fad1b6eb16a97e5d732", + "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" + }, + { + "repo": "rapp-user-engine", + "capability_ids": [ + "capability.railiance.user-engine-package" + ], + "consented_commit": "f35108f9e1b8702fb6c526fe42b2fec5ca032738", + "native_raw_url": "https://forgejo.coulomb.social/api/v1/repos/coulomb/rapp-user-engine/raw/registry/indexes/capabilities.yaml?ref=f35108f9e1b8702fb6c526fe42b2fec5ca032738", + "index_sha256": "95b4ed2d0b189f6847b1c0899f740d1da46933a8f40491e1a02f2d4e57c819fc", + "auth_env": "REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN" + } + ], + "policy_before_sha256": "fab29572fe82fc6674837e430f616409070f97a3867a411b7e21b5141dfaba20", + "policy_candidate_sha256": "788bb9c49ab571e522beeecf7a5e29d1c79c842a84fe6d801978655facd3b5bd", + "caller_writer_policy_sha256": "53dd5eecc94fd8d7fc281a858f5d9fc27c8c895fd79161fd113cd3a1387a1257", + "lifecycle": { + "owner": "railiance-platform", + "target_owner": "railiance-forge", + "consumer": "reuse-surface hosted process only", + "rotation_days": 90, + "expiry": "No PAT native expiry demonstrated; 90-day attended rotation is proposed owner policy, not implemented expiry enforcement.", + "automatic_rotation": false, + "revoke_on": [ + "compromise", + "scope drift", + "owner or consumer change", + "90-day rotation after replacement verifies" + ], + "replacement_overlap_max_hours": 24, + "outage": "Private refresh fails closed; prior consented cache visibly stale, public sources continue. Never substitute admin/personal/core-hub PAT." + }, + "approval": { + "supervisor": "Bernd Worsch, GOVERN @ estate", + "approved_by": null, + "approved_at": null, + "approved_digest": null, + "metadata_disclosure_is_not_credential_approval": true + }, + "pre_execution_gates": [ + "own scoped metadata survey or platform sanitized equivalent", + "Forgejo owner Q1-Q3 mechanism confirmation", + "platform CCR allocation and reviewed silent provisioner", + "effective exact-seven authorization proof design", + "own owner reviews including reuse native fetch and apps rollout", + "founder exact revision approval", + "headroom/PVC/rollout preflight", + "reuse owner redirect patch reviewed and fixed image approved", + "verify fixed image before projecting reader PAT into hub process", + "full consumer source-authorization patch reviewed, not redirect-only", + "runtime owner exact14 allowlist and existing auth-source migration reviewed" + ], + "verification": { + "pre_apply": [ + "Pin exact CCR and plan revision/digest, owner reviews, founder disposition and rollout artifacts. Resolve existing identity/team/path conflicts before any mutation.", + "Confirm live namespace/Deployment and its image digest, current ESO identity/binding and secret field presence through safe suppressing helper; no Secret dump.", + "Check CPU headroom and rollout strategy/PVC constraints; retain exact prior source manifest/image and server dry-run/client diff.", + "Current native fetch redirect forwarding hazard must be fixed in the reviewed image before PAT delivery to the hub. An unchanged vulnerable image is not acceptable.", + "Full consumer patch must reject registration-controlled auth_env/URL destinations before credential lookup; configure owner-reviewed allowlist and migrate existing authenticated sources before rollout." + ], + "positive": [ + "PAT metadata scope exactly read:repository; exact seven team repos with no other private grants.", + "Actual native fetch_remote_index_text from hub process with the approved auth_env fetches all seven pinned raw index URLs; validate schema, one expected capability each and exact index SHA256. No token or fetched private source output.", + "ESO Ready and materialized key present checked without values; Deployment Ready on reviewed fixed-image digest after controlled rollout; redirect credential isolation verified.", + "Register private sources only after credential and native fetch receipts; fresh hosted federation then proves all70 reviewed IDs exactly once and matching metadata." + ], + "negative": [ + "Reader cannot fetch a known private repository outside the seven (preselected by platform using metadata, no unauthorized body retention).", + "Forgejo writes, admin/user operations and non-code unit access denied; probe design must avoid creating writes if an unexpected permission exists.", + "Default identity and scoped writer OIDC caller cannot read new KV path; ESO role cannot read any other sibling path, and wrong SA/namespace/audience cannot authenticate.", + "Native missing-auth and anonymous private-index fetch fail closed; no fallback to admin/personal/core-hub credentials.", + "Registration-selected auth_env or unlisted same-host/other-host/unpinned/wrong-query URL is refused before credential lookup; token value is never read or transmitted.", + "Authenticated redirects fail closed without forwarding Authorization, including same-origin path changes. Runtime allowlist contains exact14 consented pinned URL strings only for new readerenv." + ], + "receipts": "Sanitized IDs, repo names, scopes, hashes, status booleans and timestamps only; no credentials, raw errors, private index bodies or Secret objects." + }, + "rollback": { + "immediate": "Revoke this dedicated PAT and remove exact new team/user grants. Disable only private registrations created by the associated attempt after reconciling ambiguous requests; preserve all public registrations.", + "delivery": "Remove only new ES data item and exact new ESO policy stanza, restore prior source revision through owner path, delete only new materialized token key if needed using suppressed owner helper, then roll the reviewed fixed image or restore a prior image only after credential removal is verified. Do not delete reuse-surface-env or rotate existing writer/webhook fields. Remove only the new reader environment mapping from runtime source allowlist while preserving separately reviewed existing mappings; coordinate image/config rollback so stale deployments never receive the PAT.", + "preserve_evidence": "Retain failed/partial outcomes, reconcile any ambiguous identity or token creation; never blindly remint after an observation timeout." + }, + "cost_estimate_eur": 0, + "cost_assumptions": "Incremental cloud infrastructure only; existing service/resources. Build and rollout of reviewed fixed image is required. Human labor/compute changes not priced; re-estimate if owner rollout changes resources.", + "credible_loss_estimate_eur": null, + "risk_unpriced_reason": "Repository-wide private source exposure and availability impact cannot be bounded from local evidence; supervised execution required.", + "revision_history": [ + { + "revision": 1, + "spec_sha256": "0d1f604c76e086c82675dc535004cf4da51ef5dc247959fab50295a673407980", + "status": "draft-unapproved-never-executed", + "ref": "custodian owner-assembly/mason-r1/" + }, + { + "revision": 2, + "reason": "Same proposal refined after consumer owner found URL/auth_env credential exfiltration in addition to redirect forwarding." + } + ] +}