Follow Discord
Sweep 22 Oct 2026 · 21:04Z Build v2.1.309 528 read Stable v2.1.308 Latest v2.1.309 Next v2.1.309 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One capture · api

One read of Claude Developer Platformapi-20261023T100709Z

143 pages moved out of 820 read.

Pages moved 143 significant first
Pages read 820 in this capture
Captured 10:07 UTC
Corpus hash 1df9c76a5544 corpus-hash

What this read moved

26-50 of 143, page 2 of 6

This capture is too large to show at once. Changes 26-50 of 143 are below, significant first; the rest are on the following screens.

build-with-claude/streaming Changed · +9 / -9 lines

from line 309
309309 
310310The API might occasionally send [errors](https://platform.claude.com/docs/en/api/errors) in the event stream. For example, during periods of high usage, you might receive an `overloaded_error`, which would normally correspond to an HTTP 529 in a non-streaming context:
311311 
312```text Example error
312```sse Example error
313313event: error
314314data: {"type": "error", "error": {"type": "overloaded_error", "message": "Overloaded"}}
315315```
from line 326
326326 
327327A `text` content block delta looks like:
328328 
329```text Text delta
329```sse Text delta
330330event: content_block_delta
331331data: {"type": "content_block_delta","index": 0,"delta": {"type": "text_delta", "text": "ello frien"}}
332332```
from line 339
339339 
340340A `tool_use` content block delta looks like:
341341 
342```text Input JSON delta
342```sse Input JSON delta
343343event: content_block_delta
344344data: {"type": "content_block_delta","index": 1,"delta": {"type": "input_json_delta","partial_json": "{\"location\": \"San Fra"}}}
345345```
from line 356
356356 
357357A typical thinking delta looks like:
358358 
359```text Thinking delta
359```sse Thinking delta
360360event: content_block_delta
361361data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "I need to find the GCD of 1071 and 462 using the Euclidean algorithm.\n\n1071 = 2 × 462 + 147"}}
362362```
from line 363
363363 
364364The signature delta looks like:
365365 
366```text Signature delta
366```sse Signature delta
367367event: content_block_delta
368368data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}
369369```
from line 530
530530 ```
531531</CodeGroup>
532532 
533```text Response
533```sse Response
534534event: message_start
535535data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-5-5", "stop_reason": null, "stop_sequence": null, "usage": {"input_tokens": 25, "output_tokens": 1}}}
536536 
from line 872
872872 ```
873873</CodeGroup>
874874 
875```text Response
875```sse Response
876876event: message_start
877877data: {"type":"message_start","message":{"id":"msg_014p7gG3wDgGV9EUtLvnow3U","type":"message","role":"assistant","model":"claude-opus-5","stop_sequence":null,"usage":{"input_tokens":472,"output_tokens":2},"content":[],"stop_reason":null}}
878878 
from line 1165
11651165 ```
11661166</CodeGroup>
11671167 
1168```text Response
1168```sse Response
11691169event: message_start
11701170data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-5-5", "stop_reason": null, "stop_sequence": null}}
11711171 
from line 1396
13961396 ```
13971397</CodeGroup>
13981398 
1399```text Response
1399```sse Response
14001400event: message_start
14011401data: {"type":"message_start","message":{"id":"msg_01G...","type":"message","role":"assistant","model":"claude-opus-5-5","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":2679,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":3}}}
14021402 

build-with-claude/structured-outputs Changed · +9 / -9 lines

from line 110
110110 
111111 Claude returns JSON like this in the response's text content block:
112112 
113 ```text Output wrap
113 ```json Output
114114 {
115115 "name": "John Smith",
116116 "email": "[email protected]",
from line 148
148148 
149149 Claude returns JSON like this in the response's text content block:
150150 
151 ```text Output wrap
151 ```json Output
152152 {
153153 "name": "John Smith",
154154 "email": "[email protected]",
from line 374
374374 
375375 The previous example outputs:
376376 
377 ```text Output wrap
377 ```json Output
378378 {"name":"John Smith","email":"[email protected]","plan_interest":"Enterprise","demo_requested":true}
379379 ```
380380 
from line 463
463463 
464464 The JSON output has this nested structure:
465465 
466 ```text Output wrap
466 ```json Output
467467 {
468468 "composedA": { "a": "hello" },
469469 "composedB": { "b": "world" }
from line 484
484484 
485485 The JSON output has this flat structure:
486486 
487 ```text Output wrap
487 ```json Output
488488 {
489489 "a": "hello",
490490 "b": "world"
from line 791
791791 
792792 Claude returns JSON like this in the response's text content block:
793793 
794 ```text Output wrap
794 ```json Output
795795 {
796796 "name": "John Smith",
797797 "email": "[email protected]",
from line 829
829829 
830830 Claude returns JSON like this in the response's text content block:
831831 
832 ```text Output wrap
832 ```json Output
833833 {
834834 "name": "John Smith",
835835 "email": "[email protected]",
from line 983
983983 
984984 The previous example outputs:
985985 
986 ```text Output wrap
986 ```json Output
987987 {"name":"John Smith","email":"[email protected]","plan_interest":"Enterprise","demo_requested":true}
988988 ```
989989 </Tab>
from line 1097
10971097 
10981098 The previous example outputs:
10991099 
1100 ```text Output wrap
1100 ```json Output
11011101 {"name":"John Smith","email":"[email protected]","plan_interest":"Enterprise"}
11021102 ```
11031103 

build-with-claude/thinking Changed · +7 / -7 lines

from line 24
2424 
2525Here is what up-front thinking looks like in a response: one or more `thinking` content blocks arrive before the `text` blocks. The thinking block is still generated content, like the `text` block that follows it, but it is separated from the canonical response. Each thinking block also carries a `signature` field, an encrypted copy of the full reasoning that you pass back unchanged in multi-turn and tool-use conversations (see [Thinking encryption](https://platform.claude.com/docs/en/build-with-claude/thinking#thinking-encryption)):
2626 
27```text
27```json
2828{
2929 "content": [
3030 {
from line 482
482482 
483483With `display: "omitted"`, the response contains `thinking` blocks with an empty `thinking` field:
484484 
485```text Output wrap
485```json Output
486486{
487487 "content": [
488488 {
from line 800
800800To reassemble complete thinking blocks with their signatures after streaming, use your SDK's message-accumulation helper, `stream.get_final_message()` (typescript: `stream.finalMessage()`; ruby: `stream.accumulated_message`; csharp: `.Aggregate()`; go: `message.Accumulate(event)`; java, php: `MessageAccumulator`), instead of concatenating deltas yourself.
801801 
802802<Accordion title="Full streaming event trace">
803 ```text Output
803 ```sse Output
804804 event: message_start
805805 data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-5-5", "stop_reason": null, "stop_sequence": null}}
806806 
from line 842
842842 
843843When `display: "omitted"` is set, the thinking block opens, a `thinking_delta` with an empty `thinking` string arrives, a single `signature_delta` follows, and the block closes. Text streaming starts immediately after:
844844 
845```text Output
845```sse Output
846846event: content_block_start
847847data: {"type":"content_block_start","index":0,"content_block":{"type":"thinking","thinking":"","signature":""}}
848848 
from line 861
861861 
862862With `display: "updates"` (beta), reasoning blocks stream as they do under `"omitted"`. Each [progress-update block](https://platform.claude.com/docs/en/build-with-claude/thinking#progress-updates) streams its text as `thinking_delta` events before the `tool_use` block it introduces. A pause of several seconds before the progress-update block opens is normal:
863863 
864```text Output
864```sse Output
865865event: content_block_start
866866data: {"type":"content_block_start","index":1,"content_block":{"type":"thinking","thinking":"","signature":""}}
867867 
from line 1021
10211021 
10221022Under `"updates"`, the start of the response that follows a `tool_result` looks like this. The first block is reasoning and stays empty, as it would under `"omitted"`. The second carries text, so it's a progress update. Under `"summarized"` both blocks carry text, and under `"omitted"` both are empty.
10231023 
1024```text Output
1024```json Output
10251025{
10261026 "content": [
10271027 {
from line 1168
11681168 
11691169In addition to regular `thinking` blocks, the API might return `redacted_thinking` blocks when portions of Claude's reasoning are safety-redacted. A `redacted_thinking` block contains encrypted thinking content in a `data` field, with no readable text:
11701170 
1171```text wrap
1171```json
11721172{
11731173 "type": "redacted_thinking",
11741174 "data": "..."

build-with-claude/token-counting Changed · +12 / -6 lines

from line 27
2727 
2828The [token counting](https://platform.claude.com/docs/en/api/messages/count_tokens) endpoint accepts the same structured list of inputs for creating a message, including support for system prompts, [tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview), [images](https://platform.claude.com/docs/en/build-with-claude/vision), and [PDFs](https://platform.claude.com/docs/en/build-with-claude/pdf-support). The response contains the total number of input tokens.
2929 
30This endpoint returns an `invalid_request_error` for a few inputs that the Messages API accepts: [server tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools) such as web search, web fetch, code execution, and tool search (every server tool except the [advisor tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool)), the [MCP connector](https://platform.claude.com/docs/en/agents-and-tools/mcp-connector), and `image` or `document` blocks with a `url` or `file` source. Send images and PDFs as base64 to count them. For requests that use server tools or MCP servers, the Messages API response reports the tokens used in its `usage` object.
30This endpoint returns an `invalid_request_error` for a few inputs that the Messages API accepts:
3131 
32* [Server tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools) such as web search, web fetch, code execution, and tool search (every server tool except the [advisor tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool))
33* The [MCP connector](https://platform.claude.com/docs/en/agents-and-tools/mcp-connector)
34* `image` or `document` blocks with a `url` or `file` source
35 
36Send images and PDFs as base64 to count them. For requests that use server tools or MCP servers, the Messages API response reports the tokens used in its `usage` object.
37 
3238<Note>
3339 The token count is an **estimate**. In some cases, the actual number of input tokens used when creating a message might differ by a small amount.
3440 
from line 192
186192 ```
187193</CodeGroup>
188194 
189```text Output wrap
195```json Output
190196{ "input_tokens": 14 }
191197```
192198 
from line 475
469475 ```
470476</CodeGroup>
471477 
472```text Output wrap
478```json Output
473479{ "input_tokens": 403 }
474480```
475481 
from line 784
778784 ```
779785</CodeGroup>
780786 
781```text Output wrap
787```json Output
782788{ "input_tokens": 1028 }
783789```
784790 
from line 1109
11031109 ```
11041110</CodeGroup>
11051111 
1106```text Output wrap
1112```json Output
11071113{ "input_tokens": 88 }
11081114```
11091115 
from line 1395
13891395 ```
13901396</CodeGroup>
13911397 
1392```text Output wrap
1398```json Output
13931399{ "input_tokens": 2188 }
13941400```
13951401 

build-with-claude/working-with-messages Changed · +4 / -4 lines

from line 133
133133 ```
134134</CodeGroup>
135135 
136```text Output wrap
136```json Output
137137{
138138 "id": "msg_01XFDUDYJgAACzvnptvVoYEL",
139139 "type": "message",
from line 300
300300 ```
301301</CodeGroup>
302302 
303```text Output wrap
303```json Output
304304{
305305 "id": "msg_018gCsTGsXkYJVqYPxTgDHBU",
306306 "type": "message",
from line 478
478478 ```
479479</CodeGroup>
480480 
481```text Output wrap
481```json Output
482482{
483483 "id": "msg_01Q8Faay6S7QPTvEUUQARt7h",
484484 "type": "message",
from line 1007
10071007 ```
10081008</CodeGroup>
10091009 
1010```text Output
1010```json Output
10111011{
10121012 "id": "msg_011CdKmWtV3oFx1C5yUbf5CY",
10131013 "type": "message",

claude_api_primer Changed · +6 / -6 lines

from line 44
4444 ```
4545</CodeGroup>
4646 
47```text Output wrap
47```json Output
4848{
4949 "id": "msg_01XFDUDYJgAACzvnptvVoYEL",
5050 "type": "message",
from line 590
590590* `name`: The name of the tool being used
591591* `input`: An object containing the input being passed to the tool
592592 
593```text wrap
593```json
594594{
595595 "role": "assistant",
596596 "content": [
from line 699
699699 
700700#### Text delta
701701 
702```text wrap
702```json
703703{
704704 "type": "content_block_delta",
705705 "index": 0,
from line 711
711711 
712712For `tool_use` content blocks, deltas are *partial JSON strings*:
713713 
714```text
714```json
715715{"type": "content_block_delta","index": 1,"delta": {"type": "input_json_delta","partial_json": "{\"location\": \"San Fra"}}}
716716```
717717 
from line 719
719719 
720720When using thinking with streaming:
721721 
722```text wrap
722```json
723723{
724724 "type": "content_block_delta",
725725 "index": 0,
from line 732
732732 
733733### Basic streaming request example
734734 
735```text
735```sse
736736event: message_start
737737data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-5-5", "stop_reason": null, "stop_sequence": null, "usage": {"input_tokens": 25, "output_tokens": 1}}}
738738 

manage-claude/access-transparency Changed · +4 / -4 lines

from line 95
9595 
9696Example JSON message:
9797 
98```text wrap
98```json
9999{
100100 "id": "activity_013b013744txqZtFHLUaRqLr",
101101 "type": "anthropic_access",
from line 132
132132 
133133Example JSON message:
134134 
135```text wrap
135```json
136136{
137137 "id": "activity_01AbCdEfGhJkMnPqRsTuVwXy",
138138 "type": "cmek_preserve",
from line 186
186186 
187187### Notification timing
188188 
189`anthropic_access` and `cmek_preserve` events are delivered to your Compliance API feed within 2 business days of the access or preservation they record. This feed should not be treated as a real-time alerting channel, and the `accessed_at` timestamp reflects when the access occurred, which might be up to 2 business days before the activity becomes visible in your feed. The `created_at` field reflects the time Anthropic recorded the event, and the event usually becomes visible in your feed shortly after that time. These events do not follow the Activity Feed's usual 1-minute [indexing lag](https://platform.claude.com/docs/en/manage-claude/compliance-integration-patterns#window-polling): an event can become visible up to 2 business days after its `created_at`. If you poll the feed by `created_at` window, overlap consecutive windows by at least 2 business days for `anthropic_access` and `cmek_preserve` events so that a late-indexed event is not dropped.
189`anthropic_access` and `cmek_preserve` events are delivered to your Compliance API feed within 2 business days of the access or preservation they record. Do not treat this feed as a real-time alerting channel. The `accessed_at` timestamp reflects when the access occurred, which might be up to 2 business days before the activity becomes visible in your feed. The `created_at` field reflects the time Anthropic recorded the event, and the event usually becomes visible in your feed shortly after that time. These events do not follow the Activity Feed's usual 1-minute [indexing lag](https://platform.claude.com/docs/en/manage-claude/compliance-integration-patterns#window-polling): an event can become visible up to 2 business days after its `created_at`. If you poll the feed by `created_at` window, overlap consecutive windows by at least 2 business days for `anthropic_access` and `cmek_preserve` events so that a late-indexed event is not dropped.
190190 
191191### Automated processing does not generate access events
192192 
from line 232
232232 </Accordion>
233233 
234234 <Accordion title="How does Access Transparency relate to CMEK?">
235 They are independent. With CMEK, safety preservation outside your key emits a separate `cmek_preserve` event on the same feed. See [CMEK content preservation](https://platform.claude.com/docs/en/manage-claude/access-transparency#cmek-content-preservation) and [Customer-managed encryption keys](https://platform.claude.com/docs/en/manage-claude/cmek).
235 They are independent. With CMEK, safety preservation outside your key emits a separate `cmek_preserve` event on the same feed. See [CMEK content preservation](https://platform.claude.com/docs/en/manage-claude/access-transparency#cmek-content-preservation) and [Limited preservation outside your key](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#limited-preservation-outside-your-key).
236236 </Accordion>
237237 
238238 <Accordion title="How can I tell that my Access Transparency record has not been altered?">

manage-claude/access-transparency-log Changed · +76 / -24 lines

## Before you start ### Upgrade for a new leaf version ## Before you begin

from line 13
1313 
1414 Your log is created when the first Access Transparency event is recorded for your organization after enablement. Until then, every transparency log endpoint returns `404`.
1515 
16 If you already run `axt-verify` on a schedule, see [Upgrade for a new leaf version](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#upgrade-for-a-new-leaf-version).
17 
1618 The transparency log is provided for your information. It is not designed or certified to satisfy any security, privacy, or regulatory requirement. You are responsible for determining whether it fits your own obligations.
1719</Note>
1820 
from line 40
3840 
3941* It does not prove that every access was recorded, or that a recorded event accurately describes the access. It proves only that what Anthropic committed to the log has not changed since.
4042* It does not change [what Access Transparency covers](https://platform.claude.com/docs/en/manage-claude/access-transparency#what-access-transparency-covers) or when events arrive.
41* Served fields outside the leaf, such as `workspace_uuid` and any field added later, are not covered by the proof.
43* Served fields that no [leaf version](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#how-an-event-becomes-a-leaf) includes, such as `workspace_uuid`, are not covered by the proof. A field added to events later is covered only once a leaf version includes it.
4244* An inclusion proof speaks for an event you were served. It does not by itself prove that the feed listed every leaf the log holds. The log's [entry bundles](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#read-an-entry-bundle) contain every leaf, so you can read the complete set of committed events directly when you need it.
4345* The presence of `transparency_log_leaf_index` on an event is a pointer, not a proof. Always verify inclusion before treating an event as committed in the log.
4446* The protection against a rewritten history comes from the checkpoints you keep. A checkpoint's signature by a key listed in [Published key fingerprints](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#published-key-fingerprints) proves that it came from Anthropic's log. A consistency proof from the checkpoint you saved last time proves that the history you already observed only grew.
4547 
46## Before you begin
48## Before you start
4749 
4850You need:
4951 
from line 150
148150 -H "anthropic-version: 2023-06-01"
149151```
150152 
151```text
153```json
152154{
153155 "type": "transparency_log_keys",
154156 "origin": "axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b",
from line 214
212214 -H "anthropic-version: 2023-06-01"
213215```
214216 
215```text
217```json
216218{
217219 "type": "transparency_log_inclusion_proof",
218220 "leaf_index": 41,
from line 260
258260 -H "anthropic-version: 2023-06-01"
259261```
260262 
261```text
263```json
262264{
263265 "type": "transparency_log_consistency_proof",
264266 "hashes": [
from line 311
309311 
310312## How an event becomes a leaf
311313 
312A leaf entry is the schema-version byte `0x01` followed by canonical JSON of 11 fields. The JSON follows [RFC 8785](https://www.rfc-editor.org/rfc/rfc8785) (JSON Canonicalization Scheme), and the fields are taken from the event exactly as the Activity Feed serves it:
314A leaf entry is one schema-version byte followed by canonical JSON of that version's fields. The JSON follows [RFC 8785](https://www.rfc-editor.org/rfc/rfc8785) (JSON Canonicalization Scheme), and the fields are taken from the event exactly as the Activity Feed serves it.
313315 
316A leaf version is a fixed set of fields, and each field is either required or optional.
317 
318Version `0x01` has 11 required fields and no optional field:
319 
314320* `id`, `type`, `created_at`, `accessed_at`, `organization_id`, `organization_uuid`, `workspace_id`, `accessor_department`, and `reason_code`
315321* `actor`, with its nested `type` and `email_address`
316322* `resource_details`, with its nested `type`, `id`, and `parent`
317323 
324Version `0x02` has the same 11 required fields and one optional field:
325 
326* `user_profile_id`, the ID of the [user profile](https://platform.claude.com/docs/en/api/beta/user_profiles) the accessed or preserved data was created under
327 
328Once your log starts writing a version, it writes every new leaf under that version until it starts writing the next one, even when the event has none of the version's optional fields. [Upgrade for a new leaf version](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#upgrade-for-a-new-leaf-version) says when your log can start writing a new version. A leaf never changes once it is written, so it keeps its version for good. One log can therefore hold leaves of more than one version. Nothing the Activity Feed or the proof endpoints serve says which version a leaf has (only the leaf's own bytes in an [entry bundle](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#read-an-entry-bundle) do), and you do not need to know: the last of the following rules says which entries to rebuild for an event.
329 
318330The rules:
319331 
320* Served fields outside that set, such as `workspace_uuid` and `transparency_log_leaf_index` itself, are ignored.
332* Served fields outside a version's set, such as `workspace_uuid` and `transparency_log_leaf_index` itself, are ignored.
321333 
322* A documented field that the served event omits enters the leaf as `null`. An empty string is distinct from `null`.
334* A required field that the served event omits, or serves as `null`, enters the leaf as `null`. An empty string is distinct from `null`.
323335 
324* `actor` and `resource_details` are objects with exactly their documented keys when the served event carries them. Under version `0x01`, `actor.email_address` and `resource_details.parent` are always `null`. When the served event omits one of these objects or serves it as `null`, the whole value is `null` in the leaf, not an object of `null` fields. Many access events carry no `resource_details`.
336* An optional field enters the leaf only when the served event has it as a string, the empty string included, and it enters as that string. When the served event omits it or serves it as `null`, the leaf has no such key at all. An optional field is never `null` in a leaf. Reject a served event that has any other JSON value for an optional field.
325337 
338* `actor` and `resource_details` are objects with exactly their documented keys when the served event carries them. `actor.email_address` and `resource_details.parent` are always `null`. When the served event omits one of these objects or serves it as `null`, the whole value is `null` in the leaf, not an object of `null` fields. Many access events carry no `resource_details`.
339 
326340* String values, including both timestamps and `reason_code`, are taken byte for byte as served. If you re-derive a timestamp from another representation, reproduce the served rendering exactly:
327341 
328342 * RFC 3339 UTC with a `Z` suffix.
from line 347
333347 
334348* The leaf hash is RFC 6962's `SHA-256(0x00 || entry)`. Interior nodes hash as `SHA-256(0x01 || left || right)`.
335349 
336* A verifier rejects an unknown version byte, and a `0x01` leaf whose `type` is not one of the two Access Transparency types. New event types or rule changes ship under a new version byte. Existing leaves never re-hash.
350* A verifier that reads leaf entries, for example from an [entry bundle](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#read-an-entry-bundle), rejects an unknown version byte, and a leaf whose `type` is not one of the two Access Transparency types. New fields, new event types, and rule changes ship under a new version byte. Existing leaves never re-hash.
337351 
352* Rebuild a served event's entry under each leaf version whose fields include every optional field the served event has as a string (every version, when it has none), and under no other version. The event verifies if its inclusion proof matches the leaf hash of any one of them. If an optional field is removed from, added to, or changed in the event you are served, the event fails verification on any verifier that rebuilds a leaf version with that field, whichever leaf the log holds.
353 
338354For example, this access event as the Activity Feed serves it:
339355 
340```text wrap
356```json
341357{
342358 "id": "activity_01GPXmAhizavrUuoXNn3tzeA",
343359 "type": "anthropic_access",
from line 371
355371}
356372```
357373 
358becomes this canonical JSON. It has exactly the 11 documented keys, sorted, on one line. `workspace_uuid` and `transparency_log_leaf_index` drop out, and `resource_details.parent`, absent from the served event, enters as `null`:
374becomes this canonical JSON. It has exactly the 11 required keys, sorted, on one line. `workspace_uuid` and `transparency_log_leaf_index` drop out, and `resource_details.parent`, absent from the served event, enters as `null`:
359375 
360```text wrap
376```json
361377{"accessed_at":"2025-07-08T18:39:58Z","accessor_department":"Trust & Safety","actor":{"email_address":null,"type":"anthropic_actor"},"created_at":"2025-07-08T18:40:00Z","id":"activity_01GPXmAhizavrUuoXNn3tzeA","organization_id":"org_015gtSHLz269eTwgrH8NX5yk","organization_uuid":"25f6429a-3293-49bf-afed-cb312911554b","reason_code":"safety_review","resource_details":{"id":"msg_01HXAMPLE12345678","parent":null,"type":"message"},"type":"anthropic_access","workspace_id":"wrkspc_01PaGUP2rbg1XDh7Z9W1CEpd"}
362378```
363379 
364The leaf entry is the byte `0x01` followed by those UTF-8 bytes. Its leaf hash, `SHA-256(0x00 || entry)`, is `6ro7vTcFq+sYDZiiGvZaFetUIoMSLig3DGDrCKK1HFU=` in base64. Use this example as a test vector for your own canonicalization code.
380This event has no optional field, so its version `0x02` and version `0x01` entries hold the same JSON and differ only in the first byte. The version `0x02` entry is the byte `0x02` followed by those UTF-8 bytes. Its leaf hash, `SHA-256(0x00 || entry)`, is `1iKC1LbEakcNTfp8OwW4LtItQu4+/K/pzaDDLVIA5XE=` in base64. The version `0x01` entry is the byte `0x01` followed by the same bytes, with leaf hash `6ro7vTcFq+sYDZiiGvZaFetUIoMSLig3DGDrCKK1HFU=`.
365381 
382The same event served with an optional field, here `"user_profile_id": "uprof_01H7Z9W1CEpdPaGUP2rbg1XD"`, has 12 keys in its version `0x02` JSON. The optional key sorts with the others, between `type` and `workspace_id`:
383 
384```json
385{"accessed_at":"2025-07-08T18:39:58Z","accessor_department":"Trust & Safety","actor":{"email_address":null,"type":"anthropic_actor"},"created_at":"2025-07-08T18:40:00Z","id":"activity_01GPXmAhizavrUuoXNn3tzeA","organization_id":"org_015gtSHLz269eTwgrH8NX5yk","organization_uuid":"25f6429a-3293-49bf-afed-cb312911554b","reason_code":"safety_review","resource_details":{"id":"msg_01HXAMPLE12345678","parent":null,"type":"message"},"type":"anthropic_access","user_profile_id":"uprof_01H7Z9W1CEpdPaGUP2rbg1XD","workspace_id":"wrkspc_01PaGUP2rbg1XDh7Z9W1CEpd"}
386```
387 
388Its version `0x02` entry, the only one to rebuild, is the byte `0x02` followed by those UTF-8 bytes, with leaf hash `onAlpkDfdXmHPvbffiTpHAgBacf/mJCzTfNDibDrYp4=`. Use these three hashes as test vectors for your own canonicalization code.
389 
366390## Verify your log
367391 
368392Verification runs on your own infrastructure. Everything the API returns is untrusted until it verifies against two things you hold yourself. The first is the origin you derive from your organization UUID. The second is the checkpoint you saved on your last run. A complete verification run does the following, in order:
from line 396
3723963. Check the checkpoint's origin line first. Compare its first line, byte for byte, with the origin you derived. Reject any checkpoint whose origin differs, before doing anything else.
3733974. Verify the checkpoint's signature. Find the signature line named for your origin whose first four decoded bytes equal the `key_hash` of a currently valid key you kept. Verify the remaining bytes as an ECDSA P-256 signature over the SHA-256 of the note body, using that key's `public_key`. If no signature line matches such a key, or the signature does not verify, reject the checkpoint.
3743985. Prove append-only. If the new tree size is smaller than the one you saved, fail. If it is equal, the root hashes must match. If it is larger, verify the RFC 9162 consistency proof from your saved size and root hash to the new size and root hash.
3756. Prove each event is included. Read every Access Transparency event the Activity Feed serves. For each new one, rebuild its [leaf](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#how-an-event-becomes-a-leaf), hash it, and fetch its [inclusion proof](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#fetch-an-inclusion-proof). Walk the audit path from your leaf hash at the event's index up to the checkpoint's root hash. A mismatch means the event you were served is not the event the log committed. The proof response can carry a different checkpoint from the one you hold. Link it into your history with a consistency proof before you verify anything against it.
3996. Prove each event is included. Read every Access Transparency event the Activity Feed serves. For each new one, rebuild each [leaf to rebuild for it](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#how-an-event-becomes-a-leaf), hash each, and fetch its [inclusion proof](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#fetch-an-inclusion-proof). Walk the audit path from each leaf hash at the event's index up to the checkpoint's root hash. The event verifies if one of them reproduces the root hash. If none does, the event you were served is not the event the log committed. The proof response can carry a different checkpoint from the one you hold. Check its origin line and signature (steps 3 and 4), and link it into your history with a consistency proof (step 5), before you verify anything against it.
3764007. Re-check what you saw before. Whenever you read an event again, it must be served with the same index and the same leaf bytes as when you verified it. No event may lose the index it had, and while you are enrolled no event may newly appear without one. The events served without an index on your first run are your pre-log history. A run that re-reads only recent events re-checks only those. To re-check older ones, verify the copies you kept (step 8) again.
3774018. Save the checkpoint you verified and a record of each event you verified. They are your evidence and your starting point for the next run.
378402 
403### Upgrade for a new leaf version
404 
405Each `axt-verify` release rebuilds only [leaf versions](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#how-an-event-becomes-a-leaf) that were defined when it was released. Assume that your log can start writing a new version at any time once a release that rebuilds it is published. Install that release as soon as it is published.
406 
407| Leaf version | `axt-verify` releases that rebuild it |
408| ------------ | ------------------------------------- |
409| `0x01` | Every release |
410| `0x02` | `v0.2.0` and later |
411 
412`axt-verify version` prints the release you run. A new installation gets the newest release. If the table's last row does not include your release, upgrade to a release in that row. If none is published yet, upgrade as soon as one is:
413 
4141. Install the newest release the way you installed before (the `go install` line in [Verify with axt-verify](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#verify-with-axt-verify)).
4152. Keep running it as before: same `--org`, same `--state` file, same schedule.
416 
417What to expect:
418 
419* **Before your log starts writing the new version.** The newer release verifies your log as before, because it also rebuilds the earlier leaf versions.
420* **After your log starts writing the new version, on a release that does not rebuild it.** The release reports every event whose leaf has that version as a verification failure, with exit status `1`, even when the event has none of the version's optional fields. Leaves of the versions your release rebuilds are not affected. They verify as they did before. The failures clear once you run a release that rebuilds the version on the same `--state` file, and the append-only check continues from where your last run ended.
421* **If you return to an earlier release.** Do not give an earlier release a state file that a newer release has saved. The earlier release reports every event that was waiting for a checkpoint as a verification failure. If you may need to return to the earlier release, copy the state file before the first run of the newer one, and give the earlier release that copy.
422 
423A verifier you maintain yourself needs a new version's fields, and the rule for which entries to rebuild, from [How an event becomes a leaf](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#how-an-event-becomes-a-leaf) before your log starts writing that version.
424 
379425### Verify with axt-verify
380426 
381[`axt-verify`](https://github.com/anthropics/axt-verify) is Anthropic's open-source verifier for this log. It is a single Go binary that you run on your own infrastructure. Each release has exactly one log signing key from [Published key fingerprints](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#published-key-fingerprints) built in, so it never asks the API which key to trust. When Anthropic rotates the key, you upgrade to the release that carries the new one on the switch date. `axt-verify` derives your origin from the organization UUID you pass with `--org`, which is the one you took from the Console in [Before you begin](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#before-you-begin). It rejects any checkpoint whose origin line differs.
427If you already run `axt-verify` on a schedule, read [Upgrade for a new leaf version](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#upgrade-for-a-new-leaf-version) first.
382428 
429[`axt-verify`](https://github.com/anthropics/axt-verify) is Anthropic's open-source verifier for this log. It is a single Go binary that you run on your own infrastructure. Each release has exactly one log signing key from [Published key fingerprints](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#published-key-fingerprints) built in, so it never asks the API which key to trust. When Anthropic rotates the key, you upgrade to the release that carries the new one on the switch date. `axt-verify` derives your origin from the organization UUID you pass with `--org`, which is the one you took from the Console in [Before you start](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#before-you-begin). It rejects any checkpoint whose origin line differs.
430 
383431Install it with Go 1.26 or newer. It reads your Compliance Access Key from the `ANTHROPIC_COMPLIANCE_ACCESS_KEY` environment variable, never from a flag or a file. The `run` command is the one to schedule:
384432 
385433```bash
from line 439
391439 run
392440```
393441 
394Each `run` fetches the latest checkpoint and verifies its signature and origin line. It then proves the log is an append-only extension of the checkpoint the previous run saved. Next it pages through the Access Transparency events on your Activity Feed. It starts seven days (by `created_at`) before the newest event the previous run read, so that events listed late or out of order are still picked up. It rebuilds each event's leaf, verifies an inclusion proof for it, and compares any event it verified before against what it recorded then. Finally, it saves the new checkpoint and its progress to the `--state` file, which the next run starts from. Run it at least daily. Hourly is reasonable. With a parent-organization key, run one copy per child organization, each with its own `--org` and `--state` file. Each child organization's UUID also comes from the Claude Console, not from the Compliance API responses you are verifying. To find it, switch to the child organization in the account menu at the bottom of the Console sidebar, then open the [Organization](https://platform.claude.com/settings/organization) page (`platform.claude.com/settings/organization`). You can also find it in your parent organization's list of organizations in the Console. `axt-verify checkpoint` does only the checkpoint and append-only steps. `axt-verify events FILE` verifies events you already hold, such as an auditor's sample or your own export. It proves that each event in the file is still committed in the log under the current checkpoint. It does not read the feed or touch the state file.
442Each `run` fetches the latest checkpoint and verifies its signature and origin line. It then proves the log is an append-only extension of the checkpoint the previous run saved. Next it pages through the Access Transparency events on your Activity Feed. It starts 7 days (by `created_at`) before the newest event the previous run read, so that events listed late or out of order are still picked up. It rebuilds each [leaf to rebuild for the event](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#how-an-event-becomes-a-leaf), verifies an inclusion proof against them, and compares any event it verified before against what it recorded then. Finally, it saves the new checkpoint and its progress to the `--state` file, which the next run starts from. Run it at least daily. Hourly is reasonable. With a parent-organization key, run one copy for each child organization, each with its own `--org` and `--state` file. Each child organization's UUID also comes from the Claude Console, not from the Compliance API responses you are verifying. To find it, switch to the child organization in the account menu at the bottom of the Console sidebar, then open the [Organization](https://platform.claude.com/settings/organization) page (`platform.claude.com/settings/organization`). You can also find it in your parent organization's list of organizations in the Console. `axt-verify checkpoint` does only the checkpoint and append-only steps. `axt-verify events FILE` verifies events you already hold, such as an auditor's sample or your own export. It proves that each event in the file is still committed in the log under the current checkpoint. It does not read the feed or touch the state file.
395443 
396444One limit follows from that window: `run` re-reads only the last 7 days of events, so it re-checks recently served events (step 7), not your whole history. Keep the events you export (see [Keep your own checkpoint archive](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#keep-your-own-checkpoint-archive)). `axt-verify events FILE` proves at any later date that those copies are still committed in the log, but it does not re-read the feed. To detect an older event removed from or rewritten on the feed, re-export that range from the Activity Feed and compare it with the copies you kept. You can also verify the re-export itself with `axt-verify events FILE`. The 7-day overlap is longer than the feed's 2-business-day delivery time, so a late-arriving event still falls inside a later run's window. `--overlap` changes the duration if you need to.
397445 
from line 449
401449 
402450`axt-verify` prints your origin, the tree size and root hash of the checkpoint it verified, the tree size the append-only check started from, and a count of events by outcome. Pass `--json` to get the same report as one JSON object on each line. Each event has one of four outcomes:
403451 
404* **Verified:** the leaf rebuilt from the served event is committed at the event's index in the signed log.
405* **Pending:** the event's index is beyond the latest published checkpoint. This is normal for a short time after an event appears. In `run`, `axt-verify` remembers the event, verifies it on a later run once a checkpoint covers it, and fails it if that takes longer than 24 hours. `events FILE` has no later run to settle it, so it waits up to a minute for a covering checkpoint to be published. If none arrives, it reports the event as not yet covered and ends with exit status `3`. Run it again later. If `events FILE` reports the same event as not yet covered on two runs at least a day apart, treat it as a verification failure and escalate as for exit status `1`.
452* **Verified:** a leaf rebuilt from the served event is committed at the event's index in the signed log.
453* **Pending:** the event's index is beyond the latest published checkpoint. This is normal for a short time after an event appears. In `run`, `axt-verify` records the event, verifies it on a later run once a checkpoint covers it, and fails it if that takes longer than 24 hours. `events FILE` has no later run to settle it, so it waits up to a minute for a covering checkpoint to be published. If none arrives, it reports the event as not yet covered and ends with exit status `3`. Run it again later. If `events FILE` reports the same event as not yet covered on two runs at least a day apart, treat it as a verification failure and escalate as for exit status `1`.
406454* **Not logged:** the event was served without an index. An event is served without `transparency_log_leaf_index` only while your organization is not enrolled in Access Transparency, or when it was recorded before your organization's log was created (see [The `transparency_log_leaf_index` field on Activity Feed events](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#the-transparency-log-leaf-index-field-on-activity-feed-events)). `axt-verify` reports such events as not logged and does not fail the run on them. An index-less event is not expected when it is dated after your log was created and falls inside a period when you were enrolled. Review the not-logged list in the run's summary or `--json` output rather than relying on the exit status alone.
407455* **Failed:** see exit status `1`.
408456 
from line 458
410458 
411459* **`0`:** Nothing failed. Not-logged events are reported, not failed, and so are pending events in `run`.
412460 
413* **`1`:** A verification failure. This is a security finding, not a transient error. Keep the state file and the output, and report it to your Anthropic account representative or [Anthropic support](https://support.claude.com). The causes are:
461* **`1`:** A verification failure. If every new event fails because its inclusion proof does not reproduce the signed root hash, first rule out a release that does not rebuild your log's newest leaf version, as that item in this list describes. If that is not the cause, and for any other failure, treat it as a security finding, not a transient error. Keep the state file and the output, and report it to your Anthropic account representative or [Anthropic support](https://support.claude.com). The causes are:
414462 
415463 * A checkpoint with the wrong origin, or a signature that does not verify under the key built into your `axt-verify` release. Compare the `key_hash` on the failing checkpoint's signature line with [Published key fingerprints](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#published-key-fingerprints). A key listed there with a switch date you have not upgraded for means you need the matching release. A key not listed there is a security finding, whatever release you run. On this failure `axt-verify` prints the key hash of every signature on the served checkpoint and the key hash of the key it trusts, as eight hex digits each. That output is enough to make the comparison.
416464 * A checkpoint that is not a well-formed signed note, for example one whose root hash is not 32 bytes.
from line 465
417465 * A log that shrank, or that cannot prove it extends the checkpoint you saved. The output then carries both checkpoints and the proof, so the evidence stands on its own.
418466 * Two signed checkpoints for the same tree size with different root hashes. The output carries both checkpoints.
419467 * A checkpoint file passed with `--from` whose signature does not verify under the key built into your `axt-verify` release, or a `--from` or `--from-trusted` file whose origin is not yours. For an archive signed before a key rotation, see [Keep your own checkpoint archive](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#keep-your-own-checkpoint-archive).
420 * An inclusion proof that does not reproduce the signed root hash for the event you were served.
468 * An inclusion proof that does not reproduce the signed root hash for the event you were served. A release that does not rebuild a leaf version reports this for every event whose leaf has that version. If every new event fails this way at once, check first that you run the newest `axt-verify` release (see [Upgrade for a new leaf version](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#upgrade-for-a-new-leaf-version)). If you do not, copy the state file, keep the copy and the output, and run the newest release on the original `--state` file. The failures clear once you run a release that rebuilds the version. If you already run the newest release, or the failures remain after you upgrade, it is a security finding.
421469 * An event inside the run's window served differently from how an earlier run recorded it: different leaf bytes, a different index, or no index where it had one.
422470 * An event still pending 24 hours after the run first saw it.
423471 * A refused inclusion proof (`400`, `401`, or `403`) for an event the feed served you.
from line 508
460508 
461509 <Accordion title="What happens when Anthropic rotates the signing key?">
462510 Planned rotations are announced in [Published key fingerprints](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#published-key-fingerprints) at least 30 days ahead, with a switch date. On the switch date Anthropic starts signing with the new key and publishes the `axt-verify` release that carries it. On the same date Anthropic re-issues every organization's latest checkpoint under the new key, even for a log that has not grown. Each `axt-verify` release carries one key, so upgrade on the switch date. Running the old release after the switch fails with exit status `1`, and so does running the new release before it. Either failure clears once you run the matching release. Checkpoints you saved under the old key stay valid starting points, because the append-only proof from a saved checkpoint to a new one does not depend on which key signed the old one. The new key appears at the front of the [verifier key set](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#read-the-verifier-keys) and earlier keys stay listed. Checkpoints you already verified or archived therefore keep verifying against that set. A verifier of your own that pins the published fingerprints needs the new fingerprint, with its switch date, added before that date. A verifier that holds the key set locally re-fetches it when it meets a signature whose key hash it does not hold. A checkpoint commits to the whole history. Once one checkpoint signed by the new key verifies, and a consistency proof from your saved checkpoint leads to it, every earlier entry is re-established as well.
511 </Accordion>
512 
513 <Accordion title="What is a leaf version, and do I need to track which one a leaf has?">
514 A leaf version is the first byte of a leaf entry. It says which set of fields the leaf commits to (see [How an event becomes a leaf](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#how-an-event-becomes-a-leaf)). You do not need to track it. Your log can hold leaves of more than one version, and a verifier rebuilds the entries that the last rule in that section names for an event, and accepts the event if its inclusion proof matches one. What you do need is an `axt-verify` release that rebuilds the newest version your log writes (see [Upgrade for a new leaf version](https://platform.claude.com/docs/en/manage-claude/access-transparency-log#upgrade-for-a-new-leaf-version)).
463515 </Accordion>
464516 
465517 <Accordion title="Can I compute proofs myself instead of calling the proof endpoints?">

manage-claude/admin-api Changed · +46 / -46 lines

from line 345
345345 
346346<CodeGroup>
347347 ```bash cURL
348 curl "https://api.anthropic.com/v1/organizations/users/user_01XyDMpzjS89pFZXqSFUBDr6" \
348 curl "https://api.anthropic.com/v1/organizations/users/user_01WxYzAbCdEfGhJkMnPqRsTu" \
349349 -H "x-api-key: $ANTHROPIC_API_KEY" \
350350 -H "anthropic-version: 2023-06-01" \
351351 -H "content-type: application/json" \
from line 354
354354 
355355 ```bash CLI
356356 ant organization:users update \
357 --user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
357 --user-id user_01WxYzAbCdEfGhJkMnPqRsTu \
358358 --role developer
359359 ```
360360 
from line 362
362362 client = anthropic.Anthropic()
363363 
364364 user = client.organization.users.update(
365 "user_01XyDMpzjS89pFZXqSFUBDr6", role="developer"
365 "user_01WxYzAbCdEfGhJkMnPqRsTu", role="developer"
366366 )
367367 
368368 print(f"id: {user.id}")
from line 372
372372 ```typescript TypeScript
373373 const client = new Anthropic();
374374 
375 const user = await client.organization.users.update("user_01XyDMpzjS89pFZXqSFUBDr6", {
375 const user = await client.organization.users.update("user_01WxYzAbCdEfGhJkMnPqRsTu", {
376376 role: "developer"
377377 });
378378 
from line 387
387387 AnthropicClient client = new();
388388 
389389 var user = await client.Organization.Users.Update(
390 "user_01XyDMpzjS89pFZXqSFUBDr6",
390 "user_01WxYzAbCdEfGhJkMnPqRsTu",
391391 new() { Role = Role.Developer }
392392 );
393393 
from line 400
400400 
401401 user, err := client.Organization.Users.Update(
402402 context.Background(),
403 "user_01XyDMpzjS89pFZXqSFUBDr6",
403 "user_01WxYzAbCdEfGhJkMnPqRsTu",
404404 anthropic.OrganizationUserUpdateParams{
405405 Role: anthropic.OrganizationUserUpdateParamsRoleDeveloper,
406406 },
from line 423
423423 .role(UserUpdateParams.Role.DEVELOPER)
424424 .build();
425425 var user = client.organization().users()
426 .update("user_01XyDMpzjS89pFZXqSFUBDr6", params);
426 .update("user_01WxYzAbCdEfGhJkMnPqRsTu", params);
427427 
428428 IO.println("id: " + user.id());
429429 IO.println("role: " + user.role().asString());
from line 437
437437 $client = new Client();
438438 
439439 $user = $client->organization->users->update(
440 userID: 'user_01XyDMpzjS89pFZXqSFUBDr6',
440 userID: 'user_01WxYzAbCdEfGhJkMnPqRsTu',
441441 role: Role::DEVELOPER,
442442 );
443443 
from line 448
448448 ```ruby Ruby
449449 client = Anthropic::Client.new
450450 
451 user_id = "user_01XyDMpzjS89pFZXqSFUBDr6"
451 user_id = "user_01WxYzAbCdEfGhJkMnPqRsTu"
452452 user = client.organization.users.update(user_id, role: :developer)
453453 
454454 puts "id: #{user.id}"
from line 460
460460 
461461<CodeGroup>
462462 ```bash cURL
463 curl -X DELETE "https://api.anthropic.com/v1/organizations/users/user_01XyDMpzjS89pFZXqSFUBDr6" \
463 curl -X DELETE "https://api.anthropic.com/v1/organizations/users/user_01WxYzAbCdEfGhJkMnPqRsTu" \
464464 -H "x-api-key: $ANTHROPIC_API_KEY" \
465465 -H "anthropic-version: 2023-06-01"
466466 ```
467467 
468468 ```bash CLI
469 ant organization:users remove --user-id user_01XyDMpzjS89pFZXqSFUBDr6
469 ant organization:users remove --user-id user_01WxYzAbCdEfGhJkMnPqRsTu
470470 ```
471471 
472472 ```python Python
473473 client = anthropic.Anthropic()
474474 
475 removed_user = client.organization.users.remove("user_01XyDMpzjS89pFZXqSFUBDr6")
475 removed_user = client.organization.users.remove("user_01WxYzAbCdEfGhJkMnPqRsTu")
476476 
477477 print(f"id: {removed_user.id}")
478478 ```
from line 480
480480 ```typescript TypeScript
481481 const client = new Anthropic();
482482 
483 const removedUser = await client.organization.users.remove("user_01XyDMpzjS89pFZXqSFUBDr6");
483 const removedUser = await client.organization.users.remove("user_01WxYzAbCdEfGhJkMnPqRsTu");
484484 
485485 console.log(`id: ${removedUser.id}`);
486486 ```
from line 488
488488 ```csharp C#
489489 AnthropicClient client = new();
490490 
491 var removedUser = await client.Organization.Users.Remove("user_01XyDMpzjS89pFZXqSFUBDr6");
491 var removedUser = await client.Organization.Users.Remove("user_01WxYzAbCdEfGhJkMnPqRsTu");
492492 
493493 Console.WriteLine($"id: {removedUser.ID}");
494494 ```
from line 496
496496 ```go Go
497497 client := anthropic.NewClient()
498498 
499 removedUser, err := client.Organization.Users.Remove(context.Background(), "user_01XyDMpzjS89pFZXqSFUBDr6")
499 removedUser, err := client.Organization.Users.Remove(context.Background(), "user_01WxYzAbCdEfGhJkMnPqRsTu")
500500 if err != nil {
501501 log.Fatal(err)
502502 }
from line 508
508508 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
509509 
510510 var removedUser = client.organization().users()
511 .remove("user_01XyDMpzjS89pFZXqSFUBDr6");
511 .remove("user_01WxYzAbCdEfGhJkMnPqRsTu");
512512 
513513 IO.println("id: " + removedUser.id());
514514 ```
from line 517
517517 $client = new Client();
518518 
519519 $removedUser = $client->organization->users->remove(
520 userID: 'user_01XyDMpzjS89pFZXqSFUBDr6',
520 userID: 'user_01WxYzAbCdEfGhJkMnPqRsTu',
521521 );
522522 
523523 echo "id: {$removedUser->id}\n";
from line 526
526526 ```ruby Ruby
527527 client = Anthropic::Client.new
528528 
529 user_id = "user_01XyDMpzjS89pFZXqSFUBDr6"
529 user_id = "user_01WxYzAbCdEfGhJkMnPqRsTu"
530530 removed_user = client.organization.users.remove(user_id)
531531 
532532 puts "id: #{removed_user.id}"
from line 859
859859 -H "anthropic-version: 2023-06-01" \
860860 -H "content-type: application/json" \
861861 -d '{
862 "user_id": "user_01XyDMpzjS89pFZXqSFUBDr6",
862 "user_id": "user_01WxYzAbCdEfGhJkMnPqRsTu",
863863 "workspace_role": "workspace_developer"
864864 }'
865865 ```
from line 867
867867 ```bash CLI
868868 ant organization:workspaces:members add \
869869 --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ \
870 --user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
870 --user-id user_01WxYzAbCdEfGhJkMnPqRsTu \
871871 --workspace-role workspace_developer
872872 ```
873873 
from line 876
876876 
877877 member = client.organization.workspaces.members.add(
878878 "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
879 user_id="user_01XyDMpzjS89pFZXqSFUBDr6",
879 user_id="user_01WxYzAbCdEfGhJkMnPqRsTu",
880880 workspace_role="workspace_developer",
881881 )
882882 
from line 890
890890 const member = await client.organization.workspaces.members.add(
891891 "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
892892 {
893 user_id: "user_01XyDMpzjS89pFZXqSFUBDr6",
893 user_id: "user_01WxYzAbCdEfGhJkMnPqRsTu",
894894 workspace_role: "workspace_developer"
895895 }
896896 );
from line 908
908908 "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
909909 new()
910910 {
911 UserID = "user_01XyDMpzjS89pFZXqSFUBDr6",
911 UserID = "user_01WxYzAbCdEfGhJkMnPqRsTu",
912912 WorkspaceRole = NoBillingWorkspaceRole.WorkspaceDeveloper
913913 }
914914 );
from line 924
924924 context.Background(),
925925 "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
926926 anthropic.OrganizationWorkspaceMemberAddParams{
927 UserID: "user_01XyDMpzjS89pFZXqSFUBDr6",
927 UserID: "user_01WxYzAbCdEfGhJkMnPqRsTu",
928928 WorkspaceRole: anthropic.NoBillingWorkspaceRoleWorkspaceDeveloper,
929929 },
930930 )
from line 944
944944 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
945945 
946946 var params = MemberAddParams.builder()
947 .userId("user_01XyDMpzjS89pFZXqSFUBDr6")
947 .userId("user_01WxYzAbCdEfGhJkMnPqRsTu")
948948 .workspaceRole(NoBillingWorkspaceRole.WORKSPACE_DEVELOPER)
949949 .build();
950950 var member = client.organization().workspaces().members()
from line 963
963963 
964964 $member = $client->organization->workspaces->members->add(
965965 workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
966 userID: 'user_01XyDMpzjS89pFZXqSFUBDr6',
966 userID: 'user_01WxYzAbCdEfGhJkMnPqRsTu',
967967 workspaceRole: NoBillingWorkspaceRole::WORKSPACE_DEVELOPER,
968968 );
969969 
from line 977
977977 workspace_id = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
978978 member = client.organization.workspaces.members.add(
979979 workspace_id,
980 user_id: "user_01XyDMpzjS89pFZXqSFUBDr6",
980 user_id: "user_01WxYzAbCdEfGhJkMnPqRsTu",
981981 workspace_role: :workspace_developer
982982 )
983983 
from line 1107
11071107 
11081108<CodeGroup>
11091109 ```bash cURL
1110 curl "https://api.anthropic.com/v1/organizations/workspaces/wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ/members/user_01XyDMpzjS89pFZXqSFUBDr6" \
1110 curl "https://api.anthropic.com/v1/organizations/workspaces/wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ/members/user_01WxYzAbCdEfGhJkMnPqRsTu" \
11111111 -H "x-api-key: $ANTHROPIC_API_KEY" \
11121112 -H "anthropic-version: 2023-06-01" \
11131113 -H "content-type: application/json" \
from line 1116
11161116 
11171117 ```bash CLI
11181118 ant organization:workspaces:members update \
1119 --user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
1119 --user-id user_01WxYzAbCdEfGhJkMnPqRsTu \
11201120 --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ \
11211121 --workspace-role workspace_admin
11221122 ```
from line 1125
11251125 client = anthropic.Anthropic()
11261126 
11271127 member = client.organization.workspaces.members.update(
1128 "user_01XyDMpzjS89pFZXqSFUBDr6",
1128 "user_01WxYzAbCdEfGhJkMnPqRsTu",
11291129 workspace_id="wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
11301130 workspace_role="workspace_admin",
11311131 )
from line 1138
11381138 const client = new Anthropic();
11391139 
11401140 const member = await client.organization.workspaces.members.update(
1141 "user_01XyDMpzjS89pFZXqSFUBDr6",
1141 "user_01WxYzAbCdEfGhJkMnPqRsTu",
11421142 {
11431143 workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
11441144 workspace_role: "workspace_admin"
from line 1155
11551155 AnthropicClient client = new();
11561156 
11571157 var member = await client.Organization.Workspaces.Members.Update(
1158 "user_01XyDMpzjS89pFZXqSFUBDr6",
1158 "user_01WxYzAbCdEfGhJkMnPqRsTu",
11591159 new()
11601160 {
11611161 WorkspaceID = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
from line 1172
11721172 
11731173 member, err := client.Organization.Workspaces.Members.Update(
11741174 context.Background(),
1175 "user_01XyDMpzjS89pFZXqSFUBDr6",
1175 "user_01WxYzAbCdEfGhJkMnPqRsTu",
11761176 anthropic.OrganizationWorkspaceMemberUpdateParams{
11771177 WorkspaceID: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
11781178 WorkspaceRole: anthropic.WorkspaceRoleWorkspaceAdmin,
from line 1198
11981198 .workspaceRole(WorkspaceRole.WORKSPACE_ADMIN)
11991199 .build();
12001200 var member = client.organization().workspaces().members()
1201 .update("user_01XyDMpzjS89pFZXqSFUBDr6", params);
1201 .update("user_01WxYzAbCdEfGhJkMnPqRsTu", params);
12021202 
12031203 IO.println("user_id: " + member.userId());
12041204 IO.println("workspace_role: " + member.workspaceRole().asString());
from line 1212
12121212 $client = new Client();
12131213 
12141214 $member = $client->organization->workspaces->members->update(
1215 userID: 'user_01XyDMpzjS89pFZXqSFUBDr6',
1215 userID: 'user_01WxYzAbCdEfGhJkMnPqRsTu',
12161216 workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
12171217 workspaceRole: WorkspaceRole::WORKSPACE_ADMIN,
12181218 );
from line 1224
12241224 ```ruby Ruby
12251225 client = Anthropic::Client.new
12261226 
1227 user_id = "user_01XyDMpzjS89pFZXqSFUBDr6"
1227 user_id = "user_01WxYzAbCdEfGhJkMnPqRsTu"
12281228 member = client.organization.workspaces.members.update(
12291229 user_id,
12301230 workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
from line 1240
12401240 
12411241<CodeGroup>
12421242 ```bash cURL
1243 curl -X DELETE "https://api.anthropic.com/v1/organizations/workspaces/wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ/members/user_01XyDMpzjS89pFZXqSFUBDr6" \
1243 curl -X DELETE "https://api.anthropic.com/v1/organizations/workspaces/wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ/members/user_01WxYzAbCdEfGhJkMnPqRsTu" \
12441244 -H "x-api-key: $ANTHROPIC_API_KEY" \
12451245 -H "anthropic-version: 2023-06-01"
12461246 ```
from line 1247
12471247 
12481248 ```bash CLI
12491249 ant organization:workspaces:members remove \
1250 --user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
1250 --user-id user_01WxYzAbCdEfGhJkMnPqRsTu \
12511251 --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ
12521252 ```
12531253 
from line 1255
12551255 client = anthropic.Anthropic()
12561256 
12571257 removed_member = client.organization.workspaces.members.remove(
1258 "user_01XyDMpzjS89pFZXqSFUBDr6", workspace_id="wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
1258 "user_01WxYzAbCdEfGhJkMnPqRsTu", workspace_id="wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
12591259 )
12601260 
12611261 print(f"user_id: {removed_member.user_id}")
from line 1265
12651265 const client = new Anthropic();
12661266 
12671267 const removedMember = await client.organization.workspaces.members.remove(
1268 "user_01XyDMpzjS89pFZXqSFUBDr6",
1268 "user_01WxYzAbCdEfGhJkMnPqRsTu",
12691269 { workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }
12701270 );
12711271 
from line 1276
12761276 AnthropicClient client = new();
12771277 
12781278 var removedMember = await client.Organization.Workspaces.Members.Remove(
1279 "user_01XyDMpzjS89pFZXqSFUBDr6",
1279 "user_01WxYzAbCdEfGhJkMnPqRsTu",
12801280 new() { WorkspaceID = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }
12811281 );
12821282 
from line 1288
12881288 
12891289 removedMember, err := client.Organization.Workspaces.Members.Remove(
12901290 context.Background(),
1291 "user_01XyDMpzjS89pFZXqSFUBDr6",
1291 "user_01WxYzAbCdEfGhJkMnPqRsTu",
12921292 anthropic.OrganizationWorkspaceMemberRemoveParams{
12931293 WorkspaceID: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
12941294 },
from line 1310
13101310 .workspaceId("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ")
13111311 .build();
13121312 var removedMember = client.organization().workspaces().members()
1313 .remove("user_01XyDMpzjS89pFZXqSFUBDr6", params);
1313 .remove("user_01WxYzAbCdEfGhJkMnPqRsTu", params);
13141314 
13151315 IO.println("user_id: " + removedMember.userId());
13161316 }
from line 1320
13201320 $client = new Client();
13211321 
13221322 $removedMember = $client->organization->workspaces->members->remove(
1323 userID: 'user_01XyDMpzjS89pFZXqSFUBDr6',
1323 userID: 'user_01WxYzAbCdEfGhJkMnPqRsTu',
13241324 workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
13251325 );
13261326 
from line 1330
13301330 ```ruby Ruby
13311331 client = Anthropic::Client.new
13321332 
1333 user_id = "user_01XyDMpzjS89pFZXqSFUBDr6"
1333 user_id = "user_01WxYzAbCdEfGhJkMnPqRsTu"
13341334 removed_member = client.organization.workspaces.members.remove(
13351335 user_id,
13361336 workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
from line 1704
17041704 ```
17051705</CodeGroup>
17061706 
1707```text wrap
1707```json
17081708{
17091709 "id": "12345678-1234-5678-1234-567812345678",
17101710 "type": "organization",

manage-claude/analytics-api Changed · +5 / -1 lines

from line 95
9595 
9696## How metrics are defined
9797 
98**Active users.** A user counts as active for a day if any of the following is true: they sent at least one chat message in Claude, they had at least one Claude Code session (local or remote) associated with your Claude Enterprise organization that included tool use or git activity, or they had at least one Cowork session with tool use or message activity.
98**Active users.** A user counts as active for a day if any of the following is true:
99 
100* They sent at least one chat message in Claude.
101* They had at least one Claude Code session (local or remote) associated with your Claude Enterprise organization that included tool use or git activity.
102* They had at least one Cowork session with tool use or message activity.
99103 
100104**Chat and Cowork unified (beta).** Chat and Cowork unified brings Cowork's features into claude.ai chat. Most activity in Chat and Cowork unified is reported under the `chat_cowork_unified` product value, not `chat` or `cowork`.
101105 

manage-claude/api-and-data-retention Changed · +3 / -3 lines

from line 78
7878 
7979Your signed BAA is the official source of truth for which features are covered. The API also enforces these restrictions automatically. When a HIPAA-enabled organization sends a request that includes a non-eligible feature, the API returns a `400` error to prevent accidental use of features not covered by your BAA:
8080 
81```text
81```json
8282{
8383 "type": "error",
8484 "error": {
from line 126
126126 
127127Claude Fable 5.1, Claude Mythos 5.1, Claude Fable 5, and Claude Mythos 5 are designated Covered Models (see the [Covered Models support article](https://support.claude.com/en/articles/15425695)) and require 30-day data retention; ZDR is therefore not available for any of them unless expressly authorized by Anthropic. On the Claude API, requests to Claude Fable 5 from an organization whose data retention configuration does not meet this requirement return a `400 invalid_request_error`:
128128 
129```text
129```json
130130{
131131 "type": "error",
132132 "error": {
from line 202
202202| [Thinking](https://platform.claude.com/docs/en/build-with-claude/thinking) | `/v1/messages`<br />with `thinking` | <Eligible>Yes</Eligible> | <Eligible>Yes</Eligible> | |
203203| [Token counting](https://platform.claude.com/docs/en/build-with-claude/token-counting) | `/v1/messages/count_tokens` | <Eligible>Yes</Eligible> | <Eligible>Yes</Eligible> | Count tokens before sending requests. |
204204| [Tool search](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool) | `/v1/messages`<br />with `tool_search` tool | <Eligible>Yes</Eligible> | <Eligible status="no">No</Eligible> | Server-side tool run by Anthropic; the tool definitions in the request are searched in memory per call and nothing is stored after the response. |
205| [User profiles](https://platform.claude.com/docs/en/manage-claude/user-profiles) | `/v1/user_profiles` | <Eligible status="no">No</Eligible> | <Eligible status="no">No</Eligible> | Profiles are metadata about your end customers and don't contain prompts or outputs. The profile data you send is retained according to standard policy until you delete the profile. Not covered under HIPAA readiness; requests to `/v1/user_profiles` are not blocked. See [What a profile contains and how Anthropic uses it](https://platform.claude.com/docs/en/manage-claude/user-profiles#what-a-profile-contains-and-how-anthropic-uses-it). |
205| [User profiles](https://platform.claude.com/docs/en/manage-claude/user-profiles) | `/v1/user_profiles` | <Eligible status="no">No</Eligible> | <Eligible status="no">No</Eligible> | Profiles are metadata about your end customers and don't contain prompts or outputs. The profile data you send is retained according to standard policy until you delete the profile. HIPAA-enabled organizations can use user profiles, but the user profiles API is not a HIPAA-eligible service and PHI must not be included in the profile data you send. See [What a profile contains and how Anthropic uses it](https://platform.claude.com/docs/en/manage-claude/user-profiles#what-a-profile-contains-and-how-anthropic-uses-it). |
206206| [Web fetch](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool) | `/v1/messages`<br />with `web_fetch` tool | <Eligible>Yes</Eligible> | <Eligible status="no">No</Eligible> | Fetched web content returned in the API response. [Dynamic filtering for web fetch](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool#dynamic-filtering) is not eligible for ZDR or HIPAA. Website publishers might retain request data (such as fetched URLs and request metadata) according to their own policies. |
207207| [Web search](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool) | `/v1/messages`<br />with `web_search` tool | <Eligible>Yes</Eligible> | <Eligible>Yes</Eligible> | Real-time web search results returned in the API response. [Dynamic filtering for web search](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool#dynamic-filtering) is not eligible for ZDR or HIPAA. |
208208 

manage-claude/cmek-admin-api New page · 740 lines, new page

## Before you start ## Create, validate, and attach the key

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: Add and attach an encryption key with the Admin API
url: https://platform.claude.com/docs/en/manage-claude/cmek-admin-api
description: Create, validate, and attach a customer-managed encryption key with three Admin API calls.
---

These calls work on Claude Platform. On Claude Enterprise or Claude Platform on AWS, follow [your setup page](https://platform.claude.com/docs/en/manage-claude/cmek#set-it-up).

Creating an external key is what **Add key** does in the Claude Console, and validating it is what **Verify** does.

## Before you start

* Customer-managed encryption keys (CMEK) are [turned on for your organization](https://platform.claude.com/docs/en/manage-claude/cmek#availability).
* You have an [Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys). The samples read it from `ANTHROPIC_API_KEY`.
* You've created your key in [AWS KMS](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#encryption-key-setup), [Google Cloud KMS](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#encryption-key-setup), or [Azure Key Vault](https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault#encryption-key-setup), and kept the values the setup steps tell you to copy.
* You have a workspace that [retains data](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#data-retention), ideally a new one, because [existing data stays under Anthropic's key](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect).

## Create, validate, and attach the key

<Steps>
  <Step title="Create the external key">
    <Tabs>
      <Tab title="AWS">
        Replace `<friendly-name>` with a display name and `<key-arn-from-create-key-step>` with the key ARN.

        <CodeGroup>
          ```bash cURL
          curl -sS "https://api.anthropic.com/v1/organizations/external_keys" \
            -H "x-api-key: $ANTHROPIC_API_KEY" \
            -H "anthropic-version: 2023-06-01" \
            -H "content-type: application/json" \
            -d '{
              "display_name": "<friendly-name>",
              "geo": "us",
              "provider_config": {
                "type": "aws",
                "kms_arn": "<key-arn-from-create-key-step>"
              }
            }'
          ```

          ```bash CLI
          ant organization:external-keys create <<'YAML'
          display_name: "<friendly-name>"
          geo: us
          provider_config:
            type: aws
            kms_arn: "<key-arn-from-create-key-step>"
          YAML
          ```

          ```python Python
          client = anthropic.Anthropic()

          external_key = client.organization.external_keys.create(
              display_name="<friendly-name>",
              geo="us",
              provider_config={"type": "aws", "kms_arn": "<key-arn-from-create-key-step>"},
          )

          print(f"id: {external_key.id}")
          print(f"display_name: {external_key.display_name}")
          ```

          ```typescript TypeScript
          const client = new Anthropic();

          const externalKey = await client.organization.externalKeys.create({
            display_name: "<friendly-name>",
            geo: "us",
            provider_config: {
              type: "aws",
              kms_arn: "<key-arn-from-create-key-step>"
            }
          });

          console.log(`id: ${externalKey.id}`);
          console.log(`display_name: ${externalKey.display_name}`);
          ```

          ```csharp C#
          using Anthropic.Models.Organization.ExternalKeys;

          AnthropicClient client = new();

          var externalKey = await client.Organization.ExternalKeys.Create(new()
          {
              DisplayName = "<friendly-name>",
              Geo = Geo.Us,
              ProviderConfig = new AwsExternalKeyConfig
              {
                  KmsArn = "<key-arn-from-create-key-step>"
              }
          });

          Console.WriteLine($"id: {externalKey.ID}");
          Console.WriteLine($"display_name: {externalKey.DisplayName}");
          ```

          ```go Go
          client := anthropic.NewClient()

          externalKey, err := client.Organization.ExternalKeys.New(context.Background(), anthropic.OrganizationExternalKeyNewParams{
          	DisplayName: anthropic.String("<friendly-name>"),
          	Geo:         anthropic.OrganizationExternalKeyNewParamsGeoUs,
          	ProviderConfig: anthropic.OrganizationExternalKeyNewParamsProviderConfigUnion{
          		OfAWS: &anthropic.AWSExternalKeyConfigParam{
          			KMSARN: "<key-arn-from-create-key-step>",
          		},
          	},
          })
          if err != nil {
          	log.Fatal(err)
          }

          fmt.Printf("id: %s\n", externalKey.ID)
          fmt.Printf("display_name: %s\n", externalKey.DisplayName)
          ```

          ```java Java
          import com.anthropic.models.organization.externalkeys.AwsExternalKeyConfig;
          import com.anthropic.models.organization.externalkeys.ExternalKeyCreateParams;

          void main() {
              AnthropicClient client = AnthropicOkHttpClient.fromEnv();

              var params = ExternalKeyCreateParams.builder()
                  .displayName("<friendly-name>")
                  .geo(ExternalKeyCreateParams.Geo.US)
                  .providerConfig(AwsExternalKeyConfig.builder()
                      .kmsArn("<key-arn-from-create-key-step>")
                      .build())
                  .build();
              var externalKey = client.organization().externalKeys().create(params);

              IO.println("id: " + externalKey.id());
              IO.println("display_name: " + externalKey.displayName().orElseThrow());
          }
          ```

          ```php PHP
          use Anthropic\Organization\ExternalKeys\ExternalKeyCreateParams\Geo;
          // ...

          $client = new Client();

          $externalKey = $client->organization->externalKeys->create(
              displayName: '<friendly-name>',
              geo: Geo::US,
              providerConfig: [
                  'type' => 'aws',
                  'kmsARN' => '<key-arn-from-create-key-step>',
              ],
          );

          echo "id: {$externalKey->id}\n";
          echo "display_name: {$externalKey->displayName}\n";
          ```

          ```ruby Ruby
          client = Anthropic::Client.new

          external_key = client.organization.external_keys.create(
            display_name: "<friendly-name>",
            geo: :us,
            provider_config: {
              type: :aws,
              kms_arn: "<key-arn-from-create-key-step>"
            }
          )

          puts "id: #{external_key.id}"
          puts "display_name: #{external_key.display_name}"
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Google Cloud">
        Replace `<friendly-name>` with a display name. Replace the value that starts with `projects/` with the full key resource name.

        <CodeGroup>
          ```bash cURL
          curl -sS "https://api.anthropic.com/v1/organizations/external_keys" \
            -H "x-api-key: $ANTHROPIC_API_KEY" \
            -H "anthropic-version: 2023-06-01" \
            -H "content-type: application/json" \
            -d '{
              "display_name": "<friendly-name>",
              "geo": "us",
              "provider_config": {
                "type": "gcp",
                "key_name": "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
              }
            }'
          ```

          ```bash CLI
          ant organization:external-keys create <<'YAML'
          display_name: "<friendly-name>"
          geo: us
          provider_config:
            type: gcp
            key_name: "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
          YAML
          ```

          ```python Python
          client = anthropic.Anthropic()

          external_key = client.organization.external_keys.create(
              display_name="<friendly-name>",
              geo="us",
              provider_config={
                  "type": "gcp",
                  "key_name": "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>",
              },
          )

          print(f"id: {external_key.id}")
          print(f"display_name: {external_key.display_name}")
          ```

          ```typescript TypeScript
          const client = new Anthropic();

          const externalKey = await client.organization.externalKeys.create({
            display_name: "<friendly-name>",
            geo: "us",
            provider_config: {
              type: "gcp",
              key_name:
                "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
            }
          });

          console.log(`id: ${externalKey.id}`);
          console.log(`display_name: ${externalKey.display_name}`);
          ```

          ```csharp C#
          using Anthropic.Models.Organization.ExternalKeys;

          AnthropicClient client = new();

          var externalKey = await client.Organization.ExternalKeys.Create(new()
          {
              DisplayName = "<friendly-name>",
              Geo = Geo.Us,
              ProviderConfig = new GcpExternalKeyConfig
              {
                  KeyName = "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
              }
          });

          Console.WriteLine($"id: {externalKey.ID}");
          Console.WriteLine($"display_name: {externalKey.DisplayName}");
          ```

          ```go Go
          client := anthropic.NewClient()

          externalKey, err := client.Organization.ExternalKeys.New(context.Background(), anthropic.OrganizationExternalKeyNewParams{
          	DisplayName: anthropic.String("<friendly-name>"),
          	Geo:         anthropic.OrganizationExternalKeyNewParamsGeoUs,
          	ProviderConfig: anthropic.OrganizationExternalKeyNewParamsProviderConfigUnion{
          		OfGCP: &anthropic.GCPExternalKeyConfigParam{
          			KeyName: "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>",
          		},
          	},
          })
          if err != nil {
          	log.Fatal(err)
          }

          fmt.Printf("id: %s\n", externalKey.ID)
          fmt.Printf("display_name: %s\n", externalKey.DisplayName)
          ```

          ```java Java
          import com.anthropic.models.organization.externalkeys.ExternalKeyCreateParams;

          void main() {
              AnthropicClient client = AnthropicOkHttpClient.fromEnv();

              var params = ExternalKeyCreateParams.builder()
                  .displayName("<friendly-name>")
                  .geo(ExternalKeyCreateParams.Geo.US)
                  .gcpProviderConfig("projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>")
                  .build();
              var externalKey = client.organization().externalKeys().create(params);

              IO.println("id: " + externalKey.id());
              IO.println("display_name: " + externalKey.displayName().orElseThrow());
          }
          ```

          ```php PHP
          use Anthropic\Organization\ExternalKeys\ExternalKeyCreateParams\Geo;
          // ...

Cut at 300 lines. The page has the rest.

manage-claude/cmek-aws-kms Changed · +85 / -561 lines

## Before you start ## In AWS: create the key ### Write the key policy ## In Claude: add and attach the key ## Prerequisites ## Amazon Resource Name (ARN) for Anthropic ## Encryption key setup ### Prepare the key policy ## Register the key with Anthropic ## Troubleshoot validation ### Expected errors in CloudTrail ## Terraform

The two sides of this change are more than 400 edits apart, too far apart to line up, so this is the differ's own diff of it and the words inside a line are not marked.

from line 1
11---
2title: Configure AWS KMS for CMEK
2title: Set up CMEK with AWS KMS
33url: https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms
4description: Use AWS KMS to provide an encryption key for your organization.
4description: Create an AWS KMS key, give Anthropic access to it, and put it to use in Claude Platform or Claude Enterprise.
55---
66 
77Let Claude Code set up this feature for you
from line 10
1010/claude-api help me configure a customer-managed encryption key with AWS KMS
1111```
1212 
13This guide shows how to use an [AWS KMS](https://aws.amazon.com/kms/) key as a [customer-managed encryption key (CMEK)](https://platform.claude.com/docs/en/manage-claude/cmek) for your Anthropic organization.
14 
15<Warning>
16 Enabling CMEK is permanent. If your key is deleted or disabled, Anthropic cannot recover the data encrypted under it. Review the [warnings and limitations](https://platform.claude.com/docs/en/manage-claude/cmek) before you start.
17</Warning>
18 
19<Note>
20 **Claude Platform on AWS:** If your Claude Console sidebar shows **Account managed by AWS**, your organization is on Claude Platform on AWS. Follow [Set up CMEK on Claude Platform on AWS](https://platform.claude.com/docs/en/manage-claude/cmek-claude-platform-on-aws) instead.
21</Note>
22 
23## Prerequisites
24 
25* An AWS account with permissions to create KMS keys and set key policies (`kms:CreateKey` and `kms:PutKeyPolicy`).
26* To create the key from the command line, the [AWS CLI](https://aws.amazon.com/cli/) installed and authenticated.
27* To register the key through the API, an Anthropic Admin API key for your organization.
28 
29## Amazon Resource Name (ARN) for Anthropic
30 
31The key policy in this guide gives the following Anthropic IAM role access to your key:
32 
33```text wrap
34arn:aws:iam::915198916910:role/anthropic-cmek-client-us
35```
36 
37<Warning>
38 Use only this published ARN. Never trust an identifier provided over email, chat, or any onboarding channel.
39</Warning>
40 
41## Encryption key setup
42 
43### Prepare the key policy
44 
45Copy this policy into a text editor:
13If your Claude Console sidebar shows **Account managed by AWS**, follow [Set up CMEK on Claude Platform on AWS](https://platform.claude.com/docs/en/manage-claude/cmek-claude-platform-on-aws) instead.
14 
15## Before you start
16 
17In Claude:
18 
19* Customer-managed encryption keys (CMEK) are [turned on for your organization](https://platform.claude.com/docs/en/manage-claude/cmek#availability).
20* You have your Anthropic organization ID, the UUID without the `org_` prefix. Copy it from [Organization](https://platform.claude.com/settings/organization) in the Claude Console, or from **Organization settings > Organization and access** on claude.ai. Whoever creates the key needs it.
21* You're an Organization Admin on Claude Platform, or an Owner or Primary Owner on Claude Enterprise.
22* On Claude Platform, you have a workspace that [retains data](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#data-retention), ideally a new one, because [existing data stays under Anthropic's key](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect).
23* On Claude Enterprise, you know [which features turn off or change](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed).
24 
25In AWS:
26 
27* You can create AWS KMS keys and set their key policies (`kms:CreateKey` and `kms:PutKeyPolicy`).
28* Any IP restriction on AWS KMS access allows [Anthropic's outbound IP addresses](https://platform.claude.com/docs/en/api/ip-addresses#outbound-ip-addresses).
29 
30## In AWS: create the key
31 
32After a failed **Verify** or **Add**, see the [fixes for AWS KMS](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#aws-kms).
33 
34### Write the key policy
35 
36This policy gives Anthropic's IAM role access to your key. Use only the role ARN published on this page, never one sent by email or chat. Copy the policy into a text editor:
4637 
4738```json key-policy.json
4839{
from line 75
8475}
8576```
8677 
87Replace the two placeholders:
88 
89* **`<AWS_ACCOUNT_ID>`:** your [AWS account ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/console-account-id.html). To print it with the AWS CLI, run `aws sts get-caller-identity --query Account --output text`.
90* **`<ORGANIZATION_UUID>`:** your Anthropic organization ID
91 
92<Note>
93 **Finding your organization ID:** Use the bare UUID, not the `org_`-prefixed ID. Copy it from one of these places:
94 
95 * **Claude Console:** the **Organization ID** field on the [Organization](https://platform.claude.com/settings/organization) page (`platform.claude.com/settings/organization`)
96 * **claude.ai:** the **Organization ID** field under **Organization settings > Organization**
97 * **Admin API:** the `id` field from the [Organization Info](https://platform.claude.com/docs/en/api/organization/retrieve) endpoint
98</Note>
99 
100Don't remove the `kms:EncryptionContext:anthropic:org_uuid` condition, or validation fails. To share one key among several Anthropic organizations, list each organization ID in it. To limit the key to specific workspaces, see the [optional workspace condition](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#workspace-condition).
101 
102<Warning>
103 **Keys that already protect data:** If the key is already configured for CMEK, add this fourth statement so that Anthropic can still decrypt the existing data. In its condition, list the [compartment ID](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#compartment-id) of every workspace the key is or was attached to.
104 
105 ```json
106 {
107 "Sid": "AllowAnthropicCMEKDecryptExistingData",
108 "Effect": "Allow",
109 "Principal": {
110 "AWS": "arn:aws:iam::915198916910:role/anthropic-cmek-client-us"
111 },
112 "Action": "kms:Decrypt",
113 "Resource": "*",
114 "Condition": {
115 "StringEquals": {
116 "kms:EncryptionContext:anthropic:compartment_uuid": ["<COMPARTMENT_UUID>"]
117 }
118 }
119 }
120 ```
121</Warning>
122 
123<Note>
124 **Optional:** To limit the key to specific workspaces, replace the `AllowAnthropicCMEKCrypto` statement in the key policy with this one. List one compartment ID for each workspace.
125 
126 ```json
127 {
128 "Sid": "AllowAnthropicCMEKCrypto",
129 "Effect": "Allow",
130 "Principal": {
131 "AWS": "arn:aws:iam::915198916910:role/anthropic-cmek-client-us"
132 },
133 "Action": ["kms:Encrypt", "kms:Decrypt"],
134 "Resource": "*",
135 "Condition": {
136 "StringEquals": {
137 "kms:EncryptionContext:anthropic:org_uuid": ["<ORGANIZATION_UUID>"]
138 },
139 "StringEqualsIfExists": {
140 "kms:EncryptionContext:anthropic:compartment_uuid": ["<COMPARTMENT_UUID>"]
141 }
142 }
143 }
144 ```
145 
146 Add each workspace's compartment ID before you attach the key to it. For a new workspace:
147 
148 1. Create the workspace without the key.
149 2. Add its compartment ID to the policy.
150 3. Attach the key.
151 
152 **Finding your compartment ID:** In the Claude Console, go to the [Data retention](https://platform.claude.com/settings/privacy) page (`platform.claude.com/settings/privacy`). Select the workspace from the dropdown menu at the top of the page. The ID is under **Encryption key**, in the **Compartment ID** field. You can also read the `compartment_id` field returned by the [Get Workspace](https://platform.claude.com/docs/en/api/organization/workspaces/retrieve) endpoint.
153 
154 On Claude Enterprise, the organization has one compartment ID. Copy it from your key under **Encryption keys** in [claude.ai > Organization settings > Data and privacy](https://claude.ai/admin-settings/data-privacy-controls).
155</Note>
78Replace `<AWS_ACCOUNT_ID>` with your [AWS account ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/console-account-id.html) and `<ORGANIZATION_UUID>` with your [Anthropic organization ID](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#prerequisites). Keep the `kms:EncryptionContext:anthropic:org_uuid` condition, or verification fails.
79 
80You can also [limit the key to specific workspaces](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms-workspaces) by listing their compartment IDs. If you're replacing the policy on a key that already protects Claude data, [add one more statement](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#existing-data).
15681 
15782### Create the key
15883 
159Create the key in a [US region](https://platform.claude.com/docs/en/manage-claude/cmek#availability-and-regions). For the lowest latency, use `us-east-2`.
84Create the key in a US region. For the lowest latency, use `us-east-2`.
85 
86To use a key you already have in AWS KMS, [replace its key policy](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms-workspaces#replace-the-key-policy).
16087 
16188<Tabs>
16289 <Tab title="AWS Console">
from line 103
176103 Click **Next**.
177104 
178105 <Frame caption="Symmetric, encrypt and decrypt, single-Region key.">
179 ![AWS KMS Create key wizard on the Configure key step, with Symmetric key type, Encrypt and decrypt key usage, and Single-Region key selected.](https://platform.claude.com/docs/images/cmek/aws-configure-key.png)
106 ![AWS KMS Configure key step with Symmetric key type, Encrypt and decrypt key usage, and Single-Region key selected.](https://platform.claude.com/docs/images/cmek/aws-configure-key.png)
180107 </Frame>
181108 </Step>
182109 
from line 136
209136 </Step>
210137 
211138 <Step title="Copy the key ARN">
212 In **Customer managed keys**, open the new key and copy its ARN. You need the ARN to register the key.
139 In **Customer managed keys**, open the new key and copy its ARN. Whoever adds the key in Claude needs it.
213140 </Step>
214141 </Steps>
215 
216 To replace the key policy on a key that already exists:
217 
218 1. Open the key and click the **Key policy** tab.
219 2. If you see **Switch to policy view**, click it.
220 3. Click **Edit**.
221 4. Replace the JSON with your key policy.
222 5. Click **Save changes**.
223142 </Tab>
224143 
225144 <Tab title="AWS CLI">
from line 152
233152 --policy file://key-policy.json
234153 ```
235154 
236 Copy `KeyMetadata.Arn` from the output. You need it to register the key.
155 Copy `KeyMetadata.Arn` from the output. Whoever adds the key in Claude needs the ARN.
237156 </Tab>
238157</Tabs>
239158 
240## Register the key with Anthropic
241 
242Validating the key adds expected access-denied errors to CloudTrail. If you alert on these errors, see [Expected errors in CloudTrail](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#expected-errors-in-cloud-trail) first.
159Each check of the key in Claude adds four expected access-denied errors to CloudTrail. You can [filter them out](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#cloudtrail).
160 
161## In Claude: add and attach the key
162 
163To script this part on Claude Platform, [use the Admin API](https://platform.claude.com/docs/en/manage-claude/cmek-admin-api) instead.
243164 
244165<Tabs>
245166 <Tab title="Claude Platform">
246 <Tabs>
247 <Tab title="Claude Console">
248 <Steps>
249 <Step title="Open the encryption key settings">
250 In the Claude Console, go to the [Data retention](https://platform.claude.com/settings/privacy#encryption-keys) page (`platform.claude.com/settings/privacy`). If you don't see **Encryption keys**, select **Organization** from the dropdown menu at the top of the page.
251 </Step>
252 
253 <Step title="Add the key">
254 Under **Encryption keys**, click **Add key**. Enter a **Display name** and select **AWS KMS**. Click **Continue**.
255 </Step>
256 
257 <Step title="Enter the key ARN">
258 The dialog box shows the **Organization ID for the key policy**. Check that your [key policy](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#key-policy) contains this ID. Paste the key ARN into **KMS key ARN** and click **Add**.
259 </Step>
260 
261 <Step title="Validate the key">
262 In the **Encryption keys** list, click **Verify** next to the key. **Connected** appears when the check passes. If it fails, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#troubleshoot-validation) for common causes.
263 </Step>
264 
265 <Step title="Attach the key to a workspace">
266 Attaching a key can't be undone. If you can, attach it to a new workspace before that workspace receives any requests. In a workspace that already receives requests, the key can take [up to a day to take effect](https://platform.claude.com/docs/en/manage-claude/cmek#how-it-works).
267 
268 On the Data retention page, select the workspace from the dropdown menu at the top of the page. Under **Encryption key**, select the key and click **Save**.
269 </Step>
270 
271 <Step title="Confirm the change">
272 Select the checkbox to confirm that you have read the CMEK documentation, then click **Confirm**.
273 </Step>
274 </Steps>
275 </Tab>
276 
277 <Tab title="API">
278 <Steps>
279 <Step title="Create the external key">
280 Replace `<friendly-name>` with a display name and `<key-arn-from-create-key-step>` with the key ARN.
281 
282 <CodeGroup>
283 ```bash cURL
284 curl -sS "https://api.anthropic.com/v1/organizations/external_keys" \
285 -H "x-api-key: $ANTHROPIC_API_KEY" \
286 -H "anthropic-version: 2023-06-01" \
287 -H "content-type: application/json" \
288 -d '{
289 "display_name": "<friendly-name>",
290 "geo": "us",
291 "provider_config": {
292 "type": "aws",
293 "kms_arn": "<key-arn-from-create-key-step>"
294 }
295 }'
296 ```
297 
298 ```bash CLI
299 ant organization:external-keys create <<'YAML'
300 display_name: "<friendly-name>"
301 geo: us
302 provider_config:
303 type: aws
304 kms_arn: "<key-arn-from-create-key-step>"
305 YAML
306 ```
307 
308 ```python Python
309 client = anthropic.Anthropic()
310 
311 external_key = client.organization.external_keys.create(
312 display_name="<friendly-name>",
313 geo="us",
314 provider_config={"type": "aws", "kms_arn": "<key-arn-from-create-key-step>"},
315 )
316 
317 print(f"id: {external_key.id}")
318 print(f"display_name: {external_key.display_name}")
319 ```
320 
321 ```typescript TypeScript
322 const client = new Anthropic();
323 
324 const externalKey = await client.organization.externalKeys.create({
325 display_name: "<friendly-name>",
326 geo: "us",
327 provider_config: {
328 type: "aws",
329 kms_arn: "<key-arn-from-create-key-step>"
330 }
331 });
332 
333 console.log(`id: ${externalKey.id}`);
334 console.log(`display_name: ${externalKey.display_name}`);
335 ```
336 
337 ```csharp C#
338 using Anthropic.Models.Organization.ExternalKeys;
339 
340 AnthropicClient client = new();
341 
342 var externalKey = await client.Organization.ExternalKeys.Create(new()
343 {
344 DisplayName = "<friendly-name>",
345 Geo = Geo.Us,
346 ProviderConfig = new AwsExternalKeyConfig
347 {
348 KmsArn = "<key-arn-from-create-key-step>"
349 }
350 });
351 
352 Console.WriteLine($"id: {externalKey.ID}");
353 Console.WriteLine($"display_name: {externalKey.DisplayName}");
354 ```
355 
356 ```go Go
357 client := anthropic.NewClient()
358 
359 externalKey, err := client.Organization.ExternalKeys.New(context.Background(), anthropic.OrganizationExternalKeyNewParams{
360 DisplayName: anthropic.String("<friendly-name>"),
361 Geo: anthropic.OrganizationExternalKeyNewParamsGeoUs,
362 ProviderConfig: anthropic.OrganizationExternalKeyNewParamsProviderConfigUnion{
363 OfAWS: &anthropic.AWSExternalKeyConfigParam{
364 KMSARN: "<key-arn-from-create-key-step>",
365 },
366 },
367 })
368 if err != nil {
369 log.Fatal(err)
370 }
371 
372 fmt.Printf("id: %s\n", externalKey.ID)
373 fmt.Printf("display_name: %s\n", externalKey.DisplayName)
374 ```
375 
376 ```java Java
377 import com.anthropic.models.organization.externalkeys.AwsExternalKeyConfig;
378 import com.anthropic.models.organization.externalkeys.ExternalKeyCreateParams;
379 
380 void main() {
381 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
382 
383 var params = ExternalKeyCreateParams.builder()
384 .displayName("<friendly-name>")
385 .geo(ExternalKeyCreateParams.Geo.US)
386 .providerConfig(AwsExternalKeyConfig.builder()
387 .kmsArn("<key-arn-from-create-key-step>")
388 .build())
389 .build();
390 var externalKey = client.organization().externalKeys().create(params);
391 
392 IO.println("id: " + externalKey.id());
393 IO.println("display_name: " + externalKey.displayName().orElseThrow());
394 }
395 ```
396 
397 ```php PHP
398 use Anthropic\Organization\ExternalKeys\ExternalKeyCreateParams\Geo;
399 // ...
400 
401 $client = new Client();
402 
403 $externalKey = $client->organization->externalKeys->create(
404 displayName: '<friendly-name>',
405 geo: Geo::US,
406 providerConfig: [
407 'type' => 'aws',
408 'kmsARN' => '<key-arn-from-create-key-step>',
409 ],
410 );
411 
412 echo "id: {$externalKey->id}\n";
413 echo "display_name: {$externalKey->displayName}\n";
414 ```
415 
416 ```ruby Ruby
417 client = Anthropic::Client.new
418 
419 external_key = client.organization.external_keys.create(
420 display_name: "<friendly-name>",
421 geo: :us,
422 provider_config: {
423 type: :aws,
424 kms_arn: "<key-arn-from-create-key-step>"
425 }
426 )
427 
428 puts "id: #{external_key.id}"
429 puts "display_name: #{external_key.display_name}"
430 ```
431 </CodeGroup>
432 
433 The `id` field of the response contains the external key ID. Copy it for the next two steps:
434 
435 ```json
436 {
437 "type": "external_key",
438 "id": "ekey_<id>",
439 "display_name": "<friendly-name>"
440 }
441 ```
442 </Step>
443 
444 <Step title="Validate the key">
445 Replace `ekey_<id>` with the external key ID.
446 
447 <CodeGroup>
448 ```bash cURL
449 curl -sS -X POST "https://api.anthropic.com/v1/organizations/external_keys/ekey_<id>/validate" \
450 -H "x-api-key: $ANTHROPIC_API_KEY" \
451 -H "anthropic-version: 2023-06-01"
452 ```
453 
454 ```bash CLI
455 ant organization:external-keys validate --external-key-id "ekey_<id>"
456 ```
457 
458 ```python Python
459 client = anthropic.Anthropic()
460 
461 validation = client.organization.external_keys.validate("ekey_<id>")
462 
463 print(f"status: {validation.status}")
464 print(f"error: {validation.error}")
465 ```
466 
467 ```typescript TypeScript
468 const client = new Anthropic();
469 
470 const validation = await client.organization.externalKeys.validate("ekey_<id>");
471 
472 console.log(`status: ${validation.status}`);
473 console.log(`error: ${validation.error}`);
474 ```
475 
476 ```csharp C#
477 AnthropicClient client = new();
478 
479 var validation = await client.Organization.ExternalKeys.Validate("ekey_<id>");
480 
481 Console.WriteLine($"status: {validation.Status.Raw()}");
482 Console.WriteLine($"error: {validation.Error}");
483 ```
484 
485 ```go Go
486 client := anthropic.NewClient()
487 
488 validation, err := client.Organization.ExternalKeys.Validate(context.Background(), "ekey_<id>")
489 if err != nil {
490 log.Fatal(err)
491 }
492 
493 fmt.Printf("status: %s\n", validation.Status)
494 fmt.Printf("error: %s\n", validation.Error)
495 ```
496 
497 ```java Java
498 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
499 
500 var validation = client.organization().externalKeys().validate("ekey_<id>");
501 
502 IO.println("status: " + validation.status().asString());
503 IO.println("error: " + validation.error().orElse(""));
504 ```
505 
506 ```php PHP
507 $client = new Client();
508 
509 $validation = $client->organization->externalKeys->validate(
510 externalKeyID: 'ekey_<id>',
511 );
512 
513 echo "status: {$validation->status}\n";
514 echo "error: {$validation->error}\n";
515 ```
516 
517 ```ruby Ruby
518 client = Anthropic::Client.new
519 
520 external_key_id = "ekey_<id>"
521 validation = client.organization.external_keys.validate(external_key_id)
522 
523 puts "status: #{validation.status}"
524 puts "error: #{validation.error}"
525 ```
526 </CodeGroup>
527 
528 A successful response looks like this:
529 
530 ```json
531 { "type": "external_key_validation", "status": "success", "error": null }
532 ```
533 
534 If validation fails, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#troubleshoot-validation).
535 </Step>
536 
537 <Step title="Attach the key to a workspace">
538 Attaching a key can't be undone. If you can, attach it to a new workspace before that workspace receives any requests. In a workspace that already receives requests, the key can take [up to a day to take effect](https://platform.claude.com/docs/en/manage-claude/cmek#how-it-works).
539 
540 Replace `<workspace-id>` with the workspace ID and `ekey_<id>` with the external key ID.
541 
542 <CodeGroup>
543 ```bash cURL
544 curl -sS -X POST "https://api.anthropic.com/v1/organizations/workspaces/<workspace-id>" \
545 -H "x-api-key: $ANTHROPIC_API_KEY" \
546 -H "anthropic-version: 2023-06-01" \
547 -H "content-type: application/json" \
548 -d '{
549 "external_key_id": "ekey_<id>"
550 }'
551 ```
552 
553 ```bash CLI
554 ant organization:workspaces update \
555 --workspace-id "<workspace-id>" \
556 --external-key-id "ekey_<id>"
557 ```
558 
559 ```python Python
560 client = anthropic.Anthropic()
561 
562 workspace = client.organization.workspaces.update(
563 "<workspace-id>", external_key_id="ekey_<id>"
564 )
565 
566 print(f"id: {workspace.id}")
567 print(f"external_key_id: {workspace.external_key_id}")
568 ```
569 
570 ```typescript TypeScript
571 const client = new Anthropic();
572 
573 const workspace = await client.organization.workspaces.update("<workspace-id>", {
574 external_key_id: "ekey_<id>"
575 });
576 
577 console.log(`id: ${workspace.id}`);
578 console.log(`external_key_id: ${workspace.external_key_id}`);
579 ```
580 
581 ```csharp C#
582 AnthropicClient client = new();
583 
584 var workspace = await client.Organization.Workspaces.Update("<workspace-id>", new()
585 {
586 ExternalKeyID = "ekey_<id>"
587 });
588 
589 Console.WriteLine($"id: {workspace.ID}");
590 Console.WriteLine($"external_key_id: {workspace.ExternalKeyID}");
591 ```
592 
593 ```go Go
594 client := anthropic.NewClient()
595 
596 workspace, err := client.Organization.Workspaces.Update(
597 context.Background(),
598 "<workspace-id>",
599 anthropic.OrganizationWorkspaceUpdateParams{
600 ExternalKeyID: anthropic.String("ekey_<id>"),
601 },
602 )
603 if err != nil {
604 log.Fatal(err)
605 }
606 
607 fmt.Printf("id: %s\n", workspace.ID)
608 fmt.Printf("external_key_id: %s\n", workspace.ExternalKeyID)
609 ```
610 
611 ```java Java
612 import com.anthropic.models.organization.workspaces.WorkspaceUpdateParams;
613 
614 void main() {
615 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
616 
617 var params = WorkspaceUpdateParams.builder()
618 .externalKeyId("ekey_<id>")
619 .build();
620 var workspace = client.organization().workspaces().update("<workspace-id>", params);
621 
622 IO.println("id: " + workspace.id());
623 IO.println("external_key_id: " + workspace.externalKeyId().orElseThrow());
624 }
625 ```
626 
627 ```php PHP
628 $client = new Client();
629 
630 $workspace = $client->organization->workspaces->update(
631 workspaceID: '<workspace-id>',
632 externalKeyID: 'ekey_<id>',
633 );
634 
635 echo "id: {$workspace->id}\n";
636 echo "external_key_id: {$workspace->externalKeyID}\n";
637 ```
638 
639 ```ruby Ruby
640 client = Anthropic::Client.new
641 
642 workspace_id = "<workspace-id>"
643 workspace = client.organization.workspaces.update(
644 workspace_id,
645 external_key_id: "ekey_<id>"
646 )
647 
648 puts "id: #{workspace.id}"
649 puts "external_key_id: #{workspace.external_key_id}"
650 ```
651 </CodeGroup>
652 </Step>
653 </Steps>
654 </Tab>
655 </Tabs>
167 <Steps>
168 <Step title="Open the encryption key settings">
169 In the Claude Console, open [Encryption keys](https://platform.claude.com/settings/privacy#encryption-keys) on the Data retention page. If the section isn't there, select **Organization** from the dropdown menu at the top.
170 </Step>
171 
172 <Step title="Add the key">
173 Under **Encryption keys**, click **Add key**. Enter a **Display name**, select **AWS KMS**, and click **Continue**.
174 </Step>
175 
176 <Step title="Enter the key ARN">
177 Check that your [key policy](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#key-policy) contains the **Organization ID for the key policy** shown in the dialog box. Paste the key ARN into **KMS key ARN** and click **Add**.
178 </Step>
179 
180 <Step title="Verify the key">
181 In the **Encryption keys** list, click **Verify** next to the key. **Connected** appears when the check passes. If **Connection failed** appears instead, see [Troubleshoot CMEK](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting).
182 </Step>
183 
184 <Step title="Attach the key to a workspace">
185 <Warning>
186 Attaching a key [can't be undone](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#what-each-action-does). You can't remove it from the workspace or replace it. If the key is deleted, Anthropic can't recover the data it protects.
187 </Warning>
188 
189 1. At the top of the Data retention page, select the workspace from the dropdown menu.
190 2. Under **Encryption key**, select the key and click **Save**.
191 3. Select the checkbox to confirm that you have read the CMEK documentation, then click **Confirm**.
192 
193 You see **Workspace settings updated.** Once the key [takes effect](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect), your cloud provider's audit log shows Anthropic's calls to the key.
194 
195 In a [ZDR organization](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#zdr-organizations), after you select the workspace, select **Standard data retention** so that **Encryption key** appears. After you click **Save**, click **Accept** on the data retention terms.
196 </Step>
197 </Steps>
656198 </Tab>
657199 
658200 <Tab title="Claude Enterprise">
659 On Claude Enterprise, CMEK applies to the whole organization, and an organization can have only one key.
201 On Claude Enterprise, CMEK applies to the whole organization, and you can add only one key.
202 
203 <Warning>
204 Adding a key [can't be undone](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#what-each-action-does). You can't remove it from the organization or replace it. If the key is deleted, Anthropic can't recover the data it protects.
205 </Warning>
206 
207 Adding the key [turns off or changes some features](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed) for every user. To try CMEK first, use a separate organization.
660208 
661209 <Steps>
662210 <Step title="Open the encryption key settings">
from line 216
668216 </Step>
669217 
670218 <Step title="Enter the key ARN">
671 The dialog box shows the **Organization ID for the key policy**. Check that your [key policy](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#key-policy) contains this ID. Paste the key ARN into **KMS key ARN** and click **Add**.
672 </Step>
673 
674 <Step title="Confirm that validation passed">
675 When the check passes, **Encryption key configured** appears, and your organization is CMEK-protected from then on. If the check fails, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#troubleshoot-validation).
219 Check that your [key policy](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#key-policy) contains the **Organization ID for the key policy** shown in the dialog box. Paste the key ARN into **KMS key ARN** and click **Add**.
220 </Step>
221 
222 <Step title="Confirm that the key was added">
223 The check can take up to 30 seconds. When **Encryption key configured.** appears, click **Done**. If **The encryption key couldn’t be added.** appears instead, [find the cause and retry](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#claude-ai-add-fails).
224 
225 Your key protects data written from then on. Tell your users [which features changed](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed).
676226 </Step>
677227 </Steps>
678228 </Tab>
679229</Tabs>
680 
681## Troubleshoot validation
682 
683If validation fails, common causes are:
684 
685* **Wrong organization ID:** Make sure the `org_uuid` condition lists your bare organization ID, not the `org_`-prefixed ID.
686* **Encryption context mismatch:** If the policy has a `kms:EncryptionContext:anthropic:compartment_uuid` condition, make sure it lists the [compartment ID](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#compartment-id) of each workspace the key is attached to.
687* **Resource control policies (RCPs):** Some RCPs deny KMS operations when `aws:PrincipalOrgID` does not match your AWS organization. An RCP like this blocks Anthropic's role. Add an exception to it for this key or for Anthropic's role ARN. Service control policies do not apply here.
688* **Access granted through IAM instead of the key policy:** Grant Anthropic's role access in the key policy itself, not through an IAM policy in your account. To check the key policy, run `aws kms get-key-policy --region <REGION> --key-id <KEY_ARN> --policy-name default`.
689* **Region mismatch:** Confirm that the key is in a US region.
690 
691### Expected errors in CloudTrail
692 
693Anthropic validates the key whenever you verify it, attach it to a workspace, or view it in the Claude Enterprise settings. Each validation adds four access-denied errors to CloudTrail. These errors are expected.
694 
695To filter them out, match all three of these values:
696 
697* `requestParameters.encryptionContext.associatedData`: `Y21lay12YWxpZGF0aW9u`
698* `userIdentity.accountId`: `915198916910`
699* `resources.ARN`: `arn:aws:kms:<REGION>:<AWS_ACCOUNT_ID>:key/<KEY_ID>`
700 
701The first value alone isn't enough, because any caller can set it.
702 
703## Terraform
704 
705To create the key with Terraform, use the `aws_kms_key` and `aws_kms_alias` resources from the `aws` provider.
706230 

manage-claude/cmek-aws-kms-workspaces New page · 47 lines, new page

## Copy the workspace's compartment ID ## Add the condition to the key policy ## Replace the key policy on an existing key

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: Limit an AWS KMS key to specific workspaces
url: https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms-workspaces
description: Add a key policy condition that names the workspaces allowed to use your AWS KMS key.
---

The [key policy from setup](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#key-policy) lets every workspace in your organization use the key. With this optional condition, a workspace that isn't listed can't use it.

Add a workspace's [compartment ID](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#what-one-key-protects) to the policy before you [attach the key](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#register-the-key-with-anthropic) to that workspace. For a new workspace, that means creating it without the key.

## Copy the workspace's compartment ID

In the Claude Console, open the [Data retention](https://platform.claude.com/settings/privacy) page and select the workspace from the dropdown menu at the top. Copy the **Compartment ID** under **Encryption key**. The [Get Workspace](https://platform.claude.com/docs/en/api/organization/workspaces/retrieve) endpoint returns it as `compartment_id`.

A Claude Enterprise organization has one compartment ID. Copy it from your key under **Encryption keys** in [claude.ai > Organization settings > Data and privacy](https://claude.ai/admin-settings/data-privacy-controls).

## Add the condition to the key policy

Replace the `AllowAnthropicCMEKCrypto` statement with this one. Fill in your Anthropic organization ID and the compartment ID of every workspace that uses the key. A key that already protects data [needs one more statement](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#existing-data).

```json
{
  "Sid": "AllowAnthropicCMEKCrypto",
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::915198916910:role/anthropic-cmek-client-us"
  },
  "Action": ["kms:Encrypt", "kms:Decrypt"],
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "kms:EncryptionContext:anthropic:org_uuid": ["<ORGANIZATION_UUID>"]
    },
    "StringEqualsIfExists": {
      "kms:EncryptionContext:anthropic:compartment_uuid": ["<COMPARTMENT_UUID>"]
    }
  }
}
```

## Replace the key policy on an existing key

1. In the [AWS KMS console](https://console.aws.amazon.com/kms), open the key and click the **Key policy** tab.
2. If you see **Switch to policy view**, click it.
3. Click **Edit**.
4. Replace the JSON with your key policy.
5. Click **Save changes**.

manage-claude/cmek-azure-key-vault Changed · +110 / -566 lines

## Before you start ## In Azure: create the key ### Check the vault ### Add the organization tag to a key you already have ## In Claude: add and attach the key ## Prerequisites ## Anthropic app information ## Encryption key setup ### Check your vault configuration ## Register the key with Anthropic ## Troubleshoot validation ## Terraform

The two sides of this change are more than 400 edits apart, too far apart to line up, so this is the differ's own diff of it and the words inside a line are not marked.

from line 1
11---
2title: Configure Azure Key Vault for CMEK
2title: Set up CMEK with Azure Key Vault
33url: https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault
4description: Use Azure Key Vault to provide an encryption key for your organization.
4description: Create an Azure Key Vault key, give Anthropic access to it, and put it to use in Claude Platform or Claude Enterprise.
55---
66 
77Let Claude Code set up this feature for you
from line 10
1010/claude-api help me configure a customer-managed encryption key with Azure Key Vault
1111```
1212 
13This guide shows how to use an Azure Key Vault key as a [customer-managed encryption key (CMEK)](https://platform.claude.com/docs/en/manage-claude/cmek) for your Anthropic organization.
14 
15<Warning>
16 Enabling CMEK is permanent. If your key is deleted or disabled, Anthropic cannot recover the data encrypted under it. Review the [warnings and limitations](https://platform.claude.com/docs/en/manage-claude/cmek) before you start.
17</Warning>
18 
19## Prerequisites
20 
21* An Azure Key Vault with these settings:
22 
23 * RBAC authorization is enabled (`enableRbacAuthorization: true`).
24 * Public network access is allowed. Private endpoints are not supported.
25 * Purge protection is enabled (`enablePurgeProtection: true`). You can't turn off purge protection after you enable it.
26 * Diagnostic settings route the `AuditEvent` log category to Log Analytics, a storage account, or an event hub. Without them, you have no audit trail of Anthropic's key operations, such as `KeyWrap`, `KeyUnwrap`, and `KeyGet`.
27 
28* Permissions to create keys in the vault and to assign RBAC roles on it.
29 
30* Permissions to create service principals in your Entra tenant (`Application Administrator`, `Cloud Application Administrator`, or an equivalent custom role).
31 
32* The [`az` CLI](https://learn.microsoft.com/en-us/cli/azure/?view=azure-cli-latest) installed and authenticated, or Cloud Shell in the Azure portal. Some steps have no portal equivalent.
33 
34* To register the key through the API, an Anthropic Admin API key for your organization.
35 
36## Anthropic app information
37 
38You give the following Anthropic multitenant application access to your key. The application requests no Microsoft Graph permissions.
39 
40| Field | Value |
41| ------------------------------ | -------------------------------------- |
42| Multitenant app client ID (US) | `8635ae1a-3e5d-44e8-a4ed-e0f614466f87` |
43| App display name | `anthropic-cmek-client-us` |
44 
45<Warning>
46 Use only this published client ID and display name. Never trust an identifier provided over email, chat, or any onboarding channel.
47</Warning>
48 
49## Encryption key setup
50 
51The key must meet these requirements:
52 
53* **Type:** RSA, 3072-bit or larger. For an HSM-backed key, use `RSA-HSM`, which requires a Premium-SKU vault.
54* **Permitted operations:** `wrapKey` and `unwrapKey`. The steps in this guide turn off every other operation, so Anthropic can only read the key and wrap and unwrap with it.
55* **Organization tag:** `anthropic-org-<ORGANIZATION_UUID>` with the value `true`. Replace `<ORGANIZATION_UUID>` with your Anthropic organization ID in lowercase. Validation fails without the tag.
56* **Access:** the `Key Vault Crypto User` role for Anthropic's service principal, assigned on the key.
57 
58<Note>
59 **Finding your organization ID:** Use the bare UUID, not the `org_`-prefixed ID. Copy it from one of these places:
60 
61 * **Claude Console:** the **Organization ID** field on the [Organization](https://platform.claude.com/settings/organization) page (`platform.claude.com/settings/organization`)
62 * **claude.ai:** the **Organization ID** field under **Organization settings > Organization**
63 * **Admin API:** the `id` field from the [Organization Info](https://platform.claude.com/docs/en/api/organization/retrieve) endpoint
64</Note>
13## Before you start
14 
15In Claude:
16 
17* Customer-managed encryption keys (CMEK) are [turned on for your organization](https://platform.claude.com/docs/en/manage-claude/cmek#availability).
18* You have your Anthropic organization ID, the UUID without the `org_` prefix. Copy it from [Organization](https://platform.claude.com/settings/organization) in the Claude Console, or from **Organization settings > Organization and access** on claude.ai. Whoever creates the key needs it.
19* You're an Organization Admin on Claude Platform, or an Owner or Primary Owner on Claude Enterprise.
20* On Claude Platform, you have a workspace that [retains data](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#data-retention), ideally a new one, because [existing data stays under Anthropic's key](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect).
21* On Claude Enterprise, you know [which features turn off or change](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed).
22 
23In Azure:
24 
25* You can create keys in your key vault and assign RBAC roles on it.
26* You can create service principals in your Entra tenant (Application Administrator, Cloud Application Administrator, or an equivalent custom role).
27* The vault has a diagnostic setting for the `AuditEvent` log category. Without one, Anthropic's key operations leave no audit trail.
28 
29## In Azure: create the key
30 
31After a failed **Verify** or **Add**, see the [fixes for Azure Key Vault](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#azure-key-vault).
32 
33These steps give Anthropic's multitenant application access to your key:
34 
35* **Name:** `anthropic-cmek-client-us`
36* **Client ID:** `8635ae1a-3e5d-44e8-a4ed-e0f614466f87`
37 
38Use only this client ID and name, never ones sent by email or chat. The application requests no Microsoft Graph permissions.
39 
40### Check the vault
41 
42For the lowest latency, use a vault in `northcentralus` or `eastus2`. Run this first, in the Azure CLI or Cloud Shell:
43 
44```bash
45az keyvault show --name <your-vault-name> \
46 --query "{rbac:properties.enableRbacAuthorization, purge:properties.enablePurgeProtection, pub:properties.publicNetworkAccess, net:properties.networkAcls.defaultAction, ipRules:properties.networkAcls.ipRules, uri:properties.vaultUri, tenantId:properties.tenantId}"
47```
48 
49| Field | Must be |
50| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
51| `rbac` | `true` |
52| `purge` | `true`. If it's `false` or `null`, turn on purge protection first. You can't turn it off again. |
53| `pub` | `"Enabled"`. Private endpoints aren't supported. |
54| `net` | `"Allow"`, or `"Deny"` with [Anthropic's outbound IP addresses](https://platform.claude.com/docs/en/api/ip-addresses#outbound-ip-addresses) in `ipRules` |
55 
56Copy `uri` (the vault URI) and `tenantId`.
6557 
6658### Create the key and grant access
59 
60On this page, `<ORGANIZATION_UUID>` is your [Anthropic organization ID](https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault#prerequisites) in lowercase. To use a key you already have, [add the organization tag](https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault#organization-tag) first.
6761 
6862<Tabs>
6963 <Tab title="Azure portal">
from line 131
137131 On the **Review + assign** tab, click **Review + assign**.
138132 </Step>
139133 </Steps>
140 
141 To use a key you already have, follow these steps instead of steps 3 to 6, then continue from step 7:
142 
143 1. In your key vault, select **Keys** and open the key. Open its current version.
144 2. Click the link next to **Tags**.
145 3. Add the organization tag and click **OK**.
146 4. Under **Permitted operations**, clear every checkbox except **Wrap Key** and **Unwrap Key**.
147 5. Click **Save**.
148134 </Tab>
149135 
150136 <Tab title="Azure CLI">
from line 186
200186 * **`<your-key-name>`:** the name of the key
201187 </Step>
202188 </Steps>
203 
204 To use a key you already have, run this command instead of step 2:
205 
206 ```bash
207 az keyvault key set-attributes \
208 --vault-name <your-vault-name> \
209 --name <your-key-name> \
210 --ops wrapKey unwrapKey \
211 --tags anthropic-org-<ORGANIZATION_UUID>=true
212 ```
213 
214 This replaces the version's existing tags. Add each existing tag to `--tags` as `name=value`.
215189 </Tab>
216190</Tabs>
217191 
218<Note>
219 **Optional:**
220 
221 * To share one key among several Anthropic organizations, add one organization tag for each. A key version can carry at most 15 tags, including your own.
222 * If the vault holds only this key, you can assign the role on the vault instead of the key.
223</Note>
224 
225### Check your vault configuration
226 
227Run this command with the Azure CLI or in Cloud Shell. Replace `<your-vault-name>` with the name of your key vault.
192Whoever adds the key in Claude needs the vault URI, the key name, and the tenant ID.
193 
194### Add the organization tag to a key you already have
195 
196Verification fails without the organization tag. The key must be RSA, 3072-bit or larger.
197 
198Instead of creating a key, run this command in the Azure CLI or Cloud Shell. It limits the key to `wrapKey` and `unwrapKey`. It also replaces the current version's tags, so list any you want to keep in `--tags` as `name=value`.
228199 
229200```bash
230az keyvault show --name <your-vault-name> \
231 --query "{rbac:properties.enableRbacAuthorization, purge:properties.enablePurgeProtection, pub:properties.publicNetworkAccess, net:properties.networkAcls.defaultAction, ipRules:properties.networkAcls.ipRules, uri:properties.vaultUri, tenantId:properties.tenantId}"
201az keyvault key set-attributes \
202 --vault-name <your-vault-name> \
203 --name <your-key-name> \
204 --ops wrapKey unwrapKey \
205 --tags anthropic-org-<ORGANIZATION_UUID>=true
232206```
233207 
234Confirm these values:
235 
236* `rbac`: `true`
237* `purge`: `true`. If it's `false` or `null`, enable purge protection before you continue.
238* `pub`: `"Enabled"`. If it's `"Disabled"`, turn on public network access.
239* `net`: `"Allow"`, or `"Deny"` with Anthropic's outbound IP ranges in `ipRules`. For the ranges, see [Outbound IP addresses](https://platform.claude.com/docs/en/api/ip-addresses#outbound-ip-addresses).
240 
241Copy these values to register the key:
242 
243* `uri`: the vault URI
244* `tenantId`: the ID of the tenant that governs the vault
245 
246## Register the key with Anthropic
208You still need the service principal and role assignment steps.
209 
210## In Claude: add and attach the key
211 
212To script this part on Claude Platform, [use the Admin API](https://platform.claude.com/docs/en/manage-claude/cmek-admin-api) instead.
247213 
248214<Tabs>
249215 <Tab title="Claude Platform">
250 <Tabs>
251 <Tab title="Claude Console">
252 <Steps>
253 <Step title="Open the encryption key settings">
254 In the Claude Console, go to the [Data retention](https://platform.claude.com/settings/privacy#encryption-keys) page (`platform.claude.com/settings/privacy`). If you don't see **Encryption keys**, select **Organization** from the dropdown menu at the top of the page.
255 </Step>
256 
257 <Step title="Add the key">
258 Under **Encryption keys**, click **Add key**. Enter a **Display name** and select **Azure Key Vault**. Click **Continue**.
259 </Step>
260 
261 <Step title="Enter the key details">
262 The dialog box shows an **Organization tag**. Check that your key has this tag. Enter these values:
263 
264 * **Vault URI:** the `uri` value that you copied
265 * **Key name:** the name of the key
266 * **Tenant ID:** the `tenantId` value that you copied
267 
268 Click **Add**.
269 </Step>
270 
271 <Step title="Validate the key">
272 In the **Encryption keys** list, click **Verify** next to the key. **Connected** appears when the check passes. If it fails, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault#troubleshoot-validation) for common causes.
273 </Step>
274 
275 <Step title="Attach the key to a workspace">
276 Attaching a key can't be undone. If you can, attach it to a new workspace before that workspace receives any requests. In a workspace that already receives requests, the key can take [up to a day to take effect](https://platform.claude.com/docs/en/manage-claude/cmek#how-it-works).
277 
278 On the Data retention page, select the workspace from the dropdown menu at the top of the page. Under **Encryption key**, select the key and click **Save**.
279 </Step>
280 
281 <Step title="Confirm the change">
282 Select the checkbox to confirm that you have read the CMEK documentation, then click **Confirm**.
283 </Step>
284 </Steps>
285 </Tab>
286 
287 <Tab title="API">
288 <Steps>
289 <Step title="Create the external key">
290 Replace the placeholders:
291 
292 * **`<friendly-name>`:** a display name for the key
293 * **`<your-vault-name>`:** the name of your key vault
294 * **`<your-key-name>`:** the name of the key
295 * **`<your-tenant-id>`:** the `tenantId` value that you copied
296 
297 <CodeGroup>
298 ```bash cURL
299 curl -sS "https://api.anthropic.com/v1/organizations/external_keys" \
300 -H "x-api-key: $ANTHROPIC_API_KEY" \
301 -H "anthropic-version: 2023-06-01" \
302 -H "content-type: application/json" \
303 -d '{
304 "display_name": "<friendly-name>",
305 "geo": "us",
306 "provider_config": {
307 "type": "azure",
308 "vault_uri": "https://<your-vault-name>.vault.azure.net/",
309 "key_name": "<your-key-name>",
310 "tenant_id": "<your-tenant-id>"
311 }
312 }'
313 ```
314 
315 ```bash CLI
316 ant organization:external-keys create <<'YAML'
317 display_name: "<friendly-name>"
318 geo: us
319 provider_config:
320 type: azure
321 vault_uri: "https://<your-vault-name>.vault.azure.net/"
322 key_name: "<your-key-name>"
323 tenant_id: "<your-tenant-id>"
324 YAML
325 ```
326 
327 ```python Python
328 client = anthropic.Anthropic()
329 
330 external_key = client.organization.external_keys.create(
331 display_name="<friendly-name>",
332 geo="us",
333 provider_config={
334 "type": "azure",
335 "vault_uri": "https://<your-vault-name>.vault.azure.net/",
336 "key_name": "<your-key-name>",
337 "tenant_id": "<your-tenant-id>",
338 },
339 )
340 
341 print(f"id: {external_key.id}")
342 print(f"display_name: {external_key.display_name}")
343 ```
344 
345 ```typescript TypeScript
346 const client = new Anthropic();
347 
348 const externalKey = await client.organization.externalKeys.create({
349 display_name: "<friendly-name>",
350 geo: "us",
351 provider_config: {
352 type: "azure",
353 vault_uri: "https://<your-vault-name>.vault.azure.net/",
354 key_name: "<your-key-name>",
355 tenant_id: "<your-tenant-id>"
356 }
357 });
358 
359 console.log(`id: ${externalKey.id}`);
360 console.log(`display_name: ${externalKey.display_name}`);
361 ```
362 
363 ```csharp C#
364 using Anthropic.Models.Organization.ExternalKeys;
365 
366 AnthropicClient client = new();
367 
368 var externalKey = await client.Organization.ExternalKeys.Create(new()
369 {
370 DisplayName = "<friendly-name>",
371 Geo = Geo.Us,
372 ProviderConfig = new AzureExternalKeyConfigParam
373 {
374 VaultUri = "https://<your-vault-name>.vault.azure.net/",
375 KeyName = "<your-key-name>",
376 TenantID = "<your-tenant-id>"
377 }
378 });
379 
380 Console.WriteLine($"id: {externalKey.ID}");
381 Console.WriteLine($"display_name: {externalKey.DisplayName}");
382 ```
383 
384 ```go Go
385 client := anthropic.NewClient()
386 
387 externalKey, err := client.Organization.ExternalKeys.New(context.Background(), anthropic.OrganizationExternalKeyNewParams{
388 DisplayName: anthropic.String("<friendly-name>"),
389 Geo: anthropic.OrganizationExternalKeyNewParamsGeoUs,
390 ProviderConfig: anthropic.OrganizationExternalKeyNewParamsProviderConfigUnion{
391 OfAzure: &anthropic.AzureExternalKeyConfigParam{
392 VaultURI: "https://<your-vault-name>.vault.azure.net/",
393 KeyName: "<your-key-name>",
394 TenantID: "<your-tenant-id>",
395 },
396 },
397 })
398 if err != nil {
399 log.Fatal(err)
400 }
401 
402 fmt.Printf("id: %s\n", externalKey.ID)
403 fmt.Printf("display_name: %s\n", externalKey.DisplayName)
404 ```
405 
406 ```java Java
407 import com.anthropic.models.organization.externalkeys.AzureExternalKeyConfigParam;
408 import com.anthropic.models.organization.externalkeys.ExternalKeyCreateParams;
409 
410 void main() {
411 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
412 
413 var params = ExternalKeyCreateParams.builder()
414 .displayName("<friendly-name>")
415 .geo(ExternalKeyCreateParams.Geo.US)
416 .providerConfig(AzureExternalKeyConfigParam.builder()
417 .vaultUri("https://<your-vault-name>.vault.azure.net/")
418 .keyName("<your-key-name>")
419 .tenantId("<your-tenant-id>")
420 .build())
421 .build();
422 var externalKey = client.organization().externalKeys().create(params);
423 
424 IO.println("id: " + externalKey.id());
425 IO.println("display_name: " + externalKey.displayName().orElseThrow());
426 }
427 ```
428 
429 ```php PHP
430 use Anthropic\Organization\ExternalKeys\ExternalKeyCreateParams\Geo;
431 // ...
432 
433 $client = new Client();
434 
435 $externalKey = $client->organization->externalKeys->create(
436 displayName: '<friendly-name>',
437 geo: Geo::US,
438 providerConfig: [
439 'type' => 'azure',
440 'vaultURI' => 'https://<your-vault-name>.vault.azure.net/',
441 'keyName' => '<your-key-name>',
442 'tenantID' => '<your-tenant-id>',
443 ],
444 );
445 
446 echo "id: {$externalKey->id}\n";
447 echo "display_name: {$externalKey->displayName}\n";
448 ```
449 
450 ```ruby Ruby
451 client = Anthropic::Client.new
452 
453 external_key = client.organization.external_keys.create(
454 display_name: "<friendly-name>",
455 geo: :us,
456 provider_config: {
457 type: :azure,
458 vault_uri: "https://<your-vault-name>.vault.azure.net/",
459 key_name: "<your-key-name>",
460 tenant_id: "<your-tenant-id>"
461 }
462 )
463 
464 puts "id: #{external_key.id}"
465 puts "display_name: #{external_key.display_name}"
466 ```
467 </CodeGroup>
468 
469 The `id` field of the response contains the external key ID. Copy it for the next two steps:
470 
471 ```json
472 {
473 "type": "external_key",
474 "id": "ekey_<id>",
475 "display_name": "<friendly-name>"
476 }
477 ```
478 </Step>
479 
480 <Step title="Validate the key">
481 Replace `ekey_<id>` with the external key ID.
482 
483 <CodeGroup>
484 ```bash cURL
485 curl -sS -X POST "https://api.anthropic.com/v1/organizations/external_keys/ekey_<id>/validate" \
486 -H "x-api-key: $ANTHROPIC_API_KEY" \
487 -H "anthropic-version: 2023-06-01"
488 ```
489 
490 ```bash CLI
491 ant organization:external-keys validate --external-key-id "ekey_<id>"
492 ```
493 
494 ```python Python
495 client = anthropic.Anthropic()
496 
497 validation = client.organization.external_keys.validate("ekey_<id>")
498 
499 print(f"status: {validation.status}")
500 print(f"error: {validation.error}")
501 ```
502 
503 ```typescript TypeScript
504 const client = new Anthropic();
505 
506 const validation = await client.organization.externalKeys.validate("ekey_<id>");
507 
508 console.log(`status: ${validation.status}`);
509 console.log(`error: ${validation.error}`);
510 ```
511 
512 ```csharp C#
513 AnthropicClient client = new();
514 
515 var validation = await client.Organization.ExternalKeys.Validate("ekey_<id>");
516 
517 Console.WriteLine($"status: {validation.Status.Raw()}");
518 Console.WriteLine($"error: {validation.Error}");
519 ```
520 
521 ```go Go
522 client := anthropic.NewClient()
523 
524 validation, err := client.Organization.ExternalKeys.Validate(context.Background(), "ekey_<id>")
525 if err != nil {
526 log.Fatal(err)
527 }
528 
529 fmt.Printf("status: %s\n", validation.Status)
530 fmt.Printf("error: %s\n", validation.Error)
531 ```
532 
533 ```java Java
534 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
535 
536 var validation = client.organization().externalKeys().validate("ekey_<id>");
537 
538 IO.println("status: " + validation.status().asString());
539 IO.println("error: " + validation.error().orElse(""));
540 ```
541 
542 ```php PHP
543 $client = new Client();
544 
545 $validation = $client->organization->externalKeys->validate(
546 externalKeyID: 'ekey_<id>',
547 );
548 
549 echo "status: {$validation->status}\n";
550 echo "error: {$validation->error}\n";
551 ```
552 
553 ```ruby Ruby
554 client = Anthropic::Client.new
555 
556 external_key_id = "ekey_<id>"
557 validation = client.organization.external_keys.validate(external_key_id)
558 
559 puts "status: #{validation.status}"
560 puts "error: #{validation.error}"
561 ```
562 </CodeGroup>
563 
564 A successful response looks like this:
565 
566 ```json
567 { "type": "external_key_validation", "status": "success", "error": null }
568 ```
569 
570 If validation fails, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault#troubleshoot-validation).
571 </Step>
572 
573 <Step title="Attach the key to a workspace">
574 Attaching a key can't be undone. If you can, attach it to a new workspace before that workspace receives any requests. In a workspace that already receives requests, the key can take [up to a day to take effect](https://platform.claude.com/docs/en/manage-claude/cmek#how-it-works).
575 
576 Replace `<workspace-id>` with the workspace ID and `ekey_<id>` with the external key ID.
577 
578 <CodeGroup>
579 ```bash cURL
580 curl -sS -X POST "https://api.anthropic.com/v1/organizations/workspaces/<workspace-id>" \
581 -H "x-api-key: $ANTHROPIC_API_KEY" \
582 -H "anthropic-version: 2023-06-01" \
583 -H "content-type: application/json" \
584 -d '{
585 "external_key_id": "ekey_<id>"
586 }'
587 ```
588 
589 ```bash CLI
590 ant organization:workspaces update \
591 --workspace-id "<workspace-id>" \
592 --external-key-id "ekey_<id>"
593 ```
594 
595 ```python Python
596 client = anthropic.Anthropic()
597 
598 workspace = client.organization.workspaces.update(
599 "<workspace-id>", external_key_id="ekey_<id>"
600 )
601 
602 print(f"id: {workspace.id}")
603 print(f"external_key_id: {workspace.external_key_id}")
604 ```
605 
606 ```typescript TypeScript
607 const client = new Anthropic();
608 
609 const workspace = await client.organization.workspaces.update("<workspace-id>", {
610 external_key_id: "ekey_<id>"
611 });
612 
613 console.log(`id: ${workspace.id}`);
614 console.log(`external_key_id: ${workspace.external_key_id}`);
615 ```
616 
617 ```csharp C#
618 AnthropicClient client = new();
619 
620 var workspace = await client.Organization.Workspaces.Update("<workspace-id>", new()
621 {
622 ExternalKeyID = "ekey_<id>"
623 });
624 
625 Console.WriteLine($"id: {workspace.ID}");
626 Console.WriteLine($"external_key_id: {workspace.ExternalKeyID}");
627 ```
628 
629 ```go Go
630 client := anthropic.NewClient()
631 
632 workspace, err := client.Organization.Workspaces.Update(
633 context.Background(),
634 "<workspace-id>",
635 anthropic.OrganizationWorkspaceUpdateParams{
636 ExternalKeyID: anthropic.String("ekey_<id>"),
637 },
638 )
639 if err != nil {
640 log.Fatal(err)
641 }
642 
643 fmt.Printf("id: %s\n", workspace.ID)
644 fmt.Printf("external_key_id: %s\n", workspace.ExternalKeyID)
645 ```
646 
647 ```java Java
648 import com.anthropic.models.organization.workspaces.WorkspaceUpdateParams;
649 
650 void main() {
651 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
652 
653 var params = WorkspaceUpdateParams.builder()
654 .externalKeyId("ekey_<id>")
655 .build();
656 var workspace = client.organization().workspaces().update("<workspace-id>", params);
657 
658 IO.println("id: " + workspace.id());
659 IO.println("external_key_id: " + workspace.externalKeyId().orElseThrow());
660 }
661 ```
662 
663 ```php PHP
664 $client = new Client();
665 
666 $workspace = $client->organization->workspaces->update(
667 workspaceID: '<workspace-id>',
668 externalKeyID: 'ekey_<id>',
669 );
670 
671 echo "id: {$workspace->id}\n";
672 echo "external_key_id: {$workspace->externalKeyID}\n";
673 ```
674 
675 ```ruby Ruby
676 client = Anthropic::Client.new
677 
678 workspace_id = "<workspace-id>"
679 workspace = client.organization.workspaces.update(
680 workspace_id,
681 external_key_id: "ekey_<id>"
682 )
683 
684 puts "id: #{workspace.id}"
685 puts "external_key_id: #{workspace.external_key_id}"
686 ```
687 </CodeGroup>
688 </Step>
689 </Steps>
690 </Tab>
691 </Tabs>
216 <Steps>
217 <Step title="Open the encryption key settings">
218 In the Claude Console, open [Encryption keys](https://platform.claude.com/settings/privacy#encryption-keys) on the Data retention page. If the section isn't there, select **Organization** from the dropdown menu at the top.
219 </Step>
220 
221 <Step title="Add the key">
222 Under **Encryption keys**, click **Add key**. Enter a **Display name**, select **Azure Key Vault**, and click **Continue**.
223 </Step>
224 
225 <Step title="Enter the key details">
226 Check that your key has the **Organization tag** shown in the dialog box. Enter the **Vault URI**, **Key name**, and **Tenant ID**, leave **Client ID** empty, and click **Add**.
227 </Step>
228 
229 <Step title="Verify the key">
230 In the **Encryption keys** list, click **Verify** next to the key. **Connected** appears when the check passes. If **Connection failed** appears instead, see [Troubleshoot CMEK](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting).
231 </Step>
232 
233 <Step title="Attach the key to a workspace">
234 <Warning>
235 Attaching a key [can't be undone](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#what-each-action-does). You can't remove it from the workspace or replace it. If the key is deleted, Anthropic can't recover the data it protects.
236 </Warning>
237 
238 1. At the top of the Data retention page, select the workspace from the dropdown menu.
239 2. Under **Encryption key**, select the key and click **Save**.
240 3. Select the checkbox to confirm that you have read the CMEK documentation, then click **Confirm**.
241 
242 You see **Workspace settings updated.** Once the key [takes effect](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect), your cloud provider's audit log shows Anthropic's calls to the key.
243 
244 In a [ZDR organization](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#zdr-organizations), after you select the workspace, select **Standard data retention** so that **Encryption key** appears. After you click **Save**, click **Accept** on the data retention terms.
245 </Step>
246 </Steps>
692247 </Tab>
693248 
694249 <Tab title="Claude Enterprise">
695 On Claude Enterprise, CMEK applies to the whole organization, and an organization can have only one key.
250 On Claude Enterprise, CMEK applies to the whole organization, and you can add only one key.
251 
252 <Warning>
253 Adding a key [can't be undone](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#what-each-action-does). You can't remove it from the organization or replace it. If the key is deleted, Anthropic can't recover the data it protects.
254 </Warning>
255 
256 Adding the key [turns off or changes some features](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed) for every user. To try CMEK first, use a separate organization.
696257 
697258 <Steps>
698259 <Step title="Open the encryption key settings">
from line 265
704265 </Step>
705266 
706267 <Step title="Enter the key details">
707 The dialog box shows an **Organization tag**. Check that your key has this tag. Enter these values:
708 
709 * **Vault URI:** the `uri` value that you copied
710 * **Key name:** the name of the key
711 * **Tenant ID:** the `tenantId` value that you copied
712 
713 Click **Add**.
714 </Step>
715 
716 <Step title="Confirm that validation passed">
717 When the check passes, **Encryption key configured** appears, and your organization is CMEK-protected from then on. If the check fails, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault#troubleshoot-validation).
268 Check that your key has the **Organization tag** shown in the dialog box. Enter the **Vault URI**, **Key name**, and **Tenant ID**, leave **Client ID** empty, and click **Add**.
269 </Step>
270 
271 <Step title="Confirm that the key was added">
272 The check can take up to 30 seconds. When **Encryption key configured.** appears, click **Done**. If **The encryption key couldn’t be added.** appears instead, [find the cause and retry](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#claude-ai-add-fails).
273 
274 Your key protects data written from then on. Tell your users [which features changed](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed).
718275 </Step>
719276 </Steps>
720277 </Tab>
721278</Tabs>
722 
723## Troubleshoot validation
724 
725If validation fails, common causes are:
726 
727* **Wrong organization tag:** Make sure the key's current version has the tag `anthropic-org-<ORGANIZATION_UUID>` with the value `true`. The organization ID must be the bare UUID in lowercase.
728* **RBAC propagation delay:** Role assignments can take a few minutes to take effect. Wait and retry.
729* **Network ACLs blocking Anthropic:** Confirm public network access and `ipRules`, as described in [Check your vault configuration](https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault#check-your-vault-configuration).
730* **Conditional access policies on workload identities:** If your tenant has conditional access policies that target service principals, exclude the Anthropic service principal. Or add Anthropic's outbound IP ranges to the policy's named locations.
731 
732## Terraform
733 
734To create the key with Terraform, use the `azurerm` and `azuread` providers.
735279 

manage-claude/cmek-claude-platform-on-aws Changed · +46 / -98 lines

## Before you start ## In AWS: create the key ### Write the key policy ## In Claude: add and attach the key ## Prerequisites ## AWS service principal for Anthropic ## Encryption key setup ### Prepare the key policy ## Register the key with Anthropic ## Troubleshoot validation ## Terraform

from line 1
11---
22title: Set up CMEK on Claude Platform on AWS
33url: https://platform.claude.com/docs/en/manage-claude/cmek-claude-platform-on-aws
4description: Use an AWS KMS key as a customer-managed encryption key on Claude Platform on AWS.
4description: Create an AWS KMS key in your AWS account and attach it to a workspace on Claude Platform on AWS.
55---
66 
7This guide shows how to use an [AWS KMS](https://aws.amazon.com/kms/) key as a [customer-managed encryption key (CMEK)](https://platform.claude.com/docs/en/manage-claude/cmek) on [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws). For Claude Platform or Claude Enterprise, follow [Configure AWS KMS for CMEK](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms) instead.
7If your Claude Console sidebar doesn't show **Account managed by AWS**, follow [Set up CMEK with AWS KMS](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms) instead.
88 
9<Warning>
10 Enabling CMEK is permanent. If your key is deleted or disabled, Anthropic cannot recover the data encrypted under it. Review the [warnings and limitations](https://platform.claude.com/docs/en/manage-claude/cmek) before you start.
11</Warning>
9## Before you start
1210 
13## Prerequisites
11* Customer-managed encryption keys (CMEK) are [turned on for your organization](https://platform.claude.com/docs/en/manage-claude/cmek#availability).
1412 
15* The AWS account that hosts your Claude Platform on AWS organization, with permissions to create KMS keys and set key policies (`kms:CreateKey` and `kms:PutKeyPolicy`).
13* In the AWS account that hosts your organization, you can create AWS KMS keys and set key policies (`kms:CreateKey` and `kms:PutKeyPolicy`).
1614 
17* To create the key from the command line, the [AWS CLI](https://aws.amazon.com/cli/) installed and authenticated.
15* You have the **Admin** role in the [Claude Console](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#using-the-claude-console).
1816 
19* The **Admin** role in the Claude Console for Claude Platform on AWS. See [Using the Claude Console](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#using-the-claude-console).
17* The IAM principal you sign in with has these permissions:
2018 
21* These permissions for the IAM principal you sign in to the Claude Console with:
19 * Sign in: `aws-external-anthropic:AssumeConsole`
20 * Add a key: `aws-external-anthropic:RegisterKey`
21 * View keys: `aws-external-anthropic:ListKeys` and `aws-external-anthropic:GetKey`
22 * Attach a key: `aws-external-anthropic:UpdateWorkspace` or `aws-external-anthropic:CreateWorkspace`, plus `kms:DescribeKey`, `kms:Encrypt`, and `kms:Decrypt` on the key
23 * Pick the key from a list (optional): `kms:ListKeys` and `kms:DescribeKey`
2224 
23 * **Sign in:** `aws-external-anthropic:AssumeConsole`
24 * **Register a key:** `aws-external-anthropic:RegisterKey`
25 * **View registered keys:** `aws-external-anthropic:ListKeys` and `aws-external-anthropic:GetKey`
26 * **Attach a key:** `aws-external-anthropic:UpdateWorkspace` or `aws-external-anthropic:CreateWorkspace`, plus `kms:DescribeKey`, `kms:Encrypt`, and `kms:Decrypt` on the key
27 * **Pick the key from a list (optional):** `kms:ListKeys` and `kms:DescribeKey`
25 To scope them, see [IAM actions](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#encryption-keys).
2826 
29 `aws-external-anthropic:RegisterKey`, `aws-external-anthropic:ListKeys`, `aws-external-anthropic:GetKey`, and `aws-external-anthropic:CreateWorkspace` are account-scoped. Grant them on `Resource: "*"`. See [IAM actions](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#encryption-keys).
27* You have a workspace with no key attached, ideally a new one, because [existing data stays under Anthropic's key](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect). The key policy lists its compartment ID.
3028 
31## AWS service principal for Anthropic
29In the Claude Console, open the [Data retention](https://platform.claude.com/settings/privacy) page and select the workspace from the dropdown menu at the top. Copy the **Compartment ID** under **Encryption key**. The [Get Workspace](https://platform.claude.com/docs/en/api/organization/workspaces/retrieve) endpoint returns it as `compartment_id`.
3230 
33The key policy in this guide gives the following AWS service principal access to your key:
31## In AWS: create the key
3432 
35```text wrap
36aws-external-anthropic.amazonaws.com
37```
33### Write the key policy
3834 
39<Warning>
40 Use only this published service principal name. Never trust an identifier provided over email, chat, or any onboarding channel.
41</Warning>
35This policy gives the AWS service principal `aws-external-anthropic.amazonaws.com` access to your key. Use only the name published on this page, never one sent by email or chat. Copy the policy into a text editor:
4236 
43## Encryption key setup
44 
45### Prepare the key policy
46 
47Copy this policy into a text editor:
48 
4937```json key-policy.json
5038{
5139 "Version": "2012-10-17",
from line 74
8674}
8775```
8876 
89The `EncryptionContext` condition is optional. It limits the key to the workspaces you list. To remove it, delete the `Condition` block from the `AllowClaudePlatformOnAWSCrypto` statement.
77Replace `<AWS_ACCOUNT_ID>` with your [AWS account ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/console-account-id.html) and `<COMPARTMENT_UUID>` with the [compartment ID](https://platform.claude.com/docs/en/manage-claude/cmek-claude-platform-on-aws#prerequisites).
9078 
91If you keep the condition, add each workspace's compartment ID before you attach the key to it. For a new workspace:
79The optional `EncryptionContext` condition limits the key to the workspaces you list. Before you attach the key to another workspace, add that workspace's compartment ID and [replace the policy on the key](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms-workspaces#replace-the-key-policy). To do without the condition, delete the `Condition` block from the `AllowClaudePlatformOnAWSCrypto` statement. If you add the condition later, list every workspace the key is already attached to.
9280 
931. Create the workspace without the key.
942. Add its compartment ID to the policy.
953. Attach the key.
81To narrow access further, use the key policy, not IP-based restrictions. Add an `aws:SourceArn` condition to both service principal statements. This one allows every workspace in your AWS account:
9682 
97If you add the condition later, list the compartment ID of every workspace the key is already attached to.
83```text wrap
84"ArnLike": {"aws:SourceArn": "arn:aws:aws-external-anthropic:*:<AWS_ACCOUNT_ID>:workspace/*"}
85```
9886 
99To limit the key policy further, see the [optional `aws:SourceArn` condition](https://platform.claude.com/docs/en/manage-claude/cmek-claude-platform-on-aws#source-arn-condition).
87For specific workspaces, list their full [workspace ARNs](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#service-details) instead, in this form:
10088 
101Replace the placeholders:
89```text wrap
90arn:aws:aws-external-anthropic:<REGION>:<AWS_ACCOUNT_ID>:workspace/<WORKSPACE_ID>
91```
10292 
103* **`<AWS_ACCOUNT_ID>`:** your [AWS account ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/console-account-id.html). To print it with the AWS CLI, run `aws sts get-caller-identity --query Account --output text`.
104* **`<COMPARTMENT_UUID>`:** the compartment ID of the workspace you attach the key to
105 
106<Note>
107 **Finding your compartment ID:** In the Claude Console, go to the [Data retention](https://platform.claude.com/settings/privacy) page (`platform.claude.com/settings/privacy`). Select the workspace from the dropdown menu at the top of the page. The ID is under **Encryption key**, in the **Compartment ID** field. You can also read the `compartment_id` field returned by the [Get Workspace](https://platform.claude.com/docs/en/api/organization/workspaces/retrieve) endpoint.
108</Note>
109 
110<Note>
111 **Optional:** To limit both service principal statements further, add an `aws:SourceArn` condition to each. The source ARN on every call is the [workspace's ARN](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#service-details), in the form `arn:aws:aws-external-anthropic:<REGION>:<AWS_ACCOUNT_ID>:workspace/<WORKSPACE_ID>`.
112 
113 * **All workspaces in your AWS account:** `"ArnLike": {"aws:SourceArn": "arn:aws:aws-external-anthropic:*:<AWS_ACCOUNT_ID>:workspace/*"}`
114 * **Specific workspaces:** the same condition, with a list of full workspace ARNs instead of the wildcard
115</Note>
116 
11793### Create the key
11894 
119Create the key in the AWS account that hosts your Claude Platform on AWS organization, in the same region as the workspace.
95Create the key in the AWS account that hosts your organization, in the same region as the workspace.
12096 
12197<Tabs>
12298 <Tab title="AWS Console">
from line 112
136112 Click **Next**.
137113 
138114 <Frame caption="Symmetric, encrypt and decrypt, single-Region key.">
139 ![AWS KMS Create key wizard on the Configure key step, with Symmetric key type, Encrypt and decrypt key usage, and Single-Region key selected.](https://platform.claude.com/docs/images/cmek/aws-configure-key.png)
115 ![AWS KMS Configure key step with Symmetric key type, Encrypt and decrypt key usage, and Single-Region key selected.](https://platform.claude.com/docs/images/cmek/aws-configure-key.png)
140116 </Frame>
141117 </Step>
142118 
from line 145
169145 </Step>
170146 
171147 <Step title="Copy the key ARN">
172 In **Customer managed keys**, open the new key and copy its ARN. You need the ARN to register the key.
148 In **Customer managed keys**, open the new key and copy its ARN. Whoever adds the key in Claude needs it.
173149 </Step>
174150 </Steps>
175 
176 To replace the key policy on a key that already exists:
177 
178 1. Open the key and click the **Key policy** tab.
179 2. If you see **Switch to policy view**, click it.
180 3. Click **Edit**.
181 4. Replace the JSON with your key policy.
182 5. Click **Save changes**.
183151 </Tab>
184152 
185153 <Tab title="AWS CLI">
from line 161
193161 --policy file://key-policy.json
194162 ```
195163 
196 Copy `KeyMetadata.Arn` from the output. You need it to register the key.
164 Copy `KeyMetadata.Arn` from the output. Whoever adds the key in Claude needs the ARN.
197165 </Tab>
198166</Tabs>
199167 
200## Register the key with Anthropic
168## In Claude: add and attach the key
201169 
202Sign in to the Claude Console through AWS with the Admin role.
170Sign in to the Claude Console through AWS. To script this part instead, use the endpoints listed in [IAM actions](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#encryption-keys).
203171 
204172<Steps>
205173 <Step title="Open the encryption key settings">
206 In the Claude Console, go to the [Data retention](https://platform.claude.com/settings/privacy#encryption-keys) page (`platform.claude.com/settings/privacy`). If you don't see **Encryption keys**, select **Organization** from the dropdown menu at the top of the page.
174 In the Claude Console, open [Encryption keys](https://platform.claude.com/settings/privacy#encryption-keys) on the Data retention page. If the section isn't there, select **Organization** from the dropdown menu at the top.
207175 </Step>
208176 
209177 <Step title="Add the key">
210 Under **Encryption keys**, click **Add key**. Enter a **Display name**.
178 Under **Encryption keys**, click **Add key** and enter a **Display name**.
211179 </Step>
212180 
213181 <Step title="Enter the key ARN">
214 Anthropic rejects alias ARNs and multi-Region keys.
215 
216 In **KMS key ARN**, paste the key ARN. If a list of keys appears instead, select your key, or click **Enter ARN manually** and paste the ARN. Click **Add**.
182 In **KMS key ARN**, select your key. If it isn't listed, click **Enter ARN manually** and paste the ARN. Anthropic rejects alias ARNs and multi-Region keys. Click **Add**.
217183 </Step>
218184 
219185 <Step title="Attach the key to a workspace">
220 Attaching a key can't be undone. If you can, attach it to a new workspace before that workspace receives any requests. In a workspace that already receives requests, the key can take [up to a day to take effect](https://platform.claude.com/docs/en/manage-claude/cmek#how-it-works).
186 <Warning>
187 Attaching a key [can't be undone](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#what-each-action-does). You can't remove it from the workspace or replace it. If the key is deleted, Anthropic can't recover the data it protects.
188 </Warning>
221189 
222 On the Data retention page, select the workspace from the dropdown menu at the top of the page. Under **Encryption key**, select the key and click **Save**.
223 </Step>
190 1. At the top of the Data retention page, select the workspace from the dropdown menu.
191 2. Under **Encryption key**, select the key and click **Save**.
192 3. Select the checkbox to confirm that you have read the CMEK documentation, then click **Confirm**.
224193 
225 <Step title="Confirm the change">
226 Select the checkbox to confirm that you have read the CMEK documentation, then click **Confirm**.
194 You see **Workspace settings updated.** Once the key [takes effect](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect), CloudTrail records the calls to your key.
195 
196 Attaching checks the key with one encrypt call and one decrypt call, so a key policy problem shows up here. If you get a KMS access error, see the [causes and fixes](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#claude-platform-on-aws).
227197 </Step>
228198</Steps>
229 
230Attaching validates the key. If it fails with a KMS access error, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-claude-platform-on-aws#troubleshoot-validation).
231 
232You can also select a key when you create a workspace in the Claude Console, if your key policy has no `EncryptionContext` condition.
233 
234To register and attach keys with the API instead, see [IAM actions](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#encryption-keys). The API identifies a key by its KMS key ARN.
235 
236## Troubleshoot validation
237 
238If validation fails, common causes are:
239 
240* **Key policy mismatch:** Make sure the key policy matches the one in [Prepare the key policy](https://platform.claude.com/docs/en/manage-claude/cmek-claude-platform-on-aws#prepare-the-key-policy). To check the key policy, run `aws kms get-key-policy --region <REGION> --key-id <KEY_ARN> --policy-name default`.
241* **Condition mismatch:** Make sure any `EncryptionContext` or `aws:SourceArn` condition includes this workspace.
242* **Key state or location:** Confirm that the key is enabled, single-Region, and in the same AWS account and region as the workspace.
243* **Missing permissions:** The principal you are signed in as needs `kms:DescribeKey`, `kms:Encrypt`, and `kms:Decrypt` on the key.
244* **Organization policies:** Make sure no service control policy or resource control policy in your AWS organization blocks the service principal or your principal.
245 
246If attaching still fails, find the denied `kms:` event in CloudTrail in the key's account. It shows the calling principal and, for cryptographic calls, the encryption context. After you fix the cause, click **Save** again.
247 
248## Terraform
249 
250To create the key with Terraform, use the `aws_kms_key` and `aws_kms_alias` resources from the `aws` provider.
251199 

manage-claude/cmek-coverage-claude-enterprise New page · 58 lines, new page

## Encrypted with your key ## Turned off or changed ## Encrypted with Anthropic's key ## Where CMEK does not apply: Claude Code telemetry

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: What CMEK covers on Claude Enterprise
url: https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise
description: Look up which Claude Enterprise data your key encrypts, what turns off or changes, and what stays under Anthropic's key.
---

For Claude Platform, see [What CMEK covers on Claude Platform](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-platform). Beta and research preview features might not be covered by customer-managed encryption keys (CMEK) and can break in CMEK organizations.

## Encrypted with your key

* Chat content, including skills and plugins.
* Chat attachments and project attachments.
* Artifacts, including Claude Design, Claude Slides, and Claude Docs in conversations and the **Artifacts** tab.
* Claude Code on the CLI, including message content.
* Cowork in Claude Desktop.
* Office agents.
* Claude in Chrome.
* Claude Science, which is in beta.
* [Plugins API](https://platform.claude.com/docs/en/manage-claude/plugins-api#customer-managed-encryption-keys) (beta) plugin versions: each version's description, release notes, components, and files. That page lists which requests still work while your key can't be used.
* Compliance API [local session transcripts](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-local-sessions) from sessions on users' machines. If your key can't be used, the messages endpoint returns [503 Service Unavailable](https://platform.claude.com/docs/en/manage-claude/compliance-errors#local-sessions-temporarily-unavailable) instead of transcript content. Session metadata is still listed.
* Backups and snapshots, which inherit the key.

## Turned off or changed

This list is not exhaustive. Review it with your team before you set up CMEK.

| Feature                                                                                                                                   | What people see                                                                                                                                                                                                                                                                                         |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Chat search                                                                                                                               | Off. Members can't search past chats, because chat titles and content are encrypted with your key. The **Search and reference chats** toggle stays off, so Claude can't either.                                                                                                                         |
| [Project knowledge search](https://support.claude.com/en/articles/11473015-retrieval-augmented-generation-rag-for-projects) (RAG)         | Off. Project knowledge loads into each conversation's context instead of being indexed and searched. A project can use substantially less knowledge, and the rest is left out.                                                                                                                          |
| Claude Code on the web                                                                                                                    | Off. New sessions can't be started, even if an admin turns the product on.                                                                                                                                                                                                                              |
| Claude in Slack                                                                                                                           | Off. Claude declines requests, even if an admin turns the product on.                                                                                                                                                                                                                                   |
| Claude Code Desktop                                                                                                                       | Off until an admin turns it on. Available for local sessions once turned on under [claude.ai > Organization settings > Claude Code](https://claude.ai/admin-settings/claude-code).                                                                                                                      |
| Artifacts                                                                                                                                 | Changed. Artifacts, including Claude Design, Claude Slides, and Claude Docs in conversations and the **Artifacts** tab, cannot be turned on in organizations that also use ZDR. In organizations with HIPAA readiness, an Owner must first accept the terms for using them.                             |
| Artifact publishing and sharing                                                                                                           | Changed. Claude Code cannot [publish artifacts](https://code.claude.com/docs/en/artifacts#availability). However, artifacts made in chat or Cowork can be shared within your organization, but not publicly.                                                                                            |
| Standalone Claude Design app                                                                                                              | Not supported. See [Encrypted with Anthropic's key](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#encrypted-with-anthropics-key).                                                                                                                                   |
| Analytics: smart reports and contribution metrics                                                                                         | Off. Certain analytics are disabled, regardless of admin settings: Claude smart reports (beta, under claude.ai/analytics/insights) and Claude Code contribution metrics from GitHub (beta, under claude.ai/analytics/claude-code).                                                                      |
| Analytics: skills and connectors                                                                                                          | Changed. Admin analytics for skills and connectors, in the claude.ai analytics dashboard and through the [Claude Enterprise Analytics API](https://platform.claude.com/docs/en/manage-claude/analytics-api), don't include usage in chat, and hide the names of custom skills, plugins, and connectors. |
| Organization data exports and audit log exports                                                                                           | Off. Both are under [claude.ai > Organization settings > Data and privacy](https://claude.ai/admin-settings/data-privacy-controls).                                                                                                                                                                     |
| Response ratings (thumbs up and thumbs down)                                                                                              | Off. Members can't rate Claude's responses.                                                                                                                                                                                                                                                             |
| [Skill and plugin security scanning](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/enterprise#skill-content-scanning) | Off. The setting can't be turned on, and skills and plugins are installed without a scan.                                                                                                                                                                                                               |
| Claude Security and routines                                                                                                              | Off. Beta and research preview features, turned off regardless of admin settings.                                                                                                                                                                                                                       |

## Encrypted with Anthropic's key

The features that store this data stay available, but the data isn't encrypted with your key. You can turn off some of these features in **Settings**.

| Data                                                | Details                                                                                                                                                                                                                                                                                                                                                                                                         |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Existing data                                       | Written before [your key takes effect](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect).                                                                                                                                                                                                                                                                         |
| Standalone Claude Design app                        | The standalone Claude Design app at claude.ai/design is not supported with CMEK, and its data might not be encrypted under your key. The standalone app is closing. Claude Design in conversations and the **Artifacts** tab is encrypted under your key, as listed under [Encrypted with your key](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#encrypted-with-your-key). |
| Personal preferences and Cowork Global instructions | [Personal preferences - Instructions for Claude section](https://claude.ai/new#settings/account) and Cowork Global instructions. These are set at the account level and shared across all of a user's organizations.                                                                                                                                                                                            |
| Account data for users in your organization         | Includes names, email addresses, and profile pictures.                                                                                                                                                                                                                                                                                                                                                          |
| Preserved records                                   | Anthropic can preserve specific records [in three narrow cases](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#limited-preservation-outside-your-key).                                                                                                                                                                                                                                   |

## Where CMEK does not apply: Claude Code telemetry

When Claude Code connects through an LLM gateway or proxy (a custom `ANTHROPIC_BASE_URL`), CMEK does not apply to Claude Code's operational telemetry. To turn this telemetry off, set the `DISABLE_TELEMETRY` environment variable to `1`, as described under [Telemetry services](https://code.claude.com/docs/en/data-usage#telemetry-services) in the Claude Code documentation.

manage-claude/cmek-coverage-claude-platform New page · 48 lines, new page

## Encrypted with your key ## Turned off or changed ## Encrypted with Anthropic's key ## Where CMEK does not apply: Claude Code telemetry

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: What CMEK covers on Claude Platform
url: https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-platform
description: Look up which Claude Platform data your key encrypts, what turns off or changes, and what stays under Anthropic's key.
---

For Claude Enterprise, see [What CMEK covers on Claude Enterprise](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise). Beta and research preview features that aren't listed here might not be covered by customer-managed encryption keys (CMEK).

## Encrypted with your key

* Message content.
* Files and attachments, whether sent inline with a request or uploaded with the Files API.
* MCP and tool configuration.
* [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) (beta) data, including agent configurations, environments, webhooks, sessions and their events, [memory stores](https://platform.claude.com/docs/en/managed-agents/memory) (beta) and their memories and memory versions, and [dreams](https://platform.claude.com/docs/en/managed-agents/dreams) (research preview).
* Batch API and Skills API data stored at rest.
* Tool data stored at rest by web search, web fetch, code execution, bash, text editor, MCP connector (beta), structured outputs, advisor tool (beta), computer use, browser use, and context management.
* Backups and snapshots, which inherit the key.

## Turned off or changed

This list is not exhaustive. Review it with your team before you set up CMEK.

| Feature                                                                                                        | What changes                                                                                                                                                                                                                           |
| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Playground in the Claude Console                                                                               | Turned off.                                                                                                                                                                                                                            |
| Structured outputs, including `strict: true` on tools, with Claude Fable or Claude Mythos models               | Turned off in CMEK organizations. With other models, data that structured outputs store at rest is [encrypted with your key](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-platform#encrypted-with-your-key). |
| [Organization webhooks](https://platform.claude.com/docs/en/manage-claude/organization-webhooks#errors) (beta) | Turned off for an organization whose default workspace uses a key. Requests return a 400 error.                                                                                                                                        |
| Zero data retention (ZDR)                                                                                      | A workspace with your key retains data. See [CMEK, data retention, and ZDR](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention).                                                                                    |

## Encrypted with Anthropic's key

The features that store this data stay available, but the data isn't encrypted with your key. You can turn off some of these features in **Settings**.

| Data                                                                                                                                                                                          | Details                                                                                                                                                                       |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Existing data                                                                                                                                                                                 | Written before [your key takes effect](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect).                                       |
| Data that isn't at rest, and data with a TTL shorter than 24 hours                                                                                                                            | For example, cache.                                                                                                                                                           |
| Activity Feed, audit logs, and telemetry network traffic such as OpenTelemetry                                                                                                                | Kept under Anthropic's key so that you can maintain compliance even if your key can't be used.                                                                                |
| Claude Managed Agents [vault credential](https://platform.claude.com/docs/en/managed-agents/vaults) values, such as OAuth tokens and client secrets                                           | Write-only and never returned in API responses.                                                                                                                               |
| [User profiles](https://platform.claude.com/docs/en/manage-claude/user-profiles)                                                                                                              | Profile fields such as `name` and `metadata`. Don't store sensitive personal data in profile `metadata`.                                                                      |
| Claude Console feedback                                                                                                                                                                       | Ratings and comments that members choose to send with the **Feedback** option. No setting turns it off.                                                                       |
| [OpenTelemetry destination](https://platform.claude.com/docs/en/manage-claude/opentelemetry/api#add-a-destination) request headers, such as the API key header of your observability platform | Write-only and never returned in API responses.                                                                                                                               |
| Account data for users in your organization                                                                                                                                                   | Includes names, email addresses, and profile pictures.                                                                                                                        |
| Preserved records                                                                                                                                                                             | Anthropic can preserve specific records [in three narrow cases](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#limited-preservation-outside-your-key). |

## Where CMEK does not apply: Claude Code telemetry

When Claude Code connects through an LLM gateway or proxy (a custom `ANTHROPIC_BASE_URL`), CMEK does not apply to Claude Code's operational telemetry. To turn this telemetry off, set the `DISABLE_TELEMETRY` environment variable to `1`, as described under [Telemetry services](https://code.claude.com/docs/en/data-usage#telemetry-services) in the Claude Code documentation.

manage-claude/cmek-data-retention New page · 29 lines, new page

## A key needs a workspace that retains data ## In a ZDR organization ## Limited preservation outside your key

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: CMEK, data retention, and ZDR
url: https://platform.claude.com/docs/en/manage-claude/cmek-data-retention
description: Why a workspace with a key retains data, what that means for ZDR, and what Anthropic can preserve outside your key.
---

On Claude Platform, customer-managed encryption keys (CMEK) and [zero data retention (ZDR)](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention) can't share a workspace. On Claude Enterprise, an organization can use CMEK and ZDR together, but it then [can't turn on artifacts](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed).

## A key needs a workspace that retains data

CMEK encrypts stored data, and under ZDR on Claude Platform, Anthropic doesn't store your prompts or responses. So you can attach a key only to a workspace with **Standard data retention** (30 days).

After you attach a key, you can't turn off data retention for that workspace. To return to ZDR, create a new workspace and move your traffic to it.

## In a ZDR organization

A ZDR organization on Claude Platform can use CMEK. You switch one workspace to **Standard data retention**, accept the data retention terms, and attach your key to it. The workspace you switch can't be the default workspace, whose retention follows the organization's. Your other workspaces keep ZDR.

[Choose your setup page](https://platform.claude.com/docs/en/manage-claude/cmek#set-it-up) and follow its attach step.

## Limited preservation outside your key

In three narrow cases, Anthropic may preserve specific records under Anthropic-managed encryption:

* Where Anthropic is required by law to retain records (for example, material reported to NCMEC under 18 U.S.C. § 2258A)
* Exigent risk of serious harm (for example, CBRNE weapons development, offensive cyberattacks, or imminent threats of violence)
* Violations of Section D.4 of Anthropic's [Commercial Terms of Service](https://www.anthropic.com/legal/commercial-terms) or equivalent terms in a customer's other applicable agreement with Anthropic

Outside of [CSAM screening](https://support.claude.com/en/articles/9020328-csam-detection-and-reporting), preservation requires a human reviewer's explicit decision and follows Anthropic's [retention policy for commercial data](https://privacy.claude.com/en/articles/10023548-how-long-do-you-store-my-data). For every instance of preservation, a corresponding [Compliance API Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed) event is generated with a reason code conveying the purpose of the preservation. See [CMEK content preservation](https://platform.claude.com/docs/en/manage-claude/access-transparency#cmek-content-preservation) for details. Safety screening metadata is retained under Anthropic-managed encryption and remains readable after key revocation. These are records derived from Anthropic's automated safety scans, such as pattern identifiers and match indicators, not conversation content.

manage-claude/cmek-google-cloud-kms Changed · +92 / -492 lines

## Before you start ## In Google Cloud: create the key ### Add the organization label to a key you already have ## In Claude: add and attach the key ## Prerequisites ## Anthropic service account email ## Encryption key setup ## Register the key with Anthropic ## Troubleshoot validation ## Terraform

The two sides of this change are more than 400 edits apart, too far apart to line up, so this is the differ's own diff of it and the words inside a line are not marked.

from line 1
11---
2title: Configure Google Cloud KMS for CMEK
2title: Set up CMEK with Google Cloud KMS
33url: https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms
4description: Use Google Cloud KMS to provide an encryption key for your organization.
4description: Create a Google Cloud KMS key, give Anthropic access to it, and put it to use in Claude Platform or Claude Enterprise.
55---
66 
77Let Claude Code set up this feature for you
from line 10
1010/claude-api help me configure a customer-managed encryption key with Google Cloud KMS
1111```
1212 
13This guide shows how to use a Google Cloud KMS key as a [customer-managed encryption key (CMEK)](https://platform.claude.com/docs/en/manage-claude/cmek) for your Anthropic organization.
14 
15<Warning>
16 Enabling CMEK is permanent. If your key is deleted or disabled, Anthropic cannot recover the data encrypted under it. Review the [warnings and limitations](https://platform.claude.com/docs/en/manage-claude/cmek) before you start.
17</Warning>
18 
19## Prerequisites
20 
21* A Google Cloud project with billing enabled.
22* The Cloud KMS API enabled (`cloudkms.googleapis.com`).
23* Permissions to create KMS key rings and keys, and to set IAM policy on them (`roles/cloudkms.admin` or equivalent).
24* Cloud KMS Data Access audit logs (Data Read and Data Write) turned on for the project, so that Cloud Logging records Anthropic's use of your key. They're off by default. To turn them on, see Google's [Enable Data Access audit logs](https://docs.cloud.google.com/logging/docs/audit/configure-data-access).
25* To create the key from the command line, the [`gcloud` CLI](https://cloud.google.com/cli) installed and authenticated.
26* To register the key through the API, an Anthropic Admin API key for your organization.
27 
28## Anthropic service account email
29 
30In this guide, you give the following Anthropic service account access to your key:
13## Before you start
14 
15In Claude:
16 
17* Customer-managed encryption keys (CMEK) are [turned on for your organization](https://platform.claude.com/docs/en/manage-claude/cmek#availability).
18* You have your Anthropic organization ID, the UUID without the `org_` prefix. Copy it from [Organization](https://platform.claude.com/settings/organization) in the Claude Console, or from **Organization settings > Organization and access** on claude.ai. Whoever creates the key needs it.
19* You're an Organization Admin on Claude Platform, or an Owner or Primary Owner on Claude Enterprise.
20* On Claude Platform, you have a workspace that [retains data](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#data-retention), ideally a new one, because [existing data stays under Anthropic's key](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect).
21* On Claude Enterprise, you know [which features turn off or change](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed).
22 
23In Google Cloud:
24 
25* The Cloud KMS API is turned on.
26* You can create key rings and keys, and set IAM policy on them (`roles/cloudkms.admin` or equivalent).
27* Cloud KMS [Data Access audit logs](https://docs.cloud.google.com/logging/docs/audit/configure-data-access) (Data Read and Data Write) are on, so Cloud Logging records Anthropic's use of your key. They're off by default.
28* If your Google Cloud organization enforces domain restricted sharing (`constraints/iam.allowedPolicyMemberDomains`), it blocks the grant to Anthropic's service account. Add a project-level exception, or allow Anthropic's Cloud Identity customer ID. Contact Anthropic for the ID.
29 
30## In Google Cloud: create the key
31 
32After a failed **Verify** or **Add**, see the [fixes for Google Cloud KMS](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#google-cloud-kms).
33 
34These steps label the key with your Anthropic organization ID in lowercase (`<ORGANIZATION_UUID>`) and grant access to Anthropic's service account:
3135 
3236```text wrap
3337anthropic-cmek-client-us@gcp-anthropic-cmek-clients.iam.gserviceaccount.com
3438```
3539 
36<Warning>
37 Use only this published service account email. Never trust an identifier provided over email, chat, or any onboarding channel.
38</Warning>
39 
40<Note>
41 **Domain restricted sharing:** If your Google Cloud organization enforces `constraints/iam.allowedPolicyMemberDomains`, it rejects the IAM bindings for this service account. Add a project-level exception to that constraint, or add Anthropic's Cloud Identity customer ID (format `C0xxxxxxxx`) to the allowed list. Contact Anthropic for the customer ID.
42</Note>
43 
44## Encryption key setup
45 
46The key must meet these requirements:
47 
48* **Location:** Use a single-region US location, such as `us-east5`. Multi-region locations such as `us` and `global` aren't supported. See [Availability and regions](https://platform.claude.com/docs/en/manage-claude/cmek#availability-and-regions).
49* **Type:** Use a symmetric key with the `ENCRYPT_DECRYPT` purpose. Anthropic strongly recommends HSM protection.
50* **Organization label:** Add the label `anthropic-org-<ORGANIZATION_UUID>` with the value `true`. Replace `<ORGANIZATION_UUID>` with your Anthropic organization ID in lowercase. Validation fails without this label. To label an existing key, see [Keys you already have](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#existing-key-label).
51* **Access:** Give Anthropic's service account the `roles/cloudkms.cryptoKeyEncrypterDecrypter` and `roles/cloudkms.viewer` roles on the key itself.
52 
53<Note>
54 **Finding your organization ID:** Use the bare UUID, not the `org_`-prefixed ID. Copy it from one of these places:
55 
56 * **Claude Console:** the **Organization ID** field on the [Organization](https://platform.claude.com/settings/organization) page (`platform.claude.com/settings/organization`)
57 * **claude.ai:** the **Organization ID** field under **Organization settings > Organization**
58 * **Admin API:** the `id` field from the [Organization Info](https://platform.claude.com/docs/en/api/organization/retrieve) endpoint
59</Note>
40Use only this address, never one sent by email or chat.
41 
42For the lowest latency, use `us-east5` or `us-central1`. Anthropic strongly recommends HSM protection.
43 
44To use a key you already have, [add the organization label](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#organization-label) first.
6045 
6146<Tabs>
6247 <Tab title="Google Cloud Console">
from line 168
183168 </Tab>
184169</Tabs>
185170 
186You register the key with its full resource name, in this format:
171Whoever adds the key in Claude needs its full resource name, in this format:
187172 
188173```text wrap
189174projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>
190175```
191176 
192<Note>
193 **Keys you already have:** Add the organization label with this command, in Cloud Shell or with the gcloud CLI:
194 
195 ```bash
196 gcloud kms keys update <your-key-name> \
197 --project=<your-project-id> \
198 --location=<region> \
199 --keyring=<your-keyring-name> \
200 --update-labels=anthropic-org-<ORGANIZATION_UUID>=true
201 ```
202 
203 The placeholders match the parts of the key's full resource name. The command merges the label with any labels the key already has. Then grant access and copy the resource name as the preceding steps describe.
204 
205 To share one key among several Anthropic organizations, add one organization label for each.
206</Note>
207 
208## Register the key with Anthropic
177### Add the organization label to a key you already have
178 
179Verification fails unless the key has the label `anthropic-org-<ORGANIZATION_UUID>` set to `true`, with your Anthropic organization ID in lowercase. To add the label, run:
180 
181```bash
182gcloud kms keys update <your-key-name> \
183 --project=<your-project-id> \
184 --location=<region> \
185 --keyring=<your-keyring-name> \
186 --update-labels=anthropic-org-<ORGANIZATION_UUID>=true
187```
188 
189The other values are in the key's full resource name, and the command keeps existing labels. Then skip to [the steps that grant access](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#encryption-key-setup).
190 
191## In Claude: add and attach the key
192 
193To script this part on Claude Platform, [use the Admin API](https://platform.claude.com/docs/en/manage-claude/cmek-admin-api) instead.
209194 
210195<Tabs>
211196 <Tab title="Claude Platform">
212 <Tabs>
213 <Tab title="Claude Console">
214 <Steps>
215 <Step title="Open the encryption key settings">
216 In the Claude Console, go to the [Data retention](https://platform.claude.com/settings/privacy#encryption-keys) page (`platform.claude.com/settings/privacy`). If you don't see **Encryption keys**, select **Organization** from the dropdown menu at the top of the page.
217 </Step>
218 
219 <Step title="Add the key">
220 Under **Encryption keys**, click **Add key**. Enter a **Display name** and select **Google Cloud KMS**. Click **Continue**.
221 </Step>
222 
223 <Step title="Enter the key resource name">
224 The dialog box shows an **Organization label**. Check that your key has this label. Paste the full key resource name into **Key resource name** and click **Add**.
225 </Step>
226 
227 <Step title="Validate the key">
228 In the **Encryption keys** list, click **Verify** next to the key. **Connected** appears when the check passes. If it fails, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#troubleshoot-validation) for common causes.
229 </Step>
230 
231 <Step title="Attach the key to a workspace">
232 Attaching a key can't be undone. If you can, attach it to a new workspace before that workspace receives any requests. In a workspace that already receives requests, the key can take [up to a day to take effect](https://platform.claude.com/docs/en/manage-claude/cmek#how-it-works).
233 
234 On the Data retention page, select the workspace from the dropdown menu at the top of the page. Under **Encryption key**, select the key and click **Save**.
235 </Step>
236 
237 <Step title="Confirm the change">
238 Select the checkbox to confirm that you have read the CMEK documentation, then click **Confirm**.
239 </Step>
240 </Steps>
241 </Tab>
242 
243 <Tab title="API">
244 <Steps>
245 <Step title="Create the external key">
246 Replace `<friendly-name>` with a display name. Replace the value that starts with `projects/` with the full key resource name.
247 
248 <CodeGroup>
249 ```bash cURL
250 curl -sS "https://api.anthropic.com/v1/organizations/external_keys" \
251 -H "x-api-key: $ANTHROPIC_API_KEY" \
252 -H "anthropic-version: 2023-06-01" \
253 -H "content-type: application/json" \
254 -d '{
255 "display_name": "<friendly-name>",
256 "geo": "us",
257 "provider_config": {
258 "type": "gcp",
259 "key_name": "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
260 }
261 }'
262 ```
263 
264 ```bash CLI
265 ant organization:external-keys create <<'YAML'
266 display_name: "<friendly-name>"
267 geo: us
268 provider_config:
269 type: gcp
270 key_name: "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
271 YAML
272 ```
273 
274 ```python Python
275 client = anthropic.Anthropic()
276 
277 external_key = client.organization.external_keys.create(
278 display_name="<friendly-name>",
279 geo="us",
280 provider_config={
281 "type": "gcp",
282 "key_name": "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>",
283 },
284 )
285 
286 print(f"id: {external_key.id}")
287 print(f"display_name: {external_key.display_name}")
288 ```
289 
290 ```typescript TypeScript
291 const client = new Anthropic();
292 
293 const externalKey = await client.organization.externalKeys.create({
294 display_name: "<friendly-name>",
295 geo: "us",
296 provider_config: {
297 type: "gcp",
298 key_name:
299 "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
300 }
301 });
302 
303 console.log(`id: ${externalKey.id}`);
304 console.log(`display_name: ${externalKey.display_name}`);
305 ```
306 
307 ```csharp C#
308 using Anthropic.Models.Organization.ExternalKeys;
309 
310 AnthropicClient client = new();
311 
312 var externalKey = await client.Organization.ExternalKeys.Create(new()
313 {
314 DisplayName = "<friendly-name>",
315 Geo = Geo.Us,
316 ProviderConfig = new GcpExternalKeyConfig
317 {
318 KeyName = "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
319 }
320 });
321 
322 Console.WriteLine($"id: {externalKey.ID}");
323 Console.WriteLine($"display_name: {externalKey.DisplayName}");
324 ```
325 
326 ```go Go
327 client := anthropic.NewClient()
328 
329 externalKey, err := client.Organization.ExternalKeys.New(context.Background(), anthropic.OrganizationExternalKeyNewParams{
330 DisplayName: anthropic.String("<friendly-name>"),
331 Geo: anthropic.OrganizationExternalKeyNewParamsGeoUs,
332 ProviderConfig: anthropic.OrganizationExternalKeyNewParamsProviderConfigUnion{
333 OfGCP: &anthropic.GCPExternalKeyConfigParam{
334 KeyName: "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>",
335 },
336 },
337 })
338 if err != nil {
339 log.Fatal(err)
340 }
341 
342 fmt.Printf("id: %s\n", externalKey.ID)
343 fmt.Printf("display_name: %s\n", externalKey.DisplayName)
344 ```
345 
346 ```java Java
347 import com.anthropic.models.organization.externalkeys.ExternalKeyCreateParams;
348 
349 void main() {
350 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
351 
352 var params = ExternalKeyCreateParams.builder()
353 .displayName("<friendly-name>")
354 .geo(ExternalKeyCreateParams.Geo.US)
355 .gcpProviderConfig("projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>")
356 .build();
357 var externalKey = client.organization().externalKeys().create(params);
358 
359 IO.println("id: " + externalKey.id());
360 IO.println("display_name: " + externalKey.displayName().orElseThrow());
361 }
362 ```
363 
364 ```php PHP
365 use Anthropic\Organization\ExternalKeys\ExternalKeyCreateParams\Geo;
366 // ...
367 
368 $client = new Client();
369 
370 $externalKey = $client->organization->externalKeys->create(
371 displayName: '<friendly-name>',
372 geo: Geo::US,
373 providerConfig: [
374 'type' => 'gcp',
375 'keyName' => 'projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>',
376 ],
377 );
378 
379 echo "id: {$externalKey->id}\n";
380 echo "display_name: {$externalKey->displayName}\n";
381 ```
382 
383 ```ruby Ruby
384 client = Anthropic::Client.new
385 
386 external_key = client.organization.external_keys.create(
387 display_name: "<friendly-name>",
388 geo: :us,
389 provider_config: {
390 type: :gcp,
391 key_name: "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
392 }
393 )
394 
395 puts "id: #{external_key.id}"
396 puts "display_name: #{external_key.display_name}"
397 ```
398 </CodeGroup>
399 
400 The `id` field of the response contains the external key ID. Copy it for the next two steps:
401 
402 ```json
403 {
404 "type": "external_key",
405 "id": "ekey_<id>",
406 "display_name": "<friendly-name>"
407 }
408 ```
409 </Step>
410 
411 <Step title="Validate the key">
412 Replace `ekey_<id>` with the external key ID.
413 
414 <CodeGroup>
415 ```bash cURL
416 curl -sS -X POST "https://api.anthropic.com/v1/organizations/external_keys/ekey_<id>/validate" \
417 -H "x-api-key: $ANTHROPIC_API_KEY" \
418 -H "anthropic-version: 2023-06-01"
419 ```
420 
421 ```bash CLI
422 ant organization:external-keys validate --external-key-id "ekey_<id>"
423 ```
424 
425 ```python Python
426 client = anthropic.Anthropic()
427 
428 validation = client.organization.external_keys.validate("ekey_<id>")
429 
430 print(f"status: {validation.status}")
431 print(f"error: {validation.error}")
432 ```
433 
434 ```typescript TypeScript
435 const client = new Anthropic();
436 
437 const validation = await client.organization.externalKeys.validate("ekey_<id>");
438 
439 console.log(`status: ${validation.status}`);
440 console.log(`error: ${validation.error}`);
441 ```
442 
443 ```csharp C#
444 AnthropicClient client = new();
445 
446 var validation = await client.Organization.ExternalKeys.Validate("ekey_<id>");
447 
448 Console.WriteLine($"status: {validation.Status.Raw()}");
449 Console.WriteLine($"error: {validation.Error}");
450 ```
451 
452 ```go Go
453 client := anthropic.NewClient()
454 
455 validation, err := client.Organization.ExternalKeys.Validate(context.Background(), "ekey_<id>")
456 if err != nil {
457 log.Fatal(err)
458 }
459 
460 fmt.Printf("status: %s\n", validation.Status)
461 fmt.Printf("error: %s\n", validation.Error)
462 ```
463 
464 ```java Java
465 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
466 
467 var validation = client.organization().externalKeys().validate("ekey_<id>");
468 
469 IO.println("status: " + validation.status().asString());
470 IO.println("error: " + validation.error().orElse(""));
471 ```
472 
473 ```php PHP
474 $client = new Client();
475 
476 $validation = $client->organization->externalKeys->validate(
477 externalKeyID: 'ekey_<id>',
478 );
479 
480 echo "status: {$validation->status}\n";
481 echo "error: {$validation->error}\n";
482 ```
483 
484 ```ruby Ruby
485 client = Anthropic::Client.new
486 
487 external_key_id = "ekey_<id>"
488 validation = client.organization.external_keys.validate(external_key_id)
489 
490 puts "status: #{validation.status}"
491 puts "error: #{validation.error}"
492 ```
493 </CodeGroup>
494 
495 A successful response looks like this:
496 
497 ```json
498 { "type": "external_key_validation", "status": "success", "error": null }
499 ```
500 
501 If validation fails, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#troubleshoot-validation).
502 </Step>
503 
504 <Step title="Attach the key to a workspace">
505 Attaching a key can't be undone. If you can, attach it to a new workspace before that workspace receives any requests. In a workspace that already receives requests, the key can take [up to a day to take effect](https://platform.claude.com/docs/en/manage-claude/cmek#how-it-works).
506 
507 Replace `<workspace-id>` with the workspace ID and `ekey_<id>` with the external key ID.
508 
509 <CodeGroup>
510 ```bash cURL
511 curl -sS -X POST "https://api.anthropic.com/v1/organizations/workspaces/<workspace-id>" \
512 -H "x-api-key: $ANTHROPIC_API_KEY" \
513 -H "anthropic-version: 2023-06-01" \
514 -H "content-type: application/json" \
515 -d '{
516 "external_key_id": "ekey_<id>"
517 }'
518 ```
519 
520 ```bash CLI
521 ant organization:workspaces update \
522 --workspace-id "<workspace-id>" \
523 --external-key-id "ekey_<id>"
524 ```
525 
526 ```python Python
527 client = anthropic.Anthropic()
528 
529 workspace = client.organization.workspaces.update(
530 "<workspace-id>", external_key_id="ekey_<id>"
531 )
532 
533 print(f"id: {workspace.id}")
534 print(f"external_key_id: {workspace.external_key_id}")
535 ```
536 
537 ```typescript TypeScript
538 const client = new Anthropic();
539 
540 const workspace = await client.organization.workspaces.update("<workspace-id>", {
541 external_key_id: "ekey_<id>"
542 });
543 
544 console.log(`id: ${workspace.id}`);
545 console.log(`external_key_id: ${workspace.external_key_id}`);
546 ```
547 
548 ```csharp C#
549 AnthropicClient client = new();
550 
551 var workspace = await client.Organization.Workspaces.Update("<workspace-id>", new()
552 {
553 ExternalKeyID = "ekey_<id>"
554 });
555 
556 Console.WriteLine($"id: {workspace.ID}");
557 Console.WriteLine($"external_key_id: {workspace.ExternalKeyID}");
558 ```
559 
560 ```go Go
561 client := anthropic.NewClient()
562 
563 workspace, err := client.Organization.Workspaces.Update(
564 context.Background(),
565 "<workspace-id>",
566 anthropic.OrganizationWorkspaceUpdateParams{
567 ExternalKeyID: anthropic.String("ekey_<id>"),
568 },
569 )
570 if err != nil {
571 log.Fatal(err)
572 }
573 
574 fmt.Printf("id: %s\n", workspace.ID)
575 fmt.Printf("external_key_id: %s\n", workspace.ExternalKeyID)
576 ```
577 
578 ```java Java
579 import com.anthropic.models.organization.workspaces.WorkspaceUpdateParams;
580 
581 void main() {
582 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
583 
584 var params = WorkspaceUpdateParams.builder()
585 .externalKeyId("ekey_<id>")
586 .build();
587 var workspace = client.organization().workspaces().update("<workspace-id>", params);
588 
589 IO.println("id: " + workspace.id());
590 IO.println("external_key_id: " + workspace.externalKeyId().orElseThrow());
591 }
592 ```
593 
594 ```php PHP
595 $client = new Client();
596 
597 $workspace = $client->organization->workspaces->update(
598 workspaceID: '<workspace-id>',
599 externalKeyID: 'ekey_<id>',
600 );
601 
602 echo "id: {$workspace->id}\n";
603 echo "external_key_id: {$workspace->externalKeyID}\n";
604 ```
605 
606 ```ruby Ruby
607 client = Anthropic::Client.new
608 
609 workspace_id = "<workspace-id>"
610 workspace = client.organization.workspaces.update(
611 workspace_id,
612 external_key_id: "ekey_<id>"
613 )
614 
615 puts "id: #{workspace.id}"
616 puts "external_key_id: #{workspace.external_key_id}"
617 ```
618 </CodeGroup>
619 </Step>
620 </Steps>
621 </Tab>
622 </Tabs>
197 <Steps>
198 <Step title="Open the encryption key settings">
199 In the Claude Console, open [Encryption keys](https://platform.claude.com/settings/privacy#encryption-keys) on the Data retention page. If the section isn't there, select **Organization** from the dropdown menu at the top.
200 </Step>
201 
202 <Step title="Add the key">
203 Under **Encryption keys**, click **Add key**. Enter a **Display name**, select **Google Cloud KMS**, and click **Continue**.
204 </Step>
205 
206 <Step title="Enter the key resource name">
207 Check that your key has the **Organization label** shown in the dialog box. Paste the key's full resource name into **Key resource name** and click **Add**.
208 </Step>
209 
210 <Step title="Verify the key">
211 In the **Encryption keys** list, click **Verify** next to the key. **Connected** appears when the check passes. If **Connection failed** appears instead, see [Troubleshoot CMEK](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting).
212 </Step>
213 
214 <Step title="Attach the key to a workspace">
215 <Warning>
216 Attaching a key [can't be undone](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#what-each-action-does). You can't remove it from the workspace or replace it. If the key is deleted, Anthropic can't recover the data it protects.
217 </Warning>
218 
219 1. At the top of the Data retention page, select the workspace from the dropdown menu.
220 2. Under **Encryption key**, select the key and click **Save**.
221 3. Select the checkbox to confirm that you have read the CMEK documentation, then click **Confirm**.
222 
223 You see **Workspace settings updated.** Once the key [takes effect](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect), your cloud provider's audit log shows Anthropic's calls to the key.
224 
225 In a [ZDR organization](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#zdr-organizations), after you select the workspace, select **Standard data retention** so that **Encryption key** appears. After you click **Save**, click **Accept** on the data retention terms.
226 </Step>
227 </Steps>
623228 </Tab>
624229 
625230 <Tab title="Claude Enterprise">
626 On Claude Enterprise, CMEK applies to the whole organization, and an organization can have only one key.
231 On Claude Enterprise, CMEK applies to the whole organization, and you can add only one key.
232 
233 <Warning>
234 Adding a key [can't be undone](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#what-each-action-does). You can't remove it from the organization or replace it. If the key is deleted, Anthropic can't recover the data it protects.
235 </Warning>
236 
237 Adding the key [turns off or changes some features](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed) for every user. To try CMEK first, use a separate organization.
627238 
628239 <Steps>
629240 <Step title="Open the encryption key settings">
from line 246
635246 </Step>
636247 
637248 <Step title="Enter the key resource name">
638 The dialog box shows an **Organization label**. Check that your key has this label. Paste the full key resource name into **Key resource name** and click **Add**.
639 </Step>
640 
641 <Step title="Confirm that validation passed">
642 When the check passes, **Encryption key configured** appears, and your organization is CMEK-protected from then on. If the check fails, see [Troubleshoot validation](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#troubleshoot-validation).
249 Check that your key has the **Organization label** shown in the dialog box. Paste the key's full resource name into **Key resource name** and click **Add**.
250 </Step>
251 
252 <Step title="Confirm that the key was added">
253 The check can take up to 30 seconds. When **Encryption key configured.** appears, click **Done**. If **The encryption key couldn’t be added.** appears instead, [find the cause and retry](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#claude-ai-add-fails).
254 
255 Your key protects data written from then on. Tell your users [which features changed](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed).
643256 </Step>
644257 </Steps>
645258 </Tab>
646259</Tabs>
647 
648## Troubleshoot validation
649 
650If validation fails, common causes are:
651 
652* **Wrong organization label:** Make sure the key has the [organization label](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#organization-label), with your bare organization ID in lowercase.
653* **VPC Service Controls:** A service perimeter that protects Cloud KMS in your project can block Anthropic. Add Anthropic to an access level on the perimeter, or exclude the key's project from it.
654* **Domain restricted sharing:** The `constraints/iam.allowedPolicyMemberDomains` org policy blocks the binding for Anthropic's service account. To check that the binding is there, run `gcloud kms keys get-iam-policy <your-key-name> --project=<your-project-id> --location=<region> --keyring=<your-keyring-name>`. To allow it, see [Anthropic service account email](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#anthropic-service-account-email).
655* **Disabled or destroyed key version:** Confirm that the key's primary version is enabled.
656 
657## Terraform
658 
659To create the key with Terraform, use the `google_kms_key_ring`, `google_kms_crypto_key`, and `google_kms_crypto_key_iam_member` resources from the `google` provider.
660260 

manage-claude/cmek-how-it-works New page · 49 lines, new page

## Your key wraps the keys that encrypt your data ## What one key protects ## Where your key lives ## When your key takes effect ## What you can see ## Latency and standards

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: How CMEK works
url: https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works
description: How your key protects stored data, what one key covers, when it takes effect, and what you can see.
---

## Your key wraps the keys that encrypt your data

Anthropic encrypts your stored data with data keys. With customer-managed encryption keys (CMEK), your key encrypts, or wraps, those data keys. This is envelope encryption. To write or read data, Anthropic asks your key management service (KMS) to wrap or unwrap a data key.

Data keys cross between Anthropic and your cloud. Your key never leaves your KMS. Your data never goes to it.

<Frame>
  ![Your key stays in your cloud's KMS and wraps Anthropic's data keys, which encrypt your data. Your cloud can log each call.](https://platform.claude.com/docs/images/cmek/key-wrapping.svg)
</Frame>

Anthropic keeps no copy of your key, so without it, Claude [can't read the data it protects](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle).

## What one key protects

On Claude Platform and Claude Platform on AWS, a key protects a workspace, and one key can serve several. On Claude Enterprise, a key protects the whole organization, which can have only one key. [Which data your key protects](https://platform.claude.com/docs/en/manage-claude/cmek#what-cmek-protects) depends on your product.

On Claude Platform and Claude Enterprise, your key carries your Anthropic organization ID, which ties the key to your organization. Depending on your KMS, the ID goes in a key policy condition, a label, or a tag. A key without the ID fails verification. A key shared between organizations carries each ID.

An AWS KMS key policy can [name workspaces](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms-workspaces) by their compartment IDs. A compartment ID is the UUID Anthropic gives each workspace for encryption, not the workspace ID that starts with `wrkspc_`.

## Where your key lives

Your key lives in AWS KMS, Google Cloud KMS, or Azure Key Vault. Your provider might charge for it.

On Claude Platform and Claude Enterprise, CMEK is available in US regions, and Anthropic processes all encryption operations there. [Each setup page](https://platform.claude.com/docs/en/manage-claude/cmek#set-it-up) names the lowest-latency regions.

## When your key takes effect

Your key protects only data written after it takes effect. Existing data (prior chats, files, and sessions) stays under Anthropic's key and isn't re-encrypted.

On Claude Platform and Claude Platform on AWS, a key attached to a workspace before its first request takes effect with that request. In a workspace in use, your key can take up to a day to take effect, and data written meanwhile stays under Anthropic's key. That's why Anthropic recommends a new workspace.

## What you can see

Your cloud's audit log can record every operation Anthropic performs with your key. Where you have to turn that logging on, your setup page lists it as a prerequisite. In AWS CloudTrail, some entries are [expected errors](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#cloudtrail).

Changes to your CMEK configuration appear in the [Compliance API Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed). Key operations don't.

## Latency and standards

Each wrap or unwrap is a round trip to your KMS, which can add a little latency to reading and writing stored data. For cryptographic standards such as FIPS, see the CMEK whitepaper in the [Trust Center](https://trust.anthropic.com/resources).

Next, read [what each key action does](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#what-each-action-does).

manage-claude/cmek-key-lifecycle New page · 37 lines, new page

## What each action does ## What disabling does, and what comes back ## If Anthropic can't reach your key ## Change keys or stop using CMEK

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: What happens when you rotate, disable, or delete your encryption key
url: https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle
description: What each action on your key does to your data, how soon, and whether you can undo it.
---

With customer-managed encryption keys (CMEK), your key lives in your key management service (KMS), and Claude keeps a record that points to it. Deleting the key and deleting the record are different actions.

## What each action does

<Frame>
  ![Key states: attaching is one-way, a disabled key can be re-enabled, and Anthropic can't recover data once the key is deleted.](https://platform.claude.com/docs/images/cmek/key-states.svg)
</Frame>

| Action                                                                              | What happens                                                                                                                                                                                                                                                                                                                     | Can you undo it?                                                                                                                                          |
| ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Attach the key to a workspace (on Claude Enterprise, add it to the organization)    | Your key protects data written [after it takes effect](https://platform.claude.com/docs/en/manage-claude/cmek-how-it-works#when-your-key-takes-effect). On Claude Platform, attaching also locks the workspace's [data retention setting](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#data-retention). | No. The key can't be removed or replaced.                                                                                                                 |
| Rotate the key material within the same key                                         | You rotate it in your KMS, on your own schedule. Rotation needs no action in Claude.                                                                                                                                                                                                                                             | Nothing to undo. Keep earlier key versions enabled.                                                                                                       |
| Disable the key, or remove (revoke) Anthropic's access to it                        | The change can take up to 1 hour to apply, and requests in flight during that hour might still succeed. After that, Claude can't read or write the data the key protects, and requests fail.                                                                                                                                     | Re-enable the key or restore Anthropic's access. [Two limits apply](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#restore-access). |
| Delete the key in your KMS, schedule it for deletion, or destroy its key material   | Anthropic can't recover the data the key protects.                                                                                                                                                                                                                                                                               | Not by Anthropic. It keeps no copy of your key.                                                                                                           |
| Delete the key's record in Claude (**Delete encryption key** in the Claude Console) | You can do this only while no workspace, including an archived one, uses the key.                                                                                                                                                                                                                                                | No.                                                                                                                                                       |

## What disabling does, and what comes back

While the key is disabled, Messages API requests in a workspace that uses it return [a 400 error with the code `cmek_key_disabled`](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#cmek-key-disabled).

Re-enabling the key, or restoring Anthropic's access to it, brings back access to the data the key protects. Two limits apply. Requests that failed while the key was disabled aren't retried. Disabling the key doesn't pause retention periods.

## If Anthropic can't reach your key

Requests that store data under your key fail while Anthropic can't reach it, for example during an outage of your KMS. On Claude Enterprise, these requests include messages in chat and in voice mode.

On the Messages API, these requests return a 503 error with the code `cmek_key_unreachable`, and you can retry them. The Message Batches API retries them for you until your key is available or the batch expires.

## Change keys or stop using CMEK

A workspace or organization can't switch to a different key or go back to having none. On Claude Platform, you can create a new workspace with a different key, or with no key, and move your traffic to it. On Claude Enterprise, there's no way to change keys or stop using CMEK within the organization.

manage-claude/cmek-troubleshooting New page · 166 lines, new page

## Requests fail after setup ### `cmek_key_disabled` ### `cmek_key_network_blocked` ### `cmek_key_unreachable` ## Verification fails: AWS KMS ### A key that already protects data ## Verification fails: Google Cloud KMS ## Verification fails: Azure Key Vault ## Attaching fails on Claude Platform on AWS ## Attaching or adding a key is refused ### The workspace doesn't retain data ### The workspace has no Encryption key setting ### There is no Encryption keys section ### The workspace already has a key ### Adding a key on claude.ai fails ## Expected errors in CloudTrail

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: Troubleshoot CMEK
url: https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting
description: Find the cause and fix for a CMEK error message, a failed verification, or an unexpected log entry.
---

**Verify** in the Claude Console, **Add** on claude.ai, and the Admin API's validate call all run the same check. When it fails (**Connection failed** in the Claude Console), see the causes for [AWS KMS](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#aws-kms), [Google Cloud KMS](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#google-cloud-kms), or [Azure Key Vault](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#azure-key-vault).

If a feature stopped working, it might be one that customer-managed encryption keys (CMEK) turn off. Check the [Claude Platform list](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-platform#turned-off-or-changed) or [Claude Enterprise list](https://platform.claude.com/docs/en/manage-claude/cmek-coverage-claude-enterprise#turned-off-or-changed).

If nothing here fits, contact your Anthropic account team.

## Requests fail after setup

### `cmek_key_disabled`

```text wrap
Customer-managed encryption key is disabled or revoked. Re-enable the key to restore access.
```

This 400 error means your key management service refused Anthropic's call. Check these causes in order:

1. The key is disabled.
2. Anthropic's access to the key was removed. [Your setup page](https://platform.claude.com/docs/en/manage-claude/cmek#set-it-up) shows the access Anthropic needs.
3. On AWS KMS, the key policy [lists workspaces](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms-workspaces) but not this one.
4. On AWS KMS, an IP condition blocks [Anthropic's outbound IP addresses](https://platform.claude.com/docs/en/api/ip-addresses#outbound-ip-addresses).

Fix the cause. [Two limits apply](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#restore-access) when access returns.

### `cmek_key_network_blocked`

```text wrap
The request to your key management service was blocked by its network access controls (for example, a KMS firewall or IP allowlist). Verify that your KMS network rules allow requests from Anthropic's published IP addresses, or contact Anthropic support if your configuration looks correct.
```

This is a 400 error. The key itself might be healthy. Allow [Anthropic's published IP addresses](https://platform.claude.com/docs/en/api/ip-addresses) in your key management service's network rules.

### `cmek_key_unreachable`

```text wrap
The workspace's customer-managed encryption key could not be reached. Try again shortly. If this continues, check that the key is available in your key management service, or contact Anthropic support.
```

This 503 error means [Anthropic couldn't reach your key](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#unreachable-key). Retry the request.

## Verification fails: AWS KMS

| Cause                                                | Fix                                                                                                                                                                                    |
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Wrong organization ID                                | The `org_uuid` condition must list [your Anthropic organization ID](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#prerequisites), the UUID without the `org_` prefix. |
| A workspace is missing from the policy               | A `compartment_uuid` condition must [list the compartment ID](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms-workspaces) of each workspace the key is attached to.     |
| Access granted through IAM instead of the key policy | Anthropic's role needs access in [the key policy itself](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#key-policy).                                                   |

To print the key policy, run:

```bash
aws kms get-key-policy \
  --region <REGION> \
  --key-id <KEY_ARN> \
  --policy-name default
```

### A key that already protects data

If you're [replacing the policy on a key](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms-workspaces#replace-the-key-policy) that already protects data, add this statement so Anthropic can still decrypt that data. In its condition, list the compartment ID of every workspace the key is or was attached to.

```json
{
  "Sid": "AllowAnthropicCMEKDecryptExistingData",
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::915198916910:role/anthropic-cmek-client-us"
  },
  "Action": "kms:Decrypt",
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "kms:EncryptionContext:anthropic:compartment_uuid": ["<COMPARTMENT_UUID>"]
    }
  }
}
```

## Verification fails: Google Cloud KMS

| Cause                             | Fix                                                                                                                                                                                   |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Wrong organization label          | The key needs the [organization label](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#organization-label), with your Anthropic organization ID in lowercase. |
| Domain restricted sharing         | This organization policy blocks the grant to Anthropic's service account. [Add an exception](https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms#prerequisites).  |
| Disabled or destroyed key version | The key's primary version must be enabled.                                                                                                                                            |

To check the grant, run:

```bash
gcloud kms keys get-iam-policy <your-key-name> \
  --project=<your-project-id> \
  --location=<region> \
  --keyring=<your-keyring-name>
```

## Verification fails: Azure Key Vault

| Cause                                     | Fix                                                                                                                                                                  |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Wrong organization tag                    | The key's current version needs the [organization tag](https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault#organization-tag).                     |
| Role assignment not yet in effect         | A new role assignment can take a few minutes. Wait, then try again.                                                                                                  |
| The vault's network rules block Anthropic | Check the rules against the [vault settings Anthropic needs](https://platform.claude.com/docs/en/manage-claude/cmek-azure-key-vault#check-your-vault-configuration). |

## Attaching fails on Claude Platform on AWS

Claude Platform on AWS has no **Verify** step, so a problem with the key shows when you attach it.

| Cause                 | Fix                                                                                                                                                                                                                                                                                                |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Key policy mismatch   | Print the key policy with the [`get-key-policy` command](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#aws-kms) and compare it with the [policy on the setup page](https://platform.claude.com/docs/en/manage-claude/cmek-claude-platform-on-aws#prepare-the-key-policy). |
| Condition mismatch    | Any `EncryptionContext` or `aws:SourceArn` condition must include this workspace.                                                                                                                                                                                                                  |
| Key state or location | The key must be enabled, single-Region, and in the same AWS account and region as the workspace.                                                                                                                                                                                                   |
| Missing permissions   | The principal you're signed in as needs `kms:DescribeKey`, `kms:Encrypt`, and `kms:Decrypt` on the key.                                                                                                                                                                                            |

If attaching still fails, find the denied `kms:` event in CloudTrail in the key's account. It shows the calling principal and, for cryptographic calls, the encryption context. Fix the cause, then click **Save** again.

## Attaching or adding a key is refused

### The workspace doesn't retain data

```text wrap
CMEK keys can only be attached to workspaces in this organization that have inference data retention enabled.
```

[Your organization uses zero data retention (ZDR)](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#zdr-organizations), and a key needs a workspace that retains data. Switch the workspace to **Standard data retention** first.

### The workspace has no Encryption key setting

Only [a workspace that retains data](https://platform.claude.com/docs/en/manage-claude/cmek-data-retention#data-retention) has this setting, so select **Standard data retention** for the workspace first. A ZDR organization's default workspace can't be switched, so use another.

### There is no Encryption keys section

In the Claude Console, select **Organization** from the dropdown menu at the top of the Data retention page. If the section is still missing, your role doesn't include it or CMEK isn't turned on for your organization. Your Anthropic account team turns CMEK on.

### The workspace already has a key

```text wrap
This workspace already has a different external key attached.
```

A workspace's key can't be replaced, so [create a new workspace](https://platform.claude.com/docs/en/manage-claude/cmek-key-lifecycle#change-keys) for a different key.

### Adding a key on claude.ai fails

```text wrap
The encryption key couldn’t be added.
```

The check on your key failed. Find the cause for [AWS KMS](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#aws-kms), [Google Cloud KMS](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#google-cloud-kms), or [Azure Key Vault](https://platform.claude.com/docs/en/manage-claude/cmek-troubleshooting#azure-key-vault). To retry, click **Add key** again. The dialog box opens with your earlier details. Select the checkbox, click **Continue**, then click **Add**.

## Expected errors in CloudTrail

On Claude Platform and Claude Enterprise, Anthropic checks the key whenever you verify it, attach it to a workspace, or view it on claude.ai. Each check adds four expected access-denied errors to CloudTrail.

To filter them out, match all three values:

* `requestParameters.encryptionContext.associatedData`: `Y21lay12YWxpZGF0aW9u`
* `userIdentity.accountId`: `915198916910`
* `resources.ARN`: `arn:aws:kms:<REGION>:<AWS_ACCOUNT_ID>:key/<KEY_ID>`

The first value alone isn't enough, because any caller can set it.

manage-claude/compliance-activity-feed Changed · +7 / -7 lines

from line 23
2323 -H "anthropic-version: 2023-06-01"
2424```
2525 
26```text Response wrap
26```json Response
2727{
2828 "data": [
2929 {
30 "id": "activity_01XyDMpzjS89pFZXqSFUBDr6",
30 "id": "activity_01DeFgHjKmNpQrStUvWxYzAb",
3131 "created_at": "2026-04-10T08:09:10Z",
3232 "organization_id": "org_01Wv6QeBcDfGhJkLmNpQrSt8",
3333 "organization_uuid": "abcdef01-2345-6789-abcd-ef0123456789",
from line 39
3939 "user_agent": "Mozilla/5.0..."
4040 },
4141 "type": "claude_chat_created",
42 "claude_chat_id": "claude_chat_01XyDMpzjS89pFZXqSFUBDr6",
42 "claude_chat_id": "claude_chat_01CdEfGhJkMnPqRsTuVwXyZa",
4343 "claude_project_id": "claude_proj_01KGp4eZNug9ri4kE35RSppq"
4444 }
4545 ],
4646 "has_more": true,
47 "first_id": "activity_01XyDMpzjS89pFZXqSFUBDr6",
48 "last_id": "activity_01XyDMpzjS89pFZXqSFUBDr6"
47 "first_id": "activity_01DeFgHjKmNpQrStUvWxYzAb",
48 "last_id": "activity_01DeFgHjKmNpQrStUvWxYzAb"
4949}
5050```
5151 
from line 152
152152 
153153| `actor.type` | When it appears | Key fields |
154154| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
155| `user_actor` | A signed-in claude.ai or Claude Console user took the action, or a process Anthropic runs on that user's behalf did (see the paragraph after this table). | `email_address`, `user_id`, `ip_address`, `user_agent` |
155| `user_actor` | A signed-in claude.ai or Claude Console user took the action. Processes Anthropic runs on the user's behalf can also appear as this type; see the paragraph after this table. | `email_address`, `user_id`, `ip_address`, `user_agent` |
156156| `api_actor` | A request called the Claude API or the Compliance API with a customer-issued API key. Compliance API calls produce this actor type for both Compliance Access Keys and Admin API keys. | `api_key_id`, `ip_address`, `user_agent` |
157157| `admin_api_key_actor` | An organization admin used an Admin API key to manage users, invites, workspaces, or API keys. | `admin_api_key_id`, `ip_address`, `user_agent` |
158158| `unauthenticated_user_actor` | An action occurred before sign-in completed, for example `sso_login_initiated`. | `unauthenticated_email_address`, `ip_address`, `user_agent` |
from line 160
160160| `system_actor` | Automated background processing performed by Anthropic systems, acting without a user or customer credential. | `service` (nullable; the name of the automated process that performed the action, when known) |
161161| `scim_directory_sync_actor` | An identity provider (such as Okta, Microsoft Entra ID, or JumpCloud) pushed a change through SCIM directory sync. | `workos_event_id`, `directory_id`, `idp_connection_type` (nullable; for example `OktaSCIMV2`, `AzureSCIMV2`) |
162162 
163A `user_actor` activity does not always mean the user took the action. Processes that Anthropic runs on a user's behalf can currently appear as `user_actor` for the affected user rather than as `system_actor`, and this attribution may change. For example, memory activities from a migration, such as `platform_memory_store_created`, `platform_memory_created`, and `platform_memory_deleted`, are attributed this way. Memory activities can show an `ip_address` of `0.0.0.0` whoever performed them, so this value does not on its own identify activity from a platform process.
163A `user_actor` activity does not always mean the user took the action. Processes that Anthropic runs on a user's behalf can currently appear as `user_actor` for the affected user rather than as `system_actor`, and this attribution may change. For example, memory activities from a migration, such as `platform_memory_store_created`, `platform_memory_created`, and `platform_memory_deleted`, are attributed this way. The memory activities `platform_memory_store_created`, `platform_memory_created`, `platform_memory_updated`, and `platform_memory_deleted` currently show an `ip_address` of `0.0.0.0` whoever performed them. As a result, this value does not on its own identify a process that Anthropic runs on the user's behalf.
164164 
165165A `claude_*_viewed` activity means a Claude app loaded content, not that a person viewed it. Types such as `claude_chat_viewed`, `claude_file_viewed`, and `claude_project_viewed` are recorded each time a Claude app loads the chat, file, or project from Anthropic's servers. Repeated loads are not deduplicated. The web, desktop, and mobile apps load content at different moments, sometimes in the background, and can display a cached copy without loading it. Counts of these activities vary by platform as a result, and they do not correspond to messages sent or screens viewed.
166166 

manage-claude/compliance-api Changed · +5 / -5 lines

from line 21
2121 
2222A successful response returns a JSON object containing `data` (an array of `Activity` records), `has_more`, `first_id`, and `last_id`:
2323 
24```text Response wrap
24```json Response
2525{
2626 "data": [
2727 {
28 "id": "activity_01XyDMpzjS89pFZXqSFUBDr6",
28 "id": "activity_01DeFgHjKmNpQrStUvWxYzAb",
2929 "created_at": "2026-04-10T08:09:10Z",
3030 "organization_id": "org_01Wv6QeBcDfGhJkLmNpQrSt8",
3131 "organization_uuid": "abcdef01-2345-6789-abcd-ef0123456789",
from line 37
3737 "user_agent": "Mozilla/5.0..."
3838 },
3939 "type": "claude_chat_created",
40 "claude_chat_id": "claude_chat_01XyDMpzjS89pFZXqSFUBDr6",
40 "claude_chat_id": "claude_chat_01CdEfGhJkMnPqRsTuVwXyZa",
4141 "claude_project_id": "claude_proj_01KGp4eZNug9ri4kE35RSppq"
4242 }
4343 ],
4444 "has_more": true,
45 "first_id": "activity_01XyDMpzjS89pFZXqSFUBDr6",
46 "last_id": "activity_01XyDMpzjS89pFZXqSFUBDr6"
45 "first_id": "activity_01DeFgHjKmNpQrStUvWxYzAb",
46 "last_id": "activity_01DeFgHjKmNpQrStUvWxYzAb"
4747}
4848```
4949 
Feedback