Prepare scoped reuse reader release with qualified content digests
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a137ca-5c77-7a71-b9ae-23ad9b0b5684
This commit is contained in:
parent
72bcad86d7
commit
fb7d56d3dc
22 changed files with 1937 additions and 0 deletions
|
|
@ -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 -}}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
30
charts/reuse-surface/values.schema.json
Normal file
30
charts/reuse-surface/values.schema.json
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
119
docs/assessments/cust81-private-reader/apps-owner-review-r2.md
Normal file
119
docs/assessments/cust81-private-reader/apps-owner-review-r2.md
Normal file
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"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": "a3a2f2db6f0a8461a0d8299825c842c8ce427f59c86238884609d463837b3b75",
|
||||
"reviewed_manifest_sha256": "45d467c2bb48462a388f5df4ba5188492d406bdddbddfbf3487bd2077486dec8",
|
||||
"reviewed_patch_sha256": "39ebaa7f4050f9204fe8ee38364fbbce874903447ac45ccd408cf434aa6e4a73",
|
||||
"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"
|
||||
],
|
||||
"proposal_id": "CUST81-APPS-PRIVATE-READER-RELEASE-R1",
|
||||
"revision": 2,
|
||||
"refinement_or_rescue": true
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
# Apps concrete phase A proposal review
|
||||
|
||||
Disposition: `approved` for proposal preparation and local render only.
|
||||
This supplement preserves the reviewed core R2 patch unchanged. It supplies
|
||||
actual `reuse` Helm release / `reuse` namespace chart rendering with the locally
|
||||
built hardened image digest. It does not authorize publication, execute a live
|
||||
change or approve platform's CCR. INTENT basis: source-controlled release
|
||||
contracts, explicit S3 handoff and evidence before confidence.
|
||||
|
||||
The proposed image is
|
||||
`forgejo.coulomb.social/coulomb/reuse-surface@sha256:2364b7e7859daccf9340a063654e2b09eed1bc27e0adf7b23cbb4b30135a7db0`.
|
||||
The local build receipt confirms no-network/read-only health and native source
|
||||
hash smoke. Registry publication is false. Before apply the exact reviewed
|
||||
artifact must be published and independently verified by registry manifest
|
||||
digest. If publication changes manifest representation/digest, revise and review
|
||||
the bound proposal rather than silently replacing the digest.
|
||||
|
||||
Current observations are node `92.205.62.239`, CPU requests3560m of4000m (440m
|
||||
free), API100m/256Mi, replicas1 with surge1/unavailable0, PVC
|
||||
`reuse-surface-data` Bound RWO1Gi, and Helm ownership without Argo tracking.
|
||||
The proposed chart retains resources, strategy and PVC. One100m/256Mi surge fits
|
||||
observed CPU headroom; recheck memory, pending pods and node headroom immediately
|
||||
before rollout. RWO single-node does not prohibit two pods on that same node,
|
||||
but driver mount behavior and SQLite concurrent-access readiness remain
|
||||
verification gates. Do not change deployment strategy or PVC to bypass a failure.
|
||||
|
||||
Exact readonly authenticated-source inventory is0 at its receipt timestamp.
|
||||
This clears the observed migration gate, but recheck before apply; no credential
|
||||
or Secret/env was read. Existing Kubernetes-auth `openbao-reuse` store is Ready
|
||||
with namespace/ServiceAccount/role matching the consumer; its current
|
||||
ExternalSecret contains only the two old fields and remains unchanged in phase A.
|
||||
|
||||
Local full-chart render and assertions passed: exact proposed image and14 URL
|
||||
allowlist; same100m/256Mi requests; same1surge/0unavailable/replicas1; no Secret,
|
||||
ExternalSecret or store objects added. Full chart includes existing landing,
|
||||
ingress, services and PVC and must receive normal full-chart server dry-run and
|
||||
client diff, not a Deployment-only narrow review.
|
||||
|
||||
Incremental infrastructure cost is EUR0 because node, replica steady state,
|
||||
requests, services and PVC capacity remain unchanged. Build/registry execution
|
||||
cost is not independently accounted. Credible operational loss is qualitative
|
||||
and not priced in EUR: rollout failure or concurrent SQLite/PVC access may cause
|
||||
service interruption or recovery work. No autopilot grant is inferred. Exact
|
||||
human review must accept these estimates and remaining readiness gates.
|
||||
|
||||
Before founder-authorized deploy, capture current Helm revision and safe rollback
|
||||
reference (old running digest
|
||||
`sha256:2c1514cb3f5e1297ffeeac912ba36a70f8a2591588a5a4643bc58293e97132de`),
|
||||
known recovery receipt and63 public capability baseline. Use actual Helm release
|
||||
`reuse`, namespace`reuse`, owner atomic/wait/timeout path after safe dry-run/diff.
|
||||
No exact deploy command is executed by this proposal. Phase A retains the current
|
||||
runtime Secret fields and supplies no reader. Verify running imageID, readiness,
|
||||
public federation and credential refusal/redirect behavior before phase B.
|
||||
If phase A fails with no reader delivered, restore the approved previous release.
|
||||
After phase B, revoke/remove reader and verify its absence before any vulnerable
|
||||
image restoration. Phase B is independently gated by approved/executed CCR and
|
||||
native14 URL/7 entry-hash proof before70/70 hosted discovery.
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"proposal_id": "CUST81-APPS-PHASE-A-LOCAL-IMAGE-R1",
|
||||
"reviewer_owner": "railiance-apps",
|
||||
"disposition": "approved",
|
||||
"approved_scope": "preparation only, local full-chart render, supervised founder review required",
|
||||
"files": {
|
||||
"docs/assessments/cust81-private-reader/phase-a-local-image-r1/apps-owner-release-review.md": "a74e96986798a727fc87c0d3c578601579778dfd8521796d0bb81df8451c751b",
|
||||
"docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-full-chart.proposed.yaml": "36c20c3e16757d3e888a3db02853032b33e791aa04a6055fe001121254345b81",
|
||||
"docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-preparation-receipt.json": "3282a17ae3724619e40dd1f34846d83b2297d9ae00030618dbd269e8e2fd7d39",
|
||||
"docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-values.proposed.yaml": "35284857ec987fc7a929f5c2eecdb44c7d3367f7835904692947de09918ab8f1"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,478 @@
|
|||
# PREPARATION RENDER ONLY; no registry publication or server validation proved.
|
||||
---
|
||||
# Source: reuse-surface/templates/landing-configmap.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: reuse-surface-landing
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
app.kubernetes.io/component: landing
|
||||
data:
|
||||
index.html: |
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
<title>REUSE federation endpoint</title>
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: light;
|
||||
--ink: #1d2733;
|
||||
--muted: #536271;
|
||||
--line: #d9e0e7;
|
||||
--paper: #f8fafc;
|
||||
--accent: #2066a8;
|
||||
--accent-dark: #164b7e;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
color: var(--ink);
|
||||
background: var(--paper);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 32px 18px;
|
||||
}
|
||||
main {
|
||||
width: min(100%, 720px);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: #ffffff;
|
||||
padding: clamp(28px, 5vw, 48px);
|
||||
box-shadow: 0 18px 48px rgba(29, 39, 51, 0.08);
|
||||
}
|
||||
.eyebrow {
|
||||
margin: 0 0 12px;
|
||||
color: var(--accent-dark);
|
||||
font-size: 0.86rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: clamp(2rem, 7vw, 3rem);
|
||||
line-height: 1.05;
|
||||
}
|
||||
p {
|
||||
max-width: 62ch;
|
||||
margin: 18px 0 0;
|
||||
color: var(--muted);
|
||||
font-size: 1rem;
|
||||
line-height: 1.65;
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.button {
|
||||
display: inline-flex;
|
||||
min-height: 44px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
background: var(--accent);
|
||||
color: #ffffff;
|
||||
padding: 0 18px;
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
}
|
||||
.button:focus,
|
||||
.button:hover {
|
||||
background: var(--accent-dark);
|
||||
}
|
||||
.links {
|
||||
margin-top: 26px;
|
||||
padding-top: 22px;
|
||||
border-top: 1px solid var(--line);
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<p class="eyebrow">reuse.coulomb.social</p>
|
||||
<h1>REUSE federation endpoint</h1>
|
||||
<p>This is the Railiance REUSE capability federation service. It is an API endpoint for automated clients and operators; there is no browser login for this service.</p>
|
||||
<div class="actions">
|
||||
<a class="button" href="/v1/federated">Open federated index</a>
|
||||
</div>
|
||||
<nav class="links" aria-label="Service links">
|
||||
<a href="/health">Health check</a>
|
||||
<a href="/v1/federated">Federated capability index</a>
|
||||
<a href="https://forgejo.coulomb.social/coulomb/railiance-apps/src/branch/main/docs/reuse-surface-on-railiance01.md">Operator runbook</a>
|
||||
</nav>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
---
|
||||
# Source: reuse-surface/templates/pvc.yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: reuse-surface-data
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
---
|
||||
# Source: reuse-surface/templates/landing-service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: reuse-surface-landing
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
app.kubernetes.io/component: landing
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/component: landing
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: reuse-surface/templates/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: reuse-surface
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/component: api
|
||||
ports:
|
||||
- name: http
|
||||
port: 8000
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: reuse-surface/templates/deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: reuse-surface
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
app.kubernetes.io/component: api
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/component: api
|
||||
spec:
|
||||
enableServiceLinks: false
|
||||
securityContext:
|
||||
{}
|
||||
containers:
|
||||
- name: reuse-surface
|
||||
image: "forgejo.coulomb.social/coulomb/reuse-surface@sha256:2364b7e7859daccf9340a063654e2b09eed1bc27e0adf7b23cbb4b30135a7db0"
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["reuse-surface", "serve"]
|
||||
securityContext:
|
||||
{}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8000
|
||||
protocol: TCP
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: "reuse-surface-env"
|
||||
env:
|
||||
- name: REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST
|
||||
value: "{\"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\"]}"
|
||||
- name: REUSE_SURFACE_LISTEN_HOST
|
||||
value: "0.0.0.0"
|
||||
- name: REUSE_SURFACE_LISTEN_PORT
|
||||
value: "8000"
|
||||
- name: REUSE_SURFACE_DB
|
||||
value: "/data/reuse.db"
|
||||
- name: REUSE_SURFACE_CACHE_DIR
|
||||
value: "/data/cache"
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8000
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8000
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: reuse-surface-data
|
||||
---
|
||||
# Source: reuse-surface/templates/landing-deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: reuse-surface-landing
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
app.kubernetes.io/component: landing
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/component: landing
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/component: landing
|
||||
spec:
|
||||
enableServiceLinks: false
|
||||
containers:
|
||||
- name: landing
|
||||
image: "nginxinc/nginx-unprivileged:1.27-alpine"
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
limits:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
volumeMounts:
|
||||
- name: landing-page
|
||||
mountPath: /usr/share/nginx/html/index.html
|
||||
subPath: index.html
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: landing-page
|
||||
configMap:
|
||||
name: reuse-surface-landing
|
||||
---
|
||||
# Source: reuse-surface/templates/ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: reuse-surface
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
tls:
|
||||
- hosts:
|
||||
- reuse.coulomb.social
|
||||
secretName: reuse-surface-tls
|
||||
rules:
|
||||
- host: reuse.coulomb.social
|
||||
http:
|
||||
paths:
|
||||
- path: /health
|
||||
pathType: Exact
|
||||
backend:
|
||||
service:
|
||||
name: reuse-surface
|
||||
port:
|
||||
number: 8000
|
||||
- path: /v1
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: reuse-surface
|
||||
port:
|
||||
number: 8000
|
||||
---
|
||||
# Source: reuse-surface/templates/landing-ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: reuse-surface-landing
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||
traefik.ingress.kubernetes.io/router.priority: "1"
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
tls:
|
||||
- hosts:
|
||||
- reuse.coulomb.social
|
||||
secretName: reuse-surface-tls
|
||||
rules:
|
||||
- host: reuse.coulomb.social
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: reuse-surface-landing
|
||||
port:
|
||||
number: 8080
|
||||
---
|
||||
# Source: reuse-surface/templates/redirect-ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: reuse-surface-http-redirect
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
traefik.ingress.kubernetes.io/router.middlewares: "reuse-reuse-surface-redirect-https@kubernetescrd"
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: reuse.coulomb.social
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: reuse-surface
|
||||
port:
|
||||
number: 8000
|
||||
---
|
||||
# Source: reuse-surface/templates/redirect-middleware.yaml
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: reuse-surface-redirect-https
|
||||
labels:
|
||||
app.kubernetes.io/name: reuse-surface
|
||||
app.kubernetes.io/instance: reuse
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/part-of: railiance-apps
|
||||
helm.sh/chart: reuse-surface-0.1.0
|
||||
spec:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"proposal_id": "CUST81-APPS-PHASE-A-LOCAL-IMAGE-R1",
|
||||
"disposition": "approved",
|
||||
"approved_scope": "concrete proposal preparation and local render only; not publish or production deploy",
|
||||
"workitem": "RAPPS-WP-0017-T02",
|
||||
"release": "reuse",
|
||||
"namespace": "reuse",
|
||||
"deployment": "reuse-surface",
|
||||
"image_reference": "forgejo.coulomb.social/coulomb/reuse-surface@sha256:2364b7e7859daccf9340a063654e2b09eed1bc27e0adf7b23cbb4b30135a7db0",
|
||||
"registry_publication_verified": false,
|
||||
"phase_b_credential_delivery_included": false,
|
||||
"incremental_infrastructure_cost_eur": 0,
|
||||
"cost_basis": "existing node, same requests and replicas, same PVC, no new service or purchased capacity; build/registry execution cost not independently accounted",
|
||||
"credible_loss_bound_eur": null,
|
||||
"risk_basis": "qualitative supervised change: transient rollout or SQLite concurrent-access outage; RWO PVC single-node mounts need preflight; no customer production admitted; data recovery and exact atomic rollback required before execution",
|
||||
"autopilot_authority": false,
|
||||
"local_render_checks": "passed",
|
||||
"evidence": {
|
||||
"hardened-reader-local-image-r1.json": {
|
||||
"path": "/home/worsch/the-custodian/docs/assessments/netkingdom-2026-10-14/hardened-reader-local-image-r1.json",
|
||||
"sha256": "ed7c2516925d7f16b573a70b5e48d5656a4875e9eb94bcc8760a8bdcbe07f59c"
|
||||
},
|
||||
"live-authenticated-source-inventory-r1.json": {
|
||||
"path": "/home/worsch/the-custodian/docs/assessments/netkingdom-2026-10-14/live-authenticated-source-inventory-r1.json",
|
||||
"sha256": "ba669d6231c8c611191c7ad28f5914d6c47332032b23b0ea40a13f753e883073"
|
||||
},
|
||||
"reuse-release-runtime-metadata-r1.json": {
|
||||
"path": "/home/worsch/the-custodian/docs/assessments/netkingdom-2026-10-14/reuse-release-runtime-metadata-r1.json",
|
||||
"sha256": "5ec901cf41b9f52628ff636c23b5bbc4789df6a9118f5cff0ff8518b287357e9"
|
||||
},
|
||||
"reuse-release-owner-eso-metadata-r1.json": {
|
||||
"path": "/home/worsch/the-custodian/docs/assessments/netkingdom-2026-10-14/reuse-release-owner-eso-metadata-r1.json",
|
||||
"sha256": "ff9aa207ae081d27d86820747a993d4bbc290ba2c354eef72388233d6733adb3"
|
||||
}
|
||||
},
|
||||
"observed_runtime": {
|
||||
"node_ip": "92.205.62.239",
|
||||
"cpu_free_m": 440,
|
||||
"api_surge_cpu_m": 100,
|
||||
"api_surge_memory_mi": 256,
|
||||
"pvc": "reuse-surface-data",
|
||||
"pvc_access": "ReadWriteOnce",
|
||||
"pvc_capacity": "1Gi",
|
||||
"previous_image_digest": "forgejo.coulomb.social/coulomb/reuse-surface@sha256:2c1514cb3f5e1297ffeeac912ba36a70f8a2591588a5a4643bc58293e97132de",
|
||||
"authenticated_sources": 0
|
||||
},
|
||||
"gates": [
|
||||
"publish exact reviewed image and verify registry digest; local digest may require reviewed update if registry transforms manifest",
|
||||
"founder approval for exact phase A and later credential CCR/phase B",
|
||||
"recheck target headroom memory node/PVC mount scheduling and authenticated inventory immediately before apply",
|
||||
"bounded safe server dry-run/client diff and current release revision/rollback capture",
|
||||
"no ESO reader field during phase A; verify actual imageID health and63public baseline before phase B",
|
||||
"revoke/remove delivered reader before any downgrade to old vulnerable image"
|
||||
],
|
||||
"render_command": [
|
||||
"helm",
|
||||
"template",
|
||||
"reuse",
|
||||
"charts/reuse-surface",
|
||||
"--namespace",
|
||||
"reuse",
|
||||
"-f",
|
||||
"helm/reuse-surface-values.yaml",
|
||||
"-f",
|
||||
"docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-values.proposed.yaml"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,665 @@
|
|||
diff --git a/docs/assessments/cust81-private-reader/phase-a-local-image-r1/apps-owner-release-review.md b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/apps-owner-release-review.md
|
||||
new file mode 100644
|
||||
index 0000000..0079fe5
|
||||
--- /dev/null
|
||||
+++ b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/apps-owner-release-review.md
|
||||
@@ -0,0 +1,57 @@
|
||||
+# Apps concrete phase A proposal review
|
||||
+
|
||||
+Disposition: `approved` for proposal preparation and local render only.
|
||||
+This supplement preserves the reviewed core R2 patch unchanged. It supplies
|
||||
+actual `reuse` Helm release / `reuse` namespace chart rendering with the locally
|
||||
+built hardened image digest. It does not authorize publication, execute a live
|
||||
+change or approve platform's CCR. INTENT basis: source-controlled release
|
||||
+contracts, explicit S3 handoff and evidence before confidence.
|
||||
+
|
||||
+The proposed image is
|
||||
+`forgejo.coulomb.social/coulomb/reuse-surface@sha256:2364b7e7859daccf9340a063654e2b09eed1bc27e0adf7b23cbb4b30135a7db0`.
|
||||
+The local build receipt confirms no-network/read-only health and native source
|
||||
+hash smoke. Registry publication is false. Before apply the exact reviewed
|
||||
+artifact must be published and independently verified by registry manifest
|
||||
+digest. If publication changes manifest representation/digest, revise and review
|
||||
+the bound proposal rather than silently replacing the digest.
|
||||
+
|
||||
+Current observations are node `92.205.62.239`, CPU requests3560m of4000m (440m
|
||||
+free), API100m/256Mi, replicas1 with surge1/unavailable0, PVC
|
||||
+`reuse-surface-data` Bound RWO1Gi, and Helm ownership without Argo tracking.
|
||||
+The proposed chart retains resources, strategy and PVC. One100m/256Mi surge fits
|
||||
+observed CPU headroom; recheck memory, pending pods and node headroom immediately
|
||||
+before rollout. RWO single-node does not prohibit two pods on that same node,
|
||||
+but driver mount behavior and SQLite concurrent-access readiness remain
|
||||
+verification gates. Do not change deployment strategy or PVC to bypass a failure.
|
||||
+
|
||||
+Exact readonly authenticated-source inventory is0 at its receipt timestamp.
|
||||
+This clears the observed migration gate, but recheck before apply; no credential
|
||||
+or Secret/env was read. Existing Kubernetes-auth `openbao-reuse` store is Ready
|
||||
+with namespace/ServiceAccount/role matching the consumer; its current
|
||||
+ExternalSecret contains only the two old fields and remains unchanged in phase A.
|
||||
+
|
||||
+Local full-chart render and assertions passed: exact proposed image and14 URL
|
||||
+allowlist; same100m/256Mi requests; same1surge/0unavailable/replicas1; no Secret,
|
||||
+ExternalSecret or store objects added. Full chart includes existing landing,
|
||||
+ingress, services and PVC and must receive normal full-chart server dry-run and
|
||||
+client diff, not a Deployment-only narrow review.
|
||||
+
|
||||
+Incremental infrastructure cost is EUR0 because node, replica steady state,
|
||||
+requests, services and PVC capacity remain unchanged. Build/registry execution
|
||||
+cost is not independently accounted. Credible operational loss is qualitative
|
||||
+and not priced in EUR: rollout failure or concurrent SQLite/PVC access may cause
|
||||
+service interruption or recovery work. No autopilot grant is inferred. Exact
|
||||
+human review must accept these estimates and remaining readiness gates.
|
||||
+
|
||||
+Before founder-authorized deploy, capture current Helm revision and safe rollback
|
||||
+reference (old running digest
|
||||
+`sha256:2c1514cb3f5e1297ffeeac912ba36a70f8a2591588a5a4643bc58293e97132de`),
|
||||
+known recovery receipt and63 public capability baseline. Use actual Helm release
|
||||
+`reuse`, namespace`reuse`, owner atomic/wait/timeout path after safe dry-run/diff.
|
||||
+No exact deploy command is executed by this proposal. Phase A retains the current
|
||||
+runtime Secret fields and supplies no reader. Verify running imageID, readiness,
|
||||
+public federation and credential refusal/redirect behavior before phase B.
|
||||
+If phase A fails with no reader delivered, restore the approved previous release.
|
||||
+After phase B, revoke/remove reader and verify its absence before any vulnerable
|
||||
+image restoration. Phase B is independently gated by approved/executed CCR and
|
||||
+native14 URL/7 entry-hash proof before70/70 hosted discovery.
|
||||
diff --git a/docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-full-chart.proposed.yaml b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-full-chart.proposed.yaml
|
||||
new file mode 100644
|
||||
index 0000000..4059c3a
|
||||
--- /dev/null
|
||||
+++ b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-full-chart.proposed.yaml
|
||||
@@ -0,0 +1,478 @@
|
||||
+# PREPARATION RENDER ONLY; no registry publication or server validation proved.
|
||||
+---
|
||||
+# Source: reuse-surface/templates/landing-configmap.yaml
|
||||
+apiVersion: v1
|
||||
+kind: ConfigMap
|
||||
+metadata:
|
||||
+ name: reuse-surface-landing
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+ app.kubernetes.io/component: landing
|
||||
+data:
|
||||
+ index.html: |
|
||||
+
|
||||
+ <!doctype html>
|
||||
+ <html lang="en">
|
||||
+ <head>
|
||||
+ <meta charset="utf-8">
|
||||
+ <meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
+ <meta name="robots" content="noindex,nofollow">
|
||||
+ <title>REUSE federation endpoint</title>
|
||||
+ <style>
|
||||
+ :root {
|
||||
+ color-scheme: light;
|
||||
+ --ink: #1d2733;
|
||||
+ --muted: #536271;
|
||||
+ --line: #d9e0e7;
|
||||
+ --paper: #f8fafc;
|
||||
+ --accent: #2066a8;
|
||||
+ --accent-dark: #164b7e;
|
||||
+ }
|
||||
+ * {
|
||||
+ box-sizing: border-box;
|
||||
+ }
|
||||
+ body {
|
||||
+ margin: 0;
|
||||
+ min-height: 100vh;
|
||||
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
+ color: var(--ink);
|
||||
+ background: var(--paper);
|
||||
+ display: grid;
|
||||
+ place-items: center;
|
||||
+ padding: 32px 18px;
|
||||
+ }
|
||||
+ main {
|
||||
+ width: min(100%, 720px);
|
||||
+ border: 1px solid var(--line);
|
||||
+ border-radius: 8px;
|
||||
+ background: #ffffff;
|
||||
+ padding: clamp(28px, 5vw, 48px);
|
||||
+ box-shadow: 0 18px 48px rgba(29, 39, 51, 0.08);
|
||||
+ }
|
||||
+ .eyebrow {
|
||||
+ margin: 0 0 12px;
|
||||
+ color: var(--accent-dark);
|
||||
+ font-size: 0.86rem;
|
||||
+ font-weight: 700;
|
||||
+ text-transform: uppercase;
|
||||
+ }
|
||||
+ h1 {
|
||||
+ margin: 0;
|
||||
+ font-size: clamp(2rem, 7vw, 3rem);
|
||||
+ line-height: 1.05;
|
||||
+ }
|
||||
+ p {
|
||||
+ max-width: 62ch;
|
||||
+ margin: 18px 0 0;
|
||||
+ color: var(--muted);
|
||||
+ font-size: 1rem;
|
||||
+ line-height: 1.65;
|
||||
+ }
|
||||
+ .actions {
|
||||
+ display: flex;
|
||||
+ flex-wrap: wrap;
|
||||
+ gap: 12px;
|
||||
+ margin-top: 28px;
|
||||
+ }
|
||||
+ a {
|
||||
+ color: var(--accent);
|
||||
+ }
|
||||
+ .button {
|
||||
+ display: inline-flex;
|
||||
+ min-height: 44px;
|
||||
+ align-items: center;
|
||||
+ justify-content: center;
|
||||
+ border-radius: 6px;
|
||||
+ background: var(--accent);
|
||||
+ color: #ffffff;
|
||||
+ padding: 0 18px;
|
||||
+ font-weight: 700;
|
||||
+ text-decoration: none;
|
||||
+ }
|
||||
+ .button:focus,
|
||||
+ .button:hover {
|
||||
+ background: var(--accent-dark);
|
||||
+ }
|
||||
+ .links {
|
||||
+ margin-top: 26px;
|
||||
+ padding-top: 22px;
|
||||
+ border-top: 1px solid var(--line);
|
||||
+ display: grid;
|
||||
+ gap: 10px;
|
||||
+ }
|
||||
+ </style>
|
||||
+ </head>
|
||||
+ <body>
|
||||
+ <main>
|
||||
+ <p class="eyebrow">reuse.coulomb.social</p>
|
||||
+ <h1>REUSE federation endpoint</h1>
|
||||
+ <p>This is the Railiance REUSE capability federation service. It is an API endpoint for automated clients and operators; there is no browser login for this service.</p>
|
||||
+ <div class="actions">
|
||||
+ <a class="button" href="/v1/federated">Open federated index</a>
|
||||
+ </div>
|
||||
+ <nav class="links" aria-label="Service links">
|
||||
+ <a href="/health">Health check</a>
|
||||
+ <a href="/v1/federated">Federated capability index</a>
|
||||
+ <a href="https://forgejo.coulomb.social/coulomb/railiance-apps/src/branch/main/docs/reuse-surface-on-railiance01.md">Operator runbook</a>
|
||||
+ </nav>
|
||||
+ </main>
|
||||
+ </body>
|
||||
+ </html>
|
||||
+---
|
||||
+# Source: reuse-surface/templates/pvc.yaml
|
||||
+apiVersion: v1
|
||||
+kind: PersistentVolumeClaim
|
||||
+metadata:
|
||||
+ name: reuse-surface-data
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+spec:
|
||||
+ accessModes:
|
||||
+ - ReadWriteOnce
|
||||
+ resources:
|
||||
+ requests:
|
||||
+ storage: 1Gi
|
||||
+---
|
||||
+# Source: reuse-surface/templates/landing-service.yaml
|
||||
+apiVersion: v1
|
||||
+kind: Service
|
||||
+metadata:
|
||||
+ name: reuse-surface-landing
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+ app.kubernetes.io/component: landing
|
||||
+spec:
|
||||
+ type: ClusterIP
|
||||
+ selector:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/component: landing
|
||||
+ ports:
|
||||
+ - name: http
|
||||
+ port: 8080
|
||||
+ targetPort: http
|
||||
+ protocol: TCP
|
||||
+---
|
||||
+# Source: reuse-surface/templates/service.yaml
|
||||
+apiVersion: v1
|
||||
+kind: Service
|
||||
+metadata:
|
||||
+ name: reuse-surface
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+spec:
|
||||
+ type: ClusterIP
|
||||
+ selector:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/component: api
|
||||
+ ports:
|
||||
+ - name: http
|
||||
+ port: 8000
|
||||
+ targetPort: http
|
||||
+ protocol: TCP
|
||||
+---
|
||||
+# Source: reuse-surface/templates/deployment.yaml
|
||||
+apiVersion: apps/v1
|
||||
+kind: Deployment
|
||||
+metadata:
|
||||
+ name: reuse-surface
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+ app.kubernetes.io/component: api
|
||||
+spec:
|
||||
+ replicas: 1
|
||||
+ selector:
|
||||
+ matchLabels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ strategy:
|
||||
+ type: RollingUpdate
|
||||
+ rollingUpdate:
|
||||
+ maxSurge: 1
|
||||
+ maxUnavailable: 0
|
||||
+ template:
|
||||
+ metadata:
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/component: api
|
||||
+ spec:
|
||||
+ enableServiceLinks: false
|
||||
+ securityContext:
|
||||
+ {}
|
||||
+ containers:
|
||||
+ - name: reuse-surface
|
||||
+ image: "forgejo.coulomb.social/coulomb/reuse-surface@sha256:2364b7e7859daccf9340a063654e2b09eed1bc27e0adf7b23cbb4b30135a7db0"
|
||||
+ imagePullPolicy: IfNotPresent
|
||||
+ command: ["reuse-surface", "serve"]
|
||||
+ securityContext:
|
||||
+ {}
|
||||
+ ports:
|
||||
+ - name: http
|
||||
+ containerPort: 8000
|
||||
+ protocol: TCP
|
||||
+ envFrom:
|
||||
+ - secretRef:
|
||||
+ name: "reuse-surface-env"
|
||||
+ env:
|
||||
+ - name: REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST
|
||||
+ value: "{\"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\"]}"
|
||||
+ - name: REUSE_SURFACE_LISTEN_HOST
|
||||
+ value: "0.0.0.0"
|
||||
+ - name: REUSE_SURFACE_LISTEN_PORT
|
||||
+ value: "8000"
|
||||
+ - name: REUSE_SURFACE_DB
|
||||
+ value: "/data/reuse.db"
|
||||
+ - name: REUSE_SURFACE_CACHE_DIR
|
||||
+ value: "/data/cache"
|
||||
+ volumeMounts:
|
||||
+ - name: data
|
||||
+ mountPath: /data
|
||||
+ readinessProbe:
|
||||
+ httpGet:
|
||||
+ path: /health
|
||||
+ port: 8000
|
||||
+ initialDelaySeconds: 10
|
||||
+ periodSeconds: 10
|
||||
+ timeoutSeconds: 5
|
||||
+ failureThreshold: 3
|
||||
+ livenessProbe:
|
||||
+ httpGet:
|
||||
+ path: /health
|
||||
+ port: 8000
|
||||
+ initialDelaySeconds: 15
|
||||
+ periodSeconds: 30
|
||||
+ timeoutSeconds: 5
|
||||
+ failureThreshold: 3
|
||||
+ resources:
|
||||
+ limits:
|
||||
+ cpu: 500m
|
||||
+ memory: 512Mi
|
||||
+ requests:
|
||||
+ cpu: 100m
|
||||
+ memory: 256Mi
|
||||
+ volumes:
|
||||
+ - name: data
|
||||
+ persistentVolumeClaim:
|
||||
+ claimName: reuse-surface-data
|
||||
+---
|
||||
+# Source: reuse-surface/templates/landing-deployment.yaml
|
||||
+apiVersion: apps/v1
|
||||
+kind: Deployment
|
||||
+metadata:
|
||||
+ name: reuse-surface-landing
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+ app.kubernetes.io/component: landing
|
||||
+spec:
|
||||
+ replicas: 1
|
||||
+ selector:
|
||||
+ matchLabels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/component: landing
|
||||
+ strategy:
|
||||
+ type: RollingUpdate
|
||||
+ rollingUpdate:
|
||||
+ maxSurge: 1
|
||||
+ maxUnavailable: 0
|
||||
+ template:
|
||||
+ metadata:
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/component: landing
|
||||
+ spec:
|
||||
+ enableServiceLinks: false
|
||||
+ containers:
|
||||
+ - name: landing
|
||||
+ image: "nginxinc/nginx-unprivileged:1.27-alpine"
|
||||
+ imagePullPolicy: IfNotPresent
|
||||
+ ports:
|
||||
+ - name: http
|
||||
+ containerPort: 8080
|
||||
+ protocol: TCP
|
||||
+ readinessProbe:
|
||||
+ httpGet:
|
||||
+ path: /
|
||||
+ port: http
|
||||
+ initialDelaySeconds: 3
|
||||
+ periodSeconds: 10
|
||||
+ timeoutSeconds: 3
|
||||
+ failureThreshold: 3
|
||||
+ livenessProbe:
|
||||
+ httpGet:
|
||||
+ path: /
|
||||
+ port: http
|
||||
+ initialDelaySeconds: 10
|
||||
+ periodSeconds: 30
|
||||
+ timeoutSeconds: 3
|
||||
+ failureThreshold: 3
|
||||
+ resources:
|
||||
+ limits:
|
||||
+ cpu: 50m
|
||||
+ memory: 64Mi
|
||||
+ requests:
|
||||
+ cpu: 10m
|
||||
+ memory: 32Mi
|
||||
+ volumeMounts:
|
||||
+ - name: landing-page
|
||||
+ mountPath: /usr/share/nginx/html/index.html
|
||||
+ subPath: index.html
|
||||
+ readOnly: true
|
||||
+ volumes:
|
||||
+ - name: landing-page
|
||||
+ configMap:
|
||||
+ name: reuse-surface-landing
|
||||
+---
|
||||
+# Source: reuse-surface/templates/ingress.yaml
|
||||
+apiVersion: networking.k8s.io/v1
|
||||
+kind: Ingress
|
||||
+metadata:
|
||||
+ name: reuse-surface
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+ annotations:
|
||||
+ cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
+ traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
+ traefik.ingress.kubernetes.io/router.tls: "true"
|
||||
+spec:
|
||||
+ ingressClassName: traefik
|
||||
+ tls:
|
||||
+ - hosts:
|
||||
+ - reuse.coulomb.social
|
||||
+ secretName: reuse-surface-tls
|
||||
+ rules:
|
||||
+ - host: reuse.coulomb.social
|
||||
+ http:
|
||||
+ paths:
|
||||
+ - path: /health
|
||||
+ pathType: Exact
|
||||
+ backend:
|
||||
+ service:
|
||||
+ name: reuse-surface
|
||||
+ port:
|
||||
+ number: 8000
|
||||
+ - path: /v1
|
||||
+ pathType: Prefix
|
||||
+ backend:
|
||||
+ service:
|
||||
+ name: reuse-surface
|
||||
+ port:
|
||||
+ number: 8000
|
||||
+---
|
||||
+# Source: reuse-surface/templates/landing-ingress.yaml
|
||||
+apiVersion: networking.k8s.io/v1
|
||||
+kind: Ingress
|
||||
+metadata:
|
||||
+ name: reuse-surface-landing
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+ annotations:
|
||||
+ traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
+ traefik.ingress.kubernetes.io/router.tls: "true"
|
||||
+ traefik.ingress.kubernetes.io/router.priority: "1"
|
||||
+spec:
|
||||
+ ingressClassName: traefik
|
||||
+ tls:
|
||||
+ - hosts:
|
||||
+ - reuse.coulomb.social
|
||||
+ secretName: reuse-surface-tls
|
||||
+ rules:
|
||||
+ - host: reuse.coulomb.social
|
||||
+ http:
|
||||
+ paths:
|
||||
+ - path: /
|
||||
+ pathType: Prefix
|
||||
+ backend:
|
||||
+ service:
|
||||
+ name: reuse-surface-landing
|
||||
+ port:
|
||||
+ number: 8080
|
||||
+---
|
||||
+# Source: reuse-surface/templates/redirect-ingress.yaml
|
||||
+apiVersion: networking.k8s.io/v1
|
||||
+kind: Ingress
|
||||
+metadata:
|
||||
+ name: reuse-surface-http-redirect
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+ annotations:
|
||||
+ traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
+ traefik.ingress.kubernetes.io/router.middlewares: "reuse-reuse-surface-redirect-https@kubernetescrd"
|
||||
+spec:
|
||||
+ ingressClassName: traefik
|
||||
+ rules:
|
||||
+ - host: reuse.coulomb.social
|
||||
+ http:
|
||||
+ paths:
|
||||
+ - path: /
|
||||
+ pathType: Prefix
|
||||
+ backend:
|
||||
+ service:
|
||||
+ name: reuse-surface
|
||||
+ port:
|
||||
+ number: 8000
|
||||
+---
|
||||
+# Source: reuse-surface/templates/redirect-middleware.yaml
|
||||
+apiVersion: traefik.io/v1alpha1
|
||||
+kind: Middleware
|
||||
+metadata:
|
||||
+ name: reuse-surface-redirect-https
|
||||
+ labels:
|
||||
+ app.kubernetes.io/name: reuse-surface
|
||||
+ app.kubernetes.io/instance: reuse
|
||||
+ app.kubernetes.io/managed-by: Helm
|
||||
+ app.kubernetes.io/version: "0.1.0"
|
||||
+ app.kubernetes.io/part-of: railiance-apps
|
||||
+ helm.sh/chart: reuse-surface-0.1.0
|
||||
+spec:
|
||||
+ redirectScheme:
|
||||
+ scheme: https
|
||||
+ permanent: true
|
||||
diff --git a/docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-preparation-receipt.json b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-preparation-receipt.json
|
||||
new file mode 100644
|
||||
index 0000000..c58f4b4
|
||||
--- /dev/null
|
||||
+++ b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-preparation-receipt.json
|
||||
@@ -0,0 +1,67 @@
|
||||
+{
|
||||
+ "proposal_id": "CUST81-APPS-PHASE-A-LOCAL-IMAGE-R1",
|
||||
+ "disposition": "approved",
|
||||
+ "approved_scope": "concrete proposal preparation and local render only; not publish or production deploy",
|
||||
+ "workitem": "RAPPS-WP-0017-T02",
|
||||
+ "release": "reuse",
|
||||
+ "namespace": "reuse",
|
||||
+ "deployment": "reuse-surface",
|
||||
+ "image_reference": "forgejo.coulomb.social/coulomb/reuse-surface@sha256:2364b7e7859daccf9340a063654e2b09eed1bc27e0adf7b23cbb4b30135a7db0",
|
||||
+ "registry_publication_verified": false,
|
||||
+ "phase_b_credential_delivery_included": false,
|
||||
+ "incremental_infrastructure_cost_eur": 0,
|
||||
+ "cost_basis": "existing node, same requests and replicas, same PVC, no new service or purchased capacity; build/registry execution cost not independently accounted",
|
||||
+ "credible_loss_bound_eur": null,
|
||||
+ "risk_basis": "qualitative supervised change: transient rollout or SQLite concurrent-access outage; RWO PVC single-node mounts need preflight; no customer production admitted; data recovery and exact atomic rollback required before execution",
|
||||
+ "autopilot_authority": false,
|
||||
+ "local_render_checks": "passed",
|
||||
+ "evidence": {
|
||||
+ "hardened-reader-local-image-r1.json": {
|
||||
+ "path": "/home/worsch/the-custodian/docs/assessments/netkingdom-2026-10-14/hardened-reader-local-image-r1.json",
|
||||
+ "sha256": "ed7c2516925d7f16b573a70b5e48d5656a4875e9eb94bcc8760a8bdcbe07f59c"
|
||||
+ },
|
||||
+ "live-authenticated-source-inventory-r1.json": {
|
||||
+ "path": "/home/worsch/the-custodian/docs/assessments/netkingdom-2026-10-14/live-authenticated-source-inventory-r1.json",
|
||||
+ "sha256": "ba669d6231c8c611191c7ad28f5914d6c47332032b23b0ea40a13f753e883073"
|
||||
+ },
|
||||
+ "reuse-release-runtime-metadata-r1.json": {
|
||||
+ "path": "/home/worsch/the-custodian/docs/assessments/netkingdom-2026-10-14/reuse-release-runtime-metadata-r1.json",
|
||||
+ "sha256": "5ec901cf41b9f52628ff636c23b5bbc4789df6a9118f5cff0ff8518b287357e9"
|
||||
+ },
|
||||
+ "reuse-release-owner-eso-metadata-r1.json": {
|
||||
+ "path": "/home/worsch/the-custodian/docs/assessments/netkingdom-2026-10-14/reuse-release-owner-eso-metadata-r1.json",
|
||||
+ "sha256": "ff9aa207ae081d27d86820747a993d4bbc290ba2c354eef72388233d6733adb3"
|
||||
+ }
|
||||
+ },
|
||||
+ "observed_runtime": {
|
||||
+ "node_ip": "92.205.62.239",
|
||||
+ "cpu_free_m": 440,
|
||||
+ "api_surge_cpu_m": 100,
|
||||
+ "api_surge_memory_mi": 256,
|
||||
+ "pvc": "reuse-surface-data",
|
||||
+ "pvc_access": "ReadWriteOnce",
|
||||
+ "pvc_capacity": "1Gi",
|
||||
+ "previous_image_digest": "forgejo.coulomb.social/coulomb/reuse-surface@sha256:2c1514cb3f5e1297ffeeac912ba36a70f8a2591588a5a4643bc58293e97132de",
|
||||
+ "authenticated_sources": 0
|
||||
+ },
|
||||
+ "gates": [
|
||||
+ "publish exact reviewed image and verify registry digest; local digest may require reviewed update if registry transforms manifest",
|
||||
+ "founder approval for exact phase A and later credential CCR/phase B",
|
||||
+ "recheck target headroom memory node/PVC mount scheduling and authenticated inventory immediately before apply",
|
||||
+ "bounded safe server dry-run/client diff and current release revision/rollback capture",
|
||||
+ "no ESO reader field during phase A; verify actual imageID health and63public baseline before phase B",
|
||||
+ "revoke/remove delivered reader before any downgrade to old vulnerable image"
|
||||
+ ],
|
||||
+ "render_command": [
|
||||
+ "helm",
|
||||
+ "template",
|
||||
+ "reuse",
|
||||
+ "charts/reuse-surface",
|
||||
+ "--namespace",
|
||||
+ "reuse",
|
||||
+ "-f",
|
||||
+ "helm/reuse-surface-values.yaml",
|
||||
+ "-f",
|
||||
+ "docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-values.proposed.yaml"
|
||||
+ ]
|
||||
+}
|
||||
diff --git a/docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-values.proposed.yaml b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-values.proposed.yaml
|
||||
new file mode 100644
|
||||
index 0000000..6e6f81e
|
||||
--- /dev/null
|
||||
+++ b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-values.proposed.yaml
|
||||
@@ -0,0 +1,21 @@
|
||||
+# PROPOSAL ONLY; digest is locally built, NOT published.
|
||||
+# Publish exact reviewed artifact and verify registry digest before any apply.
|
||||
+image:
|
||||
+ repository: forgejo.coulomb.social/coulomb/reuse-surface
|
||||
+ digest: sha256:2364b7e7859daccf9340a063654e2b09eed1bc27e0adf7b23cbb4b30135a7db0
|
||||
+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/phase-a-local-image-r1/manifest.json b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/manifest.json
|
||||
new file mode 100644
|
||||
index 0000000..15cc477
|
||||
--- /dev/null
|
||||
+++ b/docs/assessments/cust81-private-reader/phase-a-local-image-r1/manifest.json
|
||||
@@ -0,0 +1,12 @@
|
||||
+{
|
||||
+ "proposal_id": "CUST81-APPS-PHASE-A-LOCAL-IMAGE-R1",
|
||||
+ "reviewer_owner": "railiance-apps",
|
||||
+ "disposition": "approved",
|
||||
+ "approved_scope": "preparation only, local full-chart render, supervised founder review required",
|
||||
+ "files": {
|
||||
+ "docs/assessments/cust81-private-reader/phase-a-local-image-r1/apps-owner-release-review.md": "a74e96986798a727fc87c0d3c578601579778dfd8521796d0bb81df8451c751b",
|
||||
+ "docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-full-chart.proposed.yaml": "36c20c3e16757d3e888a3db02853032b33e791aa04a6055fe001121254345b81",
|
||||
+ "docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-preparation-receipt.json": "3282a17ae3724619e40dd1f34846d83b2297d9ae00030618dbd269e8e2fd7d39",
|
||||
+ "docs/assessments/cust81-private-reader/phase-a-local-image-r1/phase-a-values.proposed.yaml": "35284857ec987fc7a929f5c2eecdb44c7d3367f7835904692947de09918ab8f1"
|
||||
+ }
|
||||
+}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# PROPOSAL ONLY; digest is locally built, NOT published.
|
||||
# Publish exact reviewed artifact and verify registry digest before any apply.
|
||||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/reuse-surface
|
||||
digest: sha256:2364b7e7859daccf9340a063654e2b09eed1bc27e0adf7b23cbb4b30135a7db0
|
||||
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
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"proposal_id": "CUST81-APPS-PRIVATE-READER-RELEASE-R1",
|
||||
"status": "local_verified_live_blocked",
|
||||
"real_image_digest": null,
|
||||
"live_execution": false,
|
||||
"cost_estimate_eur": null,
|
||||
"risk_estimate_eur": null,
|
||||
"estimate_status": "live cost/loss bounds require release-specific runtime headroom, recovery and image evidence; not executable before supervisor-approved estimates",
|
||||
"paths": {
|
||||
"charts/reuse-surface/templates/_helpers.tpl": "sha256:789606a31ac8da6dfb7a5f6ace6a77269e3be3867d2e9a11e52b19aadf6977df",
|
||||
"charts/reuse-surface/templates/deployment.yaml": "sha256:2ec0be6d9aa24ed026b0c6629ab8ba003669eb0460d722fe413cd4934111540c",
|
||||
"charts/reuse-surface/values.schema.json": "sha256:ea73e027e4dcd832cc0bd48fc7ccfa29158153033ca02a8dc7b25b7df0d6c2b5",
|
||||
"charts/reuse-surface/values.yaml": "sha256:d1aeff71df0c53e4ecb3f4ebaac50ced7691b52c673fe9b49fbaeee6ca02c226",
|
||||
"docs/assessments/cust81-private-reader/apps-owner-review-r2.md": "sha256:a3a2f2db6f0a8461a0d8299825c842c8ce427f59c86238884609d463837b3b75",
|
||||
"docs/assessments/cust81-private-reader/local-verification-r2.json": "sha256:d723561845a05a76be9554596011c267fc67dd24953160f3bd7bd26a85c4812c",
|
||||
"docs/assessments/cust81-private-reader/private-reader-values.r1.yaml": "sha256:e02a319aca9c4860cdb8338009e60af6723bdb1fc17a591db0824273206eff83",
|
||||
"docs/assessments/cust81-private-reader/reuse-surface-runtime-externalsecret.r1.yaml": "sha256:adfb34c0ee4d01bc602f57cd2320f1658465fb8f8660978828fffa05a5b604b5",
|
||||
"docs/assessments/cust81-private-reader/runtime-auth-source-allowlist-r1.json": "sha256:e1948c537e206b30fc72b9e4732a3f600d92e131813e6f7ecfd4bfbb18c27286",
|
||||
"docs/assessments/cust81-private-reader/supervision-preparation-r1.json": "sha256:232f195026d704164b5973b5098002205445ff3ed6b0d2dd0c4a3c92c6ad9ca5",
|
||||
"docs/assessments/cust81-private-reader/verify_preparation.py": "sha256:c07921ea3fcd7c646aa6f28f34f7cdcb552e893341fe53dc7102ee376541d04d",
|
||||
"scripts/reuse_authenticated_source_inventory.py": "sha256:42eed5513db090d338daec39258b89a4ce2e9369d175c3c8312904ed68867ee1",
|
||||
"workplans/RAPPS-WP-0017-reuse-private-reader-release.md": "sha256:3a114a461647b46f3cc8e0ff9aa16b69aed0429cbc1578edf9b0fed5e220cc55"
|
||||
},
|
||||
"chart_patch_sha256": "39ebaa7f4050f9204fe8ee38364fbbce874903447ac45ccd408cf434aa6e4a73",
|
||||
"revision": 2,
|
||||
"refinement_or_rescue": true,
|
||||
"original_revision_preserved": "root owner-assembly/apps-r1 archive",
|
||||
"correction": "pod SQL native registration url projection plus exact SQLite readonly fixture, safe legacy routes and untrusted successful output refusal"
|
||||
}
|
||||
|
|
@ -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"]}
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"proposal_id": "CUST81-APPS-PRIVATE-READER-RELEASE-R1",
|
||||
"owner": "railiance-apps",
|
||||
"review_revision": 3,
|
||||
"disposition": "approved",
|
||||
"approved_scope": "ordinary source-only standard digest representation correction; no live runtime change",
|
||||
"refinement_or_rescue": true,
|
||||
"original_manifest_sha256": "45d467c2bb48462a388f5df4ba5188492d406bdddbddfbf3487bd2077486dec8",
|
||||
"qualified_manifest_sha256": "324757f27a36090e34101adf9a68feb8f19530463303e53fec46abe2092943b8",
|
||||
"source_file_digests_unchanged": true,
|
||||
"scanner_rule": "generic-api-key",
|
||||
"affected_field": "paths[docs/assessments/cust81-private-reader/reuse-surface-runtime-externalsecret.r1.yaml]",
|
||||
"scanner_version": "8.30.1",
|
||||
"pinned_scanner_sha256": "88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509",
|
||||
"original_scanner_exit": 20,
|
||||
"candidate_scanner_exit": 0,
|
||||
"mechanism": "standard sha256-qualified metadata identifier; unchanged scanner/config, no ignore/exception/bypass",
|
||||
"backup_ref": "custody/cust81-apps-unpublished-r2",
|
||||
"original_commits": [
|
||||
"4e8e0f5",
|
||||
"6a8a54d"
|
||||
],
|
||||
"live_execution_approved": false
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
94
docs/assessments/cust81-private-reader/verify_preparation.py
Normal file
94
docs/assessments/cust81-private-reader/verify_preparation.py
Normal file
|
|
@ -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'])}))
|
||||
62
scripts/reuse_authenticated_source_inventory.py
Normal file
62
scripts/reuse_authenticated_source_inventory.py
Normal file
|
|
@ -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())
|
||||
57
workplans/RAPPS-WP-0017-reuse-private-reader-release.md
Normal file
57
workplans/RAPPS-WP-0017-reuse-private-reader-release.md
Normal file
|
|
@ -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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue