--- title: "Agents & Execution" canonical: "https://admiral.io/docs/agents" description: "Agents pull their work from Admiral, a Terraform agent wherever it can reach your cloud and a Kubernetes agent inside the cluster." --- # Agents & Execution Components describe *what* should exist. Agents are *who makes it real*. They are the execution layer, and they always call Admiral, never the other way round. ## Why does the agent call out? [#why-does-the-agent-call-out] The agent calls out so Admiral never has a path into your cloud or your clusters. The cloud credential used to plan and apply stays on the agent. The agent already runs where that access is. A Terraform agent runs on a machine you operate, wherever that machine can reach your cloud, and pulls the Terraform bundle. A Kubernetes agent runs inside the cluster it manages. Admiral renders a Helm chart into manifests before that pull, includes raw manifests as written, and the agent pulls those manifests. ```mermaid flowchart TB S["Admiral
server"] T["Terraform agent
runs where it has cloud access"] K["Kubernetes agent
runs in the cluster"] T -->|pulls the bundle| S K -->|pulls manifests| S ``` For the people who approve the connection, the ask is one outbound path. There is no inbound rule to review, and no cloud or cluster credential to store, rotate, or revoke inside Admiral. ## What does each kind of agent run? [#what-does-each-kind-of-agent-run] Terraform and Kubernetes are the two **kinds** of the one Agent concept. The kind determines what an agent executes and where it runs. | Agent kind | Executes | Runs | Pulls | | -------------- | --------------------------------------- | -------------------------------------------------- | -------------------- | | **Terraform** | `infrastructure` components (terraform) | on a machine you operate that can reach your cloud | the Terraform bundle | | **Kubernetes** | `workload` components (helm / manifest) | inside the target Kubernetes cluster | rendered manifests | A **Terraform agent** runs on a machine you operate, wherever that machine can reach your cloud. It pulls the Terraform bundle, runs plan and apply, and streams results back. A **Kubernetes agent** runs inside the Kubernetes cluster it manages. Admiral renders a Helm chart into manifests, includes raw manifests as written, and the agent pulls those manifests and reconciles them. ## How does work reach an agent? [#how-does-work-reach-an-agent] An environment selects the Kubernetes agent it deploys through, from the agents granted to it. A run sends each workload component's work to that agent. ```mermaid flowchart LR C["Component
kind: workload"] E["Environment
prod"] A["Kubernetes agent
prod-k8s"] C -->|lives in| E E -->|deploys through| A ``` The component's kind decides which agent gets the work, so a Helm release cannot reach a Terraform agent, and a Terraform job cannot reach a Kubernetes agent. ## How does an agent prove who it is? [#how-does-an-agent-prove-who-it-is] This section describes the Kubernetes agent. The Terraform agent has not shipped, and its enrollment is not documented yet. Admiral trusts the cluster, not a shared secret. A Kubernetes agent is a namespace and service account in a cluster, and one cluster can hold several agents. The agent holds no long-lived credential. It presents a service-account token that the kubelet issues for Admiral and rotates, and Admiral checks that token against the cluster's public signing keys: * On a cluster whose token issuer is public (GKE, EKS), Admiral fetches those keys from the issuer. * On a cluster without a public issuer (kind, on-premises), the agent sends the keys once. It uses an enrollment key that an admin creates in Admiral, which can do nothing else and stops working once used or after an hour. When the cluster's keys change later, an admin accepts the new set. Admiral never trusts keys an agent reports on its own. The signing keys are public, so they are not a secret to protect. Admiral accepts the agent's token only on the agent API, and every other API refuses it. Who may use an agent is a grant. The agent's owner grants it to the organization, a team, an application, or one environment. An environment's editor then picks an agent within those grants. Your organization's first agent is open to everyone in it. See the [agent lifecycle guide](https://admiral.io/docs/agents/lifecycle.md) for operations. ## What may the Kubernetes agent do in my cluster? [#what-may-the-kubernetes-agent-do-in-my-cluster] What its role allows, so decide that before you install it. By default the agent is bound to a ClusterRole that grants `get`, `list`, `patch`, and `create` on every resource in every namespace. That is more than most clusters should grant. List the namespaces the agent serves in the chart's `rbac.namespaces`, and the chart grants a Role in each of those instead. * Today the agent plans only. Every write it sends is a dry run. Kubernetes RBAC cannot tell a dry run from a real write, so grant only what you would let it change. * A plan reads Secrets, including their values, to tell a changed key from an unchanged one. The agent never sends a value it reads. A plan shows only which keys were added, changed, or removed. * The agent reads the cluster's service-account signing keys, to enroll and to report a key rotation. ## Who may deploy, and what may the deploy do? [#who-may-deploy-and-what-may-the-deploy-do] A deployment has two permissions, and most tools collapse them into one credential. The first is who on the team is allowed to ship. The second is what the cloud or the cluster will allow that run to do. The usual fix is to store the cloud credential in the product, or to require the person running the job to hold it. Granting a team access to deploy then means handing them that credential, or letting them trigger a run that uses a shared privileged credential the product holds. You cannot give a team the access they need without also widening what that credential can do. Everyone who can apply exercises the same cloud role, and the product becomes a standing holder of your account. Admiral keeps the two permissions apart. The cloud or the cluster authorizes the agent, and only the agent. A Terraform agent deploys with the identity of the place it runs: an IAM role, an instance profile, or other cloud credentials you grant when you install it. A Kubernetes agent reconciles with its in-cluster service account. Admiral does not store those credentials, and it has no standing access to the account or the cluster. Who may act is decided in Admiral. Access to an application or an environment, granted to a person or a team, decides who can open a changeset, review it, and apply it. Those people can cause the agent for that environment to run. They do not receive the cloud or cluster credentials, and they do not need an account there to do the work. Each side is scoped on its own. A production agent carries the production role in the cloud. A development agent carries a narrower one. Adding someone to a team in Admiral does not change what the cloud role can do. Narrowing or rotating the cloud role does not change who can apply. This is separate from a [Credential](https://admiral.io/docs/concepts/sources-and-catalog.md#credentials), which is the stored secret a private Source uses for fetching, not an execution identity. > **Note:** A team can ship through Admiral without holding the cloud or cluster credentials the agent uses, and without Admiral holding them either. ## Where to go next [#where-to-go-next] * [Changesets & Runs](https://admiral.io/docs/concepts/changesets-and-runs.md): How a run hands work to agents wave by wave