Retain exact Policy Nexus publication proposal and rollback
This commit is contained in:
parent
dbf62aef47
commit
dc585ab5b2
35 changed files with 1549 additions and 0 deletions
152
docs/changes/CUST-WP-0079/policy-publication-r1/PLAN.md
Normal file
152
docs/changes/CUST-WP-0079/policy-publication-r1/PLAN.md
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
# POLICY-PUB-20261019-BUILD-MODE-GUARDRAIL-R1
|
||||
|
||||
Status: prepared, **not approved or executed**. Proposed founder batch: publish
|
||||
one already-accepted canon guardrail through the existing policy host. Receipt
|
||||
and source artifacts belong to this same proposal; refinements are not new
|
||||
successful trials. The supervisor must bind the final packet digest and real
|
||||
approval reference before execution. No old approval is reused.
|
||||
|
||||
## Exact intended change
|
||||
|
||||
Image `forgejo.coulomb.social/coulomb/policy-nexus@sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1`.
|
||||
Paired publication `8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e`;
|
||||
inventory `e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd`;
|
||||
source set `b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682`;
|
||||
raw lock `c150c6c0745441b4b69884ecc6cf55e97db26080fcf4c2224775b1f755580529`.
|
||||
Source policy commit `9fabcce1cb4c83165bcaba8be58d76788b4d87a1`.
|
||||
|
||||
74 documents replace73; exactly `canon-build-mode-change-authorization` is
|
||||
added, with no existing document removal or source-digest change. Original local
|
||||
OCI artifact and readback are in `/tmp/custodian-policy-image-20261019`.
|
||||
|
||||
Source patches are prepared, not applied:
|
||||
|
||||
* `rapp-policy-nexus.patch`: `bindings/reef-railiance.yaml` pins the proposed
|
||||
artifact and marks its release proposed. Existing reef production admission
|
||||
remains the environment classification, not approval of this release.
|
||||
* `railiance-apps.patch`: production binding plus production/candidate values
|
||||
carry the same four deployment pins. The binding explicitly clears previous
|
||||
approval date/reference and live-verification claims and says release-proposed.
|
||||
|
||||
The binding checker correctly refuses this unapproved candidate. After the
|
||||
founder approves this exact packet, the supervisor records actual approval
|
||||
date/reference and sets release-approved in both release metadata records;
|
||||
no image/source/content field may change. This clerical metadata completion is
|
||||
part of the approved action, not permission to choose another artifact. Native
|
||||
verification fields remain unset until evidence exists.
|
||||
|
||||
## Verified baseline and drift
|
||||
|
||||
`live-observation.json` binds railiance01 SSH alias, expected node IP
|
||||
92.205.62.239, host machine-ID digest and UTC capture. It reads only selected
|
||||
image/release fields plus readiness and Helm metadata. Output contains equality
|
||||
predicates, not raw annotations, Secrets or errors.
|
||||
|
||||
Observed: Helm revision9 deployed, replicas1/ready1; image and three deployment
|
||||
release digests equal the known rollback `4e0db6...99d06` and apps production
|
||||
binding. The live public manifest matches its approved73-document release.
|
||||
|
||||
Important source drift: `rapp-policy-nexus/bindings/reef-railiance.yaml` still
|
||||
contains historical `23df0ab3...3cea` pins, while apps and live agree on4e0db6.
|
||||
The proposed rApp patch reconciles that stale source as part of the new release.
|
||||
Never reverse it blindly as a runtime rollback. `rollback-rapp-binding.yaml`
|
||||
and the rollback patches target verified4e0db6, retaining its actual existing
|
||||
approval reference from apps, not stale23df0ab3.
|
||||
|
||||
`source-pins.json` records exact owner heads and original/changed file hashes.
|
||||
Both patches pass `git apply --check`; neither owner checkout was edited.
|
||||
|
||||
## Render and server verification
|
||||
|
||||
`candidate-rendered.yaml`, `rollback-rendered.yaml`, `rendered.diff` use the
|
||||
unchanged owner Helm chart. Nine resources render. Exactly seven fields differ,
|
||||
all in Deployment/policy-nexus: container image and three release digest fields
|
||||
on Deployment metadata and pod-template metadata. No replica, resource, service,
|
||||
ingress, TLS, NetworkPolicy, service account or access-policy changes.
|
||||
|
||||
`server-dry-run.json`: all nine exact candidate resources passed
|
||||
`kubectl apply --dry-run=server --validate=true -f - -o name` on railiance01,
|
||||
with no stderr and no persisted change. Raw errors are suppressed by the retained
|
||||
recipe. This does not prove image pull availability or Helm upgrade success.
|
||||
Owner `make check` passed9 packaging tests plus Helm lint; both checkouts pass
|
||||
`git diff --check`. Registry candidate availability remains pending because
|
||||
the exact OCI image has not been uploaded.
|
||||
|
||||
Current headroom observation: CPU requests3605m (90%), memory9856Mi (61%).
|
||||
The rollout asks for one additional10m CPU/32Mi request (limit100m/64Mi) because
|
||||
maxSurge1/maxUnavailable0. Recheck before execution: stale headroom evidence is
|
||||
not scheduling permission. Abort if spare requested capacity cannot fit this
|
||||
surge; do not alter another workload to create capacity under this proposal.
|
||||
|
||||
## Exact post-approval execution sequence
|
||||
|
||||
1. Supervisor records founder approval, exact proposal revision/digest, target,
|
||||
cost/risk and abort owner. Confirm source files/heads, chart content, live
|
||||
revision9/rollback pins and host identity still match. If any differ, stop
|
||||
and reconcile the proposal; do not silently substitute a newer candidate.
|
||||
2. Artifact owner transfers the retained OCI candidate to Forgejo through its
|
||||
scoped package-write route, preserving the manifest digest; no :main update
|
||||
or fresh rebuild is required. Verify remote manifest and image release files
|
||||
match all five pins. A rebuilt/converted digest is a different candidate and
|
||||
stops this execution. No credential values enter the packet or logs.
|
||||
3. Apply the exact paired source patches to their owners, complete real approval
|
||||
metadata as above, run owner checks, and commit the production-tier source
|
||||
changes. If the proposed metadata has changed meanwhile, regenerate the
|
||||
reviewed patches rather than force-applying. Keep old approved evidence.
|
||||
4. From `/home/worsch/railiance-apps`, run existing owner targets:
|
||||
`make policy-nexus-check-binding`, `make policy-nexus-check-image`,
|
||||
`make policy-nexus-render`, then recheck exact rendered field diff and current
|
||||
headroom. Capture check-image errors privately and emit only bounded failure
|
||||
classifications; its generic helper can otherwise echo raw errors.
|
||||
5. Run `make policy-nexus-server-dry-run` (owner uses a nonpersistent default
|
||||
namespace probe), plus the retained exact production-namespace server probe
|
||||
if source/runtime preconditions changed. Require success before deployment.
|
||||
6. Run `make policy-nexus-deploy POLICY_NEXUS_TARGET=railiance01` once. Existing
|
||||
owner target packages chart0.2.0, copies it to the host, and uses Helm upgrade
|
||||
with `--atomic --wait --timeout 5m`; no ArgoCD claim or manual kubectl apply.
|
||||
7. Run `make policy-nexus-smoke` with the approved binding, keeping only bounded
|
||||
expected-pin outcomes; independently hash public publication/inventory/lock,
|
||||
require source-set equality, verify74 document metadata and the new guardrail
|
||||
bytes/expiry banner against the candidate, confirm previous73 source hashes
|
||||
unchanged, and confirm the deployed image/three release fields and1/1 ready.
|
||||
Retain new Helm revision and safe verification evidence after success only.
|
||||
|
||||
The transition gate is explicitly production-tier/direct-administer until
|
||||
2026-12-21, per owner `docs/change-gate.md`. The final live record needs
|
||||
`activation=APPROVED` and the real founder approval reference, not a fabricated
|
||||
approval in this preparation packet. ArgoCD does not currently own this release.
|
||||
|
||||
## Abort and rollback
|
||||
|
||||
Abort owner: `rapp-policy-nexus` for actuation/runtime, coordinated by
|
||||
`railiance-apps`; supervisor/residual-risk owner `the-custodian`. Stop before
|
||||
actuation on any source/host/pin/registry/headroom/dry-run mismatch.
|
||||
After actuation, stop on failed atomic upgrade, readiness timeout, incorrect
|
||||
public hash/content, TLS/redirect failure or degraded existing pages. Do not
|
||||
repeat an upgrade blindly.
|
||||
|
||||
Helm's atomic rollback is the first failure recovery. If explicit recovery is
|
||||
required, use the existing owner path:
|
||||
`make -C /home/worsch/railiance-apps policy-nexus-rollback POLICY_NEXUS_REVISION=9 POLICY_NEXUS_TARGET=railiance01`.
|
||||
This exact observed revision must still be the prechange approved release.
|
||||
Verify4e0db6 image and all paired values from `rollback-binding.json`, public
|
||||
73-document manifest and readiness. Reconcile owner source records to
|
||||
`rollback-rapp-binding.yaml` and `rollback-binding.json`; rollback patch context
|
||||
must account for newly recorded approval metadata (never force the preparation
|
||||
patch if metadata differs). Retain failure/recovery outcomes and new Helm
|
||||
revision; rollback can create a new revision carrying old content.
|
||||
|
||||
## Estimated bounds and limitations
|
||||
|
||||
Incremental infrastructure spend EUR0; no provider subscription, purchase or
|
||||
external model call. One local26.6MB OCI transfer; unchanged persistent resources.
|
||||
One upgrade <=5min plus, if needed, one rollback <=5min; allow15min attended
|
||||
verification/recovery. Public-content/change risk moderate, runtime risk low
|
||||
but nonzero on the already90%-requested node. No data migration, database,
|
||||
credential, network exposure or storage change. Supervisor must accept these
|
||||
estimates; they are not a cost guarantee.
|
||||
|
||||
Existing runtime package database/nginx config equality is retained in image
|
||||
evidence. No new vulnerability scan or native CI success is claimed. Source
|
||||
commit9fabcce fixes the observed CI failure locally;65 tests and full owner build
|
||||
passed. This packet is ready for approval review, not proof of public release.
|
||||
33
docs/changes/CUST-WP-0079/policy-publication-r1/SHA256SUMS
Normal file
33
docs/changes/CUST-WP-0079/policy-publication-r1/SHA256SUMS
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
6f8c7860b371460e1695027241d1d14b9ca5e46f7003ee92d4c717c26147740a PLAN.md
|
||||
ceb2451c3c236f196527718ee9f0148014aad4d66a15b77d8303c0df36848c04 candidate-binding.json
|
||||
a9de1adb22d83fa47a676e3685edf4fad578e3215db2db493ef4a8ca138dd36e candidate-candidate-values.yaml
|
||||
dfdbe7a570fe2910c67f9074050df10ddc560780cdfabe7bd0c2b4343329add8 candidate-rapp-binding.yaml
|
||||
62b369b913d610508fb135834e7cb166f62649f3d9e61eddbe02e8fca542a953 candidate-rendered.yaml
|
||||
a9de1adb22d83fa47a676e3685edf4fad578e3215db2db493ef4a8ca138dd36e candidate-values.yaml
|
||||
fbe2fb76ba284a98c31ed0c412e7425de88e89d1f22eb86bf0b0110782ec8158 chart/Chart.yaml
|
||||
39cf25665540a2a02f0b73962647cbfc3e95c92f4db38c4fcaa750fb272dab62 chart/templates/_helpers.tpl
|
||||
eb32277328c67a5e3f1e0581569f935b9ec2194003392d856ed05274c36d1f9f chart/templates/deployment.yaml
|
||||
b02907d7c7e0e13507fe33132032cac517012c142ed77c0fafe4d06d2eedf615 chart/templates/ingress.yaml
|
||||
f5ff4ea020635906f4fff9c11ceabdbccbda1f4383902878f6d1c44120423752 chart/templates/networkpolicy.yaml
|
||||
46cf8a2659d8cb35fe2f16cc4fa80dee3dfe97a8b37ad2b1ec10c13e1de3d371 chart/templates/service.yaml
|
||||
a107006a0ad1c702f65e4c4eff0ad45f2c5ab2f401f5532a3ca14a406a9540cc chart/templates/serviceaccount.yaml
|
||||
a53f7801a38451cf7d0da679a7fbe54666a7452e391326fa515e002bc970026d chart/values.yaml
|
||||
2a5ab9ae708ee922c467234243c60df73ed21ca1be9f3cc365ede23b7509b051 headroom-recipe.py
|
||||
9ad208bd65b644d1f41b2a1bbc269bed82ed6db50f20189c115a378187d73512 headroom.json
|
||||
e438c8e207cdce2afb2cdf64bb9ce481887db9f3274b1f8de8ae2652ea15110a live-observation.json
|
||||
4a6734aadabd0610cc8d1fb13338e3da88038ea4e047d866ebf38cb7fac0c88d observe_remote.py
|
||||
226d0225e11e1088cda2aee4c83c5ce31d0fe0215bd01a371b380c2e8c7f1033 pending-binding-check.json
|
||||
9c2ceb3db33317bb6c5e8c24ffb4f8f173a9e8e53926abccac98f09d48f41c15 railiance-apps-rollback.patch
|
||||
63dc49fd7d4149eb7764da974f6dbd46b341a87a191f5944763aa4b1684cb1dc railiance-apps.patch
|
||||
e20a28be6ef09fa1ae41c998a0caef1ece8a12d24741034f0898b5e536d50c9a rapp-policy-nexus-rollback.patch
|
||||
4f4d8cf8765a75f5c9d1dbfb3e3187b027e5e2e368d1f1022b76187a141a2d51 rapp-policy-nexus.patch
|
||||
cf6a13992ca364a08d326622b4853ecb501b8b410052665f02b196d871fec305 render-verification.json
|
||||
b00de95ba86eeb50fe939dca94287d740bf524e7916af3b1f5ef39edb63b318b rendered.diff
|
||||
65b8c1a339ed1e75cbf72d0f6ac474d72bad1be9c381ebbeea700c7a9455f33e rollback-binding.json
|
||||
08a4c10423cb4e7673529a555bdcd0c4a3620daaf7594e26cab21183ef9ffb82 rollback-rapp-binding.yaml
|
||||
df457588fea55d5c927d078e9231530c04ec7771a293cc644104e315db860187 rollback-rendered.yaml
|
||||
6e0f5a529b450f6b8f00f6fc59c50a7e5b652520f0a370b199a49cb416fac062 rollback-values.yaml
|
||||
cbdd40a12c9c6bf76f827fd1d788bb176c46abbd675ee6d4901bdfbadde67f31 server-dry-run-recipe.py
|
||||
6e8c468604606b8982e53197e0d888429d56459fcfb35d1ed00ade2be4986df0 server-dry-run.json
|
||||
fa622bfda8e40a45f451c9e8227fd348a76a177fa7ef01ccbe26e5b4a0eb5ef4 source-pins.json
|
||||
8090c96d2bb869a7568c779156ed364b412a2e8b3ed3ba6481121e3d4ee443c4 validation.json
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"schema_version": "policy-nexus-production-binding/v1",
|
||||
"status": "release-proposed",
|
||||
"approved_on": null,
|
||||
"rapp_repo": "rapp-policy-nexus",
|
||||
"reef": "reef-railiance",
|
||||
"rail": "rail-kubernetes",
|
||||
"namespace": "policy-nexus",
|
||||
"release": "policy-nexus",
|
||||
"hostname": "policy.coulomb.social",
|
||||
"image_repository": "forgejo.coulomb.social/coulomb/policy-nexus",
|
||||
"image_digest": "sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1",
|
||||
"publication_manifest_digest": "8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e",
|
||||
"source_inventory_digest": "e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd",
|
||||
"source_set_digest": "b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682",
|
||||
"residual_risk_owner": "the-custodian",
|
||||
"proposal_id": "POLICY-PUB-20261019-BUILD-MODE-GUARDRAIL-R1",
|
||||
"publication_source_revision": "9fabcce1cb4c83165bcaba8be58d76788b4d87a1",
|
||||
"source_lock_digest": "c150c6c0745441b4b69884ecc6cf55e97db26080fcf4c2224775b1f755580529",
|
||||
"approval_ref": null,
|
||||
"verified_helm_revision": null,
|
||||
"native_verification_ref": null
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
digest: sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1
|
||||
publicationManifestDigest: 8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e
|
||||
sourceInventoryDigest: e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd
|
||||
sourceSetDigest: b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
schema_version: rapp-binding/v1
|
||||
rapp_id: rapp-policy-nexus
|
||||
reef_id: reef-railiance
|
||||
rail_id: rail-kubernetes
|
||||
admission: production-approved
|
||||
approved_on: "2026-09-01"
|
||||
namespace: policy-nexus
|
||||
release: policy-nexus
|
||||
hostname: policy.coulomb.social
|
||||
cluster_issuer: letsencrypt-prod
|
||||
image_repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
image_digest: sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1
|
||||
publication_manifest_digest: 8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e
|
||||
source_inventory_digest: e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd
|
||||
source_set_digest: b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682
|
||||
residual_risk_owner: the-custodian
|
||||
release_status: proposed
|
||||
release_proposal_id: POLICY-PUB-20261019-BUILD-MODE-GUARDRAIL-R1
|
||||
release_approval_ref: null
|
||||
source_lock_digest: c150c6c0745441b4b69884ecc6cf55e97db26080fcf4c2224775b1f755580529
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
---
|
||||
# Source: policy-nexus/templates/networkpolicy.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: policy-nexus-default-deny
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
---
|
||||
# Source: policy-nexus/templates/networkpolicy.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: policy-nexus-traefik
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: traefik
|
||||
ports:
|
||||
- port: 8080
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: policy-nexus/templates/networkpolicy.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: policy-nexus-acme-solver
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
acme.cert-manager.io/http01-solver: "true"
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: traefik
|
||||
ports:
|
||||
- port: 8089
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: policy-nexus/templates/serviceaccount.yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: policy-nexus
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
automountServiceAccountToken: false
|
||||
---
|
||||
# Source: policy-nexus/templates/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: policy-nexus
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: policy-nexus/templates/deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: policy-nexus
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
annotations:
|
||||
policy.coulomb.social/publication-manifest-digest: "8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e"
|
||||
policy.coulomb.social/source-inventory-digest: "e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd"
|
||||
policy.coulomb.social/source-set-digest: "b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682"
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 0
|
||||
maxSurge: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
annotations:
|
||||
policy.coulomb.social/publication-manifest-digest: "8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e"
|
||||
policy.coulomb.social/source-inventory-digest: "e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd"
|
||||
policy.coulomb.social/source-set-digest: "b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682"
|
||||
spec:
|
||||
serviceAccountName: policy-nexus
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 101
|
||||
runAsGroup: 101
|
||||
fsGroup: 101
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: policy-nexus
|
||||
image: "forgejo.coulomb.social/coulomb/policy-nexus@sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
volumeMounts:
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
volumes:
|
||||
- name: tmp
|
||||
emptyDir:
|
||||
sizeLimit: 16Mi
|
||||
---
|
||||
# Source: policy-nexus/templates/ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: policy-nexus-http
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
traefik.ingress.kubernetes.io/router.middlewares: "policy-nexus-policy-nexus-https-redirect@kubernetescrd"
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: "policy.coulomb.social"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: policy-nexus
|
||||
port:
|
||||
name: http
|
||||
---
|
||||
# Source: policy-nexus/templates/ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: policy-nexus-https
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.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:
|
||||
- "policy.coulomb.social"
|
||||
secretName: policy-coulomb-social-tls
|
||||
rules:
|
||||
- host: "policy.coulomb.social"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: policy-nexus
|
||||
port:
|
||||
name: http
|
||||
---
|
||||
# Source: policy-nexus/templates/ingress.yaml
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: policy-nexus-https-redirect
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
digest: sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1
|
||||
publicationManifestDigest: 8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e
|
||||
sourceInventoryDigest: e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd
|
||||
sourceSetDigest: b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: v2
|
||||
name: policy-nexus
|
||||
description: Hardened public runtime for the immutable policy-nexus site artifact
|
||||
type: application
|
||||
version: 0.2.0
|
||||
appVersion: "0.2.0"
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
{{- define "policy-nexus.name" -}}
|
||||
policy-nexus
|
||||
{{- end }}
|
||||
|
||||
{{- define "policy-nexus.fullname" -}}
|
||||
{{- if .Release.Name }}{{ .Release.Name | trunc 63 | trimSuffix "-" }}{{ else }}policy-nexus{{ end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "policy-nexus.labels" -}}
|
||||
app.kubernetes.io/name: {{ include "policy-nexus.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "policy-nexus.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "policy-nexus.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "policy-nexus.image" -}}
|
||||
{{- if not (regexMatch "^sha256:[a-f0-9]{64}$" .Values.image.digest) -}}
|
||||
{{- fail "image.digest must be an immutable lowercase sha256:<64-hex> OCI digest" -}}
|
||||
{{- end -}}
|
||||
{{- printf "%s@%s" .Values.image.repository .Values.image.digest -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "policy-nexus.publicationDigest" -}}
|
||||
{{- if not (regexMatch "^[a-f0-9]{64}$" .Values.publicationManifestDigest) -}}
|
||||
{{- fail "publicationManifestDigest must be the lowercase 64-hex SHA-256 of publication-manifest.json" -}}
|
||||
{{- end -}}
|
||||
{{- .Values.publicationManifestDigest -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "policy-nexus.sourceInventoryDigest" -}}
|
||||
{{- if not (regexMatch "^[a-f0-9]{64}$" .Values.sourceInventoryDigest) -}}
|
||||
{{- fail "sourceInventoryDigest must be the lowercase 64-hex SHA-256 of source-inventory.json" -}}
|
||||
{{- end -}}
|
||||
{{- .Values.sourceInventoryDigest -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "policy-nexus.sourceSetDigest" -}}
|
||||
{{- if not (regexMatch "^[a-f0-9]{64}$" .Values.sourceSetDigest) -}}
|
||||
{{- fail "sourceSetDigest must be the lowercase 64-hex digest recorded in source-inventory.json" -}}
|
||||
{{- end -}}
|
||||
{{- .Values.sourceSetDigest -}}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "policy-nexus.fullname" . }}
|
||||
labels:
|
||||
{{- include "policy-nexus.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
policy.coulomb.social/publication-manifest-digest: {{ include "policy-nexus.publicationDigest" . | quote }}
|
||||
policy.coulomb.social/source-inventory-digest: {{ include "policy-nexus.sourceInventoryDigest" . | quote }}
|
||||
policy.coulomb.social/source-set-digest: {{ include "policy-nexus.sourceSetDigest" . | quote }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
revisionHistoryLimit: 10
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 0
|
||||
maxSurge: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "policy-nexus.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "policy-nexus.selectorLabels" . | nindent 8 }}
|
||||
annotations:
|
||||
policy.coulomb.social/publication-manifest-digest: {{ include "policy-nexus.publicationDigest" . | quote }}
|
||||
policy.coulomb.social/source-inventory-digest: {{ include "policy-nexus.sourceInventoryDigest" . | quote }}
|
||||
policy.coulomb.social/source-set-digest: {{ include "policy-nexus.sourceSetDigest" . | quote }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "policy-nexus.fullname" . }}
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 101
|
||||
runAsGroup: 101
|
||||
fsGroup: 101
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: policy-nexus
|
||||
image: {{ include "policy-nexus.image" . | quote }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
volumes:
|
||||
- name: tmp
|
||||
emptyDir:
|
||||
sizeLimit: 16Mi
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: {{ include "policy-nexus.fullname" . }}-https-redirect
|
||||
labels:
|
||||
{{- include "policy-nexus.labels" . | nindent 4 }}
|
||||
spec:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "policy-nexus.fullname" . }}-http
|
||||
labels:
|
||||
{{- include "policy-nexus.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
traefik.ingress.kubernetes.io/router.middlewares: {{ printf "%s-%s-https-redirect@kubernetescrd" .Release.Namespace (include "policy-nexus.fullname" .) | quote }}
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: {{ .Values.site.hostname | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "policy-nexus.fullname" . }}
|
||||
port:
|
||||
name: http
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "policy-nexus.fullname" . }}-https
|
||||
labels:
|
||||
{{- include "policy-nexus.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: {{ .Values.tls.clusterIssuer | quote }}
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.site.hostname | quote }}
|
||||
secretName: {{ .Values.tls.secretName }}
|
||||
rules:
|
||||
- host: {{ .Values.site.hostname | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "policy-nexus.fullname" . }}
|
||||
port:
|
||||
name: http
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: {{ include "policy-nexus.fullname" . }}-default-deny
|
||||
labels:
|
||||
{{- include "policy-nexus.labels" . | nindent 4 }}
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: {{ include "policy-nexus.fullname" . }}-traefik
|
||||
labels:
|
||||
{{- include "policy-nexus.labels" . | nindent 4 }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
{{- include "policy-nexus.selectorLabels" . | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: traefik
|
||||
ports:
|
||||
- port: 8080
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: {{ include "policy-nexus.fullname" . }}-acme-solver
|
||||
labels:
|
||||
{{- include "policy-nexus.labels" . | nindent 4 }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
acme.cert-manager.io/http01-solver: "true"
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: traefik
|
||||
ports:
|
||||
- port: 8089
|
||||
protocol: TCP
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "policy-nexus.fullname" . }}
|
||||
labels:
|
||||
{{- include "policy-nexus.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "policy-nexus.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "policy-nexus.fullname" . }}
|
||||
labels:
|
||||
{{- include "policy-nexus.labels" . | nindent 4 }}
|
||||
automountServiceAccountToken: false
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
publicationManifestDigest: ""
|
||||
sourceInventoryDigest: ""
|
||||
sourceSetDigest: ""
|
||||
|
||||
site:
|
||||
hostname: policy.coulomb.social
|
||||
|
||||
tls:
|
||||
clusterIssuer: letsencrypt-prod
|
||||
secretName: policy-coulomb-social-tls
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
||||
|
||||
podAnnotations: {}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import subprocess,json,os,re,datetime
|
||||
env=dict(os.environ,KUBECONFIG='/etc/rancher/k3s/k3s.yaml')
|
||||
try:
|
||||
p=subprocess.run(['kubectl','describe','nodes'],capture_output=True,text=True,env=env,timeout=20)
|
||||
if p.returncode:raise ValueError()
|
||||
block=p.stdout.split('Allocated resources:',1)[1].split('Events:',1)[0]
|
||||
values={}
|
||||
for kind in ['cpu','memory']:
|
||||
m=re.search(r'^\s*'+kind+r'\s+(\S+)\s+\((\d+)%\)\s+(\S+)\s+\((\d+)%\)',block,re.M)
|
||||
if not m:raise ValueError()
|
||||
values[kind]={'requests':m[1],'requests_percent':int(m[2]),'limits':m[3],'limits_percent':int(m[4])}
|
||||
print(json.dumps({'capture_utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'allocated_resources':values,'raw_output_suppressed':True}))
|
||||
except Exception:print(json.dumps({'headroom_observed':False,'raw_errors_suppressed':True}))
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"capture_utc": "2026-10-19T13:19:05.475265+00:00",
|
||||
"allocated_resources": {
|
||||
"cpu": {
|
||||
"requests": "3605m",
|
||||
"requests_percent": 90,
|
||||
"limits": "37500m",
|
||||
"limits_percent": 937
|
||||
},
|
||||
"memory": {
|
||||
"requests": "9856Mi",
|
||||
"requests_percent": 61,
|
||||
"limits": "34562Mi",
|
||||
"limits_percent": 216
|
||||
}
|
||||
},
|
||||
"raw_output_suppressed": true
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"capture_utc": "2026-10-19T13:16:46.645924+00:00",
|
||||
"cluster_mutated": false,
|
||||
"expected_node_ip": "92.205.62.239",
|
||||
"expected_node_ip_present": true,
|
||||
"helm_revision": 9,
|
||||
"helm_status": "deployed",
|
||||
"image_matches_rollback": true,
|
||||
"machine_id_sha256": "fe7367a60951922122af7ba18ed2cde65c7e0a232bbedfb045cb575de2094c2f",
|
||||
"ready_replicas": 1,
|
||||
"release_pin_matches": {
|
||||
"publication-manifest-digest": true,
|
||||
"source-inventory-digest": true,
|
||||
"source-set-digest": true
|
||||
},
|
||||
"replicas": 1,
|
||||
"secret_values_observed": false,
|
||||
"ssh_alias": "railiance01"
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import datetime,hashlib,json,os,pathlib,re,subprocess
|
||||
EXPECTED={
|
||||
'image':'forgejo.coulomb.social/coulomb/policy-nexus@sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06',
|
||||
'publication-manifest-digest':'ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a',
|
||||
'source-inventory-digest':'40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5',
|
||||
'source-set-digest':'15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256'}
|
||||
def run(args):
|
||||
p=subprocess.run(args,stdout=subprocess.PIPE,stderr=subprocess.PIPE,env=dict(os.environ,KUBECONFIG='/etc/rancher/k3s/k3s.yaml'),timeout=20)
|
||||
if p.returncode:raise ValueError('command_refused')
|
||||
return p.stdout.decode().strip()
|
||||
try:
|
||||
out={'capture_utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'ssh_alias':'railiance01','expected_node_ip':'92.205.62.239','secret_values_observed':False,'cluster_mutated':False}
|
||||
nodes=json.loads(run(['kubectl','get','nodes','-o','json']))
|
||||
out['expected_node_ip_present']=any(a.get('address')=='92.205.62.239' for n in nodes['items'] for a in n['status']['addresses'])
|
||||
if not out['expected_node_ip_present']:raise ValueError('target_mismatch')
|
||||
out['machine_id_sha256']=hashlib.sha256(pathlib.Path('/etc/machine-id').read_bytes()).hexdigest()
|
||||
base=['kubectl','-n','policy-nexus','get','deployment','policy-nexus','-o']
|
||||
actual=run(base+['jsonpath={.spec.template.spec.containers[0].image}'])
|
||||
out['image_matches_rollback']=actual==EXPECTED['image']
|
||||
out['release_pin_matches']={}
|
||||
for key in list(EXPECTED)[1:]:
|
||||
value=run(base+['jsonpath={.metadata.annotations.policy\\.coulomb\\.social/'+key+'}'])
|
||||
out['release_pin_matches'][key]=value==EXPECTED[key]
|
||||
for key,expr in [('replicas','.spec.replicas'),('ready_replicas','.status.readyReplicas')]:
|
||||
value=run(base+['jsonpath={'+expr+'}']);out[key]=int(value) if value.isdigit() else None
|
||||
releases=json.loads(run(['helm','list','--namespace','policy-nexus','--filter','^policy-nexus$','-o','json']))
|
||||
if len(releases)!=1:raise ValueError('release_count')
|
||||
r=releases[0];out['helm_revision']=int(r['revision']);out['helm_status']=r['status'] if r['status'] in ['deployed','failed','pending-upgrade','pending-rollback'] else 'other'
|
||||
print(json.dumps(out,sort_keys=True))
|
||||
except Exception:
|
||||
print(json.dumps({'observation_completed':False,'reason':'bounded_read_failed','raw_errors_suppressed':True}))
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"candidate_rejected_while_unapproved": true,
|
||||
"returncode": 2
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
--- a/bindings/policy-nexus-production.json
|
||||
+++ b/bindings/policy-nexus-production.json
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"schema_version": "policy-nexus-production-binding/v1",
|
||||
- "status": "release-proposed",
|
||||
- "approved_on": null,
|
||||
+ "status": "release-approved",
|
||||
+ "approved_on": "2026-10-11",
|
||||
"rapp_repo": "rapp-policy-nexus",
|
||||
"reef": "reef-railiance",
|
||||
"rail": "rail-kubernetes",
|
||||
@@ -9,15 +9,15 @@
|
||||
"release": "policy-nexus",
|
||||
"hostname": "policy.coulomb.social",
|
||||
"image_repository": "forgejo.coulomb.social/coulomb/policy-nexus",
|
||||
- "image_digest": "sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1",
|
||||
- "publication_manifest_digest": "8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e",
|
||||
- "source_inventory_digest": "e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd",
|
||||
- "source_set_digest": "b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682",
|
||||
+ "image_digest": "sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06",
|
||||
+ "publication_manifest_digest": "ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a",
|
||||
+ "source_inventory_digest": "40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5",
|
||||
+ "source_set_digest": "15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256",
|
||||
"residual_risk_owner": "the-custodian",
|
||||
- "proposal_id": "POLICY-PUB-20261019-BUILD-MODE-GUARDRAIL-R1",
|
||||
- "publication_source_revision": "9fabcce1cb4c83165bcaba8be58d76788b4d87a1",
|
||||
- "source_lock_digest": "c150c6c0745441b4b69884ecc6cf55e97db26080fcf4c2224775b1f755580529",
|
||||
- "approval_ref": null,
|
||||
- "verified_helm_revision": null,
|
||||
- "native_verification_ref": null
|
||||
+ "proposal_id": "POLICY-PUB-20261011-SECURITY-LAYER-V08-R1",
|
||||
+ "publication_source_revision": "b64a0c52ec1ea8d1efa99dd7f870e580d7c60df8",
|
||||
+ "source_lock_digest": "99c695f46a54ead4cfe8f560f3648bf4db19404fe198b156c740115c97d3ed40",
|
||||
+ "approval_ref": "informed-decision:infd-20261011-policy-nexus-hosting-r1@1; approval:52a3c479-2cb1-4074-abec-6a88117ad596",
|
||||
+ "verified_helm_revision": 9,
|
||||
+ "native_verification_ref": "rapp-policy-nexus/docs/evidence/2026-10-11-security-layer-v08-native-hosting/"
|
||||
}
|
||||
--- a/values/policy-nexus-production.yaml
|
||||
+++ b/values/policy-nexus-production.yaml
|
||||
@@ -1,6 +1,6 @@
|
||||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
- digest: sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1
|
||||
-publicationManifestDigest: 8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e
|
||||
-sourceInventoryDigest: e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd
|
||||
-sourceSetDigest: b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682
|
||||
+ digest: sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06
|
||||
+publicationManifestDigest: ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a
|
||||
+sourceInventoryDigest: 40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5
|
||||
+sourceSetDigest: 15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256
|
||||
--- a/values/policy-nexus-production-candidate.yaml
|
||||
+++ b/values/policy-nexus-production-candidate.yaml
|
||||
@@ -1,6 +1,6 @@
|
||||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
- digest: sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1
|
||||
-publicationManifestDigest: 8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e
|
||||
-sourceInventoryDigest: e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd
|
||||
-sourceSetDigest: b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682
|
||||
+ digest: sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06
|
||||
+publicationManifestDigest: ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a
|
||||
+sourceInventoryDigest: 40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5
|
||||
+sourceSetDigest: 15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
--- a/bindings/policy-nexus-production.json
|
||||
+++ b/bindings/policy-nexus-production.json
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"schema_version": "policy-nexus-production-binding/v1",
|
||||
- "status": "release-approved",
|
||||
- "approved_on": "2026-10-11",
|
||||
+ "status": "release-proposed",
|
||||
+ "approved_on": null,
|
||||
"rapp_repo": "rapp-policy-nexus",
|
||||
"reef": "reef-railiance",
|
||||
"rail": "rail-kubernetes",
|
||||
@@ -9,15 +9,15 @@
|
||||
"release": "policy-nexus",
|
||||
"hostname": "policy.coulomb.social",
|
||||
"image_repository": "forgejo.coulomb.social/coulomb/policy-nexus",
|
||||
- "image_digest": "sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06",
|
||||
- "publication_manifest_digest": "ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a",
|
||||
- "source_inventory_digest": "40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5",
|
||||
- "source_set_digest": "15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256",
|
||||
+ "image_digest": "sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1",
|
||||
+ "publication_manifest_digest": "8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e",
|
||||
+ "source_inventory_digest": "e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd",
|
||||
+ "source_set_digest": "b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682",
|
||||
"residual_risk_owner": "the-custodian",
|
||||
- "proposal_id": "POLICY-PUB-20261011-SECURITY-LAYER-V08-R1",
|
||||
- "publication_source_revision": "b64a0c52ec1ea8d1efa99dd7f870e580d7c60df8",
|
||||
- "source_lock_digest": "99c695f46a54ead4cfe8f560f3648bf4db19404fe198b156c740115c97d3ed40",
|
||||
- "approval_ref": "informed-decision:infd-20261011-policy-nexus-hosting-r1@1; approval:52a3c479-2cb1-4074-abec-6a88117ad596",
|
||||
- "verified_helm_revision": 9,
|
||||
- "native_verification_ref": "rapp-policy-nexus/docs/evidence/2026-10-11-security-layer-v08-native-hosting/"
|
||||
+ "proposal_id": "POLICY-PUB-20261019-BUILD-MODE-GUARDRAIL-R1",
|
||||
+ "publication_source_revision": "9fabcce1cb4c83165bcaba8be58d76788b4d87a1",
|
||||
+ "source_lock_digest": "c150c6c0745441b4b69884ecc6cf55e97db26080fcf4c2224775b1f755580529",
|
||||
+ "approval_ref": null,
|
||||
+ "verified_helm_revision": null,
|
||||
+ "native_verification_ref": null
|
||||
}
|
||||
--- a/values/policy-nexus-production.yaml
|
||||
+++ b/values/policy-nexus-production.yaml
|
||||
@@ -1,6 +1,6 @@
|
||||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
- digest: sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06
|
||||
-publicationManifestDigest: ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a
|
||||
-sourceInventoryDigest: 40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5
|
||||
-sourceSetDigest: 15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256
|
||||
+ digest: sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1
|
||||
+publicationManifestDigest: 8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e
|
||||
+sourceInventoryDigest: e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd
|
||||
+sourceSetDigest: b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682
|
||||
--- a/values/policy-nexus-production-candidate.yaml
|
||||
+++ b/values/policy-nexus-production-candidate.yaml
|
||||
@@ -1,6 +1,6 @@
|
||||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
- digest: sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06
|
||||
-publicationManifestDigest: ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a
|
||||
-sourceInventoryDigest: 40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5
|
||||
-sourceSetDigest: 15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256
|
||||
+ digest: sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1
|
||||
+publicationManifestDigest: 8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e
|
||||
+sourceInventoryDigest: e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd
|
||||
+sourceSetDigest: b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
--- a/bindings/reef-railiance.yaml
|
||||
+++ b/bindings/reef-railiance.yaml
|
||||
@@ -9,12 +9,12 @@
|
||||
hostname: policy.coulomb.social
|
||||
cluster_issuer: letsencrypt-prod
|
||||
image_repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
-image_digest: sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1
|
||||
-publication_manifest_digest: 8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e
|
||||
-source_inventory_digest: e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd
|
||||
-source_set_digest: b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682
|
||||
+image_digest: sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06
|
||||
+publication_manifest_digest: ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a
|
||||
+source_inventory_digest: 40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5
|
||||
+source_set_digest: 15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256
|
||||
residual_risk_owner: the-custodian
|
||||
-release_status: proposed
|
||||
-release_proposal_id: POLICY-PUB-20261019-BUILD-MODE-GUARDRAIL-R1
|
||||
-release_approval_ref: null
|
||||
-source_lock_digest: c150c6c0745441b4b69884ecc6cf55e97db26080fcf4c2224775b1f755580529
|
||||
+release_status: release-approved
|
||||
+release_proposal_id: POLICY-PUB-20261011-SECURITY-LAYER-V08-R1
|
||||
+release_approval_ref: "informed-decision:infd-20261011-policy-nexus-hosting-r1@1; approval:52a3c479-2cb1-4074-abec-6a88117ad596"
|
||||
+source_lock_digest: 99c695f46a54ead4cfe8f560f3648bf4db19404fe198b156c740115c97d3ed40
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
--- a/bindings/reef-railiance.yaml
|
||||
+++ b/bindings/reef-railiance.yaml
|
||||
@@ -9,8 +9,12 @@
|
||||
hostname: policy.coulomb.social
|
||||
cluster_issuer: letsencrypt-prod
|
||||
image_repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
-image_digest: sha256:23df0ab3dc80d2a92b8058eeb572c222ceb05d17434f173a24142b2450ab3cea
|
||||
-publication_manifest_digest: 09f9f7edcc46e31d4b3f73b62d16fdf17808ae1f893f312242b7b9e2037319e0
|
||||
-source_inventory_digest: 9658803bc79d19cef1a9c842d1a8c161f1998d59ce6e4bc4df3c88aba2f4c9c4
|
||||
-source_set_digest: 03f04902a3559099433795453829d75470aa1490dd243b42e7703b6eab87772f
|
||||
+image_digest: sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1
|
||||
+publication_manifest_digest: 8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e
|
||||
+source_inventory_digest: e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd
|
||||
+source_set_digest: b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682
|
||||
residual_risk_owner: the-custodian
|
||||
+release_status: proposed
|
||||
+release_proposal_id: POLICY-PUB-20261019-BUILD-MODE-GUARDRAIL-R1
|
||||
+release_approval_ref: null
|
||||
+source_lock_digest: c150c6c0745441b4b69884ecc6cf55e97db26080fcf4c2224775b1f755580529
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"rendered_resources": 9,
|
||||
"changed_paths": [
|
||||
"Deployment/policy-nexus/metadata/annotations/policy.coulomb.social/publication-manifest-digest",
|
||||
"Deployment/policy-nexus/metadata/annotations/policy.coulomb.social/source-inventory-digest",
|
||||
"Deployment/policy-nexus/metadata/annotations/policy.coulomb.social/source-set-digest",
|
||||
"Deployment/policy-nexus/spec/template/metadata/annotations/policy.coulomb.social/publication-manifest-digest",
|
||||
"Deployment/policy-nexus/spec/template/metadata/annotations/policy.coulomb.social/source-inventory-digest",
|
||||
"Deployment/policy-nexus/spec/template/metadata/annotations/policy.coulomb.social/source-set-digest",
|
||||
"Deployment/policy-nexus/spec/template/spec/containers/0/image"
|
||||
],
|
||||
"other_resources_unchanged": true,
|
||||
"replicas_changed": false,
|
||||
"resource_requests_changed": false,
|
||||
"network_exposure_changed": false,
|
||||
"rbac_changed": false,
|
||||
"approval_pending": true
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
--- rollback-rendered.yaml
|
||||
+++ candidate-rendered.yaml
|
||||
@@ -122,9 +122,9 @@
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
annotations:
|
||||
- policy.coulomb.social/publication-manifest-digest: "ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a"
|
||||
- policy.coulomb.social/source-inventory-digest: "40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5"
|
||||
- policy.coulomb.social/source-set-digest: "15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256"
|
||||
+ policy.coulomb.social/publication-manifest-digest: "8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e"
|
||||
+ policy.coulomb.social/source-inventory-digest: "e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd"
|
||||
+ policy.coulomb.social/source-set-digest: "b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682"
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
@@ -143,9 +143,9 @@
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
annotations:
|
||||
- policy.coulomb.social/publication-manifest-digest: "ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a"
|
||||
- policy.coulomb.social/source-inventory-digest: "40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5"
|
||||
- policy.coulomb.social/source-set-digest: "15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256"
|
||||
+ policy.coulomb.social/publication-manifest-digest: "8c74b4e414f7760429600b7ba0b3627fcfe438417bfe6695f55acfa6905d352e"
|
||||
+ policy.coulomb.social/source-inventory-digest: "e84453b6b411a7d66d2b5efbf083cd0033441d6b12983326442933da87bf61fd"
|
||||
+ policy.coulomb.social/source-set-digest: "b00535063c56ede08f0a292b301a47add18bf70f81904bf3f434c8faa5ebe682"
|
||||
spec:
|
||||
serviceAccountName: policy-nexus
|
||||
automountServiceAccountToken: false
|
||||
@@ -159,7 +159,7 @@
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: policy-nexus
|
||||
- image: "forgejo.coulomb.social/coulomb/policy-nexus@sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06"
|
||||
+ image: "forgejo.coulomb.social/coulomb/policy-nexus@sha256:214b122c3d175563f114552fa1826dac9642433be019c736c3265d0a3ef379f1"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"schema_version": "policy-nexus-production-binding/v1",
|
||||
"status": "release-approved",
|
||||
"approved_on": "2026-10-11",
|
||||
"rapp_repo": "rapp-policy-nexus",
|
||||
"reef": "reef-railiance",
|
||||
"rail": "rail-kubernetes",
|
||||
"namespace": "policy-nexus",
|
||||
"release": "policy-nexus",
|
||||
"hostname": "policy.coulomb.social",
|
||||
"image_repository": "forgejo.coulomb.social/coulomb/policy-nexus",
|
||||
"image_digest": "sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06",
|
||||
"publication_manifest_digest": "ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a",
|
||||
"source_inventory_digest": "40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5",
|
||||
"source_set_digest": "15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256",
|
||||
"residual_risk_owner": "the-custodian",
|
||||
"proposal_id": "POLICY-PUB-20261011-SECURITY-LAYER-V08-R1",
|
||||
"publication_source_revision": "b64a0c52ec1ea8d1efa99dd7f870e580d7c60df8",
|
||||
"source_lock_digest": "99c695f46a54ead4cfe8f560f3648bf4db19404fe198b156c740115c97d3ed40",
|
||||
"approval_ref": "informed-decision:infd-20261011-policy-nexus-hosting-r1@1; approval:52a3c479-2cb1-4074-abec-6a88117ad596",
|
||||
"verified_helm_revision": 9,
|
||||
"native_verification_ref": "rapp-policy-nexus/docs/evidence/2026-10-11-security-layer-v08-native-hosting/"
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
schema_version: rapp-binding/v1
|
||||
rapp_id: rapp-policy-nexus
|
||||
reef_id: reef-railiance
|
||||
rail_id: rail-kubernetes
|
||||
admission: production-approved
|
||||
approved_on: "2026-09-01"
|
||||
namespace: policy-nexus
|
||||
release: policy-nexus
|
||||
hostname: policy.coulomb.social
|
||||
cluster_issuer: letsencrypt-prod
|
||||
image_repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
image_digest: sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06
|
||||
publication_manifest_digest: ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a
|
||||
source_inventory_digest: 40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5
|
||||
source_set_digest: 15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256
|
||||
residual_risk_owner: the-custodian
|
||||
release_status: release-approved
|
||||
release_proposal_id: POLICY-PUB-20261011-SECURITY-LAYER-V08-R1
|
||||
release_approval_ref: "informed-decision:infd-20261011-policy-nexus-hosting-r1@1; approval:52a3c479-2cb1-4074-abec-6a88117ad596"
|
||||
source_lock_digest: 99c695f46a54ead4cfe8f560f3648bf4db19404fe198b156c740115c97d3ed40
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
---
|
||||
# Source: policy-nexus/templates/networkpolicy.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: policy-nexus-default-deny
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
---
|
||||
# Source: policy-nexus/templates/networkpolicy.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: policy-nexus-traefik
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: traefik
|
||||
ports:
|
||||
- port: 8080
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: policy-nexus/templates/networkpolicy.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: policy-nexus-acme-solver
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
acme.cert-manager.io/http01-solver: "true"
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: traefik
|
||||
ports:
|
||||
- port: 8089
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: policy-nexus/templates/serviceaccount.yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: policy-nexus
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
automountServiceAccountToken: false
|
||||
---
|
||||
# Source: policy-nexus/templates/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: policy-nexus
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: policy-nexus/templates/deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: policy-nexus
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
annotations:
|
||||
policy.coulomb.social/publication-manifest-digest: "ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a"
|
||||
policy.coulomb.social/source-inventory-digest: "40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5"
|
||||
policy.coulomb.social/source-set-digest: "15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256"
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 0
|
||||
maxSurge: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
annotations:
|
||||
policy.coulomb.social/publication-manifest-digest: "ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a"
|
||||
policy.coulomb.social/source-inventory-digest: "40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5"
|
||||
policy.coulomb.social/source-set-digest: "15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256"
|
||||
spec:
|
||||
serviceAccountName: policy-nexus
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 101
|
||||
runAsGroup: 101
|
||||
fsGroup: 101
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: policy-nexus
|
||||
image: "forgejo.coulomb.social/coulomb/policy-nexus@sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
volumeMounts:
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
volumes:
|
||||
- name: tmp
|
||||
emptyDir:
|
||||
sizeLimit: 16Mi
|
||||
---
|
||||
# Source: policy-nexus/templates/ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: policy-nexus-http
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
traefik.ingress.kubernetes.io/router.middlewares: "policy-nexus-policy-nexus-https-redirect@kubernetescrd"
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: "policy.coulomb.social"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: policy-nexus
|
||||
port:
|
||||
name: http
|
||||
---
|
||||
# Source: policy-nexus/templates/ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: policy-nexus-https
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.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:
|
||||
- "policy.coulomb.social"
|
||||
secretName: policy-coulomb-social-tls
|
||||
rules:
|
||||
- host: "policy.coulomb.social"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: policy-nexus
|
||||
port:
|
||||
name: http
|
||||
---
|
||||
# Source: policy-nexus/templates/ingress.yaml
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: policy-nexus-https-redirect
|
||||
labels:
|
||||
app.kubernetes.io/name: policy-nexus
|
||||
app.kubernetes.io/instance: policy-nexus
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: "0.2.0"
|
||||
helm.sh/chart: policy-nexus-0.2.0
|
||||
spec:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/policy-nexus
|
||||
digest: sha256:4e0db6a57eb00f577159aa6ee10f910dd67b03fd0541c6ce849f5426fdb99d06
|
||||
publicationManifestDigest: ba53cc4900e6bb9ab8aa4bac4e58cb5fe7a03d656bafb3f9cb3d9c8ebff7843a
|
||||
sourceInventoryDigest: 40d9e8852fe4c9e75b71f371d0fdae38664b068e7498711b0ac5671d0f41efb5
|
||||
sourceSetDigest: 15bda2e332285afc862df8974cf29de403737df5073fa362adfc6d203cf2f256
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"capture_utc": "2026-10-19T13:18:34.372960+00:00",
|
||||
"returncode": 0,
|
||||
"server_dry_run_passed": true,
|
||||
"resource_names_match": true,
|
||||
"resource_count": 9,
|
||||
"stderr_present": false,
|
||||
"raw_errors_suppressed": true,
|
||||
"cluster_mutated": false
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"railiance-apps": {
|
||||
"head": "0e1d2b3cfe426d2404ec52fecbb6fd8ca6462288",
|
||||
"files": {
|
||||
"bindings/policy-nexus-production.json": {
|
||||
"before_sha256": "65b8c1a339ed1e75cbf72d0f6ac474d72bad1be9c381ebbeea700c7a9455f33e",
|
||||
"after_sha256": "ceb2451c3c236f196527718ee9f0148014aad4d66a15b77d8303c0df36848c04"
|
||||
},
|
||||
"values/policy-nexus-production.yaml": {
|
||||
"before_sha256": "6e0f5a529b450f6b8f00f6fc59c50a7e5b652520f0a370b199a49cb416fac062",
|
||||
"after_sha256": "a9de1adb22d83fa47a676e3685edf4fad578e3215db2db493ef4a8ca138dd36e"
|
||||
},
|
||||
"values/policy-nexus-production-candidate.yaml": {
|
||||
"before_sha256": "6e0f5a529b450f6b8f00f6fc59c50a7e5b652520f0a370b199a49cb416fac062",
|
||||
"after_sha256": "a9de1adb22d83fa47a676e3685edf4fad578e3215db2db493ef4a8ca138dd36e"
|
||||
}
|
||||
}
|
||||
},
|
||||
"rapp-policy-nexus": {
|
||||
"head": "333f5fa9acb9c169bef4ef84aca0258d43688e50",
|
||||
"files": {
|
||||
"bindings/reef-railiance.yaml": {
|
||||
"before_sha256": "237ce7297b0806f995247c6ae01d489213120afa89808067021817cce82f3e1e",
|
||||
"after_sha256": "dfdbe7a570fe2910c67f9074050df10ddc560780cdfabe7bd0c2b4343329add8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"capture_utc": "2026-10-19T13:21:47.091266+00:00",
|
||||
"owner_packaging_tests_passed": 9,
|
||||
"helm_lint_passed": true,
|
||||
"rendered_resources": 9,
|
||||
"expected_changed_fields": 7,
|
||||
"server_dry_run_passed": true,
|
||||
"both_patch_apply_checks_passed": true,
|
||||
"unapproved_binding_rejected": true,
|
||||
"owner_checkouts_clean": {
|
||||
"rapp-policy-nexus": true,
|
||||
"railiance-apps": true
|
||||
},
|
||||
"hosting_source_applied": false,
|
||||
"hosting_source_pushed": false,
|
||||
"cluster_mutated": false,
|
||||
"public_release": false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue