Skip to content
This documentation covers the kagent 1.0 alpha. For the latest 0.x release, see the 0.x docs.

For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.

Egress policies

Page as Markdown

Grant an Agent or a standalone sandbox access to HTTP and HTTPS destinations beyond its model and tools, and inject a credential into requests to those destinations.

An AgentAgentA Kubernetes custom resource that pairs one AgentTemplate with one Harness. Each side takes either an inline spec or a reference to an existing resource, and the controller compiles the pair into a revision.Learn more reaches only the destinations that its AgentTemplate needs, such as its model provider, its Model Context Protocol (MCP) servers, and its skill sources. kagent infers these destinations and compiles them into the agent’s egress policy. The egress gateway denies every other destination.

To grant an Agent or SandboxTemplate access to destinations beyond the inferred set, you can create an EgressPolicy resource. The Agent or SandboxTemplate selects one or more policies by name in its spec.egressPolicyRefs field. An EgressPolicy only adds access, and cannot remove a destination that kagent inferred from the model or the tools.

A policy can also reference a credential in a Kubernetes Secret. The gateway adds the credential to each request, so the value never enters the agent’s sandbox. Typical uses include a package registry that a skill installs from, or an internal API that a tool script calls.

Before you begin

Create the resource that you want to grant access to. The examples on this page use the kagent namespace.

  • Agent: Create your first agent, so that you have the my-first-agent Agent. Use commands in the “Agent” tabs in the following steps.
  • Standalone sandbox: Create the scratch SandboxTemplate, as described in Create a SandboxTemplate. Use commands in the “Standalone sandbox” tabs in the following steps.

Grant access to a destination

Create an EgressPolicy that lists the destinations that you want to grant access to, and then select the policy on the Agent or SandboxTemplate.

  1. Create the EgressPolicy in the namespace of the Agent or SandboxTemplate. A resource can select only the policies in its own namespace. This example grants access to the npm registry and the Node.js download site.

    kubectl apply -f - <<EOF
    apiVersion: api.kagent.dev/v1alpha3
    kind: EgressPolicy
    metadata:
      name: node-dependencies
      namespace: kagent
    spec:
      destinations:
        - origin: https://registry.npmjs.org
        - origin: https://nodejs.org
    EOF

    Review the following table to understand this configuration. Each destination grants one origin, and the grant covers every path on that origin. For the complete schema, see the API reference.

    FieldDescription
    destinationsThe destinations to grant, from 1 to 64 entries.
    destinations[].originA scheme, a DNS hostname, and an optional port, such as https://registry.npmjs.org or https://search.example.com:8443. For the accepted forms, see Origin format.
    destinations[].authenticationOptional. A credential for the gateway to add to each request. For more information, see Inject a credential.
  2. Select the policy in the spec.egressPolicyRefs field.

    The AgentTemplate and the Harness cannot select a policy, so two Agents that share an AgentTemplate can have different access. The grant applies to the whole ActorActorThe sandboxed unit of compute, provided by Agent Substrate, that runs a Session's conversation loop. Every Session is backed by one.Learn more, including the subagents that run in it.

    kubectl patch agent my-first-agent -n kagent --type merge \
      -p '{"spec":{"egressPolicyRefs":[{"name":"node-dependencies"}]}}'

  3. Check that kagent admitted the grant. When kagent admits every selected policy, the EgressPoliciesApplied condition reports True with the reason Applied.

    kubectl get agent my-first-agent -n kagent \
      -o jsonpath='{range .status.conditions[?(@.type=="EgressPoliciesApplied")]}{.status} {.reason} {.message}{end}'

    Example output:

    True Applied All requested egress grants are admitted
    

The grant reaches existing workloads as well as new ones. kagent updates the policy of every running and suspended Actor without restarting it. For an Agent, this update covers every SessionSessionA running conversation with one Agent. Unlike the resources it is built from, a Session is not a Kubernetes resource: kagent's gRPC API creates it and its PostgreSQL database tracks it.Learn more. For a SandboxTemplate, the update covers every Sandbox that was created from the template. The update is asynchronous, so a request that is sent immediately after the change might still use the previous policy.

Origin format

An origin names exactly one scheme, host, and port. The scheme must be http or https. When the port is omitted, kagent uses 443 for https and 80 for http. The API server rejects an origin that contains a path, a query, a fragment, user information, or an IP address.

A wildcard can replace the leftmost label of the hostname. For example, https://*.example.com matches api.example.com, but it matches neither example.com nor a.b.example.com. The API server rejects * and https://*.com.

A redirect to another origin needs its own grant. For example, a package registry often serves downloads from a separate host. An install fails at that host until the policy grants it as well.

The API server rejects a policy or an egressPolicyRefs list that exceeds the first two of the following limits. The compiled policy limit also counts the destinations that kagent inferred, so an Agent with many tools reaches it sooner.

LimitValue
Policies that one Agent or SandboxTemplate selects16
Destinations in one policy64
Rules in the compiled policy of one Actor256
Credential headers for one origin16

Inject a credential

