Skip to main content
Calico Open Source 3.29 (latest) documentation

Configure RBAC for tiered policies

Big picture

Configure fine-grained user access controls for tiered policies.

Value

Self-service is an important part of CI/CD processes for containerization and microservices. Calico provides fine-grained access control (RBAC) for:

  • Calico policy and tiers
  • Kubernetes network policy

Concepts

Standard Kubernetes RBAC

Calico implements the standard Kubernetes RBAC Authorization APIs with Role and ClusterRole types. The Calico API server integrates with Kubernetes RBAC Authorization APIs as an extension API server.

RBAC for policies and tiers

In Calico, global network policy and network policy resources are associated with a specific tier. Admins can configure access control for these Calico policies using standard Kubernetes Role and ClusterRole resource types. This makes it easy to manage RBAC for both Kubernetes network policies and Calico tiered network policies. RBAC permissions include managing resources using Calico Manager, and kubectl.

RBAC definitions for Calico Enterprise network policy

To specify per-tier RBAC for the Calico network policy and Calico global network policy, use pseudo resource kinds and names in the Role and ClusterRole definitions. For example,

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tier-default-reader
rules:
- apiGroups: ['projectcalico.org']
resources: ['tiers']
resourceNames: ['default']
verbs: ['get']
- apiGroups: ['projectcalico.org']
resources: ['tier.networkpolicies']
resourceNames: ['default.*']
verbs: ['get', 'list']

Where:

  • resources: tier.globalnetworkpolicies and tier.networkpolicies
  • resourceNames:
    • Blank - any policy of the specified kind across all tiers.
    • <tiername>.* - any policy of the specified kind within the named tier.
    • <tiername.policyname> - the specific policy of the specified kind. Because the policy name is prefixed with the tier name, this also specifies the tier.

Before you begin...

Required

A cluster-admin role with full permissions to create and modify resources.

Recommended

A rough idea of your tiered policy workflow, and who should access what. See Configure tiered policies.

How to

note

kubectl auth can-i cannot be used to check RBAC for tiered policy.

Create Admin users, full permissions

Create an Admin user with full access to the Calico Manager (as well as everything else in the cluster) using the following command. See the Kubernetes documentation to identify users based on your chosen authentication method, and how to use the RBAC resources.

kubectl create clusterrolebinding permissive-binding \
--clusterrole=cluster-admin \
--user=<USER\>

Tutorial

This tutorial shows how to use RBAC to control access to resources and CRUD actions for a non-Admin user, John, with the username john.

The RBAC examples shown will include:

User cannot read policies in any tier

User 'john' is forbidden from reading policies in any tier (default tier, and net-sec tier).

When John issues the following command:

kubectl get networkpolicies.p

It returns:

Error from server (Forbidden): networkpolicies.projectcalico.org is forbidden: User "john" cannot list networkpolicies.projectcalico.org in tier "default" and namespace "default" (user cannot get tier)

Similarly, when John issues this command:

kubectl get networkpolicies.p -l projectcalico.org/tier==net-sec

It returns:

Error from server (Forbidden): networkpolicies.projectcalico.org is forbidden: User "john" cannot list networkpolicies.projectcalico.org in tier "net-sec" and namespace "default" (user cannot get tier)
note

The .p' extension (networkpolicies.p) is short for "networkpolicies.projectcalico.org" and used to differentiate it from the Kubernetes NetworkPolicy resource and the underlying CRDs (if using the Kubernetes Datastore Driver).

note

The label for selecting a tier is projectcalico.org/tier. When a label selector is not specified, the server defaults the selection to the default tier. Alternatively, a field selector (spec.tier) may be used to select a tier.

kubectl get networkpolicies.p --field-selector spec.tier=net-sec

User can view all policies, and modify policies in the default namespace and tier

  1. Download the read-all-crud-default-rbac.yaml manifest.

  2. Run the following command to replace <USER\> with the name or email of the user you are providing permissions to:

    sed -i -e 's/<USER\>/<name or email>/g' read-all-crud-default-rbac.yaml
  3. Use the following command to install the bindings:

    kubectl apply -f read-all-crud-default-rbac.yaml

