Enforce caller-auth on flex-auth-user-engine and record the live A2 probe
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

Helm-adopted the kubectl-managed user-engine pin, promoted sha256:138aa347
warn then enforce. Reviewer volume needs fsGroup 65532; reviewer tokens
must use the API default audiences or TokenReview 401s on this k3s.
Live probe from user-engine-8569d7cb87-fp7px: 200 / 401 / 403. tenant-engine
is unchanged. tenancy.current.A stays 0 until that pin moves.
This commit is contained in:
tegwick 2026-08-19 14:00:53 +02:00
parent ebde4ecba6
commit b2431e3cad
12 changed files with 60 additions and 26 deletions

View file

@ -20,6 +20,9 @@ spec:
{{- end }}
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
containers:
@ -71,7 +74,9 @@ spec:
defaultMode: 0440
sources:
- serviceAccountToken:
{{- if .Values.callerAuth.reviewer.audience }}
audience: {{ .Values.callerAuth.reviewer.audience | quote }}
{{- end }}
expirationSeconds: {{ .Values.callerAuth.reviewer.expirationSeconds }}
path: token
- configMap:

View file

@ -38,7 +38,11 @@ callerAuth:
binding: ""
reviewer:
mountPath: /var/run/secrets/flex-auth-reviewer
audience: https://kubernetes.default.svc
# Empty: kubelet mints the API server's default audiences so TokenReview
# authenticates. A custom audience (e.g. https://kubernetes.default.svc)
# 401s on this k3s cluster, whose API audiences are
# https://kubernetes.default.svc.cluster.local and k3s.
audience: ""
expirationSeconds: 3600
resources:

View file

@ -96,8 +96,8 @@ last-known-good digest below.
| `flex-auth-tenant-engine` *(live until warn promote)* | `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-user-engine` | `sha256:138aa3471c46bca6e814691fa1e6520aedda3dffd743e6b09141ab433afdb64b` | **pin, not live** — caller-auth **warn** (FLEX-WP-0015-T02), CI `main-3de72fe` |
| `flex-auth-user-engine` *(live until warn promote)* | `sha256:1f5290376dc5fcf456dc7a785e394d8b90949dabecd1d3e856f38557149bb5f4` | FLEX-WP-0009-T04, nine fixtures (incl. registration-applicant) verified live 2026-08-16 |
| `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 |
Rolling back the tenant-engine service to `c25fc34a…` restores fail-closed

View file

@ -63,7 +63,10 @@ spec:
name: flex-auth-reviewer
readOnly: true
securityContext:
fsGroup: 65532
runAsGroup: 65532
runAsNonRoot: true
runAsUser: 65532
seccompProfile:
type: RuntimeDefault
volumes:
@ -72,7 +75,6 @@ spec:
defaultMode: 0440
sources:
- serviceAccountToken:
audience: https://kubernetes.default.svc
expirationSeconds: 3600
path: token
- configMap:

View file

@ -25,7 +25,7 @@ spec:
- --policy
- /opt/flex-auth/examples/user-engine/policy_package.md
- --caller-auth-mode
- warn
- enforce
- --caller-kubernetes-url
- https://10.43.0.1
- --caller-binding
@ -63,7 +63,10 @@ spec:
name: flex-auth-reviewer
readOnly: true
securityContext:
fsGroup: 65532
runAsGroup: 65532
runAsNonRoot: true
runAsUser: 65532
seccompProfile:
type: RuntimeDefault
volumes:
@ -72,7 +75,6 @@ spec:
defaultMode: 0440
sources:
- serviceAccountToken:
audience: https://kubernetes.default.svc
expirationSeconds: 3600
path: token
- configMap:

View file

@ -22,7 +22,11 @@ Use Kubernetes ServiceAccount tokens with audience `flex-auth`. flex-auth calls
the Kubernetes TokenReview API through a separately projected reviewer token
and binds the authenticated ServiceAccount principal to every
`resource.system` in the request. Both the single and batch endpoints use the
same choke point; health remains unauthenticated.
same choke point; health remains unauthenticated. The reviewer token uses the
API server's default audiences so it can authenticate to TokenReview; a
custom audience of `https://kubernetes.default.svc` 401s on this cluster
(`https://kubernetes.default.svc.cluster.local` and `k3s`). Caller tokens
keep audience `flex-auth`.
Each deployed policy instance has an explicit, exact binding. For example:

View file

@ -271,7 +271,7 @@ volunteer.
| Task | |
|---|---|
| T01 | Publish the posture vector and this review; reply to `rapp-postgres` |
| T02 | **Close the A0**: TokenReview source + warn-first overlay pin done; operator promote-then-per-consumer-enforce pending |
| T02 | **Close the A0**: user-engine live enforce + A2 probe 2026-08-19; tenant-engine pin still unauthenticated |
| T03 | Deleted the unused tenant-engine live-roles adapter |
| T04 | AuthZEN endpoint — `wait`, with a written trigger |
| T05 | `make verify-posture` guards declaration/source/deployment drift |

View file

@ -106,6 +106,6 @@ or re-apply the last-known-good digest in `deploy/README.md`.
| `flex-auth-tenant-engine` *(live until warn promote)* | `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 |
| `flex-auth-tenant-engine` *(rollback)* | `sha256:c25fc34a6cd7e64d955f8723ec70e176a583d5ae71d76280c4e2d89fba0fe0aa` | four-action policy; lifecycle actions deny `unknown_action` |
| `flex-auth-user-engine` | `sha256:138aa3471c46bca6e814691fa1e6520aedda3dffd743e6b09141ab433afdb64b` | **pin, not live** — caller-auth warn (FLEX-WP-0015-T02), CI `main-3de72fe` |
| `flex-auth-user-engine` *(live until warn promote)* | `sha256:1f5290376dc5fcf456dc7a785e394d8b90949dabecd1d3e856f38557149bb5f4` | FLEX-WP-0009-T04, nine fixtures, live 2026-08-16 |
| `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, live 2026-08-16 |
| `flex-auth-user-engine` *(previous)* | `sha256:a31961c45215aa6baf3bc748c6741ab703c2c8325e61aa7983a355026195e51b` | FLEX-WP-0009-T03, six fixtures |

View file

