Aqua Security’s Network Security policies are the key to enforcing container firewall rules, preventing unauthorized communication between your pods and external services.

Here’s a live example:

apiVersion: security.aqua.io/v1alpha1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress-except-http
  namespace: default
spec:
  podSelector: {} # Selects all pods in the namespace
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - ipBlock:
        cidr: 192.168.0.0/16
    ports:
    - protocol: TCP
      port: 5432

This policy, when applied to the default namespace, does two things:

  1. Ingress: It allows incoming traffic only to pods that have the label app: frontend on TCP port 80. All other ingress traffic is denied.
  2. Egress: It allows outgoing traffic from any pod to the IP range 192.168.0.0/16 on TCP port 5432. All other egress traffic is denied.

This demonstrates how Aqua’s Network Policies provide fine-grained control over both inbound and outbound traffic for your containerized applications.

The fundamental problem Aqua’s Network Security policies solve is the inherent network openness of container orchestrators like Kubernetes. By default, all pods within a cluster can communicate with each other, and often have broad access to external services. This "allow all" posture is a significant security risk, as a compromise in one pod can easily lead to lateral movement across the entire cluster. Aqua’s Network Policies introduce a declarative, Kubernetes-native way to define and enforce explicit communication rules, effectively turning your container environment into a segmented, secure network.

Internally, Aqua integrates with the Kubernetes API to manage NetworkPolicy resources. When you define an Aqua NetworkPolicy, it translates these rules into the underlying network plugins (like Calico, Cilium, or even the native Kubernetes kube-proxy mode) that manage packet filtering. The podSelector acts as the "what" – it determines which pods the policy applies to. The ingress and egress sections define the "where" and "how" – specifying the allowed sources/destinations and protocols/ports for network traffic. The policyTypes field explicitly states whether the policy applies to ingress, egress, or both.

You control the network behavior by manipulating these selectors and port definitions. For instance, changing podSelector: {} to podSelector: {matchLabels: {app: backend}} would mean the policy only applies to pods with the app: backend label. Similarly, modifying the ports section can restrict or broaden the allowed communication channels. You can also use namespaceSelector to apply policies across different namespaces.

The most surprising thing about these policies is how they interact with Kubernetes’ default behavior. If no NetworkPolicy is defined for a namespace, all ingress and egress traffic is allowed. However, the moment any NetworkPolicy is created in a namespace that selects a pod, that pod becomes isolated by default. Only traffic explicitly allowed by a NetworkPolicy will be permitted. This "default deny" behavior for pods targeted by any policy is crucial for security, but it often catches people off guard when they first implement policies and find their applications suddenly stop communicating.

The next step in securing your container network is to explore advanced features like NetworkPolicy StatefulSet integration and integrating these policies into your CI/CD pipeline for automated security checks.

Want structured learning?

Take the full Aqua course →