The roles and bindings in this file provide the permissions to read all policies across all tiers and to fully manage policies in the default tier and default namespace. This file includes the minimum required ClusterRole and ClusterRoleBinding definitions for all UI users (see min-ui-user-rbac.yaml above).

User can read policies only in both the default tier and namespace

In this example, we give user 'john' permission to read policies only in both the default tier and namespace.

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tigera-example-get-default-tier
rules:
# To access Calico policy in a tier, the user requires "get" access to that tier.
- apiGroups: ["projectcalico.org"]
resources: ["tiers"]
resourceNames: ["default"]
verbs: ["get"]

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tigera-example-read-policies-in-default-tier
rules:
# This allows "get" and "list" of the Calico NetworkPolicy resources in the default tier.
- apiGroups: ["projectcalico.org"]
resources: ["tier.networkpolicies"]
resourceNames: ["default.*"]
verbs: ["get", "list"]

---

# tigera-example-get-default-tier is applied globally
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: john-can-get-default-tier
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: tigera-example-get-default-tier
apiGroup: rbac.authorization.k8s.io

---

# tigera-example-read-policies-in-default-tier is applied per-namespace
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: john-can-read-policies-in-default-tier-and-namespace
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: tigera-example-read-policies-in-default-tier
apiGroup: rbac.authorization.k8s.io

With the above, user john is able to list all NetworkPolicy resources in the default tier:

kubectl get networkpolicies.p --all-namespaces

With some example policies on the cluster, returns:

NAMESPACE   NAME                                        CREATED AT
blue default.calico-np-blue-ns-default-tier 2021-07-26T09:05:11Z
default default.calico-np-default-ns-default-tier 2021-07-26T09:05:11Z
green default.calico-np-green-ns-default-tier 2021-07-26T09:05:13Z
red default.calico-np-red-ns-default-tier 2021-07-26T09:05:12Z
yellow default.calico-np-yellow-ns-default-tier 2021-07-26T09:05:13Z

As intended, user john can only examine those in the default namespace:

kubectl get networkpolicies.p default.calico-np-green-ns-default-tier -o yaml -n=green

Correctly returns:

Error from server (Forbidden): networkpolicies.projectcalico.org "default.calico-np-green-ns-default-tier" is forbidden: User "john" cannot get networkpolicies.projectcalico.org in tier "default" and namespace "green"

John also still cannot access tier net-sec, as intended:

kubectl get networkpolicies.p -l projectcalico.org/tier==net-sec

This returns:

Error from server (Forbidden): networkpolicies.projectcalico.org is forbidden: User "john" cannot list networkpolicies.projectcalico.org in tier "net-sec" and namespace "default" (user cannot get tier)

User can read policies only in both a specific tier and in the default namespace

Let's assume that the kubernetes-admin gives user 'john' the permission to list the policies in tier net-sec, but only examine the detail of the policies that are also in the default namespace. To provide these permissions to user 'john', use the following ClusterRoles,ClusterRoleBinding and RoleBinding.

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tigera-example-get-net-sec-tier
rules:
# To access Calico policy in a tier, the user requires "get" access to that tier.
- apiGroups: ["projectcalico.org"]
resources: ["tiers"]
resourceNames: ["net-sec"]
verbs: ["get"]

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tigera-example-read-policies-in-net-sec-tier
rules:
# This allows "get" and "list" of the Calico NetworkPolicy resources in the net-sec tier.
- apiGroups: ["projectcalico.org"]
resources: ["tier.networkpolicies"]
resourceNames: ["net-sec.*"]
verbs: ["get", "list"]

---

# tigera-example-get-net-sec-tier is applied globally
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: john-can-get-net-sec-tier
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: tigera-example-get-net-sec-tier
apiGroup: rbac.authorization.k8s.io

---

# tigera-example-read-policies-in-net-sec-tier is applied per-namespace
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: john-can-read-policies-in-net-sec-tier-and-namespace
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: tigera-example-read-policies-in-net-sec-tier
apiGroup: rbac.authorization.k8s.io