@ -39,12 +39,12 @@ tenancy:
decision point judges asserted claims, it cannot be the verifier of its
own inputs. Not a defect and not a target for movement.
A: >-
The running immutable digest still authenticates no caller, so current
remains A0. Source, overlay, and reviewed desired manifests implement
A2 with an audience-scoped Kubernetes TokenReview choke point and exact
protected-system-to-ServiceAccount bindings. The first production pin
is warn, independently per consumer, under FLEX-WP-0011/FLEX-WP-0015-T02.
Current moves to A2 only after enforce and a live unbound-request probe.
flex-auth-user-engine is live A2 as of 2026-08-19: digest
sha256:138aa347…, callerAuth.mode=enforce, unbound request returns
401 and a cross-system token is 403. flex-auth-tenant-engine still
runs sha256:1bf060e6… with no caller authentication, so the service
declaration stays current A0 until that pin is warn-then-enforce.
Source and overlay implement A2 on both consumers.
E: >-
No tenant data at rest. Tenant scoping in decisions runs through one
choke point (internal/decision/engine.go normalizeRequest and the

View file

@ -14,7 +14,8 @@ done
user_render="$(helm template flex-auth-user-engine charts/flex-auth -f values/user-engine.yaml --namespace flex-auth)"
echo "$user_render" | grep -q -- '--caller-auth-mode' || { echo "user-engine render omits caller-auth-mode" >&2; exit 1; }
echo "$user_render" | grep -A1 -- '--caller-auth-mode' | grep -q warn || { echo "user-engine first pin must be warn" >&2; exit 1; }
echo "$user_render" | grep -A1 -- '--caller-auth-mode' | grep -Eq 'warn|enforce' \
|| { echo "user-engine caller-auth-mode must be warn or enforce" >&2; exit 1; }
echo "$user_render" | grep -q tokenreviews || { echo "user-engine render omits TokenReview RBAC" >&2; exit 1; }
echo "$user_render" | grep -q flex-auth-reviewer || { echo "user-engine render omits reviewer projection" >&2; exit 1; }

View file

@ -1,6 +1,7 @@
# Production pin for the user-engine policy service. Independently rollable.
# First caller-auth pin is warn (FLEX-WP-0015-T02). Flip mode to enforce only
# after warn logs are clean of unauthenticated callers for this consumer.
# Caller-auth pin. Warn logs on 2026-08-19 were clean for the user-engine
# projected token; this consumer is enforce. Do not copy this to
# values/tenant-engine.yaml until its warn logs are clean.
name: flex-auth-user-engine
image:
repository: forgejo.coulomb.social/coulomb/flex-auth
@ -14,7 +15,7 @@ args:
- --policy
- /opt/flex-auth/examples/user-engine/policy_package.md
callerAuth:
mode: warn
mode: enforce
kubernetesURL: https://10.43.0.1
binding: user-engine=system:serviceaccount:user-engine:user-engine
consumer:

View file

@ -67,7 +67,7 @@ corrections. Done 2026-08-17.
```task
id: FLEX-WP-0015-T02
status: wait
status: progress
priority: high
state_hub_task_id: "b2e87a81-b63d-4be4-ad44-01426b7e6f74"
```
@ -134,6 +134,13 @@ would delay user-engine A2 evidence for no safety gain. Sequence:
flex-auth-<consumer> charts/flex-auth --namespace flex-auth -f
values/<consumer>.yaml`. Isolated canary may boot the same digest with
caller-auth disabled. Do not `kubectl apply` an enforce manifest.
**user-engine done 2026-08-19** (Helm release `flex-auth-user-engine`
rev 4). Live objects were kubectl-managed; they were labelled for Helm
adoption first. Two production bugs had to be fixed during warn: the
reviewer volume needed `fsGroup: 65532`, and the reviewer token must
use the API server's default audiences (a custom
`https://kubernetes.default.svc` audience 401s TokenReview on this
k3s). tenant-engine is still the old digest.
3. Confirm warn logs per consumer. `user-engine` is migrated and deployed
as of 2026-08-18 (image `sha256:c501aeb2…`, token at
`/var/run/secrets/flex-auth-caller/token`). On 2026-08-19 they confirmed
@ -148,15 +155,23 @@ would delay user-engine A2 evidence for no safety gain. Sequence:
written in user-engine `docs/flex-auth-caller-identity.md`; they must
not run against warn, because "no token returns 401" would still be a
decision.
**Done 2026-08-19** from pod `user-engine-8569d7cb87-fp7px`:
(1) Bearer projected token → 200 `decision:350b46fb42989606`;
(2) no Authorization → **401** `unauthenticated`;
(3) `resource.system=tenant-engine`**403** `forbidden`.
Digests: flex-auth `sha256:138aa347…`, user-engine `sha256:c501aeb2…`.
Live user-engine also needed `fsGroup: 10001` or the projected token
was `0440 root:root` and uid 10001 could not send it — persist that
in rapp-user-engine `manifests/runtime.yaml`.
5. Flip tenant-engine to enforce only after its warn logs are clean.
6. Only then may `policy.enabled` flip anywhere — `ops-warden` names that
the real deadline, and it is the same gate as FLEX-WP-0007.
**Operator gate.** Steps 25 need cluster credentials this session does not
have: `kubectl` returns `Unauthorized` and the context is `default`, which
`tenant-engine` documented on 2026-08-16 as indistinguishable from a
wrong-cluster KUBECONFIG. Promotion follows FLEX-WP-0011 and the CI image,
not a hand-built image.
**Operator gate.** Default `KUBECONFIG` pointed at HostEurope and is
Unauthorized. railiance01 is `~/.kube/config-railiance01`. user-engine
warn→enforce used that kubeconfig. tenant-engine warn-then-enforce is
the remaining operator step. Promotion follows FLEX-WP-0011 and the CI
image, not a hand-built image.
`RISK-F-0001` (risk-nexus) tracks this A0 externally. Their NetworkPolicy
question was answered 2026-08-18: both Deployments carry an ingress policy