Bind policy nexus release 2 for production
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

This commit is contained in:
tegwick 2026-08-18 13:59:28 +02:00
parent 234cdfa4bb
commit 7cfcf8b5d1
4 changed files with 34 additions and 12 deletions

View file

@ -45,6 +45,8 @@ POLICY_NEXUS_TARGET ?= railiance01
POLICY_NEXUS_IMAGE_REPOSITORY ?= $(shell python3 -c 'import json; print(json.load(open("$(POLICY_NEXUS_BINDING)"))["image_repository"])')
POLICY_NEXUS_IMAGE_DIGEST ?= $(shell python3 -c 'import json; print(json.load(open("$(POLICY_NEXUS_BINDING)")).get("image_digest") or "")')
POLICY_NEXUS_PUBLICATION_DIGEST ?= $(shell python3 -c 'import json; print(json.load(open("$(POLICY_NEXUS_BINDING)")).get("publication_manifest_digest") or "")')
POLICY_NEXUS_SOURCE_INVENTORY_DIGEST ?= $(shell python3 -c 'import json; print(json.load(open("$(POLICY_NEXUS_BINDING)")).get("source_inventory_digest") or "")')
POLICY_NEXUS_SOURCE_SET_DIGEST ?= $(shell python3 -c 'import json; print(json.load(open("$(POLICY_NEXUS_BINDING)")).get("source_set_digest") or "")')
POLICY_NEXUS_REVISION ?=
COULOMBCORE_KUBECONFIG ?= $(HOME)/.kube/config
@ -598,19 +600,25 @@ policy-nexus-render: policy-nexus-check-binding ## Render the rApp chart with th
$(MAKE) -C "$(POLICY_NEXUS_RAPP)" render \
IMAGE_REPOSITORY="$(POLICY_NEXUS_IMAGE_REPOSITORY)" \
IMAGE_DIGEST="$(POLICY_NEXUS_IMAGE_DIGEST)" \
PUBLICATION_MANIFEST_DIGEST="$(POLICY_NEXUS_PUBLICATION_DIGEST)"
PUBLICATION_MANIFEST_DIGEST="$(POLICY_NEXUS_PUBLICATION_DIGEST)" \
SOURCE_INVENTORY_DIGEST="$(POLICY_NEXUS_SOURCE_INVENTORY_DIGEST)" \
SOURCE_SET_DIGEST="$(POLICY_NEXUS_SOURCE_SET_DIGEST)"
policy-nexus-server-dry-run: policy-nexus-check-binding ## Validate the approved policy package against Railiance01
$(MAKE) -C "$(POLICY_NEXUS_RAPP)" server-dry-run TARGET="$(POLICY_NEXUS_TARGET)" \
IMAGE_REPOSITORY="$(POLICY_NEXUS_IMAGE_REPOSITORY)" \
IMAGE_DIGEST="$(POLICY_NEXUS_IMAGE_DIGEST)" \
PUBLICATION_MANIFEST_DIGEST="$(POLICY_NEXUS_PUBLICATION_DIGEST)"
PUBLICATION_MANIFEST_DIGEST="$(POLICY_NEXUS_PUBLICATION_DIGEST)" \
SOURCE_INVENTORY_DIGEST="$(POLICY_NEXUS_SOURCE_INVENTORY_DIGEST)" \
SOURCE_SET_DIGEST="$(POLICY_NEXUS_SOURCE_SET_DIGEST)"
policy-nexus-deploy: policy-nexus-check-binding ## Deploy the approved policy release through its rApp package
$(MAKE) -C "$(POLICY_NEXUS_RAPP)" deploy TARGET="$(POLICY_NEXUS_TARGET)" \
IMAGE_REPOSITORY="$(POLICY_NEXUS_IMAGE_REPOSITORY)" \
IMAGE_DIGEST="$(POLICY_NEXUS_IMAGE_DIGEST)" \
PUBLICATION_MANIFEST_DIGEST="$(POLICY_NEXUS_PUBLICATION_DIGEST)"
PUBLICATION_MANIFEST_DIGEST="$(POLICY_NEXUS_PUBLICATION_DIGEST)" \
SOURCE_INVENTORY_DIGEST="$(POLICY_NEXUS_SOURCE_INVENTORY_DIGEST)" \
SOURCE_SET_DIGEST="$(POLICY_NEXUS_SOURCE_SET_DIGEST)"
policy-nexus-status: ## Show the policy-nexus Helm release state
$(MAKE) -C "$(POLICY_NEXUS_RAPP)" status TARGET="$(POLICY_NEXUS_TARGET)"
@ -619,7 +627,9 @@ policy-nexus-smoke: policy-nexus-check-binding ## Verify public content, TLS, an
$(MAKE) -C "$(POLICY_NEXUS_RAPP)" verify-live TARGET="$(POLICY_NEXUS_TARGET)" \
IMAGE_REPOSITORY="$(POLICY_NEXUS_IMAGE_REPOSITORY)" \
IMAGE_DIGEST="$(POLICY_NEXUS_IMAGE_DIGEST)" \
PUBLICATION_MANIFEST_DIGEST="$(POLICY_NEXUS_PUBLICATION_DIGEST)"
PUBLICATION_MANIFEST_DIGEST="$(POLICY_NEXUS_PUBLICATION_DIGEST)" \
SOURCE_INVENTORY_DIGEST="$(POLICY_NEXUS_SOURCE_INVENTORY_DIGEST)" \
SOURCE_SET_DIGEST="$(POLICY_NEXUS_SOURCE_SET_DIGEST)"
policy-nexus-rollback: ## Roll back to a named previous Helm revision
@test -n "$(POLICY_NEXUS_REVISION)" || { echo "POLICY_NEXUS_REVISION is required" >&2; exit 2; }

