This episode covers Calico's application layer: ApplicationLayerPolicy with the Envoy integration, L7 traffic visibility, policy based on HTTP methods such as GET and POST, and Calico's position in service mesh traffic.

All the policies you've written so far work at the L3/L4 layer: IP, port, and protocol. But what if you want to allow GET /api/users while denying DELETE /api/users? That requires understanding the HTTP payload — this is the L7 (application layer).
Episode 12 covers Calico's Application Layer Policy (ALP): how the Envoy proxy provides application awareness, how policies write HTTP methods and paths, and how Calico coexists with service meshes like Istio.
ALP places an Envoy proxy in the path of selected traffic. Envoy inspects HTTP requests, then decides based on the L7 rules defined by policy. Because the proxy has to see the traffic, ALP requires more resources than L3/L4 policy — so use it only for workloads that really need it.
ALP is enabled via the Installation resource. Enable it first, then deploy the Calico-managed Envoy:
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
applicationLayer:
enabled: trueAfter it's applied, Calico deploys the Envoy DaemonSet and manages its configuration. Check its status:
kubectl patch installation default --type merge \
-p '{"spec":{"applicationLayer":{"enabled":true}}}'
kubectl get pods -l k8s-app=calico-envoy -A
kubectl get tigerastatus | grep -i appkubectl get tigerastatus shows the ALP component status once Envoy is ready.
An ApplicationLayerPolicy selects workloads with a selector, then writes HTTP rules:
apiVersion: projectcalico.org/v3
kind: ApplicationLayerPolicy
metadata:
name: api-read-only
namespace: payments
spec:
selector: app == 'api'
http:
methods:
- GET
- POST
paths:
- /api/*
action: AllowThis policy only allows GET and POST to the /api/* paths. Other requests — including DELETE — don't match the Allow policy, and if there's a default deny in an upper layer, those requests are denied.
ALP doesn't replace network policy; it layers on top of it. The evaluation flow:
NetworkPolicy (L3/L4) -> ApplicationLayerPolicy (L7) -> forwarding
IP/port match? method/path match?The rule of thumb: L3/L4 filters destinations and ports, L7 filters request contents. Both must pass for traffic to be allowed.
Because Envoy sees the payload, its logs contain application details: HTTP method, path, response status, and duration. This is valuable material for auditing and debugging. See the Envoy logs on the node handling the workload:
kubectl logs -l k8s-app=calico-envoy -A | grep -E "GET|POST|DELETE"
kubectl get pods -l app == 'api' -o nameGrepping "GET|POST|DELETE" shows the HTTP access lines passing through the proxy.
For auditing or quick mitigation, create a rule that logs dangerous actions:
apiVersion: projectcalico.org/v3
kind: ApplicationLayerPolicy
metadata:
name: log-delete
namespace: payments
spec:
selector: app == 'api'
http:
methods:
- DELETE
action: LogThe Log action doesn't change the allow/deny decision, but records matching requests. It's a safe way to observe before enforcing stricter policy.
Calico can run inside a service mesh like Istio. When Istio manages traffic between pods with its Envoy sidecars, Calico still holds the L3/L4 network policy at the dataplane level. The two complement each other: Istio handles routing and mTLS, Calico enforces the network boundary.
To make sure ALP is applied to a specific endpoint:
calicoctl get applicationlayerpolicy -n payments -o yaml
calicoctl get workloadendpoints -n payments -o wide
kubectl exec -n payments deploy/api -- \
curl -s -o /dev/null -w "%{http_code}" -X DELETE http://api/api/usersA denied DELETE request returns a non-2xx code, proving the L7 policy is active.
Episode 12 raises Calico to the application layer: Envoy as the L7 eyes, ApplicationLayerPolicy for controlling HTTP methods and paths, and an understanding of when Calico coexists with a service mesh.
Key takeaways:
methods, paths, and action.Log action is useful for observation before enforcement.In the next episode, episode 13, we enter the security phase: zero trust security — building default-deny per namespace and per pod, label-based microsegmentation, and modeling workload endpoints as the foundation of zero trust.