---
title: CMEK를 위한 AWS KMS 구성
url: https://platform.claude.com/docs/ko/manage-claude/cmek-aws-kms
description: AWS KMS를 사용하여 조직에 암호화 키를 제공하세요.
---

Claude Code가 이 기능을 설정하도록 하세요

```text
/claude-api AWS KMS로 고객 관리형 암호화 키를 구성하도록 도와줘
```

이 가이드는 Anthropic 조직을 위한 [고객 관리 암호화 키(customer-managed encryption key, CMEK)](https://platform.claude.com/docs/ko/manage-claude/cmek)로 [AWS KMS](https://aws.amazon.com/kms/) 키를 구성하는 과정을 안내합니다.

<Warning>
  CMEK 활성화는 영구적입니다. KMS 키가 삭제되거나 비활성화되면 Anthropic은 해당 키로 암호화된 데이터를 복구할 수 없습니다. 시작하기 전에 [경고 및 제한 사항](https://platform.claude.com/docs/ko/manage-claude/cmek)을 검토하세요.
</Warning>

<Note>
  **Claude Platform on AWS:** [Claude Platform on AWS](https://platform.claude.com/docs/ko/build-with-claude/claude-platform-on-aws)에서는 키 정책이 Anthropic의 IAM 역할 대신 AWS 서비스 주체에 액세스 권한을 부여하며, 별도의 검증 단계가 없고, Claude Console에서 키를 등록하고 연결합니다. 다음 섹션의 단계 대신 이 페이지의 [Claude Platform on AWS에서 CMEK 설정](https://platform.claude.com/docs/ko/manage-claude/cmek-aws-kms#claude-platform-on-aws)을 따르세요.
</Note>

## 사전 요구 사항

* KMS 키를 생성하고 키 정책을 설정할 수 있는 권한(`kms:CreateKey` 및 `kms:PutKeyPolicy`)이 있는 AWS 계정.
* 조직을 위한 Anthropic Admin API 키.
* 설치 및 인증된 [AWS CLI](https://aws.amazon.com/cli/).

## Anthropic을 위한 Amazon 리소스 이름(ARN)

Anthropic이 암호화 키를 사용하도록 하려면 Anthropic의 IAM 역할에 데이터 암호화에 사용할 수 있는 KMS 키를 제공해야 합니다. Anthropic CMEK의 ARN은 다음과 같습니다:

```text wrap
arn:aws:iam::915198916910:role/anthropic-cmek-client-us
```

<Warning>
  이 게시된 ARN만 사용하세요. 이메일, 채팅 또는 온보딩 채널을 통해 제공된 식별자는 절대 신뢰하지 마세요.
</Warning>

## 암호화 키 설정

<Steps>
  <Step title="교차 계정 키 정책으로 KMS 키 생성">
    <Note>
      **Claude Platform on AWS:** 이 단계를 건너뛰세요. 키 정책이 AWS 서비스 주체에 액세스 권한을 부여하며, 조직 조건이 없습니다. [Claude Platform on AWS에서 CMEK 설정](https://platform.claude.com/docs/ko/manage-claude/cmek-aws-kms#claude-platform-on-aws)에서 해당 정책을 제공합니다.
    </Note>

    키 정책은 Anthropic의 IAM 역할에 교차 계정 액세스 권한을 부여합니다. 세 가지 명령문이 필요합니다:

    1. **계정 루트 관리자:** 표준 KMS 패턴입니다. 계정이 전체 관리자 제어 권한을 유지합니다.
    2. **Anthropic 암호화 및 복호화:** `kms:Encrypt` 및 `kms:Decrypt` 작업으로, Anthropic이 워크스페이스 데이터를 보호하는 데이터 키를 암호화하고 복호화하는 데 사용합니다(봉투 암호화).
    3. **Anthropic describe:** Anthropic이 시작 시 수행하는 메타데이터 읽기입니다. `DescribeKey`에는 `EncryptionContext` 매개변수가 없으므로 이 작업에 대한 `EncryptionContext` 조건은 항상 거부되기 때문에 별도로 부여됩니다.

    [AWS 계정 ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/console-account-id.html)를 찾으려면 `aws sts get-caller-identity --query Account --output text`를 실행하세요.

    정책에서 `<AWS_ACCOUNT_ID>`를 AWS 계정 ID로, `<ORGANIZATION_UUID>`를 조직 ID로 바꾸세요. `kms:EncryptionContext:anthropic:org_uuid`에 대한 `StringEquals` 조건은 키를 Anthropic 조직에 바인딩하며, 검증은 이것이 없는 키를 거부합니다. 여러 Anthropic 조직 간에 하나의 키를 공유하려면 조건 값에 각 조직 ID를 나열하세요.

    <Note>
      **조직 ID 찾기:** Claude Console의 [Organization](https://platform.claude.com/settings/organization) 페이지(`platform.claude.com/settings/organization`) 또는 claude.ai의 **Organization settings > Organization**에서 **Organization ID** 필드를 복사하거나, [Organization Info](https://platform.claude.com/docs/ko/api/organization/retrieve) 엔드포인트에서 `id` 필드를 읽으세요. `org_` 접두사가 붙은 ID가 아닌 순수 UUID를 사용하세요.
    </Note>

    정책을 `key-policy.json`으로 저장하세요. 대신 AWS Console에서 키를 생성하려면 이 단계의 뒷부분에서 설명하는 대로 정책을 거기에 붙여넣으세요.

    ```json key-policy.json
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AccountRootAdmin",
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::<AWS_ACCOUNT_ID>:root"
          },
          "Action": "kms:*",
          "Resource": "*"
        },
        {
          "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>"]
            }
          }
        },
        {
          "Sid": "AllowAnthropicCMEKDescribe",
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::915198916910:role/anthropic-cmek-client-us"
          },
          "Action": "kms:DescribeKey",
          "Resource": "*"
        }
      ]
    }
    ```

    <Note>
      **선택 사항:** 키를 일부 워크스페이스로 제한하려면 앞의 정책 JSON에 있는 것 대신 이 `AllowAnthropicCMEKCrypto` 명령문을 사용하고, 각 워크스페이스마다 하나의 컴파트먼트 ID를 지정하세요. 키를 워크스페이스에 연결하기 전에 해당 워크스페이스의 컴파트먼트 ID를 추가하세요. 새 워크스페이스의 경우 키 없이 생성하고, 컴파트먼트 ID를 추가한 다음 키를 연결하세요.

      ```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>"]
          }
        }
      }
      ```
    </Note>

    ```bash
    aws kms create-key \
      --region <REGION> \
      --description "Anthropic CMEK" \
      --key-usage ENCRYPT_DECRYPT \
      --policy file://key-policy.json
    ```

    출력에서 `KeyMetadata.Arn`을 캡처하세요. 다음 단계에서 키를 등록할 때 필요합니다.

    <Warning>
      키가 이미 CMEK용으로 구성되어 있고 기존 데이터를 보호하는 경우, 앞의 정책에 있는 세 가지 명령문 외에 Anthropic이 해당 데이터를 복호화할 수 있도록 하는 명령문을 추가해야 합니다. 해당 조건에 키가 연결되어 있거나 연결되었던 모든 워크스페이스의 컴파트먼트 ID를 나열하세요.

      ```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>"]
          }
        }
      }
      ```
    </Warning>

    Anthropic은 키를 검증하거나 워크스페이스에 연결할 때 키를 검증합니다. 각 검증은 CloudTrail에 네 개의 액세스 거부 오류를 추가합니다. 이는 예상된 것입니다. 이를 필터링해야 하는 경우 다음 세 가지 값 모두에 대해 필터링하세요. 첫 번째 값만으로는 충분하지 않은데, 어떤 호출자든 이를 설정할 수 있기 때문입니다:

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

    <Note>
      **컴파트먼트 ID 찾기:** **Register the key with Anthropic** 아래의 **Claude Platform** 탭을 참조하세요.
    </Note>

    AWS Console에서도 키를 생성할 수 있습니다. 암호화 및 복호화 키 사용이 있는 대칭 키, 단일 리전 키, KMS 키 자료 원본을 선택하세요. 키 생성 마법사는 **Review** 단계에서 키 정책을 커밋합니다: 거기서 키 사용 권한 아래에 Anthropic의 계정 ID `915198916910`을 추가하면, 생성된 정책이 `EncryptionContext` 조건 없이 전체 Anthropic 계정에 더 광범위한 작업(예: `kms:ReEncrypt*` 및 `kms:GenerateDataKey*`)을 부여하며, 검증이 이를 거부합니다. 과도하게 허용된 키를 남기지 않으려면 관리 권한만으로 마법사를 완료한 다음, 키의 **Key policy** 탭을 열고 JSON을 이 단계의 앞부분에 표시된 `key-policy.json` 정책으로 바꾸세요.

    <Frame caption="키 구성(Configure key): 대칭, 암호화 및 복호화, 단일 리전 키.">
      ![대칭 키 유형, 암호화 및 복호화 키 사용, 단일 리전 키가 선택된 AWS KMS 키 생성 마법사의 키 구성(Configure key) 단계.](https://platform.claude.com/docs/images/cmek/aws-configure-key.png)
    </Frame>

    <Frame caption="키에 대한 별칭(alias)과 설명을 추가합니다.">
      ![별칭이 anthropic-cmek이고 설명이 Anthropic CMEK인 AWS KMS 레이블 추가(Add labels) 단계.](https://platform.claude.com/docs/images/cmek/aws-add-labels.png)
    </Frame>

    <Frame caption="키 관리 권한(key administrative permissions)을 정의합니다(선택 사항). 계정이 전체 관리자 제어 권한을 유지합니다.">
      ![키를 관리할 수 있는 IAM 역할이 나열된 AWS KMS 키 관리 권한 정의(Define key administrative permissions) 단계.](https://platform.claude.com/docs/images/cmek/aws-admin-permissions.png)
    </Frame>

    <Frame caption="여기에 Anthropic의 계정 ID를 추가하지 마세요. 이 마법사 단계는 과도하게 허용된 정책을 생성합니다. 사용 권한(usage permissions)을 비워두고 생성 후 Key policy JSON을 편집하세요(앞의 키 정책 참조).">
      ![다른 AWS 계정(Other AWS accounts) 아래에 Anthropic의 계정 ID가 입력된 AWS KMS 키 사용 권한 정의(Define key usage permissions) 단계.](https://platform.claude.com/docs/images/cmek/aws-usage-permissions.png)
    </Frame>
  </Step>
</Steps>

## Anthropic에 키 등록

키를 등록하는 방법은 사용하는 제품에 따라 다릅니다.

<Tabs>
  <Tab title="Claude Platform">
    <Note>
      **Claude Platform on AWS:** 주체, 키 정책 및 등록 흐름이 다르며, 별도의 검증 단계가 없습니다. 이 탭 대신 [Claude Platform on AWS에서 CMEK 설정](https://platform.claude.com/docs/ko/manage-claude/cmek-aws-kms#claude-platform-on-aws)을 따르세요.
    </Note>

    <Note>
      **컴파트먼트 ID 찾기:** 각 워크스페이스에는 CMEK 데이터의 범위를 지정하는 컴파트먼트 ID가 있습니다. Claude Console에서 찾으려면 [Data retention](https://platform.claude.com/settings/privacy) 페이지(`platform.claude.com/settings/privacy`)로 이동하여 페이지 상단의 드롭다운 메뉴에서 워크스페이스를 선택하세요. ID는 **Encryption key** 아래의 **Compartment ID** 필드에 있습니다. [Get Workspace](https://platform.claude.com/docs/ko/api/organization/workspaces/retrieve) 엔드포인트가 반환하는 `compartment_id` 필드를 읽을 수도 있습니다.
    </Note>

    Claude Console에서 또는 Admin API를 통해 키를 설정할 수 있으며, 결과는 동일합니다.

    <Tabs>
      <Tab title="Claude Console">
        <Steps>
          <Step title="Anthropic에 키 등록">
            Claude Console에서 [Data retention](https://platform.claude.com/settings/privacy#encryption-keys) 페이지(`platform.claude.com/settings/privacy`)로 이동하세요. **Encryption keys**가 보이지 않으면 페이지 상단의 드롭다운 메뉴에서 **Organization**을 선택하세요. **Encryption keys** 아래에서 **Add key**를 클릭하세요. 표시 이름을 입력하고 **AWS KMS**를 선택한 다음 **Continue**를 클릭하세요. **KMS key ARN**에 키 ARN을 붙여넣고 **Add**를 클릭하세요.

            키 세부 정보 단계에 조직 ID가 표시됩니다. **Add**를 클릭하기 전에 [키 정책](https://platform.claude.com/docs/ko/manage-claude/cmek-aws-kms#key-policy)에 추가하세요.
          </Step>

          <Step title="키 검증">
            **Encryption keys** 목록에서 키 옆의 **Verify**를 클릭하세요. 검사가 통과하면 **Connected**가 표시됩니다. 실패하면 메시지에 그 이유가 표시됩니다.
          </Step>

          <Step title="워크스페이스에 키 연결">
            Claude Console에서 [Data retention](https://platform.claude.com/settings/privacy) 페이지(`platform.claude.com/settings/privacy`)로 이동하여 페이지 상단의 드롭다운 메뉴에서 워크스페이스를 선택하세요. **Encryption key** 아래에서 키를 선택하고 **Save**를 클릭한 다음 확인하세요. 키 연결은 취소할 수 없습니다. 이미 요청을 받고 있는 워크스페이스의 경우 키가 [적용되기까지 최대 하루](https://platform.claude.com/docs/ko/manage-claude/cmek#how-it-works)가 걸릴 수 있습니다.
          </Step>
        </Steps>
      </Tab>

      <Tab title="API">
        <Steps>
          <Step title="Anthropic에 키 등록">
            Admin API를 통해 외부 키 구성을 생성하세요.

            <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>

            응답에는 외부 키 ID가 포함됩니다:

            ```json
            {
              "type": "external_key",
              "id": "ekey_<id>",
              "display_name": "<friendly-name>"
            }
            ```
          </Step>

          <Step title="키 검증">
            키에 대해 암호화 및 복호화 왕복을 트리거하세요.

            <CodeGroup>
              ```bash cURL
              curl -sS -X POST "https://api.anthropic.com/v1/organizations/external_keys/ekey_<id>/validate" \
                -H "x-api-key: $ANTHROPIC_API_KEY" \
                -H "anthropic-version: 2023-06-01"
              ```

              ```bash CLI
              ant organization:external-keys validate --external-key-id "ekey_<id>"
              ```

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

              validation = client.organization.external_keys.validate("ekey_<id>")

              print(f"status: {validation.status}")
              print(f"error: {validation.error}")
              ```

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

              const validation = await client.organization.externalKeys.validate("ekey_<id>");

              console.log(`status: ${validation.status}`);
              console.log(`error: ${validation.error}`);
              ```

              ```csharp C#
              AnthropicClient client = new();

              var validation = await client.Organization.ExternalKeys.Validate("ekey_<id>");

              Console.WriteLine($"status: {validation.Status.Raw()}");
              Console.WriteLine($"error: {validation.Error}");
              ```

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

              validation, err := client.Organization.ExternalKeys.Validate(context.Background(), "ekey_<id>")
              if err != nil {
              	log.Fatal(err)
              }

              fmt.Printf("status: %s\n", validation.Status)
              fmt.Printf("error: %s\n", validation.Error)
              ```

              ```java Java
              AnthropicClient client = AnthropicOkHttpClient.fromEnv();

              var validation = client.organization().externalKeys().validate("ekey_<id>");

              IO.println("status: " + validation.status().asString());
              IO.println("error: " + validation.error().orElse(""));
              ```

              ```php PHP
              $client = new Client();

              $validation = $client->organization->externalKeys->validate(
                  externalKeyID: 'ekey_<id>',
              );

              echo "status: {$validation->status}\n";
              echo "error: {$validation->error}\n";
              ```

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

              external_key_id = "ekey_<id>"
              validation = client.organization.external_keys.validate(external_key_id)

              puts "status: #{validation.status}"
              puts "error: #{validation.error}"
              ```
            </CodeGroup>

            성공적인 응답은 다음과 같습니다:

            ```json
            { "type": "external_key_validation", "status": "success", "error": null }
            ```

            검증이 실패하는 경우 일반적인 원인은 다음과 같습니다:

            * **암호화 컨텍스트 불일치:** 정책에 `kms:EncryptionContext:anthropic:compartment_uuid` 조건이 있는 경우, 키가 연결된 각 워크스페이스의 컴파트먼트 ID를 나열하는지 확인하세요. 검증은 검사하는 워크스페이스의 컴파트먼트 ID를 전송합니다. 컴파트먼트 명령문이 여전히 `kms:Encrypt`를 허용하는 이전 키는 연결되지 않은 동안 모두 0인 값(`00000000-0000-0000-0000-000000000000`)으로 검증되므로, 해당 값을 목록에 유지하세요.
            * **리소스 제어 정책(RCP):** AWS 조직에 `aws:PrincipalOrgID`가 조직과 일치하지 않을 때 KMS 작업을 거부하는 RCP가 있는 경우, Anthropic의 교차 계정 역할을 차단합니다. RCP에는 이 키 또는 Anthropic의 역할 ARN에 대한 예외가 필요합니다. 서비스 제어 정책은 리소스 기반 정책을 통해 호출하는 외부 주체에 대해 평가하지 않으므로 여기에 적용되지 않습니다.
            * **키 정책 대신 IAM을 통해 부여된 액세스:** 교차 계정 KMS 액세스는 계정의 IAM 정책이 아닌 키 정책 자체에서 부여해야 합니다. `aws kms get-key-policy --key-id <id> --policy-name default`로 확인하세요.
            * **리전 불일치:** 키의 리전이 구성한 지리적 계층에 대해 Anthropic이 운영하는 리전 중 하나인지 확인하세요.
          </Step>

          <Step title="워크스페이스에 키 연결">
            키가 검증되면 해당 워크스페이스에 요청을 보내기 전에 새 워크스페이스에 연결하세요. 이미 요청을 받고 있는 워크스페이스의 경우 키가 [적용되는 데 최대 하루가 걸릴 수 있습니다](https://platform.claude.com/docs/ko/manage-claude/cmek#how-it-works).

            <CodeGroup>
              ```bash cURL
              curl -sS -X POST "https://api.anthropic.com/v1/organizations/workspaces/<workspace-id>" \
                -H "x-api-key: $ANTHROPIC_API_KEY" \
                -H "anthropic-version: 2023-06-01" \
                -H "content-type: application/json" \
                -d '{
                  "external_key_id": "ekey_<id>"
                }'
              ```

              ```bash CLI
              ant organization:workspaces update \
                --workspace-id "<workspace-id>" \
                --external-key-id "ekey_<id>"
              ```

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

              workspace = client.organization.workspaces.update(
                  "<workspace-id>", external_key_id="ekey_<id>"
              )

              print(f"id: {workspace.id}")
              print(f"external_key_id: {workspace.external_key_id}")
              ```

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

              const workspace = await client.organization.workspaces.update("<workspace-id>", {
                external_key_id: "ekey_<id>"
              });

              console.log(`id: ${workspace.id}`);
              console.log(`external_key_id: ${workspace.external_key_id}`);
              ```

              ```csharp C#
              AnthropicClient client = new();

              var workspace = await client.Organization.Workspaces.Update("<workspace-id>", new()
              {
                  ExternalKeyID = "ekey_<id>"
              });

              Console.WriteLine($"id: {workspace.ID}");
              Console.WriteLine($"external_key_id: {workspace.ExternalKeyID}");
              ```

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

              workspace, err := client.Organization.Workspaces.Update(
              	context.Background(),
              	"<workspace-id>",
              	anthropic.OrganizationWorkspaceUpdateParams{
              		ExternalKeyID: anthropic.String("ekey_<id>"),
              	},
              )
              if err != nil {
              	log.Fatal(err)
              }

              fmt.Printf("id: %s\n", workspace.ID)
              fmt.Printf("external_key_id: %s\n", workspace.ExternalKeyID)
              ```

              ```java Java
              import com.anthropic.models.organization.workspaces.WorkspaceUpdateParams;

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

                  var params = WorkspaceUpdateParams.builder()
                      .externalKeyId("ekey_<id>")
                      .build();
                  var workspace = client.organization().workspaces().update("<workspace-id>", params);

                  IO.println("id: " + workspace.id());
                  IO.println("external_key_id: " + workspace.externalKeyId().orElseThrow());
              }
              ```

              ```php PHP
              $client = new Client();

              $workspace = $client->organization->workspaces->update(
                  workspaceID: '<workspace-id>',
                  externalKeyID: 'ekey_<id>',
              );

              echo "id: {$workspace->id}\n";
              echo "external_key_id: {$workspace->externalKeyID}\n";
              ```

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

              workspace_id = "<workspace-id>"
              workspace = client.organization.workspaces.update(
                workspace_id,
                external_key_id: "ekey_<id>"
              )

              puts "id: #{workspace.id}"
              puts "external_key_id: #{workspace.external_key_id}"
              ```
            </CodeGroup>
          </Step>
        </Steps>
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Claude Enterprise">
    [claude.ai > Organization settings > Data and privacy](https://claude.ai/admin-settings/data-privacy-controls)에서 **Encryption keys**를 연 다음 **Add key**를 클릭하세요. **AWS**를 선택하고 **Continue**를 클릭한 다음, 이전 단계의 Key ARN을 붙여넣고 **Add**를 클릭하세요. Anthropic은 암호화 및 복호화 왕복으로 키를 검증합니다. 검증됨으로 표시되면 해당 시점부터 조직이 CMEK로 보호됩니다.

    이 흐름의 키 세부 정보 단계에는 복사 버튼과 함께 **키 정책을 위한 Organization ID**가 표시됩니다. 키 정책에서 `<ORGANIZATION_UUID>`를 해당 값으로 대체하세요. 키를 생성하기 전에 흐름을 열어 ID를 복사할 수 있습니다.

    Claude Enterprise에서는 CMEK가 전체 조직에 적용되므로 별도의 워크스페이스 연결 단계가 없으며, 조직은 하나의 키만 가질 수 있습니다.
  </Tab>
</Tabs>

## Claude Platform on AWS에서 CMEK 설정

[Claude Platform on AWS](https://platform.claude.com/docs/ko/build-with-claude/claude-platform-on-aws)에서 CMEK는 AWS KMS 키만 사용하며, 설정은 다음과 같은 방식으로 앞의 섹션과 다릅니다:

* **주체:** 키 정책이 AWS 서비스 주체 `aws-external-anthropic.amazonaws.com`에 액세스 권한을 부여합니다. Anthropic의 IAM 역할과 계정 ID는 사용되지 않으므로 [Anthropic을 위한 ARN](https://platform.claude.com/docs/ko/manage-claude/cmek-aws-kms#amazon-resource-name-arn-for-anthropic)은 적용되지 않습니다.
* **키 요구 사항:** 키는 암호화 및 복호화 사용이 있는 대칭 KMS 키여야 하며, 단일 리전이어야 하고, 연결하는 워크스페이스와 동일한 AWS 계정 및 리전에 있어야 합니다. 교차 계정 키는 지원되지 않습니다: 키는 조직을 호스팅하는 AWS 계정에 있어야 합니다. 다중 리전 키(`mrk-`로 시작하는 키 ID)와 별칭 ARN은 키를 등록할 때 거부됩니다; 키 ARN을 사용하세요.
* **별도의 검증 단계 없음:** 등록 시 키 ARN에 대한 이러한 검사 외에, 키는 워크스페이스에 연결할 때 검증됩니다. 연결 호출은 해당 워크스페이스의 컴파트먼트 ID를 암호화 컨텍스트로 사용하여 키에 대해 암호화/복호화 왕복을 수행하므로, 키 정책 문제가 등록 시가 아닌 연결 시에 나타납니다. 따라서 `EncryptionContext` 조건에는 모두 0인 항목이 필요하지 않습니다.
* **키 관리 위치:** Admin 역할로 AWS를 통해 로그인하여 Claude Console에서 키를 등록하고 연결하세요. 외부 키 엔드포인트는 [IAM 작업](https://platform.claude.com/docs/ko/api/claude-platform-on-aws-iam-actions#encryption-keys)을 통해 승인되어 Claude Platform on AWS에서도 사용할 수 있습니다; 거기서 키는 `ekey_` ID가 아닌 KMS 키 ARN으로 식별됩니다.

<Warning>
  이 게시된 서비스 주체 이름만 사용하세요. 이메일, 채팅 또는 온보딩 채널을 통해 제공된 식별자는 절대 신뢰하지 마세요.
</Warning>

### 사전 요구 사항

* KMS 키를 생성하고 키 정책을 설정할 수 있는 권한(`kms:CreateKey` 및 `kms:PutKeyPolicy`)이 있는, Claude Platform on AWS 조직을 호스팅하는 AWS 계정.
* Claude Platform on AWS용 Claude Console의 **Admin** 역할. [Claude Console 사용하기](https://platform.claude.com/docs/ko/build-with-claude/claude-platform-on-aws#using-the-claude-console)를 참조하세요.
* Claude Console에 로그인하는 IAM 주체의 경우: 키 등록, 나열, 연결은 AWS 게이트웨이를 거치므로 `aws-external-anthropic:AssumeConsole` 외에 그곳에서 수행하는 작업에 대한 [IAM 작업](https://platform.claude.com/docs/ko/api/claude-platform-on-aws-iam-actions#encryption-keys)이 필요합니다. 키 등록은 `RegisterKey`(등록 내역을 보려면 `ListKeys` 및 `GetKey` 포함)이고, 키 연결은 `UpdateWorkspace` 또는 `CreateWorkspace`입니다. 외부 키 작업(및 `CreateWorkspace`)은 계정 범위이므로 `Resource: "*"`에 대해 부여하세요. 워크스페이스 ARN으로 제한된 정책에는 이러한 작업이 포함되지 않습니다.
* 키를 워크스페이스에 연결하는 IAM 주체(Claude Console에 로그인한 ID)의 경우: 키에 대한 `kms:DescribeKey`, `kms:Encrypt`, `kms:Decrypt`. 키에 대한 주체의 액세스는 서비스 주체의 액세스 외에 연결할 때 확인됩니다.
* 선택 사항, Claude Console의 키 선택기의 경우: 로그인하는 주체에 대한 `kms:ListKeys` 및 `kms:DescribeKey`. 이것들이 없으면 대신 키 ARN을 붙여넣으세요.

### KMS 키 생성

키 정책에는 세 가지 명령문이 있습니다: 계정의 루트 관리자 명령문, Claude Platform on AWS 서비스 주체가 데이터 키를 암호화, 복호화 및 생성할 수 있도록 하는 명령문, 그리고 `kms:DescribeKey`에 대한 별도의 명령문입니다. 암호화 명령문에는 나열한 워크스페이스에 키를 바인딩하는 선택적 `EncryptionContext` 조건이 포함됩니다. `DescribeKey`에는 `EncryptionContext` 매개변수가 없어 해당 작업에 `EncryptionContext` 조건을 걸면 항상 거부되므로, 별도로 부여됩니다.

여기에 표시된 선택적 `EncryptionContext` 조건을 사용하려면 먼저 워크스페이스를 (키 없이) 생성하고, 컴파트먼트 ID를 복사하여 `<compartment-uuid>`를 대체하세요. Claude Console에서 ID를 찾으려면 [Data retention](https://platform.claude.com/settings/privacy) 페이지(`platform.claude.com/settings/privacy`)로 이동하여 페이지 상단의 드롭다운 메뉴에서 워크스페이스를 선택하세요. ID는 **Encryption key** 아래의 **Compartment ID** 필드에 있습니다. [Get Workspace](https://platform.claude.com/docs/ko/api/organization/workspaces/retrieve) 엔드포인트가 반환하는 `compartment_id` 필드에서 읽을 수도 있습니다. 조건을 사용하지 않으려면 해당 명령문에서 `Condition` 블록을 삭제하세요.

```bash
export YOUR_ACCOUNT=$(aws sts get-caller-identity --query Account --output text)

aws kms create-key \
  --region <workspace-region> \
  --description "Anthropic CMEK (Claude Platform on AWS)" \
  --key-usage ENCRYPT_DECRYPT \
  --policy "{
    \"Version\": \"2012-10-17\",
    \"Statement\": [
      {
        \"Sid\": \"AccountRootAdmin\",
        \"Effect\": \"Allow\",
        \"Principal\": {\"AWS\": \"arn:aws:iam::${YOUR_ACCOUNT}:root\"},
        \"Action\": \"kms:*\",
        \"Resource\": \"*\"
      },
      {
        \"Sid\": \"AllowClaudePlatformOnAWSCrypto\",
        \"Effect\": \"Allow\",
        \"Principal\": {\"Service\": \"aws-external-anthropic.amazonaws.com\"},
        \"Action\": [\"kms:Encrypt\", \"kms:Decrypt\", \"kms:GenerateDataKey\"],
        \"Resource\": \"*\",
        \"Condition\": {
          \"StringEquals\": {
            \"kms:EncryptionContext:anthropic:compartment_uuid\": [
              \"<compartment-uuid>\"
            ]
          }
        }
      },
      {
        \"Sid\": \"AllowClaudePlatformOnAWSDescribe\",
        \"Effect\": \"Allow\",
        \"Principal\": {\"Service\": \"aws-external-anthropic.amazonaws.com\"},
        \"Action\": \"kms:DescribeKey\",
        \"Resource\": \"*\"
      }
    ]
  }"
```

출력에서 `KeyMetadata.Arn`을 캡처하세요. 키를 등록할 때 필요합니다.

`EncryptionContext` 조건은 선택 사항입니다. 연결 시 확인을 포함하여 워크스페이스에 대해 수행되는 모든 암호화, 복호화 및 데이터 키 호출은 해당 워크스페이스의 컴파트먼트 ID를 `anthropic:compartment_uuid`로 전달하므로, 조건에는 키를 연결하는 각 워크스페이스의 컴파트먼트 ID를 나열하며 모두 0인 항목은 필요하지 않습니다. 이 조건을 추가하면 IAM 계층에서도 나열한 워크스페이스에 키가 바인딩됩니다. 컴파트먼트 ID는 워크스페이스가 생성된 후에만 존재하므로, 순서는 다음과 같습니다: 워크스페이스를 생성하고, 해당 컴파트먼트 ID를 조건에 넣은 다음(키 생성 시 또는 나중에 `kms:PutKeyPolicy`로), 키를 연결합니다. 추가 워크스페이스에 키를 연결할 때마다 그 전에 같은 방식으로 해당 워크스페이스의 컴파트먼트 ID를 추가하세요. 조건 없이 시작하려면 `AllowClaudePlatformOnAWSCrypto` 명령문에서 `Condition` 블록을 삭제하세요. 나중에 조건을 추가하는 경우 키가 이미 연결된 모든 워크스페이스의 컴파트먼트 ID를 포함하세요.

`aws:SourceArn` 조건으로 두 서비스 주체 명령문을 추가로 제한할 수 있습니다. 서비스는 키를 사용하는 모든 호출에서 [워크스페이스의 ARN](https://platform.claude.com/docs/ko/api/claude-platform-on-aws-iam-actions#service-details)(`arn:aws:aws-external-anthropic:<region>:<account-id>:workspace/<workspace-id>`)을 소스 ARN으로 전달하므로, `"ArnLike": {"aws:SourceArn": "arn:aws:aws-external-anthropic:*:<account-id>:workspace/*"}`는 권한 부여 범위를 자신의 AWS 계정에 있는 워크스페이스로 제한하고, 전체 워크스페이스 ARN 목록은 해당 워크스페이스로 제한합니다. 이 조건은 필수가 아닙니다. `EncryptionContext` 조건만으로도 나열한 워크스페이스에 키가 바인딩됩니다.

AWS Console에서도 키를 생성할 수 있습니다: 워크스페이스의 리전에서 암호화 및 복호화 키 사용이 있는 대칭 키, 단일 리전 키, KMS 키 자료 원본을 선택하세요. 키 생성 마법사에서 키 사용 권한을 비워둔 다음, 키의 **Key policy** 탭을 열고 JSON을 여기에 표시된 정책으로 바꾸세요.

### 키 등록 및 연결

<Steps>
  <Step title="키 등록">
    Claude Console에서 [Data retention](https://platform.claude.com/settings/privacy#encryption-keys) 페이지(`platform.claude.com/settings/privacy`)로 이동하세요. **Encryption keys**가 보이지 않으면 페이지 상단의 드롭다운 메뉴에서 **Organization**을 선택하세요. **Encryption keys** 아래에서 **Add key**를 클릭하세요. 표시 이름을 입력한 다음, 키 선택기에서 키를 선택하거나 **Enter ARN manually**를 선택하고 키 ARN을 붙여넣은 후 **Add**를 클릭하세요. 키는 조직을 호스팅하는 AWS 계정에 있어야 하며, 교차 계정 키는 지원되지 않습니다. 선택기는 조직의 리전 중 하나에 있는 계정의 활성화된 고객 관리형 대칭 단일 리전 키를 나열합니다. 선택기에 나열되지 않는 키의 경우 ARN을 입력하세요. 선택기는 로그인한 주체가 `kms:ListKeys` 및 `kms:DescribeKey`를 호출할 수 있는 경우에만 키를 나열합니다.
  </Step>

  <Step title="워크스페이스에 키 연결">
    새 워크스페이스에 요청을 보내기 전에 해당 워크스페이스에 키를 연결하세요. 이미 요청을 받고 있는 워크스페이스의 경우 키가 [적용되기까지 최대 하루](https://platform.claude.com/docs/ko/manage-claude/cmek#how-it-works)가 걸릴 수 있습니다. Claude Console에서 [Data retention](https://platform.claude.com/settings/privacy) 페이지(`platform.claude.com/settings/privacy`)로 이동하여 페이지 상단의 드롭다운 메뉴에서 워크스페이스를 선택하세요. **Encryption key** 아래에서 키를 선택하고 **Save**를 클릭한 다음 확인하세요. Claude Console에서 워크스페이스를 생성할 때 키를 선택할 수도 있지만, 워크스페이스의 컴파트먼트 ID는 생성 시 할당되므로 키 정책이 아직 특정 워크스페이스를 지정하지 않은 경우(`EncryptionContext` 조건 없음)에만 가능합니다. 일단 연결되면 워크스페이스의 키는 변경할 수 없습니다.

    이때 키가 검증됩니다: 연결 호출은 키에 대한 주체의 액세스를 확인하고 워크스페이스의 컴파트먼트 ID를 암호화 컨텍스트로 사용하여 키에 대해 암호화/복호화 왕복을 수행하므로, 키 정책 또는 주체의 권한 문제가 해당 호출에서 오류로 나타납니다. 연결이 KMS 액세스 오류로 실패하는 경우 다음을 확인하세요:

    * 키 정책이 `aws-external-anthropic.amazonaws.com` 서비스 주체를 지정하고 `kms:Encrypt`, `kms:Decrypt`, `kms:GenerateDataKey`를 부여하며, `EncryptionContext` 조건이 없는 별도의 명령문에서 `kms:DescribeKey`를 부여합니다.
    * 모든 `EncryptionContext` 조건에 이 워크스페이스의 컴파트먼트 ID가 포함되어 있고, 추가한 모든 `aws:SourceArn` 조건이 이 워크스페이스의 ARN과 일치합니다.
    * 키가 활성화되어 있고, 단일 리전이며, 워크스페이스와 동일한 AWS 계정 및 리전에 있습니다.
    * 로그인한 주체가 키에 대한 `kms:DescribeKey`, `kms:Encrypt`, `kms:Decrypt`를 가지고 있습니다.
    * AWS 조직의 어떤 서비스 제어 정책이나 리소스 제어 정책도 서비스 주체나 주체가 키를 사용하는 것을 막지 않습니다.
    * 정책이 올바른 것 같은데도 연결이 계속 실패하면, 키가 있는 계정의 CloudTrail에서 거부된 `kms:` 이벤트를 찾은 다음(호출 주체와, 암호화 호출의 경우 암호화 컨텍스트가 표시됨), `kms:PutKeyPolicy`로 조건을 수정하고 다시 시도하세요.
  </Step>
</Steps>

## Terraform

코드형 인프라(infrastructure-as-code) 배포의 경우, 동일한 단계가 `aws_kms_key` 및 `aws_kms_alias` 리소스와 함께 `aws` 공급자에 매핑됩니다.
