Ports and endpoints
Every port each MAQPNA component listens on, the protocol and main endpoints behind it, which ones you can expose outside the cluster, and the NetworkPolicies the chart and the operator create.
This page lists every port MAQPNA components listen on, in a cluster and on a laptop. Use it when you write firewall rules or NetworkPolicies, expose the gateway to clients outside the cluster, or point Prometheus at the right port. For the design behind the network rules, read Network and egress and Trust zones.
Network at a glance#
flowchart LR
subgraph ext["Outside the cluster"]
C["MCP clients, SDKs,<br/>maqpna CLI"]
T["MCP servers, model APIs,<br/>SIEM, WORM, OIDC"]
end
subgraph agents["Agent namespace (maqpna-agents)"]
S["Sandbox pod<br/>exec :8888 (code interpreter)<br/>relay 127.0.0.1:3128 (browser)"]
end
subgraph sys["MAQPNA namespace (maqpna-system)"]
GW["Gateway<br/>http :8080<br/>admin (adminListen)"]
ID["Identity broker<br/>http :8081<br/>bootstrap :8083"]
OP["Operator<br/>metrics :8080<br/>health :8081"]
AT["Attestation<br/>http :8082"]
EC["mcp-echo :8090"]
end
DNS["kube-dns :53"]
C -->|"Service type NodePort or LoadBalancer,<br/>or your Ingress"| GW
S -->|"TCP 8080"| GW
S -->|"UDP/TCP 53"| DNS
S -.->|"warm pool only: TCP 8083"| ID
S -.->|"attested tiers"| AT
GW -->|"TCP 8888 (exec)"| S
GW -->|"JWKS, token exchange"| ID
OP -->|"mint tokens"| ID
GW --> EC
GW -->|"egress, allowlisted"| T
Solid arrows are always allowed by the default policies. Dotted arrows are allowed only when the feature is on. Only the gateway reaches hosts outside the cluster. Sandboxes reach DNS and the gateway, nothing else.
Kubernetes installation#
Defaults come from the binaries' flags and the Helm chart (deploy/helm/maqpna/values.yaml). Names below assume the release is called maqpna in namespace maqpna-system, so the Services are maqpna-gateway, maqpna-identity and so on. Every Service the chart renders is ClusterIP, except the gateway's, whose type you choose.
| Component | Port name | Default port | Protocol | Helm value | What it serves | Reachable from (default policy) |
|---|---|---|---|---|---|---|
| Gateway | http |
8080 |
HTTP/1.1 and HTTP/2; HTTPS when tls.certFile is set |
gateway.port |
MCP (/mcp/{server}), model calls (/llm/{route}/...), A2A (/a2a/...), the admin API (/v1/...), /healthz, /readyz, /metrics, /version; HTTP CONNECT egress proxy when egress.enabled |
Agent namespaces and pods of the release namespace |
| Gateway | admin |
none (off) | HTTP | gateway.config.adminListen |
Admin API, /metrics and /debug/pprof/ (admin role) only. With it set, those paths answer 404 on http. |
No pod, unless you list peers in networkPolicy.controlPlane.gatewayAdminFrom or metricsFrom. Use kubectl port-forward. |
| Identity broker | http |
8081 |
HTTP; HTTPS with -tls-cert and -tls-key |
identity.port |
Token mint and exchange (/v1/token, /v1/exchange, ...), /.well-known/jwks.json, /.well-known/openid-configuration, /metrics (build info) |
Pods labelled app.kubernetes.io/part-of: maqpna |
| Identity broker | bootstrap |
8083 |
HTTP | identity.bootstrap.port |
POST /v1/bootstrap for warm-pool sandboxes (late binding) |
Agent namespaces, when identity.bootstrap.enabled |
| Operator | metrics |
8080 |
HTTP | operator.metrics.port |
/metrics (--metrics-bind-address) |
Pods of the release namespace, plus metricsFrom |
| Operator | health |
8081 |
HTTP | operator.health.port |
/healthz, /readyz (--health-probe-bind-address) |
Pods of the release namespace. No Service port. |
| Attestation service | http |
8082 |
HTTP | attestation.port |
Releases and renewals (/v1/releases, /v1/renewals), /healthz, /version, /metrics |
Agent namespaces and MAQPNA pods, plus metricsFrom. Only when attestation.enabled. |
| mcp-echo (example) | http |
8090 |
HTTP | examples.mcpEcho.port |
A harmless test MCP server | The gateway. On by default; turn it off in production. |
| llamay (optional) | http |
8081 |
HTTP | llamay.port |
Local model server | The gateway. Only when llamay.enabled. |
Inside a sandbox pod, two more listeners exist. Neither has a Service.
| Process | Default address | Set by | Notes |
|---|---|---|---|
maqpna-exec (code-interpreter sidecar) |
:8888 |
MAQPNA_EXEC_LISTEN |
Only the gateway calls it. The session NetworkPolicy admits ingress from gateway pods only. |
maqpna-egress-relay (browser sandboxes) |
127.0.0.1:3128 |
MAQPNA_EGRESS_RELAY_LISTEN |
Loopback forward proxy for Chromium. It adds the session token and forwards to the gateway's egress proxy. |
Gateway endpoints by listener#
| Path | Listener | Auth | Reference |
|---|---|---|---|
POST /mcp/{server}, GET /mcp/{server}, DELETE /mcp/{server} |
http |
Session token | Gateway API |
GET /.well-known/oauth-protected-resource/mcp/{server} |
http |
None | Gateway API |
POST /llm/{route}/v1/..., POST /llm/{route}/anthropic/v1/... |
http |
Session token | Gateway API |
POST /a2a/{ns}/{agent}, GET /a2a/jwks.json |
http |
Session token (calls) | Gateway API |
/v1/... admin endpoints |
http, or admin when adminListen is set |
Access token or admin token | Admin API |
GET /metrics |
http, or admin when adminListen is set |
None | Metrics |
/debug/pprof/ |
admin only |
Admin role | — |
GET /healthz, GET /readyz, GET /version |
http (and admin) |
None | — |
What you can expose outside the cluster#
The chart renders no Ingress, Route or Gateway API object. Only the gateway is meant to be reached from outside, in one of three ways:
gateway.service.type: LoadBalancer: your cloud gives themaqpna-gatewayService an external address on port8080.gateway.service.type: NodePortwithgateway.service.nodePort(for example30080on kind).- Your own Ingress, OpenShift Route or HTTPRoute to the
maqpna-gatewayService, port8080, with TLS terminated there. See Production install with Helm.
Keep these cluster-internal: the identity broker, the operator, the attestation service, mcp-echo and llamay. The CLI reaches them, and the gateway admin port, with port-forwarding (maqpna console, maqpna port-forward).
NetworkPolicies#
MAQPNA needs a CNI that enforces NetworkPolicy (Calico, Cilium, OVN-Kubernetes and others).
From the chart#
| Policy | Namespace | Selects | Ingress | Egress | Value |
|---|---|---|---|---|---|
maqpna-default-deny |
each agent namespace | sandbox pods not labelled maqpna.com/egress=deny-all |
none | kube-dns UDP/TCP 53; gateway TCP gateway.port; identity broker bootstrap port (when on); attestation service port (when on); extraEgress |
networkPolicy.agentNamespaces |
maqpna-deny-all-tier |
each agent namespace | pods labelled maqpna.com/egress=deny-all |
none | none | networkPolicy.agentNamespaces |
| gateway | release namespace | gateway pods | TCP gateway.port from agent namespaces and the release namespace; admin port from gatewayAdminFrom; metrics port from metricsFrom |
not restricted (see FQDN egress) | networkPolicy.controlPlane |
| identity broker | release namespace | identity pods | TCP identity.port from MAQPNA pods; bootstrap port from agent namespaces |
not restricted | networkPolicy.controlPlane |
| attestation service | release namespace | attest pods | TCP attestation.port from agent namespaces, MAQPNA pods and metricsFrom |
not restricted | networkPolicy.controlPlane |
| operator | release namespace | operator pods | metrics and health ports from the release namespace; metrics from metricsFrom |
not restricted | networkPolicy.controlPlane |
| mcp-echo | release namespace | mcp-echo pods | TCP examples.mcpEcho.port from gateway pods |
not restricted | examples.mcpEcho |
| llamay | release namespace | llamay pods | TCP llamay.port from gateway pods |
none; DNS 53 and TCP 443 when llamay.models.pull is on |
llamay |
Agent namespaces are those listed in networkPolicy.agentNamespaces.names (default maqpna-agents) and any namespace labelled maqpna.com/agent-namespace: "true".
FQDN egress for the gateway (optional)#
With networkPolicy.fqdnEgress.enabled: true, the chart mirrors the gateway's own egress allowlist (sovereignty.allowedEgressHosts, allowedEgressCIDRs and fqdnEgress.extraHosts) into the CNI, on fqdnEgress.ports (default [443]). The kernel then drops what the gateway would refuse.
provider |
Objects |
|---|---|
cilium (default) |
CiliumNetworkPolicy with toFQDNs |
gke |
FQDNNetworkPolicy (Dataplane V2) plus a NetworkPolicy |
eks |
ApplicationNetworkPolicy (VPC CNI) plus a NetworkPolicy |
For gke and eks, add the Kubernetes API server CIDR to fqdnEgress.clusterCIDRs when gateway.configSync or gateway.activity is on; the chart refuses to render otherwise.
From the operator, per session#
The operator creates one NetworkPolicy per session, selecting that session's pods:
| Trust tier egress | Ingress | Egress |
|---|---|---|
| gateway-only | gateway pods | DNS 53; gateway pods; attestation service when attested; identity broker bootstrap port for warm-pool sessions |
deny-all |
gateway pods | nothing; or DNS and the attestation service when attested; plus the bootstrap port for warm-pool sessions |
A quarantined session gets an empty policy: no ingress and no egress. The policy stays until the session is deleted, so a lingering pod stays fenced.
Local MAQPNA (maqpna dev up)#
Everything binds to 127.0.0.1 unless you pass --kosa8, which serves the gateway on the host's LAN address.
| Process | Default | Flag |
|---|---|---|
| Gateway | 127.0.0.1:8080 |
--gateway-port |
| Identity broker | 127.0.0.1:8081 |
--identity-port |
| mcp-echo | 127.0.0.1:8090 |
--echo-port, off with --no-echo |
| stub-llm | 127.0.0.1:8000 |
--stub-llm-port, with --stub-llm |
| llamay | 11435 |
--llamay-port, with --llamay |
Other CLI listeners:
| Command | Default | Flag |
|---|---|---|
maqpna console |
127.0.0.1:8088 |
--port (0: any free port) |
maqpna desk |
127.0.0.1:0 (a free port) |
--addr (loopback only) |
maqpna port-forward |
127.0.0.1 |
--address |
See maqpna dev up and maqpna console.
Check it worked#
List the Services and their ports:
kubectl -n maqpna-system get svc -o wide
kubectl -n maqpna-system get networkpolicy
From a sandbox namespace, the gateway answers and the identity broker's main port does not:
kubectl -n maqpna-agents run nettest --rm -it --restart=Never --image=curlimages/curl -- \
sh -c 'curl -s -m 3 http://maqpna-gateway.maqpna-system.svc:8080/healthz; echo; curl -s -m 3 http://maqpna-identity.maqpna-system.svc:8081/healthz || echo blocked'
On a laptop, curl -s http://127.0.0.1:8080/healthz answers {"status":"ok"} while maqpna dev up runs.
What can go wrong#
| Symptom | Cause | Fix |
|---|---|---|
| Agents time out calling the gateway | The agent namespace is not in networkPolicy.agentNamespaces.names and not labelled maqpna.com/agent-namespace: "true". |
Add the name, or label the namespace. |
404 on /v1/... or /metrics from outside |
adminListen is set; those paths are served only on the admin port. |
Use maqpna console or port-forward to the admin port. |
| Prometheus cannot scrape | The control-plane policies admit only pods of the release namespace. | Set networkPolicy.controlPlane.metricsFrom. |
| Warm-pool sessions never become ready | Identity bootstrap port blocked, or identity.bootstrap.enabled: false. |
Keep the bootstrap port open from agent namespaces. |
| The gateway cannot reach a model API after turning on FQDN egress | The host is not in the allowlist. | Add it to sovereignty.allowedEgressHosts or networkPolicy.fqdnEgress.extraHosts. |
| Policies have no effect | The CNI does not enforce NetworkPolicy. | Use a CNI that does (Calico, Cilium, OVN-Kubernetes). |
Next steps#
- Network and egress: why sandboxes reach only the gateway.
- Gateway configuration:
listen,adminListen,tlsandegress. - Metrics: what each component exports on its metrics port.
- Security hardening: lock down exposure in production.
- Helm values: every
networkPolicy.*,gateway.service.*and port value.