Skip to content

Network Policy design prevents pods from accessing multiple exposed applications #104

@blafry

Description

@blafry

Problem Description

The current network policy implementation uses a single label key wormhole.glothriel.github.com/network-policy-consumes-app with the application name as the value. This design fundamentally prevents any pod from accessing more than one Wormhole-exposed application, because Kubernetes does not allow a pod to have the same label key with multiple different values.

Current Behavior

Each network policy created by Wormhole requires pods to have a specific label to allow ingress traffic:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: app1
spec:
  podSelector:
    matchLabels:
      application: wormhole-client
  ingress:
  - from:
    - podSelector:
        matchLabels:
          wormhole.glothriel.github.com/network-policy-consumes-app: app1
      namespaceSelector: {}

For a pod to access one application:

apiVersion: v1
kind: Pod
metadata:
  name: my-service
  labels:
    wormhole.glothriel.github.com/network-policy-consumes-app: app1
spec:
  # ... pod spec

This works fine. However, if the same pod needs to access two applications (app1 and app2), it would need:

labels:
  wormhole.glothriel.github.com/network-policy-consumes-app: app1
  wormhole.glothriel.github.com/network-policy-consumes-app: app2  # IMPOSSIBLE!

This is impossible in Kubernetes - each label key can only have one value.

Impact

This limitation has severe consequences:

  1. Microservices cannot communicate with multiple services - A typical microservice architecture requires services to communicate with multiple dependencies
  2. Forces disabling network policies entirely - Users must choose between security (network policies) and functionality (multi-service access)
  3. Breaks service mesh patterns - Modern architectures require pods to access multiple backends
  4. All-or-nothing security - No granular control; either a pod has network policies disabled globally or can only access one service

Real-World Scenario

┌─────────────────┐
│   Frontend Pod  │  Needs to access:
│                 │  - auth-service
│                 │  - api-gateway
│                 │  - metrics-service
└─────────────────┘
        ❌ IMPOSSIBLE with current network policy implementation

The frontend pod can only label itself for ONE of these services, breaking the application.

Code Reference

The problematic logic is in pkg/k8s/networkpolicies.go:70-79:

From: []networkingv1.NetworkPolicyPeer{
    {
        PodSelector: &metav1.LabelSelector{
            MatchLabels: map[string]string{
                consumesNpLabel: metadata.originalApp.Name,  // Single app name only
            },
        },
        NamespaceSelector: &metav1.LabelSelector{},
    },
},

The label is defined at line 21:

const consumesNpLabel = "wormhole.glothriel.github.com/network-policy-consumes-app"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions