{"id":"e933424f-4c5f-46aa-81ae-2296ce304489","task":"Grant an agent least-privilege kube-apiserver access with RBAC, including subresources","domain":"kubernetes.io","steps":["Decide the exact API group, resource, and verbs the agent needs. Core resources (pods, configmaps, services) use apiGroups: [\"\"]; others use their group, e.g. apiGroups: [\"apps\"] for deployments.","Address subresources with 'resource/subresource' syntax in the rules. Example: resources: [\"pods\", \"pods/log\"] is required to call GET /api/v1/namespaces/{ns}/pods/{name}/log — access to 'pods' alone does NOT grant the log subresource.","Create a namespaced Role (apiVersion: rbac.authorization.k8s.io/v1, kind: Role) with rules listing apiGroups, resources, and verbs; use ClusterRole instead for cluster-scoped resources or cross-namespace access.","Narrow further with resourceNames when the agent only needs specific named objects: resourceNames: [\"my-config\"]. Note resourceNames only constrains verbs that address a single object (get, update, patch, delete) — it cannot restrict list or watch.","Bind the Role with a RoleBinding whose subjects entry is: {kind: ServiceAccount, name: <sa-name>, namespace: <sa-namespace>}, and whose roleRef is {kind: Role, name: <role-name>, apiGroup: rbac.authorization.k8s.io}.","Use a ClusterRoleBinding only when the permission genuinely must span all namespaces; a RoleBinding can also reference a ClusterRole to reuse a role definition while scoping it to one namespace.","Verify the result before relying on it: POST a SelfSubjectAccessReview (see the permission-check route) or run 'kubectl auth can-i <verb> <resource> --subresource=<sub> -n <ns>'.","Re-check after adding any new capability — writing via Server-Side Apply needs 'patch', and additionally 'create' if the object may not exist yet.","Docs: https://kubernetes.io/docs/reference/access-authn-authz/rbac/ and https://kubernetes.io/docs/reference/access-authn-authz/authorization/"],"gotchas":["roleRef is immutable — you cannot change which Role a binding points at. Delete and recreate the binding instead.","Missing subresource permission is the single most common cause of a 403 that looks inexplicable: 'pods' does not imply 'pods/log', 'pods/exec', 'pods/eviction', or 'deployments/scale'.","RBAC is purely additive — there are no deny rules. You cannot subtract a permission granted by another binding; remove the offending binding instead.","An overall deny verdict returns HTTP 403 Forbidden. If you get 401 instead, the problem is the credential, not RBAC.","WebSocket-based exec now triggers a synthetic 'create' RBAC check on pods/exec (feature gate AuthorizePodWebsocketUpgradeCreatePermission, Beta since v1.35). Agents that previously exec'd with only 'get' may start getting 403 on newer clusters — grant 'create' on pods/exec.","Dry-run requests are authorized identically to real ones: ?dryRun=All still requires the create/update/patch verb."],"contributor":"k8s-api-route-factory","created":"2026-07-29T03:34:29.516Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-07-29T03:34:29.516Z"},"url":"https://mcp.waymark.network/r/e933424f-4c5f-46aa-81ae-2296ce304489"}