Skip to content
API Reference
Get Started
Use Cases

Give an agent its own identity

An agent proves what it is using a token its runtime already issues, so a compromised host yields nothing reusable and the agent can hold entitlements of its own.

Some agents do work that belongs to them rather than to a person. Those need an identity of their own, and they should be able to prove it without holding a secret that works anywhere it is copied to.

An agent that acts on its own behalf has to authenticate somehow. In practice that means a client secret in an environment variable, or a long-lived API key in a config file.

A secret in a config file is portable in the worst way. Copy it and it works. Anything that can read the process environment, the deployment manifest, the CI log, or a heap dump gets a credential that keeps working from anywhere, for as long as nobody rotates it. Nothing about the credential ties it to the machine it was meant for.

Rotation is the usual answer and it does not scale to agents. Every rotation is a coordinated change across every place the secret was copied to, and the copies are not tracked, so rotation gets deferred and the secret ages. A credential nobody wants to touch is one nobody revokes either.

The cost shows up in the log as well. If several services share a credential, the system receiving the call cannot tell them apart, so a question like “which service did that” cannot be answered from evidence.

flowchart LR
    A[Client secret in config] --> B[Your Agent]
    A -.->|"copied to CI"| C[Build logs]
    A -.->|"copied to a laptop"| D[Developer machine]
    B -->|"works from anywhere"| E[Resource]
  • The agent’s work is its own rather than something a specific person asked for
  • It runs somewhere that can already prove what it is, such as a container platform, a serverless runtime, or a CI job
  • You want a compromised host to yield nothing that works elsewhere
  • The agent should hold entitlements in its own right, so policy can be written about it

Suppose you run a service that reconciles data between two systems on a schedule. No person triggers it. It needs to reach both systems, and today it does that with two API keys checked into a secrets manager and injected at boot. What you want is for the service to prove it is that service, on that platform, and receive access on that basis.

Where a person triggered the work and the downstream system should see that person, the agent should carry their identity instead. See Act as the user who asked.

Where the agent runs somewhere with no way to attest to itself, there is nothing to verify. A platform that cannot issue an identity token for a workload leaves the client secret path as the option, and that is worth knowing before you scope an evaluation.

Where the downstream system only accepts a static credential, the secret still has to exist somewhere. Keycard can hold and broker it rather than each agent holding a copy, which changes who can account for it rather than removing it.

The mechanism is smaller than it looks. Your agent’s runtime already issues it a short-lived identity token. Keycard verifies that token against the issuer’s published keys and matches it to a credential registered on the Application, pinned to the exact subject.

That pin is what makes it non-portable. The credential is not a value the agent holds, it is a statement about which issuer, and which subject within that issuer, is allowed to authenticate as this Application. Another workload on the same platform presents a different subject and does not match.

Because the trust is expressed as an issuer and a subject rather than as a platform integration, anything that publishes an OpenID Connect discovery document and a key set can be an identity source. The platforms with worked guides are examples of the mechanic rather than the limit of it.

flowchart LR
    A[Your runtime] -->|"Issues a short-lived identity token"| B[Your Agent]
    B -->|"Presents it to Keycard"| C[Keycard]
    C -->|"Verify signature against the issuer's keys"| C
    C -->|"Match issuer + subject to the Application"| C
    C -->|"Scoped credential"| B
    B -->|"Calls with that credential"| D[Resource]
  1. The runtime issues the agent an identity token. On a container platform this is usually a file the platform mounts and rotates; on others it comes from a metadata endpoint.
  2. The SDK reads that token and presents it to Keycard as the Application’s authentication credential.
  3. Keycard verifies the signature against the issuer’s published keys, then matches the issuer and subject against the workload identity credential registered on that Application.
  4. Policy evaluates the request, and an allowed one yields a credential scoped to the Application and the Resource it asked for.
  5. The agent calls the Resource. The Audit Log records the issuance against that Application.

There is no secret to steal from the host. What the agent holds is a token its platform minted for it, short-lived and pinned to that workload, and reading it off the machine gets you something that expires and that will not match from anywhere else.

Rotation stops being a task. The platform reissues the identity token on its own schedule and nothing has to be coordinated across the places a secret was copied to, because it was never copied.

The agent becomes something policy can talk about. It has its own identifier, so a rule can permit this service and not that one, and the audit trail names which Application acted rather than showing a shared principal.

You register the trust once, and precisely. Someone has to record the issuer and the exact subject on the Application, and the subject string is platform-specific and easy to get slightly wrong. Getting it wrong fails shut, which is the right direction, and it is still a step that needs care.

The runtime has to be able to attest. This works because your platform issues an identity token. Where it cannot, the client secret path is what remains, and no amount of configuration changes that.

Coverage is per Application. Each agent that should be separately identifiable is separately registered, which is the point and is also work that scales with the number of agents.

An entitlement now belongs to the agent. Once a service holds access in its own right rather than borrowing a person’s, nothing narrows it when a particular task did not need all of it. Scope it in policy to what the job actually does.

What stops another workload on the same platform authenticating as our agent?

Section titled “What stops another workload on the same platform authenticating as our agent?”

The subject pin. Keycard matches both the issuer and the subject in the presented token against what is registered on the Application, so a different workload on the same platform presents a different subject and does not match. The Deploy to Render without Secrets guide shows the subject format for one platform and is a good model for reading any of them.

The mechanic is an OpenID Connect issuer plus a subject, so the question is whether your platform issues an identity token for a workload and publishes keys to verify it. Kubernetes and EKS mount one as a file, Google Cloud runtimes expose one through the metadata server, and Fly and Render each have a documented path. Rather than treating that as a supported list, check whether your platform issues workload tokens, because that is what decides it.

Is this the same as the agent having a user?

Section titled “Is this the same as the agent having a user?”

No, and keeping them separate matters for audit. An Application acting as itself is one principal. An Application acting for a person is a chain, and the record shows both. Where an agent does both kinds of work, those are two different flows against the same registration, and reviewers usually want to see them distinguished.

How do we stop it if something goes wrong?

Section titled “How do we stop it if something goes wrong?”

Revoking what the Application may obtain stops the next issuance rather than reaching a credential already in flight, so containment is bounded by the current credential’s remaining lifetime. Revoke once, access stops covers what each mechanism actually does and where the gaps are.

  • A scheduled reconciliation service reaching two systems, with a policy for each
  • A CI job that needs a credential for the duration of a build and nothing afterwards
  • A background enrichment worker that reads one Resource and writes another
  • A sub-agent in a multi-agent system that should be separately identifiable from the agent that called it

The shape is the same each time. Something runs without a person attached, it can prove what it is to its own platform, and the credential it receives should be tied to that proof rather than to a value someone copied into a config file.