access-engine/docs/compact-sitting-v14-release-runbook.md
tegwick 58a12d258f FLEX-WP-0040-T07: compact-sitting v14 release candidate and founder runbook
Values (direct edit; not applied): sitting release -> CI image main-2de0f86
sha256:154726d25ba2ce88ef41551dcb3bb395557095eff19e767a29d0331fafec4776 and the
v14 policy path; access-engine twin regenerated for this pin only. The image's
policy directory is byte-identical to 2de0f86 and its package digest is
sha256:8911458f...0fde. Image in force per FLEX-WP-0034 rev 13 is 6c6dc263
(v13); rollback values are values/informed-decision-lifecycle-review.candidate.yaml.
Scan: the same four Go 1.26.7 stdlib HIGH CVEs as the image in force (founder
gate in the runbook). Runbook: docs/compact-sitting-v14-release-runbook.md,
coordinated with informed-decision's v14 pin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5502@bnt-lap001
Assistant-Session: 68b3b02f-5d0f-4e71-8421-796f62e50196
2026-11-01 11:26:26 +01:00

10 KiB

Runbook: release compact-sitting v14 to flex-auth-informed-decision-sitting

Date prepared: 2026-11-01 (owner: access-engine / flex-auth; nothing below has been run) Workplan: workplans/FLEX-WP-0040-bounded-execution-pdp-gate.md, FLEX-WP-0040-T07 Owner note: docs/compact-sitting-v14-present-existing.md ("Live steps") Approval: founder, 2026-11-01, relayed by the net-kingdom coordinator Runs: the founder, from an access-engine checkout at the commit carrying this file Evidence: docs/evidence/2026-11-01-compact-sitting-v14/release-candidate-checks.json

Coordinated with informed-decision (same window)

This release is one half of a pair. informed-decision pins the policy package it expects (policy object of its review runtime: deploy/lifecycle/service.candidate.json runtime.json and deploy/lifecycle/admission.candidate.json) and compares the policy_package / policy_version / policy_package_digest of every decision with that pin. A version or digest mismatch fails closed: from the moment this upgrade completes until the consumer pins v14, every review request is refused, and the reverse holds if the consumer moves first. Run both in one window, this release first, the consumer pin immediately after; roll both back together.

before (in force) after
package informed-decision.compact-sitting same
version v13 v14
package_digest sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873 sha256:8911458f36f1a60598aa19592a2d752a74dffe2617fd86238407ac87bc300fde

The consumer's approval_action context change (owner note, "Consumer change required") is needed only for service:nk-bind-executor present-existing requests. Without it those are refused with approval_action_not_admitted; requests for requester informed-decision are unaffected by v14.

Release candidate

Field Value
release / namespace flex-auth-informed-decision-sitting / flex-auth
chart charts/flex-auth (this checkout)
values values/informed-decision-sitting.yaml (edited directly; twin values/access-engine/informed-decision-sitting.yaml regenerated, not deployed)
image forgejo.coulomb.social/coulomb/flex-auth@sha256:154726d25ba2ce88ef41551dcb3bb395557095eff19e767a29d0331fafec4776
image tag / source main-2de0f86, OCI revision label 2de0f862f9875f344f090b633813239a33d63426 (CI .forgejo/workflows/image.yaml, push to main)
policy /opt/flex-auth/examples/informed-decision-present-existing-review/policy.md (file sha256 dcfae737…40141, package digest verified from the image)
registry unchanged path /opt/flex-auth/examples/informed-decision-lifecycle-review/registry.json (byte-identical to the present-existing copy)

Gate: image scan (founder decision)

Trivy (HIGH/CRITICAL) finds four Go stdlib 1.26.7 CVEs in both binaries of the candidate (CVE-2026-111943, CVE-2026-78667, CVE-2026-78669, CVE-2026-97031; fixed in Go 1.26.9 / 1.26.10). The image in force (6c6dc263) has the same four, so the candidate does not regress, but the earlier release bar (zero HIGH/CRITICAL, FLEX-WP-0034) is not met. Either accept for this release (no regression) or ask the owner for a Go toolchain bump and rebuild first, which yields a new digest and requires re-running the checks in the evidence file. Do not proceed without choosing.

Image in force (source evidence)

values/informed-decision-sitting.yaml recorded bdac62bc… (FLEX-WP-0033 cutover, 2026-10-04) but was never promoted after FLEX-WP-0034. Source evidence says the release runs 6c6dc263:

  • FLEX-WP-0034-T02 (2026-10-05): Helm revision 13 deployed with --atomic from owner CI image 6c6dc263 (source f234d01), values values/informed-decision-lifecycle-review.candidate.yaml (commit 941ffa6), consumer pinned v13 31be5985.
  • registry/release-units/flex-auth-informed-decision-sitting.yaml pins the live OCI image 6c6dc263…168e.
  • FLEX-WP-0038 (2026-10-22): a diff of the values file against live showed the sitting release "also changes image", i.e. live is not bdac62bc; that release was not upgraded.

So the pre-release state is expected to be: revision 13, image 6c6dc263, v13 policy at …/informed-decision-lifecycle-review/policy.md, memory request 32Mi. Step 0 confirms it read-only; if it differs, stop and report.

Steps

export KUBECONFIG=$HOME/.kube/config-railiance01
cd ~/access-engine            # the commit carrying this runbook
REL=flex-auth-informed-decision-sitting
NS=flex-auth

0. Record the state in force (read-only)

helm -n $NS history $REL --max 5
helm -n $NS get values $REL -o yaml > /tmp/$REL.values-before.yaml
kubectl -n $NS get deploy $REL -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}{.spec.template.spec.containers[0].args}{"\n"}'

Expect: last revision deployed (13 unless something has run since), image …@sha256:6c6dc263f4a7f6461e109e133c004c080e8e373acfead8611856c5fb3e44168e, --policy /opt/flex-auth/examples/informed-decision-lifecycle-review/policy.md. Write down the revision number as PREV; it is the rollback target. If the image differs, stop.

1. Server dry-run and diff (read-only)

helm -n $NS upgrade $REL charts/flex-auth -f values/informed-decision-sitting.yaml \
  --dry-run=server > /tmp/$REL.dry-run.txt && echo dry-run-ok
helm template $REL charts/flex-auth -n $NS -f values/informed-decision-sitting.yaml \
  | kubectl -n $NS diff -f -

Expected diff, Deployment flex-auth-informed-decision-sitting only:

  • image @sha256:6c6dc263…168e → @sha256:154726d25ba2ce88ef41551dcb3bb395557095eff19e767a29d0331fafec4776
  • --policy …/informed-decision-lifecycle-review/policy.md → …/informed-decision-present-existing-review/policy.md
  • memory request 32Mi → 40Mi (FLEX-WP-0038 right-sizing, already in the values file)
  • possibly two added args --caller-audience flex-auth (FLEX-WP-0038 saw this chart drift). flex-auth is the binary's default, so behaviour is unchanged; the consumer's token audience is untouched.
  • possibly Helm-managed labels/annotations (chart version, revision).

Anything else (NetworkPolicy, RBAC, Service, caller binding, registry path, replicas) means stop and report to the owner.

2. Upgrade

helm -n $NS upgrade $REL charts/flex-auth -f values/informed-decision-sitting.yaml \
  --atomic --wait --timeout 3m
kubectl -n $NS rollout status deploy/$REL --timeout=2m

--atomic reverts to PREV by itself if the pod does not become ready.

3. Pin the consumer (informed-decision, same window)

Per informed-decision's own runbook: set the review runtime's policy object to informed-decision.compact-sitting / v14 / sha256:8911458f36f1a60598aa19592a2d752a74dffe2617fd86238407ac87bc300fde and release it. Until then review requests fail closed.

4. Verify (read-only decision checks with synthetic claims)

The service admits only the informed-decision pod and the system:serviceaccount:informed-decision:review caller, so check through a port-forward with a short-lived token for that ServiceAccount (the documented pattern of docs/operator-caller-access-path.md). Both requests are synthetic and must be denied; no approval or memo is touched.

kubectl -n $NS get deploy $REL -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
kubectl -n $NS logs deploy/$REL --tail=20

kubectl -n $NS port-forward svc/$REL 18080:8080 >/dev/null 2>&1 & PF=$!
sleep 2
TOKEN=$(kubectl -n informed-decision create token review --audience=flex-auth --duration=10m)
E=docs/evidence/2026-11-01-compact-sitting-v14
for f in verify-self-approval verify-missing-action; do
  jq --argjson now "$(date +%s)" '.subject.attributes.assurance.at = $now' $E/$f.request.json \
  | curl -s -X POST localhost:18080/v1/check -H "Authorization: Bearer $TOKEN" \
      -H 'Content-Type: application/json' -d @- \
  | jq -c --arg f $f '[$f,.effect,.reason,.provenance.policy_version,.provenance.policy_package_digest]'
done
curl -s -o /dev/null -w 'no-token http %{http_code}\n' -X POST localhost:18080/v1/check \
  -H 'Content-Type: application/json' -d @$E/verify-self-approval.request.json
unset TOKEN; kill $PF

Expected:

["verify-self-approval","deny","self_approval_refused","v14","sha256:8911458f36f1a60598aa19592a2d752a74dffe2617fd86238407ac87bc300fde"]
["verify-missing-action","deny","approval_action_not_admitted","v14","sha256:8911458f36f1a60598aa19592a2d752a74dffe2617fd86238407ac87bc300fde"]
no-token http 401

(The same two requests against v13 answer unknown_class, so these reasons prove v14 is serving. They were checked offline against the image's own check command.) Then confirm in informed-decision that an ordinary review read for requester informed-decision still succeeds with the v14 pin (its own check). Any other result: roll back.

5. Rollback (both halves)

helm -n $NS rollback $REL $PREV --wait --timeout 3m
kubectl -n $NS get deploy $REL -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'

Expect image @sha256:6c6dc263f4a7f6461e109e133c004c080e8e373acfead8611856c5fb3e44168e and the lifecycle-review policy path. Then restore informed-decision's v13 pin (v13, sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873).

Rollback values, if helm rollback is unavailable (exact revision-13 values, kept in the repo): values/informed-decision-lifecycle-review.candidate.yaml

image:   forgejo.coulomb.social/coulomb/flex-auth@sha256:6c6dc263f4a7f6461e109e133c004c080e8e373acfead8611856c5fb3e44168e
--registry /opt/flex-auth/examples/informed-decision-lifecycle-review/registry.json
--policy   /opt/flex-auth/examples/informed-decision-lifecycle-review/policy.md   # v13, 31be5985…
resources.requests: cpu 5m, memory 32Mi
helm -n $NS upgrade $REL charts/flex-auth -f values/informed-decision-lifecycle-review.candidate.yaml --atomic --wait --timeout 3m

The candidate image also carries the v13 package unchanged (same path, same digest), so reverting only --policy on the new image is a valid partial rollback if the image itself is not the problem.

After a successful release (owner follow-up)

  • Record the Helm revision and the step-4 output under docs/evidence/2026-11-01-compact-sitting-v14/ and mark FLEX-WP-0040-T07 accordingly.
  • Update registry/release-units/flex-auth-informed-decision-sitting.yaml to the new image digest and source.
  • Keep values/informed-decision-lifecycle-review.candidate.yaml as the v13 rollback reference until the v14 pair has run cleanly.