LLM Application Security intermediate 7 min read 6 flashcards

Agent Identity and Workload Credentials

Why an agent is a third party rather than a proxy for the user, what goes wrong when it authenticates with a shared long-lived key, and how workload identity replaces that key with an attested, short-lived credential that names the running process.

Most agent deployments answer the question "who is calling?" with a string in an environment variable. One API key, one service account, one OAuth refresh token, issued once and reused by every run of every agent for as long as it works. That design is inherited from the batch job the agent replaced, and it was already a bad idea there. It is worse here, because an agent takes instructions from text it fetched at runtime, so the credential is now held by a process whose behaviour an outsider can influence.

The August 2025 Salesloft Drift incident is the clean version of the failure. Attackers obtained OAuth tokens belonging to the Drift chat integration and used them, between 8 and 18 August, to query the Salesforce instances of numerous organisations and export support case text, then grep it for AWS access keys, Snowflake tokens and passwords. Nothing was compromised on the customer side; the tokens were simply valid, broad and long-lived, and every holder of one was indistinguishable from the legitimate integration (Google Threat Intelligence, 2025, Widespread Data Theft Targets Salesforce Instances via Salesloft Drift). Salesloft and Salesforce revoked all active access and refresh tokens on 20 August, which is the only remediation a bearer token allows.

Three identities, not one

A tool call made by an agent carries at least three claims, and collapsing them into one credential is what makes incidents unbounded.

The user is the person whose authority is being spent. The workload is the specific process making the call: this build of this agent, in this cluster, at this moment. The session is one bounded unit of work, with a task, a start and an end. A key in an environment variable encodes only a fourth thing, the application, and it encodes that permanently.

Separating them is what makes a log line answerable. "Account 4471 was read" tells you nothing. "Workload spiffe://acme.dev/ns/support/sa/triage-agent, running build a91f0c3, acting for user 18822, in session r-9f21, read account 4471" tells you whether to revoke a token, roll back a deploy, or call the user.

Workload identity

The mature answer outside AI is SPIFFE, which issues cryptographically verifiable identities to software workloads rather than to the people or machines running them. A SPIFFE ID is a URI of the form spiffe://trust-domain/path, where the trust domain is the root of trust for one organisation or environment (SPIFFE, SPIFFE-ID standard). The workload proves it holds that identity with an SVID, a SPIFFE Verifiable Identity Document, issued as either an X.509 certificate or a JWT.

The part that matters for agents is how the SVID is obtained. The workload does not present a secret to get one. A local agent attests it, checking properties the process cannot forge about itself, such as its kubernetes service account, its image digest, or the node's hardware root of trust, and only then issues a credential with a lifetime measured in minutes. There is no long-lived secret on disk to steal, and a stolen SVID expires before most exfiltration pipelines finish.

The same shape exists without SPIFFE. Cloud workload identity federation, OIDC tokens minted for a CI job, and instance metadata credentials all follow the pattern: prove what you are, receive a short-lived token, never hold a static one.

Machine identity is not user identity

A workload credential says what is calling. It does not say on whose behalf, and the confusion between the two is the root of the confused deputy problem covered in delegated authority and the confused deputy.

Concretely, an agent authenticated only as a workload has exactly one permission set, the union of everything any user might legitimately ask it to do. Ask that agent to summarise your own expenses and the credential it presents is equally capable of reading everyone's. The model is then the only thing standing between a hostile input and the rest of the data, which is the situation OWASP names excessive permissions, one of the three root causes of excessive agency in LLM applications (OWASP, 2025, LLM06:2025 Excessive Agency). OWASP's corresponding mitigation is blunt: execute tool calls in the specific user's security context, not the application's.

When it breaks

Attestation has to attest something real. If the node agent will hand an SVID to any process in the namespace, workload identity is a shared secret with extra steps. The strength of the identity is exactly the strength of the selector used to attest it.

Short lifetimes move the failure, they do not remove it. A five-minute credential still lets an attacker who is already inside the process do five minutes of damage, and agents are precisely the processes attackers get inside. Short lifetimes bound persistence, not blast radius; capability scoping is a different control and both are needed.

Third-party integrations inherit your data, not your controls. Drift's tokens were not stolen from Salesforce customers, and no control a Salesforce customer applied to their own users applied to them. Any OAuth grant to an external agent platform is a copy of your authority living under someone else's operational security, which is why scope narrowing at grant time is the only lever you keep.

Rotation without inventory is theatre. You cannot rotate credentials you cannot enumerate. An agent fleet that authenticates with per-workload attested identities is enumerable by construction; one that authenticates with keys pasted into deployment manifests is not, and its incident response begins with a search of the configuration store.

References and further reading

Every source this page cites, in the order it cites them. All of them open in a new tab.

  1. Google Threat Intelligence, 2025, Widespread Data Theft Targets Salesforce Instances via Salesloft Drift cloud.google.com
  2. SPIFFE, SPIFFE-ID standard github.com
  3. OWASP, 2025, LLM06:2025 Excessive Agency owasp.org
Check yourself

6 flashcards for this concept

Click a card to reveal the answer.

Drill the whole track