View file

@ -9,7 +9,9 @@
"release": "policy-nexus",
"hostname": "policy.coulomb.social",
"image_repository": "forgejo.coulomb.social/coulomb/policy-nexus",
"image_digest": "sha256:23318442d1b3a5bdced54f0b407fa5b32834020b80c60d72dea04c03bfbf51e7",
"publication_manifest_digest": "1d8ae5cd683e385d82d29a78729948f7be95d902401a5fbdcfb5e8230cdbfee6",
"image_digest": "sha256:0d4786096ef557c3edb12da34a15ad28c6fdf5ccc6d204ffa0d9122cc421cf95",
"publication_manifest_digest": "f8c4d52fca28c3ce0925f9295b8cd6d27714761fe7b55a48e7f53b2cbae5ad43",
"source_inventory_digest": "6635743cdc73e182373a3e050cc6548ba3daecbe8daa3a0dd778013f1590ce00",
"source_set_digest": "dfb7fbc15f3da6656807abf305857345209eecbc3ff6c05cb43b0b54b9f94163",
"residual_risk_owner": "the-custodian"
}

View file

@ -9,17 +9,21 @@ the chart.
## Binding a release
The source-controlled binding is
`bindings/policy-nexus-production.json`. Before deployment, replace both null
values and set `status` to `release-approved`:
`bindings/policy-nexus-production.json`. Before deployment, record all four
candidate identities and set `status` to `release-approved`:
- `image_digest`: the registry-resolved `sha256:...` digest of the image
published by `policy-nexus`;
- `publication_manifest_digest`: the 64-hex SHA-256 printed by the release
verifier for the exact `publication-manifest.json` in that image.
- `source_inventory_digest`: the 64-hex SHA-256 of the exact
`source-inventory.json` in that image;
- `source_set_digest`: the deterministic 64-hex digest of every upstream
repository revision audited for that candidate.
Tags are not accepted as production identity. The image digest and publication
digest must be reviewed in the same change; this binds runtime bytes to policy
source provenance without making this repository a second policy authority.
Tags are not accepted as production identity. All four identities must be
reviewed in the same change; this binds runtime bytes to policy source
provenance without making this repository a second policy authority.
## Preflight and deployment
@ -51,6 +55,6 @@ make policy-nexus-rollback POLICY_NEXUS_REVISION=<revision>
make policy-nexus-smoke
```
After an emergency rollback, restore the binding file to the two immutable
After an emergency rollback, restore the binding file to the four immutable
identities actually serving and capture the smoke output. The package promises
restart recovery on the single-node reef, not multi-node high availability.

View file

@ -25,6 +25,12 @@ def main() -> int:
r"[a-f0-9]{64}", binding.get("publication_manifest_digest") or ""
):
parser.error("binding publication_manifest_digest must be 64 lowercase hex")
if not re.fullmatch(
r"[a-f0-9]{64}", binding.get("source_inventory_digest") or ""
):
parser.error("binding source_inventory_digest must be 64 lowercase hex")
if not re.fullmatch(r"[a-f0-9]{64}", binding.get("source_set_digest") or ""):
parser.error("binding source_set_digest must be 64 lowercase hex")
if binding.get("hostname") != "policy.coulomb.social":
parser.error("binding hostname must be policy.coulomb.social")