Skip to content

feature: Per-agent egress scoping for verified agent NetworkPolicies #224

@kevincogan

Description

@kevincogan

Feature Description

Add optional per-agent egress rules to the AgentCard CRD, allowing operators to scope outbound traffic for verified agents instead of using the current allow-all egress default.

Current Behaviour

Verified agents currently receive an allow-all egress NetworkPolicy. While verification proves the agent is trusted (SPIRE-signed, identity-bound, correct trust domain), allow-all egress does not follow the principle of least privilege. A compromised but verified agent could exfiltrate data to any destination.

The original scoped egress rules on main (verified peers + DNS + K8s API only) were silently dropped by OVN-Kubernetes on OpenShift, breaking DNS resolution and external API access. PR #221 replaced them with allow-all egress as a working baseline.

Proposed Solution

Add an optional spec.networkPolicy field to the AgentCard CRD using standard Kubernetes NetworkPolicy egress rule format:

apiVersion: agent.kagenti.dev/v1alpha1
kind: AgentCard
metadata:
  name: currency-agent-card
spec:
  targetRef:
    kind: Deployment
    name: currency-agent
  networkPolicy:
    egress:
      - ports:
          - port: 443
            protocol: TCP
          - port: 80
            protocol: TCP
        to:
          - ipBlock:
              cidr: 0.0.0.0/0
      - ports:
          - port: 53
            protocol: UDP
          - port: 53
            protocol: TCP

Behavior:

  • When spec.networkPolicy.egress is not set, the operator defaults to allow-all egress (current behavior, backward-compatible).
  • When spec.networkPolicy.egress is set, the operator uses the provided rules for the permissive NetworkPolicy.
  • The restrictive policy (unverified agents) is unaffected and continues to allow only K8s API egress on port 6443.

Changes required

  1. AgentCard CRD (api/v1alpha1/agentcard_types.go): Add NetworkPolicy *AgentCardNetworkPolicy to AgentCardSpec with an Egress []NetworkPolicyEgressRule field.
  2. NetworkPolicy controller (internal/controller/agentcard_networkpolicy_controller.go): Read spec.networkPolicy.egress in createPermissivePolicy and use it when present instead of allow-all.
  3. CRD manifests: Regenerate with make manifests.
  4. Tests: Add unit tests for custom egress rules, empty egress (deny-all), and nil (default allow-all).

Options evaluated

Option FQDN Support Portable OpenShift (OVN-K8s) Complexity Selected
CRD-level egress rules (K8s NetworkPolicy) No (CIDR only) Yes Yes Low Yes
OVN-Kubernetes EgressFirewall Yes (dnsName) No (OpenShift only) Yes Medium No
Istio ServiceEntry + REGISTRY_ONLY Yes (needs mesh) Yes Yes High No
Cilium CiliumNetworkPolicy toFQDNs Yes No (Cilium only) No Medium No
Calico GlobalNetworkPolicy domains Yes No (Calico only) No Medium No

The CRD-level approach was selected because it is portable across all CNIs and platforms, requires no external tooling, and follows the existing CRD pattern. The FQDN limitation is acceptable because broad CIDR rules (e.g., 0.0.0.0/0:443 for HTTPS + DNS on port 53) cover the primary use case of agents calling external LLM APIs.

Want to contribute?

  • I would like to work on this issue.

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions