What You Need to Know
This topic covers three jobs that developers usually treat as one. They are managing secrets, credentials and API keys across development and production; identity validation, authentication and level verification; and authorised access monitoring. A credential proves a caller may use the Claude API. Identity is whose authority a request carries. Attribution is knowing, afterwards, which caller made a request.
A florist sells bouquets online. A Claude chat assistant on its website helps customers write gift-card messages. A second service drafts replies to delivery enquiries. A freelance developer built both on one personal key, made under her login in the florist's organisation.
Where Keys Live, and Why the Client Cannot Hold One
Learn the rule as a property of distribution, not a list of forbidden places. Anything shipped to a client is public: a JavaScript bundle, a mobile binary, a desktop application. The running code must read the credential, so anyone who runs the code can read it too. Minification, renaming and encoding are obfuscation, not secrecy: the code reverses them on every start. The same reasoning covers source control, log lines, screenshots and the prompt itself. Each is a copy that outlives the moment and travels somewhere you did not plan. A key in the florist's chat assistant is readable by every visitor.
The fix is a boundary rather than a hiding place: the client talks to your backend, which holds the credential and calls Claude. That gives three benefits. It removes the credential from the client. It gives you a place to authenticate the end user and authorise what they may ask for, which a direct call never had. And it is the enforcement point for per-user rate limiting and quota, so one user cannot spend the whole organisation's budget. The florist's chat box sends text to its server, which adds the key, calls Claude and limits each user.
Keep keys in a secrets manager or the platform secret store, injected at run time. Use a distinct key per environment, never shared between development and production, so a leak from a laptop repository is not a production incident. In code that is an environment read, never a literal. The florist's server and the freelancer's laptop hold different keys.
import anthropic
# The SDK picks up ANTHROPIC_API_KEY from the environment. Injected at run time
# from a secrets manager, distinct per environment, never a literal in source.
client = anthropic.Anthropic()Claude Managed Agents has its own secret store, vaults, in beta as of September 2026. You register an end user's third-party credentials once and reference the vault by ID when creating a session. An environment_variable credential sits in the sandbox as an opaque placeholder, swapped for the real secret at egress. The agent never sees the value, and rotation reaches running sessions without a restart. Substitution is outbound only, so a token the sandbox fetches with the stored secret arrives unredacted. Run exchange-based flows such as a client-credentials grant yourself and store the resulting token. Vaults are also workspace-scoped, so any key with workspace access can reference them.
Lifetime, Rotation, and the Exposure Playbook
A static key is an sk-ant-api... secret sent as a bearer token in the Authorization header. Every client SDK reads it from ANTHROPIC_API_KEY. As of September 2026 the older x-api-key header is documented as legacy but still supported. The documented hygiene: store API keys in a secrets manager, rotate them periodically, and disable or delete any key you suspect has leaked. Disable can be undone. Delete archives the key for good.
Each key has a type, chosen at creation, which decides whose identity it carries. A personal key is identity-backed: every request made with it acts as the user it belongs to, with their roles. A service account key acts as a service account, the documented identity for shared or automated workloads such as CI and production services. Such a workload has its own identity and does not break when a person leaves. A workspace key acts as no one and belongs to its workspace. It still works, but the docs call it legacy and prefer identity-backed keys or Workload Identity Federation. On the freelancer's key, both services act as her. They belong on a service account key.
Expiration is often mistaken for the answer. You choose it at creation from a preset of 3 hours, 1 day, 7 days or 30 days, a custom duration, or Never. It cannot be changed afterwards. An expired key returns a 401 authentication_error and cannot be reactivated. The docs say expiration limits the lifetime of a leaked credential but is not a substitute for secret hygiene. If the florist chose Never, the expiry cannot be shortened after a leak. Only disabling or deleting the key ends its life.
Workload Identity Federation is the structural improvement. The workload exchanges an identity token from an IdP you already trust at POST /v1/oauth/token for a short-lived Claude token. The SDK refreshes it automatically. There is no sk-ant-api... string to mint, distribute or rotate. The documented caveat: the trust chain is only as strong as the identity provider's configuration, and a long-lived secret one hop upstream still undermines it.
The exposure playbook is four steps, in order.
- Kill the credential. Disable, delete or rotate it. Until the exposed key is dead, the attacker still has a working credential while you tidy, so every other step waits.
- Remove it from wherever it leaked. Git history, build caches, CDN copies and screenshots keep their own copies, so deleting the current file is not removal.
- Fix the design that put it there. That is usually the client-side architecture rather than a careless commit.
- Review the access logs for use you did not authorise. Only then decide whether the incident is closed.
If the florist's key turns up in its JavaScript, it disables the key first. Then it scrubs git history and the CDN, moves the call server-side and checks the logs.
Programmatically, step one is an Admin API update to the key's status: inactive disables it reversibly, and archived is the permanent delete. You create API keys only in the Claude Console. The Admin API can only read, rename and change the status of existing keys, so it is for revocation and audit, not provisioning.
# An Admin API key (sk-ant-admin...) goes in the x-api-key header.
curl --request POST "https://api.anthropic.com/v1/organizations/api_keys/$KEY_ID" \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--header "x-api-key: $ANTHROPIC_ADMIN_KEY" \
--data '{"status": "inactive"}'Verification at the Point of Use, and Attribution After the Fact
Authenticate the caller at the edge. Then verify the level at the point of use, per action rather than once at the door. An elevated operation re-checks entitlement instead of inheriting the answer the session got when it opened. An agent acting on somebody's behalf carries that person's authority in its tool calls, not a service account's. Approval flows belong here too: who may authorise an elevated action, and how that decision is recorded so it can be produced later. A florist customer signed in an hour ago is still re-checked before a refund.
Monitoring gets skipped, yet scenarios test it, because its failure makes no noise. A key with no attribution cannot be investigated. If three services share one credential, an anomalous spike names none of them. The first fix is a distinct key per service, ahead of any better alert, so the alert has something to point at. Usage and cost attribution runs per key and per workspace, so keys scoped by project or environment give every line of spend a caller. With one key per florist service, a spike names its source.
The Admin API lists keys with status, workspace and expires_at, so rotation can be audited rather than remembered. The Usage and Cost API and the Rate Limits API report the numbers. The Compliance API Activity Feed carries the audit record.
For Claude Code, as of September 2026, the audit source is OpenTelemetry events delivered through the OTLP logs exporter. They tie tool calls, MCP activity and permission decisions to the user who triggered them. Two settings decide whether that record answers "who ran this". Tool arguments such as the Bash command are logged only with OTEL_LOG_TOOL_DETAILS=1. A session authenticated with an API key carries no account, so attach each person's identity with OTEL_RESOURCE_ATTRIBUTES through managed settings.
Organisation roles are user, claude_code_user, developer, billing and admin, with workspace roles separate. So "who may manage keys" has a concrete answer. Offboarding depends on the key type. Personal keys stop working and are archived when their owner is removed. Service account keys keep working unless the service account itself is archived. Legacy workspace keys keep working whoever created them. Removing a leaver therefore kills their personal keys, which is why a production service should never run on one. Removing the freelancer would stop both services that day.
In the exam
The guide asks for all three jobs together. Items here are rarely about whether a practice is good. They ask which step comes first, and every wrong answer is a real step in the wrong order. Or they ask whether the scenario wants prevention or attribution. For the backend boundary, count three benefits, because distractors usually fix only the first. Two documented details make good items: the organisation roles, and what offboarding does to each key type.
A Dated Exception: App Attest
Verified 2026-08-21, this exception is narrow. App Attest lets a genuine, attested installation of a registered iOS or macOS app call the Claude API directly, with no back end or proxy. The installation proves itself through Apple's App Attest service. Anthropic then issues short-lived tokens scoped to your workspace, which expire after one hour and authorise only Messages API calls. That is an attestation mechanism for native apps. It is not a licence to put a key in a web page, and a browser bundle remains the wrong architecture. The florist's website still needs its server.
Exam Traps
Answering the exposure scenario with the headline fix and stopping there: move the call server-side, adopt a secrets manager, and consider the incident handled.
Both are correct and both come second. If the exposed credential is still valid when the answer ends, the answer is wrong, because the attacker keeps a working key throughout. Distractors in this space are built from real steps in the wrong order, which is why they all read as reasonable.
Treating expiration or a shorter time to live as the control that fixes a leaked key.
It limits how long a leaked credential stays usable, and the docs still call it no substitute for secret hygiene. It also cannot be changed after creation, so it is not something you can apply to the key already in the wild. Rate limiting the compromised key has the same flaw: it caps the bill rather than the access.
Assuming an identity check at the session boundary covers the privileged action that happens later in the session.
Level verification happens per action at the point of use, not once at the door, and an agent acting on somebody's behalf should carry that person's authority rather than a service account's. A session that authenticated an hour ago tells you nothing about whether this particular operation is permitted.
Reading an attribution scenario as a prevention scenario, and answering with throttling, alerting or heavier logging.
If the console shows the spend but not the source, the gap is one shared credential with no per-caller identity. A distinct key per service in its own workspace is what makes usage and cost reporting answer the question who, and no amount of throttling supplies an identity that was never issued.
Practice Scenario
A chainmaker's works runs three services on one production Claude API key: a quotation drafter, a test-certificate summariser and a stock-enquiry bot. The monthly spend jumps sharply and the console shows the total but nothing about which service caused it. Finance will accept a breakdown only if it comes from the console itself. What does the team most need?
Build Exercise
Give Every Caller Its Own Identity, Then Prove You Could Investigate One
What you'll learn
- How to inventory every place a Claude credential currently exists
- How to split a shared key into per-service, per-workspace identities
- How to run the exposure playbook in the documented order against a disposable key
- How to turn on the attribution you would need during an incident
- Inventory every place a Claude credential exists for your project: environment files, CI settings, deployment configuration, laptops, and anywhere a screenshot or a log line might have captured one.
Why: You cannot rotate what you cannot find, and the copies people forget are exactly the ones that outlive the rotation.
You should see: A written list, longer than you expected, with at least one entry you had not thought about.
- Split the shared key: issue a distinct key per service, each in its own workspace, injected from a secrets manager at run time, with development keys separate from production ones.
Why: Distinct keys give you an investigable trail and an isolated failure at the same time, which is the pairing the exam keys in attribution scenarios.
You should see: One key per service, each visible separately in usage and cost reporting.
- Move every construction to an environment read so no literal remains in source, then grep the repository history rather than the working tree, because history is where the old copies live.
Why: Deleting the current file is not removal, and a history scan is the step that turns a tidy-up into an actual remediation.
You should see: A zero-arg client constructor everywhere, and a clean history scan or a list of commits to deal with.
- Rehearse the exposure playbook against one non-production key, in order: set it to inactive through the Admin API, confirm the 401, remove it from the place it lived, then check what the departure of a leaver would and would not revoke.
Why: Rehearsing the order is the point, because what separates a good answer from a wrong one in this space is which step ran first.
You should see: A 401 authentication_error from the deactivated key, and a written note on what offboarding does not touch.
- Turn on the attribution you would need in an incident: usage and cost reporting per workspace, and an alert on an unusual pattern rather than only on a monthly total. Write down the question who used this and when, next to the exact report that answers it.
Why: An alert that cannot name a caller only tells you that something happened, and the pairing of a question with the report that answers it is what makes the monitoring real.
You should see: One named report per question, and an alert that fires on a shape rather than on a month end.
Sources
- Authentication — Anthropic, the three methods, the Authorization header and the legacy x-api-key header, ANTHROPIC_API_KEY, key types, disable and delete, key expiration, Workload Identity Federation and App Attest
- Admin API — Anthropic, changing a key status to inactive or archived, Console-only creation, what happens to each key type when a user is removed, roles, workspaces and the monitoring surfaces
- Security — Anthropic, secure credential storage and OpenTelemetry monitoring for Claude Code
- Monitoring — Anthropic, OpenTelemetry events as the audit source for Claude Code, OTEL_LOG_TOOL_DETAILS and OTEL_RESOURCE_ATTRIBUTES
- Authenticate with vaults — Anthropic, Managed Agents vaults, egress substitution and its outbound-only limit
- API and data retention — Anthropic, the Compliance API Activity Feed retention and what the audit record covers
- Claude Certified Developer Foundations Exam Guide — Domain 7, Identity, Secrets, and Key Management — Anthropic