Skip to content

Instantly share code, notes, and snippets.

@mohashari
Created July 9, 2026 01:03
Show Gist options
  • Select an option

  • Save mohashari/47eb2471a28afaf2a91ca14654cde6f8 to your computer and use it in GitHub Desktop.

Select an option

Save mohashari/47eb2471a28afaf2a91ca14654cde6f8 to your computer and use it in GitHub Desktop.
Hardening Kubernetes Control Planes against SSRF: Configuring Cilium Egress Gateways with SPIFFE Identities — code snippets
helm upgrade cilium cilium/cilium \
--namespace kube-system \
--reuse-values \
--set authentication.enabled=true \
--set authentication.mutual.spire.enabled=true \
--set authentication.mutual.spire.install.enabled=true \
--set authentication.mutual.spire.install.server.dataStorage.enabled=true \
--set egressGateway.enabled=true \
--set bpf.masquerade=true
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSpiffeID
metadata:
name: payment-processor-spiffe
spec:
spiffeIdTemplate: "spiffe://prod.muklis.dev/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodMeta.ServiceAccount }}"
podSelector:
matchLabels:
app: payment-processor
workloadSelectors:
- "k8s:ns:payment-system"
- "k8s:sa:payment-processor"
- "k8s:container-image:docker.io/library/payment-processor:v2.4.1"
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: restrict-workload-egress
namespace: payment-system
spec:
endpointSelector:
matchLabels:
app: payment-processor
egress:
# 1. Allow DNS queries to the internal Kube-DNS service
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
"k8s:k8s-app": kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
# 2. Allow egress to the target payment API (Stripe) while denying all other IPs (including 169.254.169.254)
- toCIDRs:
- "3.18.12.0/23"
toPorts:
- ports:
- port: "443"
protocol: TCP
apiVersion: cilium.io/v2
kind: CiliumEgressGatewayPolicy
metadata:
name: payment-gateway-policy
spec:
selectors:
- podSelector:
matchLabels:
"spiffe:prod.muklis.dev/ns/payment-system/sa/payment-processor": ""
destinationCIDRs:
- "3.18.12.0/23"
egressGateway:
nodeSelector:
matchLabels:
role: egress-gateway-node
egressIP: "203.0.113.100"
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: restrict-egress-to-spiffe
namespace: payment-system
spec:
endpointSelector:
matchLabels:
"spiffe:prod.muklis.dev/ns/payment-system/sa/payment-processor": ""
egress:
- toCIDRs:
- "3.18.12.0/23"
toPorts:
- ports:
- port: "443"
protocol: TCP
# 1. List Cilium endpoints and verify the resolved SPIFFE identity labels
cilium endpoint list -o jsonpath='{range .[*]}{.status.id}{"\t"}{.status.identity.labels}{"\n"}{end}' | grep spiffe
# 2. Check the eBPF IPcache to ensure the pod IP maps to the SPIFFE label
cilium map get cilium_ipcache | grep "spiffe:"
# 3. Retrieve the SVID issued to the workload via the SPIRE Agent API
kubectl exec -n spire spire-agent-0 -c spire-agent -- \
/opt/spire/bin/spire-agent api fetch show -socketPath /run/spire/sockets/agent.sock
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment