WIP keycloak stack (gate probe)

This commit is contained in:
jakman85 committed 2026-08-24 19:52:25 -05:00
1 parent 254d50a20c
commit ce83c6af3b
28 files changed
+776 -102

No files matched your search

@@ -1,13 +1,19 @@
# =============================================================================
# L2 BEHAVIORAL SCAFFOLD — SSO / forward-auth (R-IDP-02)
# L2 BEHAVIORAL — SSO / forward-auth (R-IDP-02) [RUNNABLE]
# Catalog: docs/14 onboarding (auth wiring) + docs/15 identity-and-access.
# Impl: platform/oauth2-proxy (forward-auth against the Keycloak `homelab` realm), ADR-0014.
#
# GIVEN a service protected via the IdP (native OIDC or oauth2-proxy forward-auth),
# WHEN an UNAUTHENTICATED request hits the endpoint -> THEN it is challenged/denied
# (redirect to IdP / 401), and
# WHEN an AUTHENTICATED session is presented -> THEN access is granted.
# GIVEN oauth2-proxy is deployed and has validated the Keycloak OIDC issuer (it only becomes Available
# after successfully discovering https://keycloak.home.keithjackson.dev/realms/homelab — this is
# the proxy->Keycloak flow working),
# WHEN an UNAUTHENTICATED request hits the forward-auth decision endpoint (/oauth2/auth)
# -> THEN it is challenged: HTTP 401 (no valid Keycloak session => access denied), and a normal
# request is redirected to the IdP to sign in. This is the R-IDP-02 acceptance gate:
# "a forward-auth-protected UI is unreachable without a valid Keycloak session".
#
# STATUS: scaffold — needs T-6.1c/T-6.1d (Keycloak + oauth2-proxy + auth render).
# Goes GREEN once the oauth2-proxy client secret hand-off is filled and oauth2-proxy is deployed
# (platform/oauth2-proxy). Until then the `given` assert times out (oauth2-proxy not Available).
# chainsaw v0.2.12: no test-level finally; block-style contains() checks.
# =============================================================================
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
@@ -19,27 +25,77 @@ metadata:
conformance.home.k3s/requirements: "R-IDP-02"
conformance.home.k3s/layer: "L2"
conformance.home.k3s/safety-critical: "false"
conformance.home.k3s/executable: "true"
conformance.home.k3s/intent: >-
Unauthenticated requests are challenged by the IdP; authenticated ones pass.
Unauthenticated requests to the forward-auth proxy are challenged (401 / redirect to Keycloak);
the proxy is Available only after it validated the Keycloak OIDC issuer.
spec:
timeouts:
apply: 60s
assert: 3m
exec: 3m
steps:
- name: given-idp-protected-service
- name: given-forward-auth-proxy-is-wired-to-keycloak
try:
- script:
content: 'echo "TODO(T-6.1d): onboard a service with auth block -> OIDC/forward-auth"'
# oauth2-proxy reaches Available only after it discovered the Keycloak realm issuer at startup
# (provider=oidc, oidc-issuer-url=.../realms/homelab). Availability == proxy->Keycloak works.
- assert:
resource:
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy
namespace: oauth2-proxy
status:
availableReplicas: 1
- name: then-unauthenticated-is-challenged
try:
- apply:
resource:
apiVersion: batch/v1
kind: Job
metadata:
name: sso-challenge-probe
spec:
backoffLimit: 2
activeDeadlineSeconds: 150
template:
spec:
restartPolicy: Never
containers:
- name: probe
image: busybox:1.36.1
command:
- sh
- -c
- |
set -u
svc="http://oauth2-proxy.oauth2-proxy.svc.cluster.local"
# (1) forward-auth decision endpoint: UNauthenticated MUST be 401.
out="$(wget -S -O /dev/null "$svc/oauth2/auth" 2>&1 || true)"
echo "--- /oauth2/auth ---"; echo "$out"
if echo "$out" | grep -qE 'HTTP/[0-9.]+ 401'; then
echo AUTH_ENDPOINT_401_OK
else
echo "FAIL: /oauth2/auth did not challenge with 401"; exit 1
fi
# (2) a normal request should start the IdP sign-in (302 -> Keycloak).
out2="$(wget -S --max-redirect=0 -O /dev/null "$svc/" 2>&1 || true)"
echo "--- / (start) ---"; echo "$out2"
if echo "$out2" | grep -qiE 'HTTP/[0-9.]+ 30[0-9]|keycloak'; then
echo REDIRECT_TO_IDP_OK
else
echo "NOTE: sign-in redirect check inconclusive (proxy config variant)"
fi
echo CHALLENGED_OK
- assert:
resource:
apiVersion: batch/v1
kind: Job
metadata:
name: sso-challenge-probe
status:
succeeded: 1
finally:
- script:
# Expect a 302 to the IdP or a 401 — never a 200 with the app body.
content: |
set -euo pipefail
code=$(kubectl -n "$NAMESPACE" exec probe -- \
curl -s -o /dev/null -w '%{http_code}' https://<service>.home.keithjackson.dev)
echo "unauth_code=$code"
case "$code" in 302|303|401|403) echo CHALLENGED_OK ;; *) exit 1 ;; esac
check:
(contains($stdout, 'CHALLENGED_OK')): true
- name: then-authenticated-is-granted
try:
- script:
content: 'echo "TODO: obtain IdP session (test user), replay, assert 200"'
content: 'echo "teardown: chainsaw deletes the per-test namespace (Job included)"'