Files
home-network-k3s-impl/platform/keycloak/k8s-oidc-rbac.yaml
T
jakman85andClaude Opus 4.8 3472f1d161 feat(auth): Keycloak OIDC login + RBAC for kubectl (cert kubeconfig stays break-glass)
Lets users kubectl into the cluster via Keycloak SSO, mapping realm groups to
cluster RBAC. The cert-based admin kubeconfig is untouched and remains a fully
independent break-glass path (works even if Keycloak/OIDC is down).

- keycloak-realm-import.yaml: new `kubernetes` PUBLIC client + PKCE (S256) — no
  client secret in any kubeconfig; kubelogin runs auth-code+PKCE to localhost.
  groups mapper + email/profile/roles scopes.
- k8s-oidc-rbac.yaml (NEW, platform-config): ClusterRoleBindings
  oidc:platform-admins -> cluster-admin, oidc:viewers -> view.
- k3s_server role: kube-apiserver-arg OIDC flags (issuer=homelab realm,
  client-id=kubernetes, username-claim=email + oidc: prefix, groups-claim=groups
  + oidc: prefix). No oidc-ca-file (nodes reach the issuer via the gateway VIP
  and trust the public LE cert). Applied via the rolling Restart k3s handler.

Keycloak/RBAC land via Flux now; the API-server flags take effect on the next
`ansible-playbook playbooks/k3s.yml` rolling restart (deferred until cluster load
from the VM-import incident settles).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-26 17:37:05 -05:00

47 lines
1.8 KiB
YAML

---
# Kubernetes RBAC for Keycloak-federated (OIDC) users. The k3s API server is configured
# (infra/ansible roles/k3s_server) with:
# oidc-issuer-url=https://keycloak.home.keithjackson.dev/realms/homelab
# oidc-client-id=kubernetes oidc-username-claim=email oidc-username-prefix=oidc:
# oidc-groups-claim=groups oidc-groups-prefix=oidc:
# so a Keycloak group `platform-admins` appears to RBAC as the group `oidc:platform-admins`, and a
# user with email [email protected] as `oidc:[email protected]`. These bindings map the Keycloak group
# claim to cluster roles. Group-based (not user-based) so access follows Keycloak group membership
# with no per-user k8s change. Applied by platform-config (dependsOn platform).
#
# BREAK-GLASS: the cert-based admin in the bootstrap kubeconfig is unaffected by any of this and
# keeps full access even if Keycloak/OIDC is down — do not remove it.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: oidc-platform-admins
labels:
app.kubernetes.io/part-of: keycloak
homelab.keithjackson.dev/oidc-rbac: "true"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: "oidc:platform-admins"
---
# Read-only tier: the Keycloak `viewers` group gets the built-in `view` ClusterRole (read most
# resources cluster-wide, excluding Secrets and RBAC escalation paths).
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: oidc-viewers
labels:
app.kubernetes.io/part-of: keycloak
homelab.keithjackson.dev/oidc-rbac: "true"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: "oidc:viewers"