rfd/0219-k8s-rbac-simplification.md
The purpose of this RFD is to propose a simplification of the Kubernetes RBAC (Role-Based Access Control) within the Teleport project.
The goal is to streamline the user experience and reduce the complexity of getting up and running on day 0 and managing permissions later on.
Today, the Kubernetes RBAC in Teleport is complex and can be difficult for users to manage. A proper setup requires some external Kubernetes config and matching role setup. This complexity leads to misconfigurations and security issues.
Simplifying the RBAC model will help improve usability and security.
A common issue currently is the un-intuitive result of complex rule sets and more critically, difficult to get setup on day 0.
self-hosted flow:
(internal) https://gravitational.slack.com/archives/C03SULRAAG3/p1715394587181739exec grant on read-only user:
(internal) https://gravitational.slack.com/archives/C32M8FP1V/p1739462454321459?thread_ts=1739462384.714419&cid=C32M8FP1VAllow preset roles to be used to get started quickly.
While initially planned to be included in this RFD, due to customer requests, the following has already been implemented and shipped:
Given this, as RBAC has already been simplified quite a lot, a scoped down version of the proposal would be to focus on new installs without impacting existing customers.
Originally, Teleport preset roles were inspired by Kubernetes roles,
specifically, edit, cluster-admin and view.
cluster-admin allows everything everywhere.edit allows CRUD on most builtin resources, but not administrative
resources.
view allows read-only access to most builtin resources.
This resulted in the following Teleport roles:
editor, which maps to cluster-admin and can do everything.access, which maps to edit and can do most CRUD operations.auditor, which maps to view and can do read-only operations.In order to be consistent and allow for seamless use of Kubernetes within Teleport, we will introduce the following new preset bindings:
kubernetes_groups -> ClusterRoleteleport:preset:edit -> edit
Can CRUD most basic builtin resources and read some limited administrative resources.teleport:preset:cluster-admin -> cluster-admin
Provides full access to all Kubernetes resources, including CRDs.teleport:preset:view -> view
Provides read-only access to some Kubernetes resources.On the Kubernetes side, we will create the corresponding ClusterRoleBindings based on kubernetes_groups.
While there is an existing binding for cluster-admin via system:masters, it
is not available everywhere and there are no binding for edit nor view.
For consistency and reliability, we will create one binding for each preset
role.
Those bindings will be available to Teleport users via the user trait feature.
Kubernetes might introduce new API endpoints that should be allowed or denied. Vendoring those roles on Teleport would require us to update the list for every Kubernetes version, and would potentially cause a permission issues if a user deploys an old Teleport version in a modern Kubernetes cluster. Relying on the Kubernetes built-in roles for RBAC frees us from the maintenance burden and prevents security issues caused by version mismatch.
Example:
tctl users add hugo --logins root --kubernetes-group teleport:preset:edit --roles=access
To enable easy setup, provisioning methods will be updated to create the required new ClusterRoleBindings.
The Helm Chart will by default provision the new Kubernetes resources starting in v19.0.0. An option will be added to the chart to allow opting out of creating the default ClusterRoleBindings. All existing release branches will have this flag set to disable the new functionality to minimize breaking changes.
Example:
roles: kube,app,discovery
authToken: foo
proxyAddr: example.devteleport.com:443
kubeClusterName: myCluster
rbac:
defaultClusterRoleBindings: true
The ClusterRoleBindings created by the chart will be prefixed with the chart release and the namespace to allow multiple deployments in the same Kubernetes cluster not to conflict since ClusterRoleBinding resources are global and not namespaced.
{{- if .Values.rbac.defaultClusterRoleBindings -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ .Release.Name }}-{{ .Release.Namespace }}-preset-edit
For simplicity, the provisioning script will be updated to always create the Kubernetes resources, and will not provide a means for users to opt out of the new behavior.
For both EKS and AKS, auto-discovery will be updated to create the expected RBAC resources.
For GKE, we will need to change the documented GCP IAM role to enable admin privileges. Teleport will attempt to impersonate a privileged group, but there is a risk GKE users will not be able to use the new preset roles out of the box.
A special attention to error management will be required to help users understand the issue and how to resolve it, which can be easily done by running the provision script for example.
Auto-update will not attempt to apply the new model, with the assumption that existing setups are already working.
On the Web UI, the initial page generates a Helm command line.
After enrollment, a test page is shown, prompting for a kubernetes_groups
value, which defaults to the user's trait and updates it if changed in this
page.
The following page is about testing the connection, and also have a form to populate a subset of the users/groups.
The initial idea was to allow the user to update it's traits on the fly to not have to logout/log back in, however, as there is no mention of traits, and because the form is present on multiple pages with different behavior, and because it requires the user to initially already have a role assigned that contains the trait interpolation, we will remove both the 'Setup access' page and the 'users/groups' form from the 'Test connection' page.
This will result in using the user's auth to test the connection instead of requiring the user to enter a subset or all of it's groups/users, knowing that the user cannot make add nor change any.
The error messages when using kubectl will be improved to include a link to
the documentation and more details on what is expected. This will help with
initial custom setups that skipped the provided provisioning scripts.
kubernetes_groups field in the
Teleport role.kubernetes_groups, (unclear what
kubernetes_users does from the docs) fields to match the custom
ClusterRoleBinding.kubernetes_resources and
kubernetes_labels to match to match or reduce the permissions granted by
the custom ClusterRole.kubernetes_groups: "teleport:preset:cluster-admin"spec.allow. kubernetes_labels to select each team's clusterteleport:preset:edit or teleport:preset:view as spec.allow.kubernetes_groupskubernetes_resources in their roles