# Your Agent Can Call Claude Without an API Key

Source: https://www.testifysec.com/blog/claude-without-an-api-key/

Author: TestifySec

Published: 2026-10-22

An enrolled TestifySec agent identity mints a five-minute, single-use token that Anthropic exchanges for Claude access through workload identity federation. No Anthropic key is stored anywhere.

*Written by an AI agent from real runs on 22 October 2026, as a reference resource. The setup guide is on [cilock.dev](https://cilock.dev/guides/call-claude-as-an-agent).* 

An AI agent that calls Claude usually carries an Anthropic API key. That key sits in an environment variable or a config file, it works from any machine that copies it, and it lives until somebody remembers to rotate it. Every agent you run is one more place for it to leak.

 

Anthropic's [workload identity federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) (WIF) removes the key. A workload proves who it is with a short-lived token from an identity provider Anthropic trusts, and gets a short-lived Claude token back. As of today, the TestifySec Platform is one of those identity providers for the agents enrolled on it.

 [![Video: an agent identity mints a token, exchanges it, calls Claude, and is refused on replay and on a foreign audience](https://www.testifysec.com/media/blog/anthropic-wif-thumbnail.jpg)](https://www.testifysec.com/media/blog/anthropic-wif.mp4) *One minute, no narration, every ID redacted. [Play the video](https://www.testifysec.com/media/blog/anthropic-wif.mp4).* 

## What the agent already has

 

`cilock enroll agent` gives an agent an identity on the platform. A person approves it in a browser with a passkey, picks its lifetime (eight hours by default, seven days at most) and its scope, and the machine stores a refresh credential `0600`. The identity is a SPIFFE ID:

 

```
spiffe://platform.testifysec.com/tenant/<tenant-id>/agent/<agent-id>
```

 

Until now that identity signed attestations. It can now also stand in for an Anthropic credential.

 

## The exchange

 

1. The agent sends its refresh credential to the platform and asks for a token with the audience `https://api.anthropic.com`.
 2. The platform answers with an ES256 JWT that lives 300 seconds. Its issuer is `https://platform.testifysec.com/fulcio/oidc`, its subject is the agent's SPIFFE ID, and it carries a `jti`.
 3. The agent hands that JWT to Anthropic's `/v1/oauth/token`. Anthropic checks the signature against the platform's published keys, matches your federation rule, and returns an access token for a Console service account, good for about ten minutes.

 

In our run the exchange returned `200` with scope `workspace:developer`, and a Messages call with the resulting token returned `federated ok`. Claude Code 2.1.308 did the same exchange on its own from the standard `ANTHROPIC_FEDERATION_RULE_ID` family of variables, with no login and no key on the machine.

 

## What it refuses

 

Two refusals matter more than the success.

 **Replay.** Presenting the same JWT a second time returned `401 Authentication failed`. Anthropic accepts each `jti` once, so a token copied out of a log or a process listing is worthless after its first use, and it expires in five minutes anyway. **Another audience.** Asking the platform for a token aimed at any other relying party returned `403 audience_not_allowed` before the credential was even checked. The platform only mints federation tokens for audiences on its allowlist, so a token meant for Anthropic can't be reused somewhere else, and a compromised agent can't ask the platform for a token to a service you never approved. 

## The rule is where the security lives

 

Anthropic decides whether to honour a token by your federation rule. Write it with both halves:

 

- the subject prefix `spiffe://platform.testifysec.com/tenant/<tenant-id>/agent/*`, or one exact agent;
 - the audience `https://api.anthropic.com`.

 

Leave out the subject and you admit other tenants' agents. Leave out the audience and you admit platform tokens minted for other relying parties.

 

## What it doesn't cover

 

Federation signs in a Console **service account** and bills the workspace your rule names. It doesn't sign in to a Claude Pro or Max subscription, so subscription usage can't be federated. And because each token is single-use, a long-running process has to mint a fresh one before each exchange; the guide shows how to refresh the token file so a reader never sees an empty one.

 

The [guide on cilock.dev](https://cilock.dev/guides/call-claude-as-an-agent) walks through the Console setup with screenshots, the commands for the agent's machine, and the errors you can hit.
