From 918ec0c9264d553ad7e7bda8883aeda21c50ed9e Mon Sep 17 00:00:00 2001 From: Mazdak Nasab Date: Mon, 21 Oct 2024 09:15:51 -0700 Subject: [PATCH] Add tiered policies to Calico OSS (#1699) Co-authored-by: Tomas Hruby <49207409+tomastigera@users.noreply.github.com> Co-authored-by: Christopher Tauchen --- .../policy-tiers/tiered-policy.mdx | 48 +- calico-cloud/reference/resources/tier.mdx | 14 +- .../policy-tiers/policy-tutorial-ui.mdx | 2 +- .../policy-tiers/tiered-policy.mdx | 32 +- .../reference/resources/tier.mdx | 10 +- calico/network-policy/policy-tiers/index.mdx | 11 + .../policy-tiers/rbac-tiered-policies.mdx | 484 ++++++++++++++++++ .../policy-tiers/tiered-policy.mdx | 181 +++++++ calico/reference/resources/tier.mdx | 62 +++ sidebars-calico.js | 10 +- 10 files changed, 823 insertions(+), 31 deletions(-) create mode 100644 calico/network-policy/policy-tiers/index.mdx create mode 100644 calico/network-policy/policy-tiers/rbac-tiered-policies.mdx create mode 100644 calico/network-policy/policy-tiers/tiered-policy.mdx create mode 100644 calico/reference/resources/tier.mdx diff --git a/calico-cloud/network-policy/policy-tiers/tiered-policy.mdx b/calico-cloud/network-policy/policy-tiers/tiered-policy.mdx index 3e85ea8b6f..8c5ff07f6c 100644 --- a/calico-cloud/network-policy/policy-tiers/tiered-policy.mdx +++ b/calico-cloud/network-policy/policy-tiers/tiered-policy.mdx @@ -1,8 +1,8 @@ --- -description: Learn about policies, tiers, and policy evaluation. +description: Understand how tiered policy works and supports microsegmentation. --- -# Policy tiers tutorial +# Get started with policy tiers ## Seamless network policy integration @@ -20,7 +20,7 @@ All {{prodname}} and Kubernetes network policies reside in tiers. You can start ![policy types](/img/calico-cloud/policy-types.svg) -Next, you can determine the priority of policies in tiers (from top to bottom). In the following example, that platform and security tiers use {{prodname}} global network policies that apply to all pods, while developer teams can safely manage pods within namespaces using Kubernetes network policy for their applications and microservices. +Next, you can determine the priority of policies in tiers (from top to bottom). In the following example, the platform and security tiers use {{prodname}} global network policies that apply to all pods, while developer teams can safely manage pods within namespaces using Kubernetes network policy for their applications and microservices. ![policy tiers](/img/calico-cloud/policy-tiers.png) @@ -50,9 +50,9 @@ spec: kubectl apply -f security.yaml ``` -## The default tier: always last +## The default tier: -The default tier is created during installation and is always the last tier. +The AdminNetworkPolicy tier where all [Kubernetes admin network policies](https://network-policy-api.sigs.k8s.io/reference/examples/) reside. It is automatically created during installation and has the order of 1,000. This value is fixed, and cannot be changed. ![default tier](/img/calico-cloud/default-tier.png) @@ -62,6 +62,10 @@ The default tier is where: - Network and global network policies are placed when you upgrade from Project Calico to {{prodname}} - Recommended policies are placed when you use the **Recommend a policy** feature +## AdminNetworkPolicy tier: + +The AdminNetworkPolicy tier is where all [Kubernetes admin network policies](https://network-policy-api.sigs.k8s.io/reference/examples/) reside. It is automatically created during installation and has the order of 1,000. + ## System tiers System tiers are added during installation and are hidden by default. Always add your tiers after `allow-tigera` and `tigera-security` (in terms of order). @@ -88,7 +92,7 @@ Now you can reorder tiers by dragging and moving them. ## Tier order -Tiers are ordered from left to right, starting with the highest priority (also called highest precedence) tiers. +Tiers are sorted by their orders (from left to right), starting from the lowest order (the highest priority) tiers. ![tier order](/img/calico-cloud/tier-order.png) @@ -96,13 +100,13 @@ In the example above, tier priorities are as follows: - **security tier** - is higher priority than platform tier - **platform tier** - is higher priority than default tier -- **default tier** - is always the last tier, and cannot be reordered +- **default tier** - is the lowest priority The tier you put as the highest priority (after system tiers), depends on your environment. In compliance-driven environments, the security tier may be the highest priority (as shown above). There is no one-size-fits-all order. ## Policy processing -Policies are processed in sequential order from top to bottom. +Policies are processed in sequential order from lowest order (highest priority) to highest order (lowest priority), which is from top to bottom in the following diagram. ![policy processing](/img/calico-cloud/policy-processing.png) @@ -135,11 +139,13 @@ The following diagrams show the relationship between all of the elements that af ### Implicit default deny -As shown in the following diagram, at the end of each tier is an implicit default deny. This is a safeguard that helps mitigate against unsecured policy. Because of this safeguard, you must explicitly apply the **Pass** action rule when you want traffic evaluation to continue. In the following example, the Pass action in a policy ensures that traffic evaluation continues, and overrides the implicit default deny. +As shown in the following diagram, at the end of each tier is an implicit default deny. This is a safeguard that helps mitigate against unsecured policy. +Because of this safeguard, you must either explicitly update tier's default action to **Pass** or apply a Pass action rule when you want traffic evaluation to continue. +In the following example, the Pass action in a policy ensures that traffic evaluation continues, and overrides the implicit default deny. -![implicit deny](/img/calico-cloud/implicit-deny.svg) +![implicit-deny](/img/calico-cloud/implicit-deny.svg) -Let’s look at a Dev/Ops global network policy in a high precedence tier (Platform). The policy denies ingress and egress traffic to workloads that match selector, `env != "stage"`. To ensure that policies continue to evaluate traffic after this policy, the policy adds a Pass action for both ingress and egress. +Let’s look at a Dev/Ops global network policy in a high precedence tier (Platform). The policy denies ingress and egress traffic to workloads that match selector, `env == "stage"`. To ensure that policies continue to evaluate traffic after this policy, the policy adds a Pass action for both ingress and egress. **Pass action rule example** @@ -167,11 +173,25 @@ spec: - Egress ``` +The other option, is to update tier's default action to **Pass** to override the implicit default deny. + +**Pass default action tier example** + +```yaml +apiVersion: projectcalico.org/v3 +kind: Tier +metadata: + name: devops +spec: + order: 300 + defautlAction: Pass +``` + ### Policy endpoint matching across tiers Whoever is responsible for tier creation, also needs to understand how policy selects matching endpoints across tiers. For normal policy processing (without apply-on-forward, pre-DNAT, and do-not-track), if no policies within a tier apply to endpoints, the tier is skipped, and the tier's implicit deny behavior is not executed. -In the following example, policy D in the Security tier includes a **Pass action** rule because we want traffic evaluation to continue to the next tier in sequence. In the Platform tier, there are no selectors in policies that match endpoints so the tier is skipped, including the end of tier deny. Evaluation continues to the Application tier. **Policy J** is the first policy with a matching endpoint. +In the following example, **policy D** in the Security tier includes a Pass action rule because we want traffic evaluation to continue to the next tier in sequence. In the Platform tier, there are no selectors in policies that match endpoints so the tier is skipped, including the end of tier deny. Evaluation continues to the Application tier. **Policy J** is the first policy with a matching endpoint. ![endpoint match](/img/calico-cloud/endpoint-match.svg) @@ -203,3 +223,7 @@ We recommend: For example, you may need to update Pass action rules to policies before or after the new tier. Intervening tiers may require changes to policies before and after, depending on the endpoints. - Use the **policy preview** feature to see effects of policy in action before enforcing it, and use the **staged network policy** feature to test the entire tier workflow before pushing it to production + +## Additional resources + +- For details on using RBAC for fine-grained access to tiers and policies, see [Configure RBAC for tiered policies](rbac-tiered-policies.mdx). diff --git a/calico-cloud/reference/resources/tier.mdx b/calico-cloud/reference/resources/tier.mdx index 0b48694e78..01e22a31c8 100644 --- a/calico-cloud/reference/resources/tier.mdx +++ b/calico-cloud/reference/resources/tier.mdx @@ -28,11 +28,9 @@ Policies in each Tier are then processed in order. - If a [NetworkPolicy](networkpolicy.mdx) or [GlobalNetworkPolicy](globalnetworkpolicy.mdx) in the Tier `Allow`s or `Deny`s the packet, then evaluation is done: the packet is handled accordingly. - If a [NetworkPolicy](networkpolicy.mdx) or [GlobalNetworkPolicy](globalnetworkpolicy.mdx) in the Tier `Pass`es the packet, the next Tier containing a Policy that applies to the endpoint processes the packet. -If the Tier applies to the endpoint, but takes no action on the packet the packet is dropped. +If the Tier applies to the endpoint, but takes no action on the packet the packet is dropped. This behaviour can be changed by setting the `defaultAction` of a tier to `Pass`. - +If the last Tier applying to the endpoint `Pass`es the packet, that endpoint's [Profiles] (profile.mdx) are evaluated. ## Sample YAML @@ -43,6 +41,7 @@ metadata: name: internal-access spec: order: 100 + defaultAction: Deny ``` ## Definition @@ -55,8 +54,9 @@ spec: ### Spec -| Field | Description | Accepted Values | Schema | Default | -|-------|--------------------------------------------------------------------------------------------------------------------------------------|-----------------|--------|-----------------------| -| order | (Optional) Indicates priority of this Tier, with lower order taking precedence. No value indicates highest order (lowest precedence) | | float | `nil` (highest order) | +| Field | Description | Accepted Values | Schema | Default | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------- | ------ | --------------------- | +| order | (Optional) Indicates priority of this Tier, with lower order taking precedence. No value indicates highest order (lowest precedence) | | float | `nil` (highest order) | +| defaultAction | (Optional) Indicates the default action, when this Tier applies to an endpoint, but takes not action on the packet | `Deny`, `Pass` | string | `Deny` | All Policies created by {{prodname}} orchestrator integrations are created in the default (last) Tier. diff --git a/calico-enterprise/network-policy/policy-tiers/policy-tutorial-ui.mdx b/calico-enterprise/network-policy/policy-tiers/policy-tutorial-ui.mdx index e964ccf215..c4023d8a86 100644 --- a/calico-enterprise/network-policy/policy-tiers/policy-tutorial-ui.mdx +++ b/calico-enterprise/network-policy/policy-tiers/policy-tutorial-ui.mdx @@ -1,5 +1,5 @@ --- -description: Covers the basics of Calico Cloud network policy. +description: Covers the basics of Calico Enterprise network policy. --- # Network policy tutorial diff --git a/calico-enterprise/network-policy/policy-tiers/tiered-policy.mdx b/calico-enterprise/network-policy/policy-tiers/tiered-policy.mdx index 803d5b24e6..9f040be43e 100644 --- a/calico-enterprise/network-policy/policy-tiers/tiered-policy.mdx +++ b/calico-enterprise/network-policy/policy-tiers/tiered-policy.mdx @@ -50,9 +50,9 @@ spec: kubectl apply -f security.yaml ``` -## The default tier: always last +## The default tier: -The default tier is created during installation and is always the last tier. +The default tier is created during installation and has the order of 1,000,000. This value is fixed, and cannot be changed. The desire is to evaluate policies in the default tier as last. ![default-tier](/img/calico-enterprise/default-tier.png) @@ -62,6 +62,10 @@ The default tier is where: - Network and global network policies are placed when you upgrade from Project Calico to {{prodname}} - Recommended policies are placed when you use the **Recommend a policy** feature +## AdminNetworkPolicy tier: + +The AdminNetworkPolicy tier is where all [Kubernetes admin network policies](https://network-policy-api.sigs.k8s.io/reference/examples/) reside. It is automatically created during installation and has the order of 1,000. This value is fixed, and cannot be changed. + ## System tiers System tiers are added during installation and are hidden by default. @@ -86,7 +90,7 @@ Now you can reorder tiers by dragging and moving them. ## Tier order -Tiers are ordered from left to right, starting with the highest priority (also called highest precedence) tiers. +Tiers are sorted by their orders (from left to right), starting from the lowest order (the highest priority) tiers. ![tier-order](/img/calico-enterprise/tier-order.png) @@ -94,13 +98,13 @@ In the example above, tier priorities are as follows: - **security tier** - is higher priority than platform tier - **platform tier** - is higher priority than default tier -- **default tier** - is always the last tier and cannot be reordered +- **default tier** - is the lowest priority The tier you put as the highest priority (after system tiers), depends on your environment. In compliance-driven environments, the security tier may be the highest priority (as shown above). There is no one-size-fits-all order. ## Policy processing -Policies are processed in sequential order from top to bottom. +Policies are processed in sequential order from lowest order (highest priority) to highest order (lowest priority), which is from top to bottom in the following diagram. ![policy-processing](/img/calico-enterprise/policy-processing.png) @@ -133,7 +137,9 @@ The following diagrams show the relationship between all of the elements that af ### Implicit default deny -As shown in the following diagram, at the end of each tier is an implicit default deny. This is a safeguard that helps mitigate against unsecured policy. Because of this safeguard, you must explicitly apply the **Pass** action rule when you want traffic evaluation to continue. In the following example, the Pass action in a policy ensures that traffic evaluation continues, and overrides the implicit default deny. +As shown in the following diagram, at the end of each tier is an implicit default deny. This is a safeguard that helps mitigate against unsecured policy. +Because of this safeguard, you must either explicitly update tier's default action to **Pass** or apply a Pass action rule when you want traffic evaluation to continue. +In the following example, the Pass action in a policy ensures that traffic evaluation continues, and overrides the implicit default deny. ![implicit-deny](/img/calico-enterprise/implicit-deny.svg) @@ -165,6 +171,20 @@ spec: - Egress ``` +The other option, is to update tier's default action to **Pass** to override the implicit default deny. + +**Pass default action tier example** + +```yaml +apiVersion: projectcalico.org/v3 +kind: Tier +metadata: + name: devops +spec: + order: 300 + defautlAction: Pass +``` + ### Policy endpoint matching across tiers Whoever is responsible for tier creation, also needs to understand how policy selects matching endpoints across tiers. For normal policy processing (without apply-on-forward, pre-DNAT, and do-not-track), if no policies within a tier apply to endpoints, the tier is skipped, and the tier's implicit deny behavior is not executed. diff --git a/calico-enterprise/reference/resources/tier.mdx b/calico-enterprise/reference/resources/tier.mdx index 973c87d2d6..63eac4dc5a 100644 --- a/calico-enterprise/reference/resources/tier.mdx +++ b/calico-enterprise/reference/resources/tier.mdx @@ -28,7 +28,7 @@ Policies in each Tier are then processed in order. - If a [NetworkPolicy](networkpolicy.mdx) or [GlobalNetworkPolicy](globalnetworkpolicy.mdx) in the Tier `Allow`s or `Deny`s the packet, then evaluation is done: the packet is handled accordingly. - If a [NetworkPolicy](networkpolicy.mdx) or [GlobalNetworkPolicy](globalnetworkpolicy.mdx) in the Tier `Pass`es the packet, the next Tier containing a Policy that applies to the endpoint processes the packet. -If the Tier applies to the endpoint, but takes no action on the packet the packet is dropped. +If the Tier applies to the endpoint, but takes no action on the packet the packet is dropped. This behaviour can be changed by setting the `defaultAction` of a tier to `Pass`. If the last Tier applying to the endpoint `Pass`es the packet, that endpoint's [Profiles](profile.mdx) are evaluated. @@ -41,6 +41,7 @@ metadata: name: internal-access spec: order: 100 + defaultAction: Deny ``` ## Definition @@ -53,8 +54,9 @@ spec: ### Spec -| Field | Description | Accepted Values | Schema | Default | -| ----- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------- | ------ | --------------------- | -| order | (Optional) Indicates priority of this Tier, with lower order taking precedence. No value indicates highest order (lowest precedence) | | float | `nil` (highest order) | +| Field | Description | Accepted Values | Schema | Default | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------- | ------ | --------------------- | +| order | (Optional) Indicates priority of this Tier, with lower order taking precedence. No value indicates highest order (lowest precedence) | | float | `nil` (highest order) | +| defaultAction | (Optional) Indicates the default action, when this Tier applies to an endpoint, but takes not action on the packet | `Deny`, `Pass` | string | `Deny` | All Policies created by {{prodname}} orchestrator integrations are created in the default (last) Tier. diff --git a/calico/network-policy/policy-tiers/index.mdx b/calico/network-policy/policy-tiers/index.mdx new file mode 100644 index 0000000000..9e9dc39a52 --- /dev/null +++ b/calico/network-policy/policy-tiers/index.mdx @@ -0,0 +1,11 @@ +--- +description: Learn how policy tiers allow diverse teams to securely manage Kubernetes policy. +hide_table_of_contents: true +--- + +# Policy tiers + +import DocCardList from '@theme/DocCardList'; +import { useCurrentSidebarCategory } from '@docusaurus/theme-common'; + + diff --git a/calico/network-policy/policy-tiers/rbac-tiered-policies.mdx b/calico/network-policy/policy-tiers/rbac-tiered-policies.mdx new file mode 100644 index 0000000000..829a5222bd --- /dev/null +++ b/calico/network-policy/policy-tiers/rbac-tiered-policies.mdx @@ -0,0 +1,484 @@ +--- +description: Configure RBAC to control access to policies and tiers. +--- + +# 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. {{prodname}} provides fine-grained access control (RBAC) for: + +- {{prodname}} policy and tiers +- Kubernetes network policy + +## Concepts + +### Standard Kubernetes RBAC + +{{prodname}} implements the standard **Kubernetes RBAC Authorization APIs** with `Role` and `ClusterRole` types. The {{prodname}} API server integrates with Kubernetes RBAC Authorization APIs as an extension API server. + +### RBAC for policies and tiers + +In {{prodname}}, global network policy and network policy resources are associated with a specific tier. Admins can configure access control for these {{prodname}} policies using standard Kubernetes `Role` and `ClusterRole` resource types. This makes it easy to manage RBAC for both Kubernetes network policies and {{prodname}} tiered network policies. RBAC permissions include managing resources using {{prodname}} Manager, and `kubectl`. + +### RBAC definitions for Calico Enterprise network policy + +To specify per-tier RBAC for the {{prodname}} network policy and {{prodname}} global network policy, use pseudo resource kinds and names in the `Role` and `ClusterRole` definitions. For example, + +```yaml +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. + - `.*` - any policy of the specified kind within the named tier. + - `` - 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](tiered-policy.mdx). + +## How to + +- [Create Admin users, full permissions](#create-admin-users-full-permissions) + +:::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 {{prodname}} 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](https://kubernetes.io/docs/reference/access-authn-authz/authentication/), and how to use the [RBAC resources](https://kubernetes.io/docs/reference/access-authn-authz/rbac/). + +```bash +kubectl create clusterrolebinding permissive-binding \ + --clusterrole=cluster-admin \ + --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-cannot-read-policies-in-any-tier) +- [User can view all policies, and modify policies in the default namespace and tier](#user-can-view-all-policies-and-modify-policies-in-the-default-namespace-and-tier) +- [User can read policies only in both the default tier and namespace](#user-can-read-policies-only-in-both-the-default-tier-and-namespace) +- [User can read policies only in both a specific tier and in the default namespace](#user-can-read-policies-only-in-both-a-specific-tier-and-in-the-default-namespace) +- [User can only view a specific tier](#user-can-only-view-a-specific-tier) +- [User can read all policies across all tiers and namespaces](#user-can-read-all-policies-across-all-tiers-and-namespaces) +- [User has full control over policies only in both a specific tier and in the default namespace](#user-has-full-control-over-policies-only-in-both-a-specific-tier-and-in-the-default-namespace) + +### 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: + +```bash +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: + +```bash +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. + +```bash +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]({{tutorialFilesURL}}/read-all-crud-default-rbac.yaml). + +1. Run the following command to replace `` with the `name or email` of + the user you are providing permissions to: + + ```bash + sed -i -e 's///g' read-all-crud-default-rbac.yaml + ``` + +1. Use the following command to install the bindings: + + ```bash + 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. + +```yaml +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: + +```bash +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: + +```bash +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: + +```bash +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`. + +```yaml +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 {{prodname}} 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. + +```yaml +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. + +```yaml +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. + +```yaml +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 +``` diff --git a/calico/network-policy/policy-tiers/tiered-policy.mdx b/calico/network-policy/policy-tiers/tiered-policy.mdx new file mode 100644 index 0000000000..88941c5d75 --- /dev/null +++ b/calico/network-policy/policy-tiers/tiered-policy.mdx @@ -0,0 +1,181 @@ +--- +description: Understand how tiered policy works and supports microsegmentation. +--- + +# Get started with policy tiers + +## Seamless network policy integration + +**Network policy** is the primary tool for securing a Kubernetes network. It lets you restrict network traffic in your cluster so only the traffic that you want to flow is allowed. {{prodname}} provides more robust policy than Kubernetes, but you can use them together -- seamlessly. {{prodname}} supports: + +- {{prodname}} network policy, (namespaced) +- {{prodname}} global network policy (non-namespaced, global) +- Kubernetes network policy + +## Tiers: what and why? + +**Tiers** are a hierarchical construct used to group policies and enforce higher precedence policies that cannot be circumvented by other teams. As you will learn in this tutorial, tiers have built-in features that support workload microsegmentation. + +All {{prodname}} and Kubernetes network policies reside in tiers. You can start "thinking in tiers" by grouping your teams and types of policies within each group. For example, we recommend these three tiers (platform, security, and application). + +![policy-types](/img/calico-enterprise/policy-types.png) + +Next, you can determine the priority of policies in tiers (from top to bottom). In the following example, the platform and security tiers use {{prodname}} global network policies that apply to all pods, while developer teams can safely manage pods within namespaces using Kubernetes network policy for their applications and microservices. + +![policy-tiers](/img/calico-enterprise/policy-tiers.png) + +## Create a tier + +The following is a sample YAML that creates a security tier and uses `kubectl` to apply it. + +```yaml +apiVersion: projectcalico.org/v3 +kind: Tier +metadata: + name: security +spec: + order: 300 +``` + +```bash +kubectl apply -f security.yaml +``` + +## The default tier: + +The default tier is created during installation and has the order of 1,000,000. This value is fixed, and cannot be changed. The desire is to evaluate policies in the default tier as last. + +The default tier is where: + +- You manage all Kubernetes network policies +- All network and global network policies without an explicit tier are placed. +- Network and global network policies are placed when you upgrade from Project Calico without tier support to {{prodname}} release with tier support. + +## AdminNetworkPolicy tier: + +The AdminNetworkPolicy tier is where all [Kubernetes admin network policies](https://network-policy-api.sigs.k8s.io/reference/examples/) reside. It is automatically created during installation and has the order of 1,000. This value is fixed, and cannot be changed. + +## Tier order + +Tiers are sorted by their orders, starting from the lowest order (the highest priority) tiers. + +## Policy processing + +Policies are processed in sequential order from lowest order (highest priority) to highest order (lowest priority). + +Two mechanisms drive how traffic is processed across tiered policies: + +- Labels and selectors +- Policy action rules + +It is important to understand the roles they play. + +### Labels and selectors + +Instead of IP addresses and IP ranges, network policies in Kubernetes depend on labels and selectors to determine which workloads can talk to each other. Workload identity is the same for Kubernetes and {{prodname}} network policies: as pods dynamically come and go, network policy is enforced based on the labels and selectors that you define. + +The following diagrams show the relationship between all of the elements that affect traffic flow: + +- **Tiers** group and order policies +- **Policy action rules** define how to process traffic in and across tiers, and policy labels and selectors specify how groups of pods are allowed to communicate with each other and other network endpoints +- The **CNI**, **{{prodname}} components**, and underlying **dataplane** (iptables/eBPF) all make use of labels and selectors as part of routing traffic. + +![tier-funnel](/img/calico-enterprise/tier-funnel.png) + +### Policy action rules + +{{prodname}} network policy uses action rules to specify how to process traffic/packets: + +- **Allow or Deny** - traffic is allowed or denied and the packet is handled accordingly. No further rules are processed. +- **Pass** - skips to the next tier that contains a policy that applies to the endpoint, and processes the packet. If the tier applies to the endpoint but no action is taken on the packet, the packet is dropped. +- **Log** - creates a log, and evaluation continues processing to the next rule + +### Implicit default deny + +As shown in the following diagram, at the end of each tier is an implicit default deny. This is a safeguard that helps mitigate against unsecured policy. +Because of this safeguard, you must either explicitly update tier's default action to **Pass** or apply a Pass action rule when you want traffic evaluation to continue. +In the following example, the Pass action in a policy ensures that traffic evaluation continues, and overrides the implicit default deny. + +![implicit-deny](/img/calico-enterprise/implicit-deny.svg) + +Let’s look at a Dev/Ops global network policy in a high precedence tier (Platform). The policy denies ingress and egress traffic to workloads that match selector, `env == "stage"`. To ensure that policies continue to evaluate traffic after this policy, the policy adds a Pass action for both ingress and egress. + +**Pass action rule example** + +```yaml +apiVersion: projectcalico.org/v3 +kind: GlobalNetworkPolicy +metadata: + name: devops.stage-env +spec: + tier: devops + order: 255 + selector: env == "stage" + ingress: + - action: Deny + source: + selector: env != "stage" + - action: Pass + egress: + - action: Deny + destination: + selector: env != "stage" + - action: Pass + types: + - Ingress + - Egress +``` + +The other option, is to update tier's default action to **Pass** to override the implicit default deny. + +**Pass default action tier example** + +```yaml +apiVersion: projectcalico.org/v3 +kind: Tier +metadata: + name: devops +spec: + order: 300 + defautlAction: Pass +``` + +### Policy endpoint matching across tiers + +Whoever is responsible for tier creation, also needs to understand how policy selects matching endpoints across tiers. For normal policy processing (without apply-on-forward, pre-DNAT, and do-not-track), if no policies within a tier apply to endpoints, the tier is skipped, and the tier's implicit deny behavior is not executed. + +In the following example, **policy D** in the Security tier includes a Pass action rule because we want traffic evaluation to continue to the next tier in sequence. In the Platform tier, there are no selectors in policies that match endpoints so the tier is skipped, including the end of tier deny. Evaluation continues to the Application tier. **Policy J** is the first policy with a matching endpoint. + +![endpoint-match](/img/calico-enterprise/endpoint-match.svg) + +### Default endpoint behavior + +Also, tier managers need to understand the default behavior for endpoints based on whether the endpoint is known or unknown, and the endpoint type. As shown in the following table: + +- **Known endpoints** - {{prodname}} resources that are managed by Felix +- **Unknown endpoints** - interfaces/resources not recognizable as part of our data model + +| Endpoint type | Default behavior for known endpoints | Default behavior for unknown endpoints (outside of our data model) | +| ---------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------ | +| Workload, {{prodname}} | Deny | Deny | +| Workload, Kubernetes | Allow ingress from same Kubernetes namespace; allow all egress | Deny | +| Host | Deny. With exception of auto host endpoints, which get `default-allow`. | Fall through and use iptables rules | + +## Best practices for tiered policy + +To control and authorize access to {{prodname}} tiers, policies, and Kubernetes network policies, you use Kubernetes RBAC. Security teams can prevent unauthorized viewing or modification of higher precedence (lower order) tiers, while still allowing developers or service owners to manage the detailed policies related to their workloads. + +We recommend: + +- Limit tier creation permissions to Admin users only; creating and reordering tiers affects your policy processing workflow + +- Limit full CRUD operations on tiers and policy management to select Admin users + +- Review your policy processing whenever you add/reorder tiers + + For example, you may need to update Pass action rules to policies before or after the new tier. Intervening tiers may require changes to policies before and after, depending on the endpoints. + + +## Additional resources + +- For details on using RBAC for fine-grained access to tiers and policies, see [Configure RBAC for tiered policies](rbac-tiered-policies.mdx). diff --git a/calico/reference/resources/tier.mdx b/calico/reference/resources/tier.mdx new file mode 100644 index 0000000000..5024f8e97e --- /dev/null +++ b/calico/reference/resources/tier.mdx @@ -0,0 +1,62 @@ +--- +description: API for this Calico resource. +--- + +# Tier + +A tier resource (`Tier`) represents an ordered collection of [NetworkPolicies](networkpolicy.mdx) +and/or [GlobalNetworkPolicies](globalnetworkpolicy.mdx). +Tiers are used to divide these policies into groups of different priorities. These policies +are ordered within a Tier: the additional hierarchy of Tiers provides more flexibility +because the `Pass` `action` in a Rule jumps to the next Tier. Some example use cases for this are. + +- Allowing privileged users to define security policy that takes precedence over other users. +- Translating hierarchies of physical firewalls directly into {{prodname}} policy. + +For `kubectl` [commands](https://kubernetes.io/docs/reference/kubectl/overview/), the following case-insensitive aliases +may be used to specify the resource type on the CLI: +`tier.projectcalico.org`, `tiers.projectcalico.org` and abbreviations such as +`tier.p` and `tiers.p`. + +## How Policy Is Evaluated + +When a new connection is processed by {{prodname}}, each tier that contains a policy that applies to the endpoint processes the packet. +Tiers are sorted by their `order` - smallest number first. + +Policies in each Tier are then processed in order. + +- If a [NetworkPolicy](networkpolicy.mdx) or [GlobalNetworkPolicy](globalnetworkpolicy.mdx) in the Tier `Allow`s or `Deny`s the packet, then evaluation is done: the packet is handled accordingly. +- If a [NetworkPolicy](networkpolicy.mdx) or [GlobalNetworkPolicy](globalnetworkpolicy.mdx) in the Tier `Pass`es the packet, the next Tier containing a Policy that applies to the endpoint processes the packet. + +If the Tier applies to the endpoint, but takes no action on the packet the packet is dropped. This behaviour can be changed by setting the `defaultAction` of a tier to `Pass`. + +If the last Tier applying to the endpoint `Pass`es the packet, that endpoint's [Profiles](profile.mdx) are evaluated. + +## Sample YAML + +```yaml +apiVersion: projectcalico.org/v3 +kind: Tier +metadata: + name: internal-access +spec: + order: 100 + defaultAction: Deny +``` + +## Definition + +### Metadata + +| Field | Description | Accepted Values | Schema | +| ----- | --------------------- | --------------- | ------ | +| name | The name of the tier. | | string | + +### Spec + +| Field | Description | Accepted Values | Schema | Default | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------- | ------ | --------------------- | +| order | (Optional) Indicates priority of this Tier, with lower order taking precedence. No value indicates highest order (lowest precedence) | | float | `nil` (highest order) | +| defaultAction | (Optional) Indicates the default action, when this Tier applies to an endpoint, but takes not action on the packet | `Deny`, `Pass` | string | `Deny` | + +All Policies created by {{prodname}} orchestrator integrations are created in the default (last) Tier. diff --git a/sidebars-calico.js b/sidebars-calico.js index a712744f3e..a75074ddc6 100644 --- a/sidebars-calico.js +++ b/sidebars-calico.js @@ -345,6 +345,15 @@ module.exports = { 'network-policy/get-started/kubernetes-default-deny', ], }, + { + type: 'category', + label: 'Tiered policy', + link: { type: 'doc', id: 'network-policy/policy-tiers/index'}, + items: [ + 'network-policy/policy-tiers/tiered-policy', + 'network-policy/policy-tiers/rbac-tiered-policies', + ], + }, { type: 'category', label: 'Policy rules', @@ -356,7 +365,6 @@ module.exports = { 'network-policy/policy-rules/service-accounts', 'network-policy/policy-rules/external-ips-policy', 'network-policy/policy-rules/icmp-ping', - ], }, {