Kubernetes User Management


Since July 21st, 2015 Kubernetes illustrates a clear container-ready path accross IT landscapes. While some setups seem valid, many struggle with handling access and cluster administration.

Access Management

Kubernetes does not offer plain user-management. It is based on roles in two layers:

  • ClusterRole
    Cluster-wide roles for administration purposes.
  • Role
    Namespace specific roles for workloads.

Example: Reader-Role (multiple notations-styles)

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader-cr
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader-r
  namespace: default
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

These are bound to entities such as string-attributes (e.g. OIDC groups, roles or usernames) or ServiceAccounts, using:

  • ClusterRoleBinding
    Cluster-wide binding, which is not limited to certain namespaces.
  • RoleBinding
    Namespace specific binding for workloads.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-reader-crb
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: pod-reader-cr
subjects:
- kind: ServiceAccount
  name: myAppServiceAccount
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-rb
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader-r
subjects:
- kind: ServiceAccount
  name: myAppServiceAccount
  namespace: default

Integrate OpenID Connect

For integrating OpenID Connect (OIDC), the cluster must be configured properly. Afterwards, bindings can reference OIDC-attributes, such as Users and Groups (instead of service accounts):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-reader-crb
subjects:
- kind: Group
  name: "oidc:/Platform Administrators"
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: "oidc:/Platform Operators"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: pod-reader-cr
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-rb
  namespace: default
subjects:
- kind: Group
  name: "oidc:/Platform Operators"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader-r
  namespace: default
  apiGroup: rbac.authorization.k8s.io

Don’t be fooled
Even though it’s called oidc:/<groupname> it is a simple string reference, pointing to an OIDC attribute. Which one is referenced, is defined by the clusters OIDC configuration.

Operating Roles

Given described insights, there are multiple perspectives on operating a cluster, such as:

  • Administration
    Requires cluster wide rights for re-configuration of the cluster.
  • Development
    Requires namespace-specific rights for deploying one or multiple workloads
  • Operation
    Requires namespace-specific rights for operating one or multiple workloads.
  • Governance
    Requires namespace-specific rights of reading a sub-set of on or multiple workloads.
  • Workload
    Uses default ServiceAccount for running containers. Workloads include operational tools, such as Service Mesh and its modules, such as visualizations.

Considering these perspectives, dedicated roles are recommended, being fit for purpose of your organization. I recommend separating ClusterRoles from Roles, even though ClusterRoles can be referenced from RoleBindings. That’s due to the nature of change and control as part of a dedicated workload at a dedicated namespace.