workstation: per-user OIDC kubectl — power-user-readonly RBAC + kubeconfig (Phase 2.2)
New oidc-power-user-readonly ClusterRole (cluster-wide get/list/watch, NO secrets/exec/write); the power-user binding re-pointed to it (the existing read+write+secrets oidc-power-user role is retained but UNBOUND per ADR-0005). Applied to the rbac stack (2 add, 1 change, 0 destroy). emo added to Vault k8s_users (secret/platform) as power-user, email emil.barzin@gmail.com — the OIDC email IS the Authentik username (verified live). Verified via impersonation: emo gets cluster-wide read, NO secrets/write/exec/delete; anca unchanged. Provisioner: install_user_kubeconfig writes a per-user OIDC kubeconfig (kubelogin/PKCE — the kubernetes Authentik client is public, no secret; server+CA copied from the admin kubeconfig) if-absent. Written for emo + ancamilea (0600). End-to-end login is interactive (browser OIDC); verified config validity + RBAC, not the live browser flow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c611ecf84d
commit
173b1fc116
2 changed files with 116 additions and 5 deletions
|
|
@ -40,8 +40,10 @@ resource "kubernetes_cluster_role_binding" "admin_users" {
|
|||
}
|
||||
}
|
||||
|
||||
# --- Power-user role ---
|
||||
# Can manage workloads cluster-wide but cannot modify RBAC, nodes, or persistent volumes
|
||||
# --- Power-user role (read+write+secrets) — RETAINED BUT UNBOUND ---
|
||||
# Superseded by oidc-power-user-readonly (below) per ADR-0005: power-users are bound
|
||||
# to the read-only role, NOT this one. Kept defined for reference/rollback; do NOT
|
||||
# bind it without a deliberate decision (it grants cluster-wide write + secrets).
|
||||
|
||||
resource "kubernetes_cluster_role" "power_user" {
|
||||
metadata {
|
||||
|
|
@ -109,17 +111,70 @@ resource "kubernetes_cluster_role" "power_user" {
|
|||
}
|
||||
}
|
||||
|
||||
# --- Power-user READ-ONLY role (ADR-0005) ---
|
||||
# Cluster-wide get/list/watch, explicitly NO secrets and NO pods/exec. This is the
|
||||
# role power-users are actually bound to (workstation tier: "cluster-wide read,
|
||||
# no Secrets"). Mirrors power_user's resource breadth minus writes/secrets/exec.
|
||||
resource "kubernetes_cluster_role" "power_user_readonly" {
|
||||
metadata {
|
||||
name = "oidc-power-user-readonly"
|
||||
}
|
||||
|
||||
rule {
|
||||
api_groups = [""]
|
||||
resources = ["pods", "pods/log", "services", "endpoints", "configmaps", "persistentvolumeclaims", "events", "namespaces", "nodes"]
|
||||
verbs = ["get", "list", "watch"]
|
||||
}
|
||||
|
||||
rule {
|
||||
api_groups = ["apps"]
|
||||
resources = ["deployments", "statefulsets", "daemonsets", "replicasets"]
|
||||
verbs = ["get", "list", "watch"]
|
||||
}
|
||||
|
||||
rule {
|
||||
api_groups = ["batch"]
|
||||
resources = ["jobs", "cronjobs"]
|
||||
verbs = ["get", "list", "watch"]
|
||||
}
|
||||
|
||||
rule {
|
||||
api_groups = ["networking.k8s.io"]
|
||||
resources = ["ingresses", "networkpolicies"]
|
||||
verbs = ["get", "list", "watch"]
|
||||
}
|
||||
|
||||
rule {
|
||||
api_groups = ["autoscaling"]
|
||||
resources = ["horizontalpodautoscalers"]
|
||||
verbs = ["get", "list", "watch"]
|
||||
}
|
||||
|
||||
rule {
|
||||
api_groups = ["storage.k8s.io"]
|
||||
resources = ["storageclasses"]
|
||||
verbs = ["get", "list", "watch"]
|
||||
}
|
||||
|
||||
rule {
|
||||
api_groups = ["rbac.authorization.k8s.io"]
|
||||
resources = ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
|
||||
verbs = ["get", "list", "watch"]
|
||||
}
|
||||
}
|
||||
|
||||
# Power-users are bound to the READ-ONLY role above (NOT the read+write+secrets one).
|
||||
resource "kubernetes_cluster_role_binding" "power_users" {
|
||||
for_each = nonsensitive({ for name, user in var.k8s_users : name => user if user.role == "power-user" })
|
||||
|
||||
metadata {
|
||||
name = "oidc-power-user-${each.key}"
|
||||
name = "oidc-power-user-readonly-${each.key}"
|
||||
}
|
||||
|
||||
role_ref {
|
||||
api_group = "rbac.authorization.k8s.io"
|
||||
kind = "ClusterRole"
|
||||
name = kubernetes_cluster_role.power_user.metadata[0].name
|
||||
name = kubernetes_cluster_role.power_user_readonly.metadata[0].name
|
||||
}
|
||||
|
||||
subject {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue