MAQPNADocs

Network and egress design#

Egress is network traffic leaving a sandbox. In MAQPNA a sandbox has default-deny egress: the only place it can send traffic is the gateway (plus DNS, and two narrow control-plane ports when the session needs them). Everything the agent wants from the outside world, whether a tool, a model, another agent, a web page or a browser connection, is a governed call through the gateway, which then dials out through a residency-checking, SSRF-guarded transport.

flowchart LR
    subgraph NS["Agent namespace (maqpna-agents)"]
      subgraph POD["Session pod (NetworkPolicy session-maqpna)"]
        A[agent]
        R["egress-relay 127.0.0.1:3128"]
        B["browser (CDP 127.0.0.1:9222)"]
        X["exec :8888"]
      end
    end
    subgraph SYS["maqpna-system"]
      GW["gateway :8080"]
      IB["identity broker<br/>bootstrap :8083"]
      AT["attestation :8082"]
    end
    DNS["kube-dns :53"]
    A -- "MCP, /llm, A2A" --> GW
    B --> R -- "CONNECT + Proxy-Authorization" --> GW
    A -. "claim mode only" .-> IB
    POD -. "attested tiers only" .-> AT
    POD --> DNS
    GW -- "ingress allowed only from the gateway" --> X
    GW == "residency dialer<br/>+ SSRF guard" ==> OUT["MCP servers, models,<br/>A2A peers, web"]

Per-session NetworkPolicy#

The operator creates <session>-maqpna for every session. It selects the session pod by maqpna.com/session=<name> (in warm-pool claim mode by agents.x-k8s.io/claim-uid=<uid>).

Direction Tier egress: gateway-only (default) Tier egress: deny-all
Ingress Only from pods labelled app.kubernetes.io/name: maqpna-gateway in the gateway namespace Same
Egress: DNS kube-dns, UDP and TCP 53 Only when attested or in claim mode
Egress: gateway Gateway pods None
Egress: attestation maqpna-attest pods, when the session is attested (also for deny-all, for the renewer) Same
Egress: bootstrap The identity broker's bootstrap port (8083), in claim mode Same

A deny-all session that is neither attested nor claimed has no egress at all.

Chart NetworkPolicies#

templates/networkpolicies.yaml adds policies the operator does not:

  1. maqpna-default-deny in each agent namespace (networkPolicy.agentNamespaces, default maqpna-agents): all pods, no ingress, egress only to kube-system DNS, the gateway port, and, when enabled, the identity bootstrap port and the attestation port. Agent namespaces are created with Pod Security enforce: baseline (warn and audit restricted).
  2. Control-plane ingress (networkPolicy.controlPlane.enabled): the gateway accepts its port only from agent namespaces (label maqpna.com/agent-namespace=true or listed) and from its own namespace; the identity broker's mint port only from its own namespace, its bootstrap port from agent namespaces; the attestation port from agent namespaces; the operator's metrics and health ports.
  3. The example mcp-echo server accepts ingress only from the gateway.

Gateway egress: two guards#

Guard Used for What it refuses
Residency dialer (pkg/sovereignty) Every upstream: MCP servers, model routes, A2A peers, OIDC and JWKS fetches, notifiers, SIEM, WORM, OpenTelemetry Any host whose resolved addresses are not all in allowedEgressCIDRs and whose name does not match allowedEgressHosts; cloud metadata and link-local ranges (169.254.0.0/16, fe80::/10, fd00:ec2::254/128) unless a CIDR explicitly allows them. Proxy-from-environment is disabled
SSRF guard (pkg/webguard) Agent-chosen destinations: maqpna-web fetch and search, browser egress Loopback, private, CGNAT, link-local, multicast, reserved, documentation and transition ranges; numeric host tricks (0x7f.1, 2130706433); plus the residency check

Both dialers resolve a name once, check every address, and dial the checked IP literal, so a second DNS answer (DNS rebinding) is never used. In sovereignty audit mode the residency dialer allows and reports violations, but metadata ranges stay blocked.

Agent-chosen destinations#

  1. Governed web (maqpna-web). A built-in MCP server in the gateway with tools fetch and search. Domains are checked against allow and deny lists from the gateway, the namespace and Agent.spec.web (strictest wins), then policy runs as for any tool call. Every result taints the session with untrusted-input (web.taintLabels).
  2. Browser egress. With Agent.spec.profile: browser, Chromium sends every request through --proxy-server=http://127.0.0.1:3128, the egress-relay sidecar. The relay adds Proxy-Authorization: Bearer <session token> (re-read per connection; the browser never sees the token) and forwards CONNECT and absolute-form requests to the gateway, which acts as a forward proxy when egress.enabled. The gateway authenticates the token (scope tools:maqpna-egress, kill switch), applies the domain policy with Agent.spec.browser.allowedDomains, evaluates ToolPolicy with server maqpna-egress and tool connect or http, dials through the SSRF guard and audits the connection. A require_approval decision is enforced as a denial (approval_required_not_supported_for_egress), because a browser cannot wait.
  3. Code interpreter. The exec sidecar listens on 8888 inside the pod; only the gateway can reach it (NetworkPolicy ingress), at POST /v1/sessions/{id}/exec. Code, output and files are DLP-scanned.

Ports#

Component Port Purpose
Gateway 8080 Data plane and (without adminListen) admin API, /metrics
Identity broker 8081 Mint, verify, exchange, JWKS (control plane only)
Identity broker 8083 /v1/bootstrap for warm-pool pods
Attestation service 8082 Releases and renewals
Example MCP server 8090 mcp-echo (dev and smoke tests)
Operator 8080 / 8081 Metrics / health probes
Session pod 3128, 9222, 6080, 8888 Egress relay, browser CDP and live view (localhost or gateway only), exec

What you see#

A domain outside the browser allow-list is refused by the egress proxy, and the agent's browser sees a failed connection; the ledger records it as a deny with server maqpna-egress. A blocked upstream on the model route returns:

{"error":{"message":"…","type":"maqpna_egress_denied","code":"egress_denied","reason":"egress_denied","domain":"maqpna.com"}}

maqpna preflight reports the CNI check, and maqpna doctor checks that every agent namespace has default-deny policies. See maqpna preflight and maqpna doctor.