Protected model access for managed Kubernetes agents.
The optional protected path makes the Model Router the controlled model-access boundary for AgentFleet-managed agents in explicitly protected namespaces.
What the protected path covers#
The end-to-end path combines workload identity, controlled egress, provider credential isolation, policy, optional Guard inspection, suspension, and audit records. Confirm enforcement with the CNI, service-mesh mode, and managed Kubernetes platform used by your deployment.
Protected request path#
- The operator gives each managed agent a dedicated ServiceAccount and a short-lived, audience-bound projected token.
- An operator-owned default-deny NetworkPolicy permits model traffic only to the Model Router, plus explicitly approved platform destinations.
- The Model Router validates the token with Kubernetes TokenReview and binds the verified ServiceAccount to the Registry tenant and agent identity.
- Policy and approval controls run before provider access. Configured Guard bindings inspect model input and output.
- The Model Router injects server-side provider credentials, calls the approved provider, and emits payload-minimized audit, usage, latency, and cost evidence.
Controls and ownership#
spec.suspended scales the agent to zero, removes it from Gateway routing, and causes workload model calls to fail with agent_suspended.Install and protect a namespace#
Use the profile only with an enforcing CNI such as Calico, Cilium, GKE Dataplane V2, or a supported managed-cloud network-policy implementation. The Helm enforcement probe fails installation when default-deny egress is not active.
helm upgrade --install agentfleet ./agentfleet \
--namespace agentfleet-system --create-namespace \
-f agentfleet/profiles/protected-path.yaml \
-f agentfleet-images.values.json \
--set gateway.config.auth.mode=entra_app \
--set gateway.config.auth.entraApp.directoryID=<directory-id> \
--set gateway.config.auth.entraApp.requiredRole=<app-role> \
--set gateway.config.auth.oidcJwt.issuer=https://login.microsoftonline.com/<directory-id>/v2.0 \
--set 'gateway.config.auth.oidcJwt.audience[0]=<token-audience>' \
--set gateway.config.auth.oidcJwt.jwksURL=https://login.microsoftonline.com/<directory-id>/discovery/v2.0/keys \
--set gateway.config.auth.entraApp.bindings.existingSecret=<identity-db-secret> \
--set gateway.config.auth.entraApp.auditDigest.existingSecret=<audit-digest-secret> \
--set modelRouter.workloadIdentity.auditDigest.existingSecret=<audit-digest-secret>
kubectl label namespace team-agents agentfleet.io/protection=managed
The protected-path profile does not choose a Gateway auth mode, so the command above chooses entra_app, which requires an approved Registry binding for each caller. off (the default), header_dev and oidc_jwt admit a caller with no Registry caller record, so the caller is not checked against the Registry: off and header_dev are for local development only, oidc_jwt may run in production (its flags are on Install with Helm), and the chart refuses to render the Gateway in any of the three unless gateway.config.auth.allowUnregisteredCallers=true acknowledges that. The protected-path profile also needs the Model Router's audit-digest Secret (modelRouter.workloadIdentity.auditDigest.existingSecret), and the chart's values note that the digest key must be the one the Gateway, Model Router and Console share, so the command names the same placeholder for both. Replace each <placeholder> with your own value: your Entra directory ID, the application role callers must hold, the audience of the tokens, and the names of two Secrets you create first (the identity-binding database DSN and the audit-digest key); the values reference lists every gateway.config.auth.entraApp key.
Plain Kubernetes is the baseline. Istio remains an optional overlay, not a requirement for the protected path.
Suspend and resume an agent#
kubectl patch agent refund-agent -n team-agents --type=merge \
-p '{"spec":{"suspended":true}}'
kubectl patch agent refund-agent -n team-agents --type=merge \
-p '{"spec":{"suspended":false}}'
The propagation target is 30 seconds. Registry state refreshes at the Model Router on a shorter interval so a published suspension normally reaches model access within about five seconds.
Security boundary#
- Protection applies only to namespaces labeled
agentfleet.io/protection=managedafter the network-policy enforcement probe passes. - External agents, unlabeled namespaces, non-enforcing CNIs, and cluster administrators remain outside this boundary.
- Guard does not claim complete prompt-injection prevention, factuality, or universal content safety.
- Guard provides deterministic inspection for configured checks; learned classification is not enabled by default.
Review Architecture, Operations, and Availability before enabling this path for customer traffic.