User can only view a specific tier

In this example, the following ClusterRole and ClusterRoleBinding can be used to provide 'get' access to the net-sec tier. This has the effect of making the net-sec tier visible in the Calico Manager (including listing the names of the policies it contains).

However, to modify or view the details of policies within the net-sec tier, additional RBAC permissions would be required.

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tigera-example-make-net-sec-tier-visible
rules:
# To access Calico policy in a tier, the user requires "get" access to that tier.
- apiGroups: ["projectcalico.org"]
resources: ["tiers"]
resourceNames: ["net-sec"]
verbs: ["get"]

---

# tigera-example-make-net-sec-tier-visible is applied globally
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: john-can-view-the-net-sec-tier
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: tigera-example-make-net-sec-tier-visible
apiGroup: rbac.authorization.k8s.io

User can read all policies across all tiers and namespaces

In this example, a single ClusterRole is used to provide read access to all policy resource types across all tiers. In this case, there is no need to use both ClusterRoleBindings and RoleBindings to map these abilities to the target user, because the intention is to for the policy to apply to all current and future namespaces on the cluster, so a ClusterRoleBinding provides the desired granularity.

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tigera-example-all-tiers-and-namespaces-policy-reader
rules:
# To access Calico policy in a tier, the user requires "get" access to that tier.
# Not specifying any specific "resourceNames" provides access to all tiers.
- apiGroups: ["projectcalico.org"]
resources: ["tiers"]
verbs: ["get"]
# This allows read access to the Kubernetes NetworkPolicy resources (these are always in the default tier).
- apiGroups: ["networking.k8s.io", "extensions"]
resources: ["networkpolicies"]
verbs: ["get","watch","list"]
# This allows read access to the Calico NetworkPolicy and GlobalNetworkPolicies.
# Not specifying any specific "resourceNames" provides access to them in all tiers.
- apiGroups: ["projectcalico.org"]
resources: ["tier.networkpolicies","tier.globalnetworkpolicies"]
verbs: ["get","watch","list"]

---

# tigera-example-all-tiers-and-namespaces-policy-reader is applied globally, with a single ClusterRoleBinding,
# since all the rules it contains apply to all current and future namespaces on the cluster.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-all-tier
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: tigera-example-all-tiers-and-namespaces-policy-reader
apiGroup: rbac.authorization.k8s.io

User has full control over policies only in both a specific tier and in the default namespace

In this example, two ClusterRole objects are used to provide full access control of Calico NetworkPolicy resource types in the net-sec tier:

  • The tiers resource is bound to a user using a ClusterRoleBinding, because it is a global resource. This results in the user having the ability to read the contents of the tier across all namespaces.
  • The networkpolicies resources are bound to a user using a RoleBinding, because the aim in this case was to make them CRUD-able only in the default namespace. You only need this one ClusterRole to be defined, but it can be applied to different namespaces using additional RoleBinding objects. If the intention was to apply it to all current and future namespaces, a ClusterRoleBinding could be used.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tigera-example-get-net-sec-tier
rules:
# To access Calico policy in a tier, the user requires "get" access to that tier.
- apiGroups: ["projectcalico.org"]
resources: ["tiers"]
resourceNames: ["net-sec"]
verbs: ["get"]

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tigera-example-crud-policies-in-net-sec-tier
rules:
# This allows full CRUD access to the Calico NetworkPolicy resources in the net-sec tier.
- apiGroups: ["projectcalico.org"]
resources: ["tier.networkpolicies"]
resourceNames: ["net-sec.*"]
verbs: ["*"]

---

# tigera-example-get-net-sec-tier is applied globally
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: john-can-get-net-sec-tier
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: tigera-example-get-net-sec-tier
apiGroup: rbac.authorization.k8s.io

---

# tigera-example-crud-policies-in-net-sec-tier is applied per-namespace
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: john-can-crud-policies-in-net-sec-tier-and-namespace
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: tigera-example-crud-policies-in-net-sec-tier
apiGroup: rbac.authorization.k8s.io