Skip to main content

Intents operator

The Otterize intents operator is an open source Kubernetes operator for easily managing service-to-service authorization by declaring the calls each service needs to make, using client intents files. The intents operator uses these files to configure network policies, Kafka ACLs, and other enforcement points (in the future) to allow just the intended calls.

If credentials such as X.509 certificates are needed for authentication for example, to connect to Kafka using mTLS the Otterize intents operator works with SPIRE via the credentials operator to automatically:

  • Establish pod service identities.
  • Generate trusted credentials for each client service.
  • Deliver the credentials to the pod's containers within a locally-mounted volume.

Deploying the intents operator

To deploy the operator, use the Helm chart.

Monitoring the intents operator

The intents operator pod exposes a Prometheus metrics endpoint on port 2112, on /metrics.

Controlling access using the intents operator

To learn how to use the intents operator to control access, head over to the Features & tutorials section on the main page, or have a look on the sidebar.

Pod annotations

You can override the service name the intents operator uses when it computes network policies and Kafka ACLs with a pod annotation.

AnnotationDescription
intents.otterize.com/service-nameUsed for service identity resolution.

Supported enforcement types

Network policies

The intents operator automatically creates, updates and deletes network policies, and automatically labels client and server pods, to reflect precisely the client-to-server calls declared in client intents files.

The intents operator can also be configured to process client intents without creating and managing network policies, to provide visibility on what would happen once enforcement via network policies is activated. More information can be found in the shadow vs active enforcement documentation.

In the example above, the checkoutservice intends to call the shippingservice. When the CRD is applied through kubectl apply, the intents operator labels the checkoutservice and shippingservice pods, and creates a network policy for the ingress of the shippingservice that references these labels and allows calls to the shippingservice from the checkoutservice.

See service identities and resolution to learn how service names are resolved for pods.

The intents operator uses the resolved identity as the service name, and combines it with the namespace of the pod and hashed to form the value of the label intents.otterize.com/server. This label is used as a selector for network policies. Another label, intents.otterize.com/access-server-<servicename>-<servicehash>, is applied to client pods which have declared their intent to access the server. This label is used as the selector to determine which client pods are allowed to access the server pod.

Learn more: Network policies deep dive

Handling external traffic

The intents operator has automatic behavior for allowing external traffic for pods which have indicated that they are supposed to accept external traffic, such as by creating a Service of type NodePort or LoadBalancer, or an Ingress resource.

As the intents operator creates network policies, and the semantics of network policies dictate that:

  1. if no network policies apply to a pod, then all traffic is allowed.
  2. once any network policy applies to a pod, only the traffic explicitly allowed in the policy is allowed

This meant that if you had no network policies on a pod, and created ClientIntents for that pod, then external traffic would be blocked. To make it easy to enable pod-to-pod traffic without affecting expected external traffic, the intents operator automatically detects resources of kind Service of type NodePort or LoadBalancer, or an Ingress resource, and if it creates the first network policy to affect those pods, it also creates a network policy that allows external traffic to those pods, as specified by the external Service/Ingress - for example, it only allows traffic to the specified ports, not all traffic.

This behavior can be disabled using the Helm chart's values.

Kafka mTLS & ACLs

The intents operator automatically creates, updates, and deletes ACLs in Kafka clusters running within your Kubernetes cluster according to the declared intents. It does not modify other ACLs. It works together with the Otterize credentials operator to easily enable secure access to Kafka from client pods, all in your Kubernetes cluster.

The intents operator can also be configured to process client intents without creating and managing Kafka ACLs, to provide visibility on what would happen once enforcement via Kafka ACLs is activated. More information can be found in the shadow vs active enforcement documentation.

The Otterize credentials operator automatically registers client pods with the credentials service either a SPIRE server, or the Otterize Cloud-managed credentials service and writes the trusted credentials generated by that service into Kubernetes secrets for use by those pods. The intents operator takes ClientIntents with type: kafka and creates Kafka ACLs that grant the requested access to the cryptographic identities (SVIDs) created by the credentials operator.

ACL creation and consumer groups

A Kafka client may specify a consumer group ID when consuming a topic. When it does so, it requires DESCRIBE and READ access to the consumer group resource. To enable this, the intents operator creates an ACL enabling all consumers to read and describe all consumer groups. The permission check performed by the AclAuthorizer for a consumer group also takes into account whether the consumer has the appropriate access to the topic it is attempting to read, so the end result is that the topic ACLs determine actual access.

PostgreSQL users & access

The intents operator automatically creates, and updates credentials in PostgreSQL databases according to the declared intents. It works together with the Otterize credentials operator to easily enable secure access to PostgreSQL from client pods, all in your Kubernetes cluster.

Try the Just-in-time PostgreSQL users & access tutorial to learn more.

Istio AuthorizationPolicy

The intents operator automatically creates, updates and deletes Istio authorization policies, automatically looks up service accounts for client pods and labels server pods, to reflect precisely the client-to-server calls declared in client intents files.

The intents operator can also be configured to process client intents without creating and managing Istio authorization policies, to provide visibility on what would happen once enforcement via Istio authorization policy is activated. More information can be found in the shadow vs active enforcement documentation.

In the example above, the checkoutservice intends to call the shippingservice. When the CRD is applied through kubectl apply, the intents operator labels the shippingservice pod, looks up checkoutservice's service account, and creates an authorization policy for the ingress of the shippingservice that references the service account and allows calls to the shippingservice from the checkoutservice.

See service identities and resolution to learn how service names are resolved for pods.

The intents operator uses the resolved identity as the service name, and combines it with the namespace of the pod and hashed to form the value of the label intents.otterize.com/server. This label is used as a selector for servers in Istio authorization policies. The same algorithm is used to look up the client from the service name in the client intents, for whom the service account is looked up.

Finally, an Istio authorization policy is created that allows communication between the client's service account and the server. If the service account covers clients other than the one requested, an event is generated on the ClientIntents to warn about this, and this appears as a warning on Otterize Cloud.

Handling external traffic

Coming soon: automated handling of external traffic based on the presence of an Ingress, Service of type LoadBalancer, IstioGateway or Gateway API, like in network policies.

When an Istio authorization policy is created for a server, it will only allow incoming traffic that matches the policy.

To allow external traffic from outside the cluster to a server, create an AuthorizationPolicy that allows all traffic, traffic that does not come from within the cluster by IP range, or traffic from ingress pods. Create this AuthorizationPolicy alongside the Ingress, Service or Gateway resource, such as in the same Helm chart.