Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
This split is deliberate, not an implementation detail to work around:

- Applying a Harness, AgentTemplate, or Agent is a **Kubernetes-native operation**, governed by Kubernetes RBAC, exactly like any other CRD.
- Creating, suspending, resuming, sharing, or deleting a Session, and holding a conversation with it, are **kagent-native operations**, governed by kagent's own gRPC authentication and authorization, independent of who can `kubectl apply` an Agent.
- Creating, sharing, or deleting a Session, and holding a conversation with that Session, are **kagent-native operations**, governed by kagent's own gRPC authentication and authorization, independent of who can `kubectl apply` an Agent.
4 changes: 2 additions & 2 deletions docs-site/content/kagent/1.x/about/architecture/kagent.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The previous page defined the [core concepts]({{< link path="about/core-concepts
kagent 1.0 splits authorization across two planes:

- The **Kubernetes plane** governs the {{< gloss "Harness" >}}Harness{{< /gloss >}} and {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} custom resources. Kubernetes Role-Based Access Control (RBAC) decides who can create, read, or edit the resources with `kubectl`, exactly as it would for any other Custom Resource Definition (CRD).
- The **kagent control plane** governs any interactions involving {{< gloss "Session" >}}Sessions{{< /gloss >}}, such as creating, suspending, resuming, sharing, deleting, and holding a conversation with a Session. kagent's own gRPC authentication and authorization decide who can complete these interactions, independent of Kubernetes RBAC.
- The **kagent control plane** governs any interactions involving {{< gloss "Session" >}}Sessions{{< /gloss >}}, such as creating, sharing, or deleting a Session, or holding a conversation with one. kagent's own gRPC authentication and authorization decide who can complete these interactions, independent of Kubernetes RBAC.

Someone with Kubernetes RBAC access to apply an Agent and the resources it names does not automatically have access to create or talk to Sessions on it. The separation runs in one direction only. kagent's gRPC API also writes those Kubernetes resources, so a caller on the kagent control plane reaches both planes. For more information on that second path, see [Identity]({{< link path="about/substrate-runtime/identity#the-kubernetes-plane" >}}).

Expand Down Expand Up @@ -74,6 +74,6 @@ From there, the caller holds a conversation over the {{< gloss "A2A" >}}A2A{{< /

## Why two planes

Kubernetes RBAC is designed to authorize configuration changes: who can create a Deployment, edit a ConfigMap, or in this case, apply a Harness, an AgentTemplate, or an Agent. It is not designed to authorize a running conversation, share access to it with another user, or scope who can suspend it. kagent's gRPC plane exists to authorize exactly those actions, at the granularity of a single Session rather than a namespace or a resource kind.
Kubernetes RBAC is designed to authorize configuration changes: who can create a Deployment, edit a ConfigMap, or in this case, apply a Harness, an AgentTemplate, or an Agent. It is not designed to authorize a running conversation, share access to it with another user, or scope who can read, rename, or delete it. kagent's gRPC plane exists to authorize exactly those actions, at the granularity of a single Session rather than a namespace or a resource kind.

This split also keeps the two lifecycles independent. Editing an Agent, or either resource it names, does not affect Sessions already running against the ActorTemplate that they were created from. It only affects new Sessions, created after the edit is compiled.
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ A token without the `kagent-agent-info` audience fails with `Invalid Agent ident

{{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} authenticates its own components rather than authenticating end users. Its API server accepts Kubernetes ServiceAccount tokens issued for its audience, and the components that carry traffic to an Actor authenticate each other with mutual Transport Layer Security (mTLS). `kagent install` creates the certificate authority pools and the JWT authority pool that these identities are issued from. No Helm chart creates these pools. For an installation that you manage with Helm, see [Export the installation to Helm]({{< link path="operations/export-to-helm" >}}).

The kagent controller sends A2A calls and Sandbox guest calls through the Agent Substrate router. When `config.substrate.routerUrl` uses `https`, the controller presents its rotating client certificate to the router and verifies the router against the Agent Substrate API certificate authority bundle. The router admits the controller only when `atenetRouter.ingressAllowedSPIFFEIDs` lists the controller's SPIFFE identity. For the Helm values, see [Agent Substrate actor ingress]({{< link path="operations/operational-considerations#agent-substrate-actor-ingress" >}}).

Each Actor also carries an identity of its own, addressed as its {{< gloss "Atespace" >}}atespace{{< /gloss >}} and name together. [Sandboxing]({{< link path="about/substrate-runtime/sandboxing" >}}) covers how the router uses that identity to reach the right Worker over mTLS.

> [!IMPORTANT]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ A model provider or an MCP server usually requires an API key or token. The agen

kagent builds these credentials from the following resources.

- Every ModelConfig that sets an `apiKeySecret` becomes a credential on the rule for that model's host.
- Every RemoteMCPServer whose `headersFrom` reads a Secret becomes a credential on the rule for its host.
- Every ModelConfig that sets `apiKeySecret` or `actorJwt` becomes a credential on the rule for that model's host.
- Every RemoteMCPServer whose `headersFrom` reads a Secret, or that sets `actorJwt`, becomes a credential on the rule for its host.
- Every EgressPolicy destination with an `authentication` block becomes a credential on the rule for its origin.

kagent attaches the credential to the destination's own rule rather than adding a rule for it, and it refuses to compile a credential whose host is not already an allowed destination.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,24 @@ An invalid field stops the controller from starting. After you apply a change, c
kubectl logs -n kagent deployment/kagent-controller
```

### Agent Substrate actor ingress {#agent-substrate-actor-ingress}

The kagent controller sends A2A calls and Sandbox guest calls through the Agent Substrate router. `kagent install` sets the router values on both charts, and an [exported installation]({{< link path="operations/export-to-helm" >}}) carries them. When you write the Helm values yourself, set both charts as follows.

1. In the kagent chart values, mount the controller's client certificate. The chart's default `config.substrate.routerUrl` already uses the router's HTTPS endpoint, and the controller presents this certificate on that endpoint.
```yaml
controller:
substrateClientCertificate:
enabled: true
```

2. In the Agent Substrate chart values, admit the controller's SPIFFE identity. The identity is built from the trust domain, the kagent namespace, and the `kagent-controller` ServiceAccount. An empty list denies every call from the controller.
```yaml
atenetRouter:
ingressAllowedSPIFFEIDs:
- spiffe://cluster.local/ns/kagent/sa/kagent-controller
```

### Runtime defaults

The only section of settings that the controller does not apply to itself is `config.runtimeDefaults`. The controller compiles those settings into each agent runtime that it starts. For a setting to apply to both the controller and the agents, such as the log level, the telemetry endpoints, or the content capture decision, configure that setting in both `config` and `config.runtimeDefaults`.
Expand Down Expand Up @@ -272,6 +290,26 @@ Each value applies per controller replica, so installation-wide delivery capacit
| `config.push.sendTimeout` | `5s` | How long each callback attempt waits for the receiver before the attempt fails. Specify seconds, such as `5s`. A Go duration such as `5000ms` is not accepted. |
| `config.push.recoveryInterval` | `60s` | How often each replica scans for callbacks that it missed and cleans up callback registrations that are no longer bound to a task. Specify seconds, such as `60s`. |

## Customize UI probes {#customize-ui-probes}

The UI image runs on a distroless base that has no shell and no `curl`, so an `exec` probe cannot run in the UI container. When you override `ui.startupProbe` or `ui.readinessProbe`, use an `httpGet` or `tcpSocket` probe. An override replaces the chart's default probe entirely. The defaults call `/health` on the `http` port.

```yaml
ui:
startupProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 1
periodSeconds: 5
failureThreshold: 20
readinessProbe:
httpGet:
path: /health
port: http
periodSeconds: 30
```

## Node operations

A {{< gloss "Worker" >}}Worker{{< /gloss >}} is an ordinary Kubernetes pod, so every node event reaches the {{< gloss "Actor" >}}Actors{{< /gloss >}} that this Worker hosts. What the event costs depends on what each Actor was doing when the node went away.
Expand Down
6 changes: 6 additions & 0 deletions docs-site/content/kagent/1.x/setup/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ The kagent CLI installs the CRDs, Agent Substrate, the Agent Substrate PodCertif
EOF
```

If your cluster uses a DNS domain other than `cluster.local`, also set `global.clusterDomain` in this file. The chart builds the URLs of the controller and the built-in `kagent-tool-server` MCP server from this domain, so agents cannot reach either service when the value is wrong.
```yaml
global:
clusterDomain: corp.example
```

2. Save a CLI configuration file that points the installer at those values. `kagent install` does not take Helm flags of its own, so chart values reach it through this file. A relative path in `valuesFiles` resolves against the configuration file's own directory.
```bash
cat > kagent-config.yaml <<EOF
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ The following fields set the token that the endpoint receives. For the token's c
| `actorJwt.audiences` | The services that can accept the token, between 1 and 16 values. The endpoint checks that its own audience is in the list. `kagent-runtime` is reserved and rejected. |
| `actorJwt.expirationSeconds` | Optional. The token lifetime, between 300 and 3600 seconds. Defaults to 900. |

Use `actorJwt` only with an endpoint that you configure, because the endpoint must accept a token that Agent Substrate issues. kagent does not exchange the Actor token for a provider credential. The API server rejects `actorJwt` on the `Bedrock`, `Gemini`, `Ollama`, `GeminiVertexAI`, `AnthropicVertexAI`, and `SAPAICore` providers, because those providers require provider-issued credentials. When `actorJwt` is set, `defaultHeaders` cannot override the credential header.
Use `actorJwt` only with an endpoint that you configure, because the endpoint must accept a token that Agent Substrate issues. kagent does not exchange the Actor token for a provider credential. The API server rejects `actorJwt` on the `Bedrock`, `Ollama`, `GeminiVertexAI`, `AnthropicVertexAI`, and `SAPAICore` providers, because those providers require provider-issued credentials. On the `Gemini` provider, the gateway sends the token as `Authorization: Bearer <token>` instead of in the `x-goog-api-key` header. When `actorJwt` is set, `defaultHeaders` cannot override the credential header.

### Turn off model streaming

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The native provider authenticates with a Bedrock API key, which kagent sends as
export AWS_BEARER_TOKEN_BEDROCK=<your-bedrock-api-key>
```

2. Create a Kubernetes Secret that holds the token under the key `AWS_BEARER_TOKEN_BEDROCK`. kagent looks that key up by name, so no other key works. Create the Secret in the same namespace as the AgentTemplates that use it, such as `kagent`.
2. Create a Kubernetes Secret that holds the token under the key `AWS_BEARER_TOKEN_BEDROCK`. kagent looks that key up by name, so no other key works. Create the Secret in the same namespace as the ModelConfig, such as `kagent`.
```bash
kubectl create secret generic bedrock-credentials -n kagent \
--from-literal AWS_BEARER_TOKEN_BEDROCK=$AWS_BEARER_TOKEN_BEDROCK
Expand Down Expand Up @@ -119,7 +119,7 @@ Bedrock also serves an [OpenAI-compatible chat completions API](https://docs.aws

## Use the ModelConfig

Reference the ModelConfig by name from an AgentTemplate in the same namespace.
Reference the ModelConfig by name from an AgentTemplate in the same namespace. To use the ModelConfig from another namespace, see [Share a ModelConfig across namespaces]({{< link path="setup/model-providers/about-model-providers#share-a-modelconfig-across-namespaces" >}}).

```yaml
spec:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The `Anthropic` provider calls the Anthropic API directly.
export ANTHROPIC_API_KEY=<your_api_key>
```

2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
2. Create a Kubernetes Secret that stores the API key. Create the Secret in the same namespace as the ModelConfig, such as `kagent`.
```bash
kubectl create secret generic kagent-anthropic -n kagent --from-literal ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY
```
Expand Down Expand Up @@ -103,7 +103,7 @@ The setting reaches only the generated ModelConfig. A ModelConfig that you creat

## Use the ModelConfig

Reference the ModelConfig by name from an AgentTemplate in the same namespace.
Reference the ModelConfig by name from an AgentTemplate in the same namespace. To use the ModelConfig from another namespace, see [Share a ModelConfig across namespaces]({{< link path="setup/model-providers/about-model-providers#share-a-modelconfig-across-namespaces" >}}).

```yaml
spec:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The `Foundry` provider calls a model deployment in an Azure AI Foundry resource.
export FOUNDRY_API_KEY=<your-foundry-api-key>
```

2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
2. Create a Kubernetes Secret that stores the API key. Create the Secret in the same namespace as the ModelConfig, such as `kagent`.
```bash
kubectl create secret generic foundry-api-key -n kagent --from-literal api-key=$FOUNDRY_API_KEY
```
Expand Down Expand Up @@ -89,13 +89,14 @@ kubectl describe modelconfig foundry-model-config -n kagent
| ------------- | ---------- |
| `apiKeySecret` is set | The API key from the referenced Secret. |
| `tokenPassthrough: true` | The bearer token from the caller's request, forwarded to Foundry as the API key. Mutually exclusive with `apiKeySecret`. |
| `actorJwt` is set | A newly issued Actor token, sent in the provider's credential header. Mutually exclusive with `apiKeySecret`, `apiKeySecretKey`, and `tokenPassthrough`. For more information, see [Authenticate as the Actor]({{< link path="setup/model-providers/about-model-providers#authenticate-as-the-actor" >}}). |

> [!WARNING]
> **Azure Workload Identity is not currently supported.** In earlier versions of kagent, omitting the credential fields fell back to Azure Workload Identity, which depended on an annotated ServiceAccount on the agent's pod. An agent now runs as a Substrate Actor rather than as a pod that kagent controls, so there is no per-agent ServiceAccount to federate an Azure identity onto. Supply an API key instead.

## Use the ModelConfig

Reference the ModelConfig by name from an AgentTemplate in the same namespace.
Reference the ModelConfig by name from an AgentTemplate in the same namespace. To use the ModelConfig from another namespace, see [Share a ModelConfig across namespaces]({{< link path="setup/model-providers/about-model-providers#share-a-modelconfig-across-namespaces" >}}).

```yaml
spec:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The `AzureOpenAI` provider calls an Azure OpenAI deployment. It differs from the
export AZURE_OPENAI_API_KEY=<your-azure-openai-api-key>
```

2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
2. Create a Kubernetes Secret that stores the API key. Create the Secret in the same namespace as the ModelConfig, such as `kagent`.
```bash
kubectl create secret generic azure-openai-api-key -n kagent --from-literal api-key=$AZURE_OPENAI_API_KEY
```
Expand Down Expand Up @@ -107,13 +107,14 @@ A link reaches Azure regardless of its media type. Inline bytes reach Azure as a
| `apiKeySecret` is set | The API key from the referenced Secret. |
| `azureOpenAI.azureAdToken` is set | The Microsoft Entra ID token given in the field. |
| `tokenPassthrough: true` | The bearer token from the caller's request, forwarded to Azure OpenAI as the API key. This is not Microsoft Entra ID authentication, and it is mutually exclusive with `apiKeySecret`. |
| `actorJwt` is set | A newly issued Actor token, sent in the `api-key` header. This is not Microsoft Entra ID authentication, and it is mutually exclusive with `apiKeySecret`, `apiKeySecretKey`, and `tokenPassthrough`. For more information, see [Authenticate as the Actor]({{< link path="setup/model-providers/about-model-providers#authenticate-as-the-actor" >}}). |

> [!WARNING]
> **Azure Workload Identity is not currently supported.** In earlier versions of kagent, omitting the credential fields fell back to Azure Workload Identity, which depended on an annotated ServiceAccount on the agent's pod. An agent now runs as a Substrate Actor rather than as a pod that kagent controls, so there is no per-agent ServiceAccount to federate an Azure identity onto. Supply a credential with one of the configurations in the preceding table.

## Use the ModelConfig

Reference the ModelConfig by name from an AgentTemplate in the same namespace.
Reference the ModelConfig by name from an AgentTemplate in the same namespace. To use the ModelConfig from another namespace, see [Share a ModelConfig across namespaces]({{< link path="setup/model-providers/about-model-providers#share-a-modelconfig-across-namespaces" >}}).

```yaml
spec:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ EOF
{{% tab name="API key authentication" %}}
When your agentgateway deployment applies an `apiKeyAuthentication` policy with `mode: Strict`, supply the API key that callers send in the `Authorization` header.

1. Create a Kubernetes Secret that stores the API key, in the same namespace as the AgentTemplates that use it.
1. Create a Kubernetes Secret that stores the API key, in the same namespace as the ModelConfig.
```bash
export AGENTGATEWAY_API_KEY=<your-api-key>
kubectl create secret generic kagent-agentgateway-key -n kagent \
Expand Down Expand Up @@ -146,7 +146,7 @@ For every `openAI` field, including its type, default, and validation rules, see

## Use the ModelConfig

Reference the ModelConfig by name from an AgentTemplate in the same namespace.
Reference the ModelConfig by name from an AgentTemplate in the same namespace. To use the ModelConfig from another namespace, see [Share a ModelConfig across namespaces]({{< link path="setup/model-providers/about-model-providers#share-a-modelconfig-across-namespaces" >}}).

```yaml
spec:
Expand Down
4 changes: 2 additions & 2 deletions docs-site/content/kagent/1.x/setup/model-providers/gemini.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Make sure that your Google Cloud account has a project with the Gemini API enabl
export GOOGLE_API_KEY=<your_api_key>
```

2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
2. Create a Kubernetes Secret that stores the API key. Create the Secret in the same namespace as the ModelConfig, such as `kagent`.
```bash
kubectl create secret generic kagent-gemini -n kagent --from-literal GOOGLE_API_KEY=$GOOGLE_API_KEY
```
Expand Down Expand Up @@ -58,7 +58,7 @@ The `gemini` block takes one optional setting. For its type, default, and valida

## Use the ModelConfig

Reference the ModelConfig by name from an AgentTemplate in the same namespace.
Reference the ModelConfig by name from an AgentTemplate in the same namespace. To use the ModelConfig from another namespace, see [Share a ModelConfig across namespaces]({{< link path="setup/model-providers/about-model-providers#share-a-modelconfig-across-namespaces" >}}).

```yaml
spec:
Expand Down
Loading
Loading