> ## Documentation Index
> Fetch the complete documentation index at: https://www.truefoundry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Governance with SPIFFE and SPIRE

> Governing agents with workload identity — SPIRE attests the agent's runtime and issues short-lived SVIDs, which TrueFoundry validates like any identity provider token.

Use this scenario when your agents run on infrastructure you control — Kubernetes, VMs, containers — and you want their identity **derived from where they run** instead of a secret you mint and distribute. The agent never holds a long-lived credential at all: the platform attests the running workload and issues it a short-lived, automatically rotated identity document. [SPIFFE](https://spiffe.io/) is the open standard for this; [SPIRE](https://spiffe.io/docs/latest/spire-about/spire-concepts/) is its reference implementation.

This is not an alternative to the other scenarios so much as a **stronger bottom layer**: SPIFFE answers "how does the agent prove who it is" with attestation instead of a stored secret, and everything above — registration, grants, delegation, token exchange — works exactly as in the [blueprint](/docs/agent-platform/agent-governance/governance-blueprint).

## Why workload identity fits agents

| Problem with distributed secrets                                            | How attestation solves it                                                                                   |
| --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| A static agent token can leak via config files, images, or prompt injection | There is no static token — credentials are short-lived (often under an hour) and rotated automatically      |
| A stolen credential works from anywhere                                     | An SVID is only issued to a workload that matches a registered attestation policy, on an attested node      |
| Revoking one agent means rotating shared secrets                            | Deregister the workload entry; instances stop receiving SVIDs at next rotation — a per-instance kill switch |
| Fleet identity is per-agent, not per-instance                               | Each running instance gets its own attested credential bound to the stable agent identity                   |

## How an agent gets its identity

<Steps>
  <Step title="SPIRE attests the workload">
    **Node attestation** proves which machine or node the workload runs on (evidence: a Kubernetes projected service account token, an AWS instance identity document, GCP instance metadata). **Workload attestation** proves which process is calling (selectors: Kubernetes service account, namespace, container image digest). Only a workload matching a registered policy gets an identity.
  </Step>

  <Step title="SPIRE issues an SVID">
    The attested workload receives a SPIFFE Verifiable Identity Document carrying its SPIFFE ID, for example `spiffe://acme.com/ns/agents/sa/research-agent`:

    | SVID type      | Format                                                                                                | Notes                                                                                 |
    | -------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
    | **X.509-SVID** | X.509 certificate (SPIFFE ID in the SAN)                                                              | For mTLS; authenticates a channel.                                                    |
    | **JWT-SVID**   | Signed JWT                                                                                            | Bearer token for `Authorization` headers — the practical fit for gateway calls today. |
    | **WIT-SVID**   | Key-bound JWT ([IETF WIMSE](https://datatracker.ietf.org/doc/draft-ietf-wimse-s2s-protocol/) profile) | Requires proof-of-possession, so it resists replay through intermediaries.            |

    SVIDs are rotated by the SPIRE agent before expiry, so the agent never experiences a credential-expiry event.
  </Step>

  <Step title="TrueFoundry validates it as an identity provider">
    SPIRE exposes an OIDC-compliant discovery endpoint. Register it under **Platform → [Identity Providers](/docs/platform/identity-providers)** (issuer, audiences, JWKS URI), then [register the agent](/docs/agent-platform/agent-governance/agent-registry#registering-an-agent) with an **identity provider-backed** identity mapping the SPIFFE ID claim to the agent. The agent presents its JWT-SVID to the gateway exactly like any other identity provider token.
  </Step>
</Steps>

```mermaid theme={"dark"}
sequenceDiagram
    participant SPIRE as SPIRE (agent + server)
    participant Agent as research-agent (pod)
    participant GW as TFY Gateway
    participant MCP as MCP Server

    SPIRE->>SPIRE: Attest node + workload against registered policy
    SPIRE-->>Agent: JWT-SVID for spiffe://acme.com/ns/agents/sa/research-agent (auto-rotated)
    Agent->>GW: Authorization: user token<br/>x-tfy-agent-authorization: JWT-SVID
    GW->>GW: Validate SVID against SPIRE JWKS<br/>resolve SPIFFE ID to registered agent
    GW->>GW: Agent allowed on target? may act for this user?
    GW->>MCP: Forward with outbound auth
    MCP-->>GW: Result
    GW-->>Agent: Result
```

<Tip>
  A common Kubernetes pattern: SPIRE trusts the cluster's projected service account tokens, and the agent reads its JWT-SVID from the SPIFFE Workload API at runtime. No secret is ever written to a config file or image.
</Tip>

## Combining SPIFFE with the other scenarios

SPIFFE identifies *the agent workload*; it says nothing about the *user* the agent acts for, and third-party resources don't accept SVIDs. The layering that works — sometimes called the portable-trust sandwich:

```mermaid theme={"dark"}
flowchart TB
    A[Vendor-neutral workload identity<br/>SPIFFE SVID from runtime attestation] --> B[Gateway resolves SVID to the registered agent identity]
    B --> C[Per-hop delegation via token exchange<br/>user as sub, agent in act, scope narrowed]
    C --> D[Target-native credential where required<br/>OBO or ID-JAG token, or gateway-held OAuth credential]
```

* **Inbound:** the agent authenticates with its SVID; the user's identity travels alongside it, as in every scenario.
* **Outbound:** the gateway performs the same [token exchange](/docs/agent-platform/agent-governance/key-concepts#token-exchange-carrying-identity-across-hops) it would for any agent — OBO within a domain, ID-JAG across domains, or per-user OAuth — minting whatever the target trusts. *(Per-hop exchange is rolling out — see [coming soon](/docs/agent-platform/agent-governance/truefoundry-implementation#coming-soon).)*
* **Cross-cloud:** because SPIFFE is vendor-neutral, the same agent identity survives a move between clouds — the gateway keeps the policy and audit schema constant while the runtime underneath changes.

<Note>
  **Coming soon:** first-class SPIFFE binding on the agent registration — attaching the SPIFFE ID directly to the agent spec so per-instance SVIDs are bound to the stable per-agent identity, giving fleet-level policy with instance-level revocation.
</Note>
