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.

kagent architecture

Page as Markdown

See how a Harness and AgentTemplate become a running conversation, across kagent’s two authorization planes.

The previous page defined the core concepts of Harness, AgentTemplate, AgentInstance, and Actor. This page connects them into one system: how applying a Harness and AgentTemplate leads to a running conversation, and which parts of that path Kubernetes governs versus which parts kagent governs itself.

Two authorization planes

kagent 1.0 splits authorization across two planes:

  • The Kubernetes plane governs the HarnessHarnessA Kubernetes custom resource defining how an agent is allowed to run: its runtime, workload image, WorkerPool and snapshot storage, and which AgentTemplates it accepts.Learn more and AgentTemplateAgentTemplateA Kubernetes custom resource defining what an agent does: its model, system prompt, tools, skills, and plugins. It runs only once a Harness accepts it.Learn more 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 plane governs any interactions involving AgentInstancesAgentInstanceA running, conversational pairing of a Harness and an AgentTemplate. Unlike the two, it is not a Kubernetes resource: kagent's gRPC API creates it and its database tracks it.Learn more, such as creating, suspending, resuming, sharing, deleting, and holding a conversation with an AgentInstance. kagent’s own gRPC authentication and authorization decide who can complete these interactions, independent of Kubernetes RBAC.

Someone with Kubernetes RBAC access to apply a Harness and AgentTemplate does not automatically have access to create or talk to AgentInstances that use them. The planes are not mirror images, though. kagent’s gRPC API also writes Harness and AgentTemplate resources, so a caller on the kagent plane reaches both. For more information on that second path, see Identity.

The following diagram shows where the boundary between the two planes falls.

    flowchart TB

    subgraph k8s["Kubernetes plane (RBAC)"]
        operator["Operator<br>kubectl apply"]
        harness["Harness"]
        template["AgentTemplate"]
        controller["kagent controller"]
        operator --> harness
        operator --> template
        harness --> controller
        template --> controller
    end

    %% Declared outside both subgraphs on purpose. An ActorTemplate is a Substrate
    %% resource reached over gRPC, not a Kubernetes object, so it belongs to
    %% neither plane. A node joins whichever subgraph first references it, so both
    %% of its edges have to live out here too.
    actortemplate["ActorTemplate (Substrate)"]
    controller -->|compiles the pair into| actortemplate

    subgraph kagentplane["kagent plane (gRPC auth)"]
        caller["Caller"]
        gateway["A2A gateway"]
        instance["AgentInstance"]
        actor["Actor (Substrate)"]
        caller -->|A2A conversation| gateway
        caller -->|CreateAgentInstance| instance
        gateway -->|routes to| actor
        instance -->|runs on| actor
    end

    actortemplate -->|instantiated as| instance
    %% Invisible link: forces the kagent plane to sit fully below the ActorTemplate,
    %% and the ActorTemplate below the Kubernetes plane. Without it the layout engine
    %% staggers the two planes diagonally, which both wastes width and scrambles the
    %% reading order. Anchor it to actortemplate, not controller: anchoring higher
    %% loses the stacking. Verified by rendering.
    actortemplate ~~~ caller

    classDef crd stroke:#a78bfa,stroke-width:2px
    class harness,template crd
  

Follow the Kubernetes plane first. An operator applies a Harness and an AgentTemplate with kubectl, governed by Kubernetes RBAC. The diagram shows this path because RBAC governs it, and kagent’s gRPC API reaches the same two resources instead. The kagent controller watches for a valid pair with a matching allowedAgentTemplates selector, and compiles it into an ActorTemplateActorTemplateThe compiled, immutable definition that the kagent controller produces from a Harness and AgentTemplate pair. Every Actor is created from one.Learn more on Substrate. The ActorTemplate sits outside both planes in the diagram because that is where it sits in reality: it is a Substrate resource that the controller creates over gRPC, not a Kubernetes object, so no Kubernetes role grants access to it.

The kagent plane starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls CreateAgentInstance through kagent’s gRPC API. This call is governed by kagent’s own authentication and authorization, not by Kubernetes RBAC. kagent creates the AgentInstance from the newest ActorTemplate that compiled successfully, and that AgentInstance runs on an ActorActorThe sandboxed unit of compute, provided by Agent Substrate, that runs an AgentInstance's conversation loop. Every AgentInstance is backed by one.Learn more.

From there, the caller holds a conversation with the AgentInstance over the A2AA2AThe Agent-to-Agent protocol, which callers and other agents use to talk to an AgentInstance. The conversation's context identifier is the AgentInstance ID, so a second message on the same ID continues the same conversation.Learn more (Agent-to-Agent) protocol. The A2A gateway routes each request to the Actor running behind the target AgentInstance. This means that the caller only ever needs to know an AgentInstance’s identity, never which Actor or WorkerWorkerA pre-started, sandboxed pod that hosts at most one Actor at a time. Actors are multiplexed across a pool of Workers over time.Learn more is behind it.

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 or AgentTemplate. 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 AgentInstance rather than a namespace or a resource kind.

This split also keeps the two lifecycles independent. Editing a Harness or AgentTemplate does not affect AgentInstances already running against the ActorTemplate that they were created from. It only affects new AgentInstances, created after the edit is compiled.