--- # 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 you@example.com as `oidc:you@example.com`. 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. # # OPERATOR KUBECONFIG (kubelogin / int128 oidc-login) — the `keycloak-oidc` user exec block: # users: # - name: keycloak-oidc # user: # exec: # apiVersion: client.authentication.k8s.io/v1beta1 # command: kubectl # args: # - oidc-login # - get-token # - --oidc-issuer-url=https://keycloak.home.keithjackson.dev/realms/homelab # - --oidc-client-id=kubernetes # - --oidc-extra-scope=offline_access # long-lived OFFLINE token — avoids frequent re-auth # The `--oidc-extra-scope=offline_access` arg makes kubelogin request an OFFLINE refresh token instead # of an ONLINE one, so the CLI is not forced to re-login on the realm's ONLINE session timeouts # (ssoSessionIdleTimeout 30m / ssoSessionMaxLifespan 10h). Offline tokens honour offlineSessionIdleTimeout # (30 days idle) with offlineSessionMaxLifespanEnabled=false (no hard cap). Backed by the `offline_access` # OPTIONAL client scope on the `kubernetes` client (see keycloak-realm-import.yaml). After adding the arg, # clear the cached ONLINE token once so the next login mints an offline one: # kubectl oidc-login clean # (or: rm -f ~/.kube/cache/oidc-login/*) # kubectl get nodes # re-login once to obtain the 30-day offline token 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"