---
title: "Get started with policy tiers"
description: "How tiered policy works in Calico Open Source — evaluation order, pass actions, and using tiers to support microsegmentation."
product: "Calico Open Source"
version: "3.32 (latest)"
section: "Network policy"
canonical_url: "https://docs.tigera.io/calico/latest/network-policy/policy-tiers/tiered-policy"
---

# 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. Calico provides more robust policy than Kubernetes, but you can use them together -- seamlessly. Calico supports:

- Calico network policy, (namespaced)
- Calico 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 Calico 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](https://docs.tigera.io/assets/images/policy-types-474301e8cc7ae4fd70228fb5259a39cc.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 Calico 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](https://docs.tigera.io/assets/images/policy-tiers-b66ba4e79aa0ce4cdbea2fed2095e53d.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 Calico release with tier support.

## kube-admin tier:

The `Tier` with name `kube-admin` is where all [Kubernetes ClusterNetworkPolicy](https://network-policy-api.sigs.k8s.io/reference/examples/) resources with Admin Tier reside. It is automatically created at startup and has the order of 1,000 and a default action of `Pass`. This is fixed, and cannot be changed.

```yaml
apiVersion: policy.networking.k8s.io/v1alpha2
kind: ClusterNetworkPolicy
metadata:
  name: accept-default
spec:
  tier: Admin
  priority: 100
  subject:
    namespaces:
      matchLabels:
        kubernetes.io/metadata.name: default
  ingress:
  - name: accept-default-ingress
    action: "Accept"
    from:
    - namespaces:
        matchLabels:
          kubernetes.io/metadata.name: default
```

Calico enforces Kubernetes `ClusterNetworkPolicy` resources with `spec.tier: Admin` in the `kube-admin` tier.

In addition to `ClusterNetworkPolicy` resources, you can also add Calico `NetworkPolicy`/`GlobalNetworkPolicy` resources to the kube-admin `Tier`. The `ClusterNetworkPolicy` `priority` field maps to the `order` field in the Calico `NetworkPolicy`/`GlobalNetworkPolicy` resources so that the two types of policy can be ordered together.

## kube-baseline tier:

The `Tier` with name `kube-baseline` is where all [Kubernetes ClusterNetworkPolicy](https://network-policy-api.sigs.k8s.io/reference/examples/) resources with Baseline tier reside. It is automatically created during startup and has the order of 10,000,000 and a default action of `Pass`. This is fixed, and cannot be changed.

```yaml
apiVersion: policy.networking.k8s.io/v1alpha2
kind: ClusterNetworkPolicy
metadata:
  name: deny-all
spec:
  tier: Baseline
  priority: 1
  subject:
    namespaces:
      matchLabels: {}
  ingress:
  - name: deny-all-ingress
    action: "Deny"
    from:
    - namespaces:
        matchLabels: {}
```

Calico places a Kubernetes `ClusterNetworkPolicy` with `spec.tier: Baseline`, like the one above, in the `kube-baseline` tier.

In addition to the `ClusterNetworkPolicy` resource, you can also add Calico `NetworkPolicy`/`GlobalNetworkPolicy` resources to the kube-baseline `Tier`. The `ClusterNetworkPolicy` `priority` field maps to the `order` field in the Calico `NetworkPolicy`/`GlobalNetworkPolicy` resources so that the two types of policy can be ordered together.

## 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 Calico 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**, **Calico components**, and underlying **data plane** (iptables/eBPF) all make use of labels and selectors as part of routing traffic.

![tier-funnel](https://docs.tigera.io/assets/images/tier-funnel-54307b875cf8092dc31db531fdb328db.png)

### Policy action rules

Calico 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](https://docs.tigera.io/assets/images/implicit-deny-bb4e0bb76a63f4c41e3ee7885ff1362f.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
  defaultAction: 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](https://docs.tigera.io/assets/images/endpoint-match-ecaab9647b9615e9154c5e134a8cba8e.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** - Calico 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, Calico     | 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 Calico 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](https://docs.tigera.io/calico/latest/network-policy/policy-tiers/rbac-tiered-policies.md).
