---
title: 為 CMEK 設定 AWS KMS
url: https://platform.claude.com/docs/zh-TW/manage-claude/cmek-aws-kms
description: 使用 AWS KMS 為您的組織提供加密金鑰。
---

讓 Claude Code 為您設定此功能

```text
/claude-api 協助我使用 AWS KMS 設定客戶管理的加密金鑰
```

本指南將引導您為您的 Anthropic 組織設定一個 [AWS KMS](https://aws.amazon.com/kms/) 金鑰作為[客戶管理的加密金鑰（customer-managed encryption key，CMEK）](https://platform.claude.com/docs/zh-TW/manage-claude/cmek)。

<Warning>
  啟用 CMEK 是永久性的。如果您的 KMS 金鑰被刪除或停用，Anthropic 無法復原在其下加密的資料。在開始之前，請檢閱[警告與限制](https://platform.claude.com/docs/zh-TW/manage-claude/cmek)。
</Warning>

<Note>
  **Claude Platform on AWS：** 在 [Claude Platform on AWS](https://platform.claude.com/docs/zh-TW/build-with-claude/claude-platform-on-aws) 上，您的金鑰政策授予存取權給 AWS 服務主體，而非 Anthropic 的 IAM 角色，沒有單獨的驗證步驟，並且您在 Claude Console 中註冊並附加金鑰。請遵循本頁的[在 Claude Platform on AWS 上設定 CMEK](https://platform.claude.com/docs/zh-TW/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 Resource Name（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/zh-TW/manage-claude/cmek-aws-kms#claude-platform-on-aws) 提供該政策。
    </Note>

    金鑰政策授予 Anthropic 的 IAM 角色跨帳戶存取權。需要三個陳述式：

    1. **帳戶根管理員：** 標準的 KMS 模式。您的帳戶保留完整的管理控制權。
    2. **Anthropic 加密與解密：** `kms:Encrypt` 和 `kms:Decrypt` 動作，Anthropic 使用它們來加密和解密保護您工作區資料的資料金鑰（信封加密）。
    3. **Anthropic 描述：** 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`）上的 **Organization ID** 欄位，或 claude.ai 中 **Organization settings > Organization** 下的該欄位，或從 [Organization Info](https://platform.claude.com/docs/zh-TW/api/organization/retrieve) 端點讀取 `id` 欄位。請使用純 UUID，而非帶有 `org_` 前綴的 ID。
    </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>
      **選用：** 若要將金鑰限制在您的部分工作區，請使用此 `AllowAnthropicCMEKCrypto` 陳述式，而非前述政策 JSON 中的陳述式，每個工作區使用一個隔間 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`，產生的政策會授予整個 Anthropic 帳戶更廣泛的動作（例如 `kms:ReEncrypt*` 和 `kms:GenerateDataKey*`）且沒有 `EncryptionContext` 條件，驗證會拒絕它。為避免留下權限過大的金鑰，請僅以管理權限完成精靈，然後開啟金鑰的 **Key policy** 標籤，並將 JSON 替換為本步驟稍早顯示的 `key-policy.json` 政策。

    <Frame caption="設定金鑰：對稱、加密和解密、單一區域金鑰。">
      ![AWS KMS 建立金鑰精靈的設定金鑰步驟，已選擇對稱金鑰類型、加密和解密金鑰用途，以及單一區域金鑰。](https://platform.claude.com/docs/images/cmek/aws-configure-key.png)
    </Frame>

    <Frame caption="為金鑰新增別名和描述。">
      ![AWS KMS 的新增標籤步驟，別名為 anthropic-cmek，描述為 Anthropic CMEK。](https://platform.claude.com/docs/images/cmek/aws-add-labels.png)
    </Frame>

    <Frame caption="定義金鑰管理權限（選用）。您的帳戶保留完整的管理控制權。">
      ![AWS KMS 的定義金鑰管理權限步驟，列出可管理該金鑰的 IAM 角色。](https://platform.claude.com/docs/images/cmek/aws-admin-permissions.png)
    </Frame>

    <Frame caption="請勿在此處新增 Anthropic 的帳戶 ID。此精靈步驟會產生權限過大的政策。將用途權限留空，並在建立後編輯 Key policy JSON（請參閱前述金鑰政策）。">
      ![AWS KMS 的定義金鑰用途權限步驟，已在其他 AWS 帳戶下輸入 Anthropic 的帳戶 ID。](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/zh-TW/manage-claude/cmek-aws-kms#claude-platform-on-aws)，而非此標籤。
    </Note>

    <Note>
      **尋找您的隔間 ID：** 每個工作區都有一個隔間 ID，用於界定其 CMEK 資料的範圍。若要在 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/zh-TW/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**。將金鑰 ARN 貼到 **KMS key ARN** 中，然後點擊 **Add**。

            金鑰詳細資訊步驟會顯示您的組織 ID。在點擊 **Add** 之前，將其新增到[金鑰政策](https://platform.claude.com/docs/zh-TW/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/zh-TW/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`，在未附加時會以全零值（`00000000-0000-0000-0000-000000000000`）進行驗證，因此請在其清單中保留該值。
            * **資源控制政策（RCP）：** 如果您的 AWS 組織有一個 RCP，當 `aws:PrincipalOrgID` 與您的組織不符時拒絕 KMS 操作，它會封鎖 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/zh-TW/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 for the key policy**，並附有複製按鈕。將該值替換金鑰政策中的 `<ORGANIZATION_UUID>`。您可以在建立金鑰之前開啟流程以複製該 ID。

    在 Claude Enterprise 上，CMEK 適用於整個組織，因此沒有單獨的工作區附加步驟，且一個組織只能有一個金鑰。
  </Tab>
</Tabs>

## 在 Claude Platform on AWS 上設定 CMEK

在 [Claude Platform on AWS](https://platform.claude.com/docs/zh-TW/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/zh-TW/manage-claude/cmek-aws-kms#amazon-resource-name-arn-for-anthropic) 不適用。
* **金鑰要求：** 金鑰必須是具有加密和解密用途的對稱 KMS 金鑰、單一區域，並且與您附加它的工作區位於相同的 AWS 帳戶和區域。不支援跨帳戶金鑰：金鑰必須位於託管您組織的 AWS 帳戶中。多區域金鑰（以 `mrk-` 開頭的金鑰 ID）和別名 ARN 在您註冊金鑰時會被拒絕；請使用金鑰 ARN。
* **沒有單獨的驗證步驟：** 除了註冊時對金鑰 ARN 的那些檢查之外，金鑰在您將其附加到工作區時進行驗證。附加呼叫會以該工作區的隔間 ID 作為加密上下文，對金鑰執行加密/解密往返，因此金鑰政策問題會在附加時而非註冊時浮現。因此 `EncryptionContext` 條件不需要全零項目。
* **您在何處管理金鑰：** 在 Claude Console 中註冊並附加金鑰，透過 AWS 以 Admin 角色登入。外部金鑰端點在 Claude Platform on AWS 上也可用，透過 [IAM 動作](https://platform.claude.com/docs/zh-TW/api/claude-platform-on-aws-iam-actions#encryption-keys)授權；在那裡，金鑰由其 KMS 金鑰 ARN 而非 `ekey_` ID 識別。

<Warning>
  僅使用此已發布的服務主體名稱。切勿信任透過電子郵件、聊天或任何入門管道提供的識別碼。
</Warning>

### 先決條件

* 託管您 Claude Platform on AWS 組織的 AWS 帳戶，具有建立 KMS 金鑰和設定金鑰政策的權限（`kms:CreateKey` 和 `kms:PutKeyPolicy`）。
* Claude Platform on AWS 的 Claude Console 中的 **Admin** 角色。請參閱[使用 Claude Console](https://platform.claude.com/docs/zh-TW/build-with-claude/claude-platform-on-aws#using-the-claude-console)。
* 對於您用來登入 Claude Console 的 IAM 主體：除了 `aws-external-anthropic:AssumeConsole` 之外，還需要您在該處執行之操作的 [IAM 動作](https://platform.claude.com/docs/zh-TW/api/claude-platform-on-aws-iam-actions#encryption-keys)，因為註冊、列出和附加金鑰都會經過 AWS 閘道。註冊金鑰需要 `RegisterKey`（並需要 `ListKeys` 和 `GetKey` 以檢視註冊項目），附加金鑰則需要 `UpdateWorkspace` 或 `CreateWorkspace`。外部金鑰動作（以及 `CreateWorkspace`）屬於帳戶範圍，因此請在 `Resource: "*"` 上授予；僅限於工作區 ARN 的政策不包含這些動作。
* 對於將金鑰附加到工作區的 IAM 主體（您登入 Claude Console 所用的身分）：金鑰上的 `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/zh-TW/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` 條件是選用的。為工作區進行的每次加密、解密和資料金鑰呼叫（包括附加時的檢查）都會以 `anthropic:compartment_uuid` 帶入該工作區的隔間 ID，因此該條件需列出您將金鑰附加到的每個工作區的隔間 ID，且不需要全零項目。新增此條件也會在 IAM 層將金鑰綁定至您列出的工作區。由於隔間 ID 只有在其工作區存在後才會存在，因此順序為：建立工作區，將其隔間 ID 放入條件中（在建立金鑰時，或稍後使用 `kms:PutKeyPolicy`），然後附加金鑰。在將金鑰附加到每個額外的工作區之前，請以相同方式新增該工作區的隔間 ID。若要在不使用此條件的情況下開始，請從 `AllowClaudePlatformOnAWSCrypto` 陳述式中刪除 `Condition` 區塊；如果您稍後再新增此條件，請包含金鑰已附加到的每個工作區的隔間 ID。

您可以使用 `aws:SourceArn` 條件進一步限制兩個服務主體陳述式。服務在使用您的金鑰進行的每次呼叫中，都會將[工作區的 ARN](https://platform.claude.com/docs/zh-TW/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/zh-TW/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 中建立工作區時選取金鑰，但前提是您的金鑰政策尚未指定特定工作區（沒有 `EncryptionContext` 條件），因為工作區的隔間 ID 是在建立時指派的。附加後，工作區的金鑰便無法變更。

    這是金鑰驗證的時機：附加呼叫會檢查您主體對金鑰的存取權，並以工作區的隔間 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

對於基礎設施即程式碼部署，相同的步驟對應到具有 `aws_kms_key` 和 `aws_kms_alias` 資源的 `aws` 提供者。