The gateway can add a credential from a Kubernetes Secret to each request for an origin. The agent sends the header with a placeholder value, and the gateway replaces this value as the request passes through. The Secret value is not stored in the agent’s revision and never reaches the sandbox.

  1. Create the Secret in the namespace of the EgressPolicy.

    kubectl create secret generic ticket-auth -n kagent \
      --from-literal=token=<your-api-token>
  2. Create an EgressPolicy with an authentication block for the destination.

    kubectl apply -f - <<EOF
    apiVersion: api.kagent.dev/v1alpha3
    kind: EgressPolicy
    metadata:
      name: ticket-api
      namespace: kagent
    spec:
      destinations:
        - origin: https://tickets.example.com
          authentication:
            header: Authorization
            prefix: "Bearer "
            secretKeyRef:
              name: ticket-auth
              key: token
    EOF

    Review the following table to understand this configuration. The gateway sets the header to the prefix followed by the Secret value.

    FieldDescription
    originThe destination. An origin with a credential must be exact, so the API server rejects a wildcard origin. On a cleartext http origin, the credential is readable on the path between the gateway and the destination. Use an http origin with a credential only for an in-cluster service whose traffic a service mesh encrypts.
    authentication.headerThe request header that carries the credential, such as Authorization or X-API-Key. The API server rejects the headers that control routing and framing, such as Host and Content-Length, and the Proxy-Authorization, Proxy-Authenticate, and Cookie headers.
    authentication.prefixOptional. Text that the gateway puts before the Secret value. The prefix is literal. Include the trailing space, as in "Bearer ". When the prefix is omitted or empty, the header contains only the Secret value.
    authentication.secretKeyRefThe Secret and key that store the credential. Both name and key are required, and the reference cannot be optional.
  3. Select the policy. A merge patch replaces the whole egressPolicyRefs list, so the command also keeps node-dependencies. Include every policy that the resource needs.

    kubectl patch agent my-first-agent -n kagent --type merge \
      -p '{"spec":{"egressPolicyRefs":[{"name":"node-dependencies"},{"name":"ticket-api"}]}}'

  4. In the script or software development kit (SDK) that sends the request, send the header with a placeholder value. The gateway replaces a header that the request already sends, and it does not add a header that is missing. Selecting a policy does not configure a tool or set an environment variable. The client must also trust the egress gateway’s certificate authority, which kagent provides to every Actor. For the variables that carry the trust bundle, see Environment variables on an Actor.

    curl -H 'Authorization: Bearer kagent-credential-injected' \
      https://tickets.example.com/tickets

To rotate the credential, update the Secret. The gateway reads the value from the Secret, so the agent’s revision does not change.

Troubleshoot a grant

The EgressPoliciesApplied condition on the Agent or SandboxTemplate reports whether kagent admitted the grants. This condition is independent of Ready. An Agent with a missing or invalid policy still reports Ready, and it still serves Sessions with its inferred destinations.

The condition message names the affected policies, and the reason identifies the problem.

StatusReasonMeaning
TrueAppliedkagent admitted every selected policy.
FalseEgressPolicyNotFoundA selected policy does not exist, or is being deleted.
FalseInvalidEgressPolicyA policy, a Secret reference, or the egressPolicyRefs list is invalid. For example, the Secret or its key does not exist.
FalseEgressGrantConflictA new grant conflicts with an existing one. kagent holds the new grants, and keeps the previously admitted grants that are still selected and compatible.

A problem with one policy does not block the others. A policy that is missing or invalid does not grant any access, and the remaining policies still apply. An egressPolicyRefs list that is itself invalid revokes every grant for that resource. For example, one name that is not a valid Kubernetes resource name, such as Node-Deps, revokes the grants of every other policy in the list.

A grant conflict happens in the following cases:

  • Two policies set a different Secret or prefix for the same origin and header.
  • A grant sets a credential for an origin that already has a credential from the model or a tool. The credential from the model or the tool always takes precedence.
  • A grant sets a credential for an origin that uses token passthrough. Token passthrough and a Secret credential cannot share an origin.
  • The compiled policy would exceed 256 rules.

In a standalone Sandbox, a destination that no grant allows does not resolve. A client therefore reports a name-resolution error, not an HTTP error. For example, curl fails with Could not resolve host and exit code 6. For how to find a denied request in the gateway’s log, see Diagnose a denied request.

Access control

An EgressPolicy is namespace-scoped, and kagent does not check who may select it. A user who can create or edit an Agent or a SandboxTemplate in a namespace can select every EgressPolicy in this namespace and use its credentials. Treat the namespace as the boundary for sharing policies and the Secrets that they reference. For more information about how Kubernetes role-based access control (RBAC) governs who can write these resources, see The Kubernetes plane.

To control who can grant access, give the permission to create and edit EgressPolicy resources only to administrators. The kagent controller needs only read access to EgressPolicy resources.

The gateway keeps a credential out of the sandbox, but it cannot stop an allowed destination from returning the credential in a response. Grant a credential only to a destination that you trust with it.

Clean up

  1. Remove the policies from the resource.

    kubectl patch agent my-first-agent -n kagent --type json \
      -p '[{"op":"remove","path":"/spec/egressPolicyRefs"}]'

  2. Delete the EgressPolicy resources and the Secret.

    kubectl delete egresspolicy node-dependencies ticket-api -n kagent
    kubectl delete secret ticket-auth -n kagent

Next steps