Enforce caller-auth on flex-auth-user-engine and record the live A2 probe
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:
parent
ebde4ecba6
commit
b2431e3cad
12 changed files with 60 additions and 26 deletions
|
|
@ -20,6 +20,9 @@ spec:
|
||||||
{{- end }}
|
{{- end }}
|
||||||
securityContext:
|
securityContext:
|
||||||
runAsNonRoot: true
|
runAsNonRoot: true
|
||||||
|
runAsUser: 65532
|
||||||
|
runAsGroup: 65532
|
||||||
|
fsGroup: 65532
|
||||||
seccompProfile:
|
seccompProfile:
|
||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
|
|
@ -71,7 +74,9 @@ spec:
|
||||||
defaultMode: 0440
|
defaultMode: 0440
|
||||||
sources:
|
sources:
|
||||||
- serviceAccountToken:
|
- serviceAccountToken:
|
||||||
|
{{- if .Values.callerAuth.reviewer.audience }}
|
||||||
audience: {{ .Values.callerAuth.reviewer.audience | quote }}
|
audience: {{ .Values.callerAuth.reviewer.audience | quote }}
|
||||||
|
{{- end }}
|
||||||
expirationSeconds: {{ .Values.callerAuth.reviewer.expirationSeconds }}
|
expirationSeconds: {{ .Values.callerAuth.reviewer.expirationSeconds }}
|
||||||
path: token
|
path: token
|
||||||
- configMap:
|
- configMap:
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,11 @@ callerAuth:
|
||||||
binding: ""
|
binding: ""
|
||||||
reviewer:
|
reviewer:
|
||||||
mountPath: /var/run/secrets/flex-auth-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
|
expirationSeconds: 3600
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
|
|
|
||||||
|
|
@ -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` *(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` *(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-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` | `sha256:138aa3471c46bca6e814691fa1e6520aedda3dffd743e6b09141ab433afdb64b` | **live** — caller-auth **enforce** (FLEX-WP-0015-T02), CI `main-3de72fe`, A2 probe 2026-08-19 |
|
||||||
| `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` *(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 |
|
| `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
|
Rolling back the tenant-engine service to `c25fc34a…` restores fail-closed
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,10 @@ spec:
|
||||||
name: flex-auth-reviewer
|
name: flex-auth-reviewer
|
||||||
readOnly: true
|
readOnly: true
|
||||||
securityContext:
|
securityContext:
|
||||||
|
fsGroup: 65532
|
||||||
|
runAsGroup: 65532
|
||||||
runAsNonRoot: true
|
runAsNonRoot: true
|
||||||
|
runAsUser: 65532
|
||||||
seccompProfile:
|
seccompProfile:
|
||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
volumes:
|
volumes:
|
||||||
|
|
@ -72,7 +75,6 @@ spec:
|
||||||
defaultMode: 0440
|
defaultMode: 0440
|
||||||
sources:
|
sources:
|
||||||
- serviceAccountToken:
|
- serviceAccountToken:
|
||||||
audience: https://kubernetes.default.svc
|
|
||||||
expirationSeconds: 3600
|
expirationSeconds: 3600
|
||||||
path: token
|
path: token
|
||||||
- configMap:
|
- configMap:
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ spec:
|
||||||
- --policy
|
- --policy
|
||||||
- /opt/flex-auth/examples/user-engine/policy_package.md
|
- /opt/flex-auth/examples/user-engine/policy_package.md
|
||||||
- --caller-auth-mode
|
- --caller-auth-mode
|
||||||
- warn
|
- enforce
|
||||||
- --caller-kubernetes-url
|
- --caller-kubernetes-url
|
||||||
- https://10.43.0.1
|
- https://10.43.0.1
|
||||||
- --caller-binding
|
- --caller-binding
|
||||||
|
|
@ -63,7 +63,10 @@ spec:
|
||||||
name: flex-auth-reviewer
|
name: flex-auth-reviewer
|
||||||
readOnly: true
|
readOnly: true
|
||||||
securityContext:
|
securityContext:
|
||||||
|
fsGroup: 65532
|
||||||
|
runAsGroup: 65532
|
||||||
runAsNonRoot: true
|
runAsNonRoot: true
|
||||||
|
runAsUser: 65532
|
||||||
seccompProfile:
|
seccompProfile:
|
||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
volumes:
|
volumes:
|
||||||
|
|
@ -72,7 +75,6 @@ spec:
|
||||||
defaultMode: 0440
|
defaultMode: 0440
|
||||||
sources:
|
sources:
|
||||||
- serviceAccountToken:
|
- serviceAccountToken:
|
||||||
audience: https://kubernetes.default.svc
|
|
||||||
expirationSeconds: 3600
|
expirationSeconds: 3600
|
||||||
path: token
|
path: token
|
||||||
- configMap:
|
- configMap:
|
||||||
|
|
|
||||||
|
|
@ -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
|
the Kubernetes TokenReview API through a separately projected reviewer token
|
||||||
and binds the authenticated ServiceAccount principal to every
|
and binds the authenticated ServiceAccount principal to every
|
||||||
`resource.system` in the request. Both the single and batch endpoints use the
|
`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:
|
Each deployed policy instance has an explicit, exact binding. For example:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ volunteer.
|
||||||
| Task | |
|
| Task | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| T01 | Publish the posture vector and this review; reply to `rapp-postgres` |
|
| 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 |
|
| T03 | Deleted the unused tenant-engine live-roles adapter |
|
||||||
| T04 | AuthZEN endpoint — `wait`, with a written trigger |
|
| T04 | AuthZEN endpoint — `wait`, with a written trigger |
|
||||||
| T05 | `make verify-posture` guards declaration/source/deployment drift |
|
| T05 | `make verify-posture` guards declaration/source/deployment drift |
|
||||||
|
|
|
||||||
|
|
@ -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` *(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` *(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-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` | `sha256:138aa3471c46bca6e814691fa1e6520aedda3dffd743e6b09141ab433afdb64b` | **live** — caller-auth enforce (FLEX-WP-0015-T02), CI `main-3de72fe`, A2 probe 2026-08-19 |
|
||||||
| `flex-auth-user-engine` *(live until warn promote)* | `sha256:1f5290376dc5fcf456dc7a785e394d8b90949dabecd1d3e856f38557149bb5f4` | FLEX-WP-0009-T04, nine fixtures, live 2026-08-16 |
|
| `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 |
|
| `flex-auth-user-engine` *(previous)* | `sha256:a31961c45215aa6baf3bc748c6741ab703c2c8325e61aa7983a355026195e51b` | FLEX-WP-0009-T03, six fixtures |
|
||||||
|
|
|
||||||
12
tenancy.yaml
12
tenancy.yaml
|
|
@ -39,12 +39,12 @@ tenancy:
|
||||||
decision point judges asserted claims, it cannot be the verifier of its
|
decision point judges asserted claims, it cannot be the verifier of its
|
||||||
own inputs. Not a defect and not a target for movement.
|
own inputs. Not a defect and not a target for movement.
|
||||||
A: >-
|
A: >-
|
||||||
The running immutable digest still authenticates no caller, so current
|
flex-auth-user-engine is live A2 as of 2026-08-19: digest
|
||||||
remains A0. Source, overlay, and reviewed desired manifests implement
|
sha256:138aa347…, callerAuth.mode=enforce, unbound request returns
|
||||||
A2 with an audience-scoped Kubernetes TokenReview choke point and exact
|
401 and a cross-system token is 403. flex-auth-tenant-engine still
|
||||||
protected-system-to-ServiceAccount bindings. The first production pin
|
runs sha256:1bf060e6… with no caller authentication, so the service
|
||||||
is warn, independently per consumer, under FLEX-WP-0011/FLEX-WP-0015-T02.
|
declaration stays current A0 until that pin is warn-then-enforce.
|
||||||
Current moves to A2 only after enforce and a live unbound-request probe.
|
Source and overlay implement A2 on both consumers.
|
||||||
E: >-
|
E: >-
|
||||||
No tenant data at rest. Tenant scoping in decisions runs through one
|
No tenant data at rest. Tenant scoping in decisions runs through one
|
||||||
choke point (internal/decision/engine.go normalizeRequest and the
|
choke point (internal/decision/engine.go normalizeRequest and the
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ done
|
||||||
|
|
||||||
user_render="$(helm template flex-auth-user-engine charts/flex-auth -f values/user-engine.yaml --namespace flex-auth)"
|
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 -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 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; }
|
echo "$user_render" | grep -q flex-auth-reviewer || { echo "user-engine render omits reviewer projection" >&2; exit 1; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
# Production pin for the user-engine policy service. Independently rollable.
|
# 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
|
# Caller-auth pin. Warn logs on 2026-08-19 were clean for the user-engine
|
||||||
# after warn logs are clean of unauthenticated callers for this consumer.
|
# 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
|
name: flex-auth-user-engine
|
||||||
image:
|
image:
|
||||||
repository: forgejo.coulomb.social/coulomb/flex-auth
|
repository: forgejo.coulomb.social/coulomb/flex-auth
|
||||||
|
|
@ -14,7 +15,7 @@ args:
|
||||||
- --policy
|
- --policy
|
||||||
- /opt/flex-auth/examples/user-engine/policy_package.md
|
- /opt/flex-auth/examples/user-engine/policy_package.md
|
||||||
callerAuth:
|
callerAuth:
|
||||||
mode: warn
|
mode: enforce
|
||||||
kubernetesURL: https://10.43.0.1
|
kubernetesURL: https://10.43.0.1
|
||||||
binding: user-engine=system:serviceaccount:user-engine:user-engine
|
binding: user-engine=system:serviceaccount:user-engine:user-engine
|
||||||
consumer:
|
consumer:
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ corrections. Done 2026-08-17.
|
||||||
|
|
||||||
```task
|
```task
|
||||||
id: FLEX-WP-0015-T02
|
id: FLEX-WP-0015-T02
|
||||||
status: wait
|
status: progress
|
||||||
priority: high
|
priority: high
|
||||||
state_hub_task_id: "b2e87a81-b63d-4be4-ad44-01426b7e6f74"
|
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
|
flex-auth-<consumer> charts/flex-auth --namespace flex-auth -f
|
||||||
values/<consumer>.yaml`. Isolated canary may boot the same digest with
|
values/<consumer>.yaml`. Isolated canary may boot the same digest with
|
||||||
caller-auth disabled. Do not `kubectl apply` an enforce manifest.
|
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
|
3. Confirm warn logs per consumer. `user-engine` is migrated and deployed
|
||||||
as of 2026-08-18 (image `sha256:c501aeb2…`, token at
|
as of 2026-08-18 (image `sha256:c501aeb2…`, token at
|
||||||
`/var/run/secrets/flex-auth-caller/token`). On 2026-08-19 they confirmed
|
`/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
|
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
|
not run against warn, because "no token returns 401" would still be a
|
||||||
decision.
|
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.
|
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
|
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.
|
the real deadline, and it is the same gate as FLEX-WP-0007.
|
||||||
|
|
||||||
**Operator gate.** Steps 2–5 need cluster credentials this session does not
|
**Operator gate.** Default `KUBECONFIG` pointed at HostEurope and is
|
||||||
have: `kubectl` returns `Unauthorized` and the context is `default`, which
|
Unauthorized. railiance01 is `~/.kube/config-railiance01`. user-engine
|
||||||
`tenant-engine` documented on 2026-08-16 as indistinguishable from a
|
warn→enforce used that kubeconfig. tenant-engine warn-then-enforce is
|
||||||
wrong-cluster KUBECONFIG. Promotion follows FLEX-WP-0011 and the CI image,
|
the remaining operator step. Promotion follows FLEX-WP-0011 and the CI
|
||||||
not a hand-built image.
|
image, not a hand-built image.
|
||||||
|
|
||||||
`RISK-F-0001` (risk-nexus) tracks this A0 externally. Their NetworkPolicy
|
`RISK-F-0001` (risk-nexus) tracks this A0 externally. Their NetworkPolicy
|
||||||
question was answered 2026-08-18: both Deployments carry an ingress policy
|
question was answered 2026-08-18: both Deployments carry an ingress policy
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue