Skip to main content
Calico Cloud documentation

Staged network policy

A staged network policy resource (StagedNetworkPolicy) represents an ordered set of rules which are applied to a collection of endpoints that match a label selector. These rules are used to preview network behavior and do not to enforce network traffic. For enforcing network traffic, see network policy resource.

StagedNetworkPolicy is a namespaced resource. StagedNetworkPolicy in a specific namespace only applies to workload endpoint resources in that namespace. Two resources are in the same namespace if the namespace value is set the same on both. See staged global network policy resource for staged non-namespaced network policy.

StagedNetworkPolicy resources can be used to define network connectivity rules between groups of Calico Cloud endpoints and host endpoints.

StagedNetworkPolicies are organized into tiers, which provide an additional layer of ordering—in particular, note that the Pass action skips to the next tier, to enable hierarchical security policy.

For kubectl commands, the following case-insensitive aliases may be used to specify the resource type on the CLI: stagednetworkpolicy.projectcalico.org, stagednetworkpolicies.projectcalico.org and abbreviations such as stagednetworkpolicy.p and stagednetworkpolicies.p.

Sample YAML

This sample policy allows TCP traffic from frontend endpoints to port 6379 on database endpoints.

apiVersion: projectcalico.org/v3
kind: StagedNetworkPolicy
metadata:
name: internal-access.allow-tcp-6379
namespace: production
spec:
tier: internal-access
selector: role == 'database'
types:
- Ingress
- Egress
ingress:
- action: Allow
protocol: TCP
source:
selector: role == 'frontend'
destination:
ports:
- 6379
egress:
- action: Allow

Definition

Metadata

FieldDescriptionAccepted ValuesSchemaDefault
nameThe name of the network policy. Required.Alphanumeric string with optional ., _, or -.string
namespaceNamespace provides an additional qualification to a resource name.string"default"

Spec

FieldDescriptionAccepted ValuesSchemaDefault
orderControls the order of precedence. Calico Cloud applies the policy with the lowest value first.float
tierName of the tier this policy belongs to.stringdefault
selectorSelects the endpoints to which this policy applies.selectorall()
typesApplies the policy based on the direction of the traffic. To apply the policy to inbound traffic, set to Ingress. To apply the policy to outbound traffic, set to Egress. To apply the policy to both, set to Ingress, Egress.Ingress, EgressList of stringsDepends on presence of ingress/egress rules*
ingressOrdered list of ingress rules applied by policy.List of Rule
egressOrdered list of egress rules applied by this policy.List of Rule
serviceAccountSelectorSelects the service account(s) to which this policy applies. Select a specific service account by name using the projectcalico.org/name label.selectorall()
performanceHintsContains a list of hints to Calico's policy engine to help process the policy more efficiently. Hints never change the enforcement behaviour of the policy. The available hints are described below.AssumeNeededOnEveryNodeList of strings

* If types has no value, Calico Cloud defaults as follows.

Ingress Rules PresentEgress Rules PresentTypes value
NoNoIngress
YesNoIngress
NoYesEgress
YesYesIngress, Egress

Rule

A single rule matches a set of packets and applies some action to them. When multiple rules are specified, they are executed in order.

FieldDescriptionAccepted ValuesSchemaDefault
metadataPer-rule metadata.RuleMetadata
actionAction to perform when matching this rule.Allow, Deny, Log, Passstring
protocolPositive protocol match.TCP, UDP, ICMP, ICMPv6, SCTP, UDPLite, 1-255string | integer
notProtocolNegative protocol match.TCP, UDP, ICMP, ICMPv6, SCTP, UDPLite, 1-255string | integer
icmpICMP match criteria.ICMP
notICMPNegative match on ICMP.ICMP
ipVersionPositive IP version match.4, 6integer
sourceSource match parameters.EntityRule
destinationDestination match parameters.EntityRule
httpMatch HTTP request parameters. Application layer policy must be enabled to use this field.HTTPMatch

After a Log action, processing continues with the next rule; Allow and Deny are immediate and final and no further rules are processed.

An action of Pass in a NetworkPolicy or GlobalNetworkPolicy will skip over the remaining policies and jump to the first profile assigned to the endpoint, applying the policy configured in the profile; if there are no Profiles configured for the endpoint the default applied action is Deny.

RuleMetadata

Metadata associated with a specific rule (rather than the policy as a whole). The contents of the metadata does not affect how a rule is interpreted or enforced; it is simply a way to store additional information for use by operators or applications that interact with Calico Cloud.

FieldDescriptionSchemaDefault
annotationsArbitrary non-identifying metadata.map of string to string

Example:

metadata:
annotations:
app: database
owner: devops

Annotations follow the same rules as Kubernetes for valid syntax and character set.

