From 259f8a20a637cd92a002735d9dd31267254b28fe Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 19 Aug 2026 14:50:04 +0200 Subject: [PATCH] Add isolated ops-warden warn pin (FLEX-WP-0016); FLEX-WP-0007 stays finished policy.enabled cannot flip against the user-engine or tenant-engine bindings. Helm release flex-auth-ops-warden rev 1 serves the production registry in warn. Workstation warden sends no caller token; enforce and the yaml flip stay ops-warden's. --- deploy/README.md | 1 + docs/workplan-planning-map.md | 3 +- railiance/README.md | 1 + tests/stage1.sh | 10 +- values/ops-warden.yaml | 22 ++++ ...WP-0016-ops-warden-incluster-policy-pin.md | 107 ++++++++++++++++++ 6 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 values/ops-warden.yaml create mode 100644 workplans/FLEX-WP-0016-ops-warden-incluster-policy-pin.md diff --git a/deploy/README.md b/deploy/README.md index 615fba0..d5cc640 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -96,6 +96,7 @@ last-known-good digest below. | `flex-auth-tenant-engine` *(previous)* | `sha256:1bf060e61122693ce98359c167cc5fe8bdafc84e097e090eaa71af94d0f27cbc` | nine-action policy (FLEX-WP-0014), CI-built from `f304688` | | `flex-auth-tenant-engine` *(previous)* | `sha256:9320df394a642eff24da8af4a0ee8886a7bb78b0f14d8ee1deeb30ea8eeeaba7` | seven-action policy, FLEX-WP-0013 restore; guardrail actions deny `unknown_action` | | `flex-auth-tenant-engine` *(rollback)* | `sha256:c25fc34a6cd7e64d955f8723ec70e176a583d5ae71d76280c4e2d89fba0fe0aa` | four-action policy; lifecycle actions deny `unknown_action` | +| `flex-auth-ops-warden` | `sha256:138aa3471c46bca6e814691fa1e6520aedda3dffd743e6b09141ab433afdb64b` | **live isolated warn** — ops-warden production registry (FLEX-WP-0016), CI `main-3de72fe` | | `flex-auth-user-engine` | `sha256:138aa3471c46bca6e814691fa1e6520aedda3dffd743e6b09141ab433afdb64b` | **live** — caller-auth **enforce** (FLEX-WP-0015-T02), CI `main-3de72fe`, A2 probe 2026-08-19 | | `flex-auth-user-engine` *(previous)* | `sha256:1f5290376dc5fcf456dc7a785e394d8b90949dabecd1d3e856f38557149bb5f4` | FLEX-WP-0009-T04, nine fixtures (incl. registration-applicant) verified live 2026-08-16 | | `flex-auth-user-engine` *(previous)* | `sha256:a31961c45215aa6baf3bc748c6741ab703c2c8325e61aa7983a355026195e51b` | FLEX-WP-0009-T03, six fixtures verified live 2026-08-10 | diff --git a/docs/workplan-planning-map.md b/docs/workplan-planning-map.md index c5286ab..8b9f51e 100644 --- a/docs/workplan-planning-map.md +++ b/docs/workplan-planning-map.md @@ -25,7 +25,8 @@ This document captures the current sequencing view for flex-auth workplans. | `FLEX-WP-0003` | complete | completed | `FLEX-WP-0002` | Markitect consumer integration and first CARING benchmark are complete: resource namespace, manifest import, action vocabulary, descriptor fixtures, decision fixtures, integration docs. | | `FLEX-WP-0004` | complete | completed | `FLEX-WP-0002`, `FLEX-WP-0005` | Delegated PDP and directory adapter boundary work is complete: Topaz adapter shape, OpenFGA/SpiceDB, OPA/Cedar, Keycloak Authorization Services, Entra/Graph/SCIM, CARING envelope preservation. | | `FLEX-WP-0006` | complete | finished | `FLEX-WP-0002`, `FLEX-WP-0005` | Ops-warden unblocker is complete: flex-auth publishes `ssh-certificate` / `sign` policies, fixtures, and `/v1/check` smoke evidence for the opt-in pre-sign gate shipped in ops-warden `WARDEN-WP-0007` and tracked for production in `WARDEN-WP-0009`. | -| `FLEX-WP-0007` | complete | finished | `FLEX-WP-0006` | Production registry fixture, sync contract, runtime command, healthz coverage, real actor/IAM tests, operator tunnel reachability, and vault-backed joint smoke are complete. `policy.enabled` remains off by maturity decision until testing/production posture calls for live enforcement. | +| `FLEX-WP-0007` | complete | finished | `FLEX-WP-0006` | Production registry fixture, sync contract, runtime command, healthz coverage, real actor/IAM tests, operator tunnel reachability, and vault-backed joint smoke are complete. `policy.enabled` remains off; the in-cluster pin that can actually serve ops-warden is FLEX-WP-0016. | +| `FLEX-WP-0016` | P1 | active | `FLEX-WP-0007`, `FLEX-WP-0015` | Isolated in-cluster `flex-auth-ops-warden` warn pin with the production registry. Enforce and `policy.enabled` wait on ops-warden's calling side. | ## Dependency Notes diff --git a/railiance/README.md b/railiance/README.md index 6f38fc5..bf90bc9 100644 --- a/railiance/README.md +++ b/railiance/README.md @@ -12,6 +12,7 @@ kubectl path; this overlay is the sanctioned shape. | `charts/flex-auth/` | One Deployment + Service + NetworkPolicy per release | | `values/tenant-engine.yaml` | Production pin for `flex-auth-tenant-engine` | | `values/user-engine.yaml` | Production pin for `flex-auth-user-engine` | +| `values/ops-warden.yaml` | Isolated warn pin for ops-warden signing policy (FLEX-WP-0016) | | `values/stage2-canary.yaml` | Isolated canary `flex-auth-canary` (no consumer ingress) | | `values/stage3-production.yaml` | Stage 3 values for that same isolated canary release | | `tests/stage1.sh` | Local render of every values file | diff --git a/tests/stage1.sh b/tests/stage1.sh index 50af296..4c0baa1 100755 --- a/tests/stage1.sh +++ b/tests/stage1.sh @@ -7,7 +7,7 @@ cd "$(dirname "${BASH_SOURCE[0]}")/.." python3 tests/validate_app_toml.py for values in values/stage1.yaml values/stage2-canary.yaml values/stage3-production.yaml \ - values/user-engine.yaml values/tenant-engine.yaml; do + values/user-engine.yaml values/tenant-engine.yaml values/ops-warden.yaml; do echo "helm template ${values}" helm template flex-auth charts/flex-auth -f "${values}" --namespace flex-auth >/dev/null done @@ -25,6 +25,14 @@ echo "$tenant_render" | grep -A1 -- '--caller-auth-mode' | grep -Eq 'warn|enforc echo "$tenant_render" | grep -q 'tenant-engine=system:serviceaccount:tenant-engine:tenant-engine' \ || { echo "tenant-engine render omits its exact binding" >&2; exit 1; } +ops_render="$(helm template flex-auth-ops-warden charts/flex-auth -f values/ops-warden.yaml --namespace flex-auth)" +echo "$ops_render" | grep -A1 -- '--caller-auth-mode' | grep -q warn \ + || { echo "ops-warden first pin must be warn" >&2; exit 1; } +echo "$ops_render" | grep -q 'ops-warden=system:serviceaccount:ops-warden:ops-warden' \ + || { echo "ops-warden render omits its exact binding" >&2; exit 1; } +echo "$ops_render" | grep -q production_registry_snapshot.json \ + || { echo "ops-warden render omits the production registry" >&2; exit 1; } + canary_render="$(helm template flex-auth-canary charts/flex-auth -f values/stage2-canary.yaml --namespace flex-auth)" if echo "$canary_render" | grep -q tokenreviews; then echo "isolated canary must not create TokenReview RBAC" >&2 diff --git a/values/ops-warden.yaml b/values/ops-warden.yaml new file mode 100644 index 0000000..7a23df5 --- /dev/null +++ b/values/ops-warden.yaml @@ -0,0 +1,22 @@ +# Independently rollable ops-warden signing-policy pin (FLEX-WP-0016). +# Isolated: no in-cluster PEP namespace yet. Workstation warden sign is not a +# Kubernetes ServiceAccount, so first mode is warn. Do not copy enforce from +# the user-engine/tenant-engine pins. +name: flex-auth-ops-warden +image: + repository: forgejo.coulomb.social/coulomb/flex-auth + digest: sha256:138aa3471c46bca6e814691fa1e6520aedda3dffd743e6b09141ab433afdb64b +args: + - serve + - --addr + - 0.0.0.0:8080 + - --registry + - /opt/flex-auth/examples/ops-warden/production_registry_snapshot.json + - --policy + - /opt/flex-auth/examples/ops-warden/policy_package.md +callerAuth: + mode: warn + kubernetesURL: https://10.43.0.1 + binding: ops-warden=system:serviceaccount:ops-warden:ops-warden +consumer: + isolated: true diff --git a/workplans/FLEX-WP-0016-ops-warden-incluster-policy-pin.md b/workplans/FLEX-WP-0016-ops-warden-incluster-policy-pin.md new file mode 100644 index 0000000..e1b7928 --- /dev/null +++ b/workplans/FLEX-WP-0016-ops-warden-incluster-policy-pin.md @@ -0,0 +1,107 @@ +--- +id: FLEX-WP-0016 +type: workplan +title: "In-cluster ops-warden policy pin so policy.enabled can flip" +domain: infotech +repo: flex-auth +status: active +owner: grok +topic_slug: netkingdom +planning_priority: P1 +planning_order: 160 +depends_on_workplans: + - FLEX-WP-0007 + - FLEX-WP-0015 +related_workplans: + - WARDEN-WP-0009 +created: "2026-08-19" +updated: "2026-08-19" +--- + +# FLEX-WP-0016 - In-cluster ops-warden policy pin so policy.enabled can flip + +FLEX-WP-0007 is **finished**. Its repo-side artifacts, tunnel smoke, and +vault-backed joint evidence already exist. What it deliberately deferred is +the production `policy.enabled: true` flip. + +That flip is not a flex-auth kubectl of FLEX-WP-0007 leftovers. Three facts +now make a new workplan the honest vehicle: + +1. FLEX-WP-0015 closed A0 on the two live pins. ops-warden's own sequencing + rule (ADHOC-2026-08-17-T01) was: `policy.enabled` must not flip anywhere + while `/v1/check` still answers unauthenticated callers. That condition + now holds for `flex-auth-user-engine` and `flex-auth-tenant-engine`. +2. Those pins cannot serve ops-warden. Each has an exact + `resource.system` → ServiceAccount binding. A `warden sign` check with + `system: ops-warden` against either pin is 403, not a signing decision. +3. There is no in-cluster ops-warden policy Service. FLEX-WP-0007 smoke used + a workstation runtime on `127.0.0.1:18090` via `flex-auth-coulombcore`. + Example `flex_auth_url` `http://flex-auth.flex-auth.svc.cluster.local:8080` + does not exist. + +## Ownership + +| Concern | Owner | +| --- | --- | +| Independently rollable in-cluster pin with the ops-warden policy package and production registry | flex-auth | +| Workstation/CoulombCore `flex_auth_url` (tunnel or port-forward) | ops-warden / operator | +| Calling-side identity on `warden sign` (TokenReview or later mTLS) | ops-warden, on its own schedule | +| `policy.enabled: true` in `warden.yaml` | ops-warden operator | + +`warden sign` on a laptop is not a Kubernetes ServiceAccount. ADR 0004's +choke point therefore cannot be `enforce` on this pin until ops-warden has a +calling identity. First pin is **warn**. Enforce and the `policy.enabled` +flip wait on that calling side. + +## Tasks + +```task +id: FLEX-WP-0016-T01 +status: done +priority: high +``` + +**Overlay pin.** Add `values/ops-warden.yaml`: same digest as the A2 pins, +`--registry` / `--policy` for `examples/ops-warden/production_registry_snapshot.json` +and `policy_package.md`, `callerAuth.mode: warn`, binding +`ops-warden=system:serviceaccount:ops-warden:ops-warden`. `consumer.isolated: +true` until there is an in-cluster PEP namespace to admit. Include it in +`tests/stage1.sh`. + +Done 2026-08-19: `values/ops-warden.yaml` on digest `sha256:138aa347…`, +warn, isolated, production registry. `tests/stage1.sh` renders it. + +```task +id: FLEX-WP-0016-T02 +status: done +priority: high +``` + +**Deploy warn.** `helm upgrade --install flex-auth-ops-warden` from the +overlay. Prove `/healthz` and one allow `/v1/check` from an operator +port-forward (isolated NetworkPolicy admits no consumer ingress). Do not +flip `policy.enabled`. + +Done 2026-08-19: Helm release `flex-auth-ops-warden` rev 1, Service +`flex-auth-ops-warden.flex-auth.svc.cluster.local:8080`. Port-forward +`:19090` `/healthz` 200; `agt-state-hub-bridge` allow +`decision:49350f1064f674d7`; TTL 999 deny `ttl_out_of_bounds` +`decision:ad1620ffa431efe0`. Unauthenticated calls log +`caller authentication warning` and still return a decision (warn). +user-engine and tenant-engine pins were not moved. + +```task +id: FLEX-WP-0016-T03 +status: wait +priority: medium +``` + +**Handoff for the flip.** Tell ops-warden the Service DNS, digest, warn mode, +and that `policy.py` currently sends no `Authorization` header. They adopt +the calling side; then this pin can enforce; then they set +`policy.enabled: true` with `fail_closed: true`. Flex-auth does not edit +`~/.config/warden/warden.yaml`. + +Asked 2026-08-19. Cluster DNS from a warden workstation is not assumed; +they pick tunnel or port-forward. `policy.py` posts JSON with no +`Authorization` header.