Namespace access control
Introduction
In authentication strategies other than anonymous Kiali supports limiting the
namespaces that are accessible on a per-user basis. The anonymous
authentication strategy does not support this, although you can still limit
privileges when using an OpenShift cluster. See the access control section in
Anonymous strategy.
To authorize namespaces, the standard Roles resources (or ClusterRoles)
and RoleBindings resources (or ClusterRoleBindings) are used.
Kiali can only restrict or grant read access to namespaces as a whole. So,
keep in mind that while the RBAC capabilities of the cluster are used to give
access, Kiali won’t offer the same privilege granularity that the cluster
supports. For example, a user that does not have privileges to get Kubernetes
Deployments via typical tools (e.g. kubectl) would still be able to get
some details of Deployments through Kiali when listing Workloads or when
viewing detail pages, or in the
Graph.
Some features allow creating or changing resources in the cluster (for example, the Wizards). For these write operations which may be sensitive, the users will need to have the required privileges in the cluster to perform updates - i.e. the cluster RBAC takes effect.
Granting access to namespaces
Kiali uses two Kubernetes RBAC verbs to determine which namespaces a user can see:
- GET – grants access to individual namespaces. A user who can GET a
specific namespace (
api/v1/namespaces/{name}) will see that namespace in Kiali. Use per-namespaceRoleBindingsto control this. - LIST – grants access to all namespaces at once. A user who can LIST
namespaces (
api/v1/namespaces) will, by default, see every namespace returned by the list. This is typically granted via aClusterRoleBinding.
In most setups, granting LIST is the simplest way to give a user access to
all namespaces, while GET via RoleBindings provides fine-grained,
per-namespace control.
You, probably, will want to have this small ClusterRole to help you in
authorizing individual namespaces in Kiali:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kiali-namespace-authorization
rules:
- apiGroups: [""]
resources:
- namespaces
- pods/log
verbs:
- get
pods/log privilege is needed for the pods Logs view.
Since logs are potentially sensitive, you could remove that privilege if you
don’t want users to be able to fetch pod logs.
Once you have created this ClusterRole, you would authorize a namespace
foobar to user john with the following RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: authorize-ns-foobar-to-john
namespace: foobar
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: kiali-namespace-authorization # The name of the ClusterRole created previously
apiGroup: rbac.authorization.k8s.io
User, which is the case when
using openid or openshift authentication strategies. For other
authentication strategies you would need to adjust the RoleBinding to use the
right subject kind.
If you want to authorize a user to access all namespaces in the cluster, the
most efficient way to do it is by creating a ClusterRole with the list verb
for namespaces and bind it to the user using a ClusterRoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kiali-all-namespaces-authorization
rules:
- apiGroups: [""]
resources:
- namespaces
- pods/log
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: authorize-all-namespaces-to-john
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: kiali-all-namespaces-authorization
apiGroup: rbac.authorization.k8s.io
ClusterRole is the list verb in the first rule.
Alternatively, you could also use the previously mentioned
kiali-namespace-authorization rather than creating a new one with the list
privilege, and it will work. However, Kiali will perform better if you grant the
list privilege.
Multi-tenant environments and require_namespace_get
By default, when a user has LIST permission on namespaces, Kiali trusts
the list result and shows all returned namespaces without checking individual
GET permission. This is efficient but can be a problem in multi-tenant
environments where LIST is granted broadly (e.g. via a ClusterRoleBinding)
while GET is restricted to specific namespaces per user via RoleBindings.
To enforce stricter access control, enable the require_namespace_get
feature flag:
spec:
kiali_feature_flags:
authz:
require_namespace_get: true
When this is enabled, Kiali will verify GET permission for each namespace individually, even if the user’s LIST call succeeds. Only namespaces where the user has GET permission will be visible. This ensures that LIST permission alone is never sufficient to see a namespace.
require_namespace_get adds a GET API call per namespace on
cache misses. In clusters with a very large number of namespaces this may
increase the time to populate the namespace list. Results are cached per
user session, so the overhead applies only on the first request after login
or cache expiry.
Granting write privileges to namespaces
Changing resources in the cluster can be a sensitive operation. Because of
this, the logged in user will need to be given the needed privileges to perform
any updates through Kiali. The following ClusterRole contains all read and write
privileges that may be used in Kiali:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kiali-write-privileges
rules:
- apiGroups: [""]
resources:
- namespaces
- pods
- replicationcontrollers
- services
verbs:
- patch
- apiGroups: ["extensions", "apps"]
resources:
- daemonsets
- deployments
- replicasets
- statefulsets
verbs:
- patch
- apiGroups: ["batch"]
resources:
- cronjobs
- jobs
verbs:
- patch
- apiGroups:
- networking.istio.io
- security.istio.io
- extensions.istio.io
- telemetry.istio.io
- gateway.networking.k8s.io
resources: ["*"]
verbs:
- get
- list
- watch
- create
- delete
- patch
Similarly to giving access to namespaces, you can either use a RoleBinding to
give read and write privileges only to specific namespaces, or use a
ClusterRoleBinding to give privileges to all namespaces.