On Linux with the iptables dataplane, rule annotations are rendered as comments in the form -m comment --comment "<key>=<value>" on the iptables rule(s) that correspond to the Calico Cloud rule.

ICMP

FieldDescriptionAccepted ValuesSchemaDefault
typeMatch on ICMP type.Can be integer 0-254integer
codeMatch on ICMP code.Can be integer 0-255integer

EntityRule

Entity rules specify the attributes of the source or destination of a packet that must match for the rule as a whole to match. Packets can be matched on combinations of:

If the rule contains multiple match criteria (for example, an IP and a port) then all match criteria must match for the rule as a whole to match a packet.

FieldDescriptionAccepted ValuesSchemaDefault
netsMatch packets with IP in any of the listed CIDRs.List of valid IPv4 CIDRs or list of valid IPv6 CIDRs (IPv4 and IPv6 CIDRs shouldn't be mixed in one rule)list of cidrs
notNetsNegative match on CIDRs. Match packets with IP not in any of the listed CIDRs.List of valid IPv4 CIDRs or list of valid IPv6 CIDRs (IPv4 and IPv6 CIDRs shouldn't be mixed in one rule)list of cidrs
selectorPositive match on selected endpoints. If a namespaceSelector is also defined, the set of endpoints this applies to is limited to the endpoints in the selected namespaces.Valid selectorselector
notSelectorNegative match on selected endpoints. If a namespaceSelector is also defined, the set of endpoints this applies to is limited to the endpoints in the selected namespaces.Valid selectorselector
namespaceSelectorPositive match on selected namespaces. If specified, only workload endpoints in the selected Kubernetes namespaces are matched. Matches namespaces based on the labels that have been applied to the namespaces. Defines the scope that selectors will apply to, if not defined then selectors apply to the NetworkPolicy's namespace. Match a specific namespace by name using the projectcalico.org/name label. Select the non-namespaced resources like GlobalNetworkSet(s), host endpoints to which this policy applies by using global() selector.Valid selectorselector
portsPositive match on the specified portslist of ports
domainsPositive match on domain names.List of exact or wildcard domain nameslist of strings
notPortsNegative match on the specified portslist of ports
serviceAccountsMatch endpoints running under service accounts. If a namespaceSelector is also defined, the set of service accounts this applies to is limited to the service accounts in the selected namespaces.ServiceAccountMatch
servicesMatch the specified service(s). If specified on egress rule destinations, no other selection criteria can be set. If specified on ingress rule sources, only positive or negative matches on ports can be specified.ServiceMatch
note

You cannot mix IPv4 and IPv6 CIDRs in a single rule using nets or notNets. If you need to match both, create 2 rules.

Selector performance in EntityRules

When rendering policy into the dataplane, Calico Cloud must identify the endpoints that match the selectors in all active rules. This calculation is optimized for certain common selector types. Using the optimized selector types reduces CPU usage (and policy rendering time) by orders of magnitude. This becomes important at high scale (hundreds of active rules, hundreds of thousands of endpoints).

The optimized operators are as follows:

  • label == "value"
  • label in { 'v1', 'v2' }
  • has(label)
  • <expression 1> && <expression 2> is optimized if either <expression 1> or <expression 2> is optimized.

The following perform like has(label). All endpoints with the label will be scanned to find matches:

  • label contains 's'
  • label starts with 's'
  • label ends with 's'

The other operators, and in particular, all(), !, || and != are not optimized.

Examples:

  • a == 'b' - optimized
  • a == 'b' && has(c) - optimized
  • a == 'b' || has(c) - not optimized due to use of ||
  • c != 'd' - not optimized due to use of !=
  • !has(a) - not optimized due to use of !
  • a == 'b' && c != 'd' - optimized, a =='b' is optimized so a == 'b' && <anything> is optimized.
  • c != 'd' && a == 'b' - optimized, a =='b' is optimized so <anything> && a == 'b' is optimized.

Exact and wildcard domain names

The domains field is only valid for egress Allow rules. It restricts the rule to apply only to traffic to one of the specified domains. If this field is specified, the parent Rule's action must be Allow, and nets and selector must both be left empty.

When a configured domain name has no wildcard (*), it matches exactly that domain name. For example:

  • microsoft.com
  • tigera.io

With a single asterisk in any part of the domain name, it matches 1 or more path components at that position. For example:

  • *.google.com matches www.google.com and www.ipv6.google.com, but not google.com
  • www.*.com matches www.sun.com and www.apple.com, but not www.com
  • update.*.mycompany.com matches update.tools.mycompany.com, update.secure.suite.mycompany.com, and so on

Not supported are:

  • Multiple wildcards in the same domain, for example: *.*.mycompany.com
  • Asterisks that are not the entire component, for example: www.g*.com
  • More general wildcards, such as regular expressions
note

Calico Cloud implements policy for domain names by learning the corresponding IPs from DNS, then programming rules to allow those IPs. This means that if multiple domain names A, B and C all map to the same IP, and there is domain-based policy to allow A, traffic to B and C will be allowed as well.

Selector

A label selector is an expression which either matches or does not match a resource based on its labels.

Calico Cloud label selectors support a number of operators, which can be combined into larger expressions using the boolean operators and parentheses.

ExpressionMeaning
Logical operators
( <expression> )Matches if and only if <expression> matches. (Parentheses are used for grouping expressions.)
! <expression>Matches if and only if <expression> does not match. Tip: ! is a special character at the start of a YAML string, if you need to use ! at the start of a YAML string, enclose the string in quotes.
<expression 1> && <expression 2>"And": matches if and only if both <expression 1>, and, <expression 2> matches
<expression 1> || <expression 2>"Or": matches if and only if either <expression 1>, or, <expression 2> matches.
Match operators
all()Match all in-scope resources. To match no resources, combine this operator with ! to form !all().
global()Match all non-namespaced resources. Useful in a namespaceSelector to select global resources such as global network sets.
k == 'v'Matches resources with the label 'k' and value 'v'.
k != 'v'Matches resources without label 'k' or with label 'k' and value not equal to v
has(k)Matches resources with label 'k', independent of value. To match pods that do not have label k, combine this operator with ! to form !has(k)
k in { 'v1', 'v2' }Matches resources with label 'k' and value in the given set
k not in { 'v1', 'v2' }Matches resources without label 'k' or with label 'k' and value not in the given set
k contains 's'Matches resources with label 'k' and value containing the substring 's'
k starts with 's'Matches resources with label 'k' and value starting with the substring 's'
k ends with 's'Matches resources with label 'k' and value ending with the substring 's'

Operators have the following precedence:

  • Highest: all the match operators
  • Parentheses ( ... )
  • Negation with !
  • Conjunction with &&
  • Lowest: Disjunction with ||

For example, the expression

! has(my-label) || my-label starts with 'prod' && role in {'frontend','business'}

Would be "bracketed" like this:

((!(has(my-label)) || ((my-label starts with 'prod') && (role in {'frontend','business'}))

It would match:

  • Any resource that did not have label "my-label".
  • Any resource that both:
    • Has a value for my-label that starts with "prod", and,
    • Has a role label with value either "frontend", or "business".

Ports

Calico Cloud supports the following syntaxes for expressing ports.

SyntaxExampleDescription
int80The exact (numeric) port specified
start:end6040:6050All (numeric) ports within the range start ≤ x ≤ end
stringnamed-portA named port, as defined in the ports list of one or more endpoints

An individual numeric port may be specified as a YAML/JSON integer. A port range or named port must be represented as a string. For example, this would be a valid list of ports:

ports: [8080, '1234:5678', 'named-port']

Named ports

Using a named port in an EntityRule, instead of a numeric port, gives a layer of indirection, allowing for the named port to map to different numeric values for each endpoint.

For example, suppose you have multiple HTTP servers running as workloads; some exposing their HTTP port on port 80 and others on port 8080. In each workload, you could create a named port called http-port that maps to the correct local port. Then, in a rule, you could refer to the name http-port instead of writing a different rule for each type of server.

note

Since each named port may refer to many endpoints (and Calico Cloud has to expand a named port into a set of endpoint/port combinations), using a named port is considerably more expensive in terms of CPU than using a simple numeric port. We recommend that they are used sparingly, only where the extra indirection is required.

ServiceAccountMatch

A ServiceAccountMatch matches service accounts in an EntityRule.

FieldDescriptionSchema
namesMatch service accounts by namelist of strings
selectorMatch service accounts by labelselector

ServiceMatch

A ServiceMatch matches a service in an EntityRule.

FieldDescriptionSchema
nameThe service's name.string
namespaceThe service's namespace.string

Performance Hints

Performance hints provide a way to tell Calico Cloud about the intended use of the policy so that it may process it more efficiently. Currently only one hint is defined:

  • AssumeNeededOnEveryNode: normally, Calico Cloud only calculates a policy's rules and selectors on nodes where the policy is actually in use (i.e. its selector matches a local endpoint). This saves work in most cases. The AssumeNeededOnEveryNode hint tells Calico Cloud to treat the policy as "in use" on every node. This is useful for large policy sets that are known to apply to all (or nearly all) endpoints. It effectively "preloads" the policy on every node so that there is less work to do when the first endpoint matching the policy shows up. It also prevents work from being done to tear down the policy when the last endpoint is drained.

Supported operations

Datastore typeCreate/DeleteUpdateGet/ListNotes
Kubernetes API datastoreYesYesYes