---
title: Configurar AWS KMS para CMEK
url: https://platform.claude.com/docs/es/manage-claude/cmek-aws-kms
description: Usa AWS KMS para proporcionar una clave de cifrado para tu organización.
---

Deja que Claude Code configure esta función por ti

```text
/claude-api ayúdame a configurar una clave de cifrado administrada por el cliente con AWS KMS
```

Esta guía explica cómo configurar una clave de [AWS KMS](https://aws.amazon.com/kms/) como una [clave de cifrado administrada por el cliente (CMEK)](https://platform.claude.com/docs/es/manage-claude/cmek) para tu organización de Anthropic.

<Warning>
  Habilitar CMEK es permanente. Si tu clave de KMS se elimina o deshabilita, Anthropic no puede recuperar los datos cifrados con ella. Revisa las [advertencias y limitaciones](https://platform.claude.com/docs/es/manage-claude/cmek) antes de comenzar.
</Warning>

<Note>
  **Claude Platform on AWS:** En [Claude Platform on AWS](https://platform.claude.com/docs/es/build-with-claude/claude-platform-on-aws), tu política de clave otorga acceso a un principal de servicio de AWS en lugar del rol de IAM de Anthropic, no hay un paso de validación separado, y registras y adjuntas la clave en la Claude Console. Sigue [Configurar CMEK en Claude Platform on AWS](https://platform.claude.com/docs/es/manage-claude/cmek-aws-kms#claude-platform-on-aws) en esta página en lugar de los pasos de las siguientes secciones.
</Note>

## Requisitos previos

* Una cuenta de AWS con permisos para crear claves de KMS y establecer políticas de clave (`kms:CreateKey` y `kms:PutKeyPolicy`).
* Una clave de API de administrador de Anthropic para tu organización.
* La [AWS CLI](https://aws.amazon.com/cli/) instalada y autenticada.

## Amazon Resource Name (ARN) para Anthropic

Para que Anthropic use tu clave de cifrado, debes darle al rol de IAM de Anthropic una clave de KMS que pueda usar para cifrar datos. El ARN para CMEK de Anthropic es:

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

<Warning>
  Usa únicamente este ARN publicado. Nunca confíes en un identificador proporcionado por correo electrónico, chat o cualquier canal de incorporación.
</Warning>

## Configuración de la clave de cifrado

<Steps>
  <Step title="Crear la clave de KMS con una política de clave entre cuentas">
    <Note>
      **Claude Platform on AWS:** Omite este paso. Tu política de clave otorga acceso a un principal de servicio de AWS, y no tiene condición de organización. [Configurar CMEK en Claude Platform on AWS](https://platform.claude.com/docs/es/manage-claude/cmek-aws-kms#claude-platform-on-aws) proporciona esa política.
    </Note>

    La política de clave otorga al rol de IAM de Anthropic acceso entre cuentas. Se requieren tres declaraciones:

    1. **Administrador raíz de la cuenta:** el patrón estándar de KMS. Tu cuenta conserva el control administrativo completo.
    2. **Cifrar y descifrar de Anthropic:** las acciones `kms:Encrypt` y `kms:Decrypt`, que Anthropic usa para cifrar y descifrar las claves de datos que protegen los datos de tu workspace (cifrado de sobre).
    3. **Describir de Anthropic:** la lectura de metadatos que Anthropic realiza al inicio. Se otorga por separado porque `DescribeKey` no tiene un parámetro `EncryptionContext`, por lo que una condición `EncryptionContext` en esta acción siempre denegaría.

    Para encontrar [tu ID de cuenta de AWS](https://docs.aws.amazon.com/IAM/latest/UserGuide/console-account-id.html), ejecuta `aws sts get-caller-identity --query Account --output text`.

    En la política, reemplaza `<AWS_ACCOUNT_ID>` con tu ID de cuenta de AWS y `<ORGANIZATION_UUID>` con tu ID de organización. La condición `StringEquals` en `kms:EncryptionContext:anthropic:org_uuid` vincula la clave a tu organización de Anthropic, y la validación rechaza una clave sin ella. Para compartir una clave entre varias organizaciones de Anthropic, enumera cada ID de organización en el valor de la condición.

    <Note>
      **Encontrar el ID de tu organización:** Copia el campo **Organization ID** en la página [Organization](https://platform.claude.com/settings/organization) (`platform.claude.com/settings/organization`) en la Claude Console, o en **Organization settings > Organization** en claude.ai, o lee el campo `id` del endpoint [Organization Info](https://platform.claude.com/docs/es/api/organization/retrieve). Usa el UUID sin prefijo, no el ID con el prefijo `org_`.
    </Note>

    Guarda la política como `key-policy.json`. Para crear la clave en la AWS Console en su lugar, pega la política allí, como se describe más adelante en este paso.

    ```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>
      **Opcional:** Para limitar la clave a algunos de tus workspaces, usa esta declaración `AllowAnthropicCMEKCrypto` en lugar de la de la política JSON anterior, con un ID de compartimento para cada workspace. Agrega el ID de compartimento de un workspace antes de adjuntarle la clave. Para un nuevo workspace, créalo sin la clave, agrega su ID de compartimento y luego adjunta la clave.

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

    Captura `KeyMetadata.Arn` de la salida. Lo necesitas cuando registres la clave en el siguiente paso.

    <Warning>
      Si la clave ya está configurada para CMEK y protege datos existentes, debes agregar una declaración que permita a Anthropic descifrar esos datos, además de las tres declaraciones de la política anterior. En su condición, enumera el ID de compartimento de cada workspace al que la clave está o estuvo adjunta.

      ```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 valida la clave cuando la verificas o la adjuntas a un workspace. Cada validación agrega cuatro errores de acceso denegado a CloudTrail. Estos son esperados. Si necesitas filtrarlos, filtra por los tres valores siguientes. El primero por sí solo no es suficiente, porque cualquier llamante puede establecerlo:

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

    <Note>
      **Encontrar tu ID de compartimento:** Consulta la pestaña **Claude Platform** en **Registrar la clave con Anthropic**.
    </Note>

    También puedes crear la clave desde la AWS Console. Elige una clave simétrica con el uso de clave de cifrar y descifrar, una clave de región única y origen de material de clave de KMS. El asistente de creación de clave confirma una política de clave en su paso **Review**: Si agregas el ID de cuenta de Anthropic `915198916910` bajo los permisos de uso de clave allí, la política generada otorga a toda la cuenta de Anthropic acciones más amplias (como `kms:ReEncrypt*` y `kms:GenerateDataKey*`) sin condición `EncryptionContext`, y la validación la rechaza. Para evitar dejar una clave con permisos excesivos, finaliza el asistente solo con permisos administrativos, luego abre la pestaña **Key policy** de la clave y reemplaza el JSON con la política `key-policy.json` mostrada anteriormente en este paso.

    <Frame caption="Configurar clave: simétrica, cifrar y descifrar, clave de región única.">
      ![Asistente de creación de clave de AWS KMS en el paso Configurar clave, con estas opciones seleccionadas: tipo de clave simétrica, uso de clave de cifrar y descifrar y clave de región única.](https://platform.claude.com/docs/images/cmek/aws-configure-key.png)
    </Frame>

    <Frame caption="Agregar un alias y una descripción para la clave.">
      ![Paso Agregar etiquetas de AWS KMS con el alias anthropic-cmek y la descripción Anthropic CMEK.](https://platform.claude.com/docs/images/cmek/aws-add-labels.png)
    </Frame>

    <Frame caption="Definir permisos administrativos de clave (opcional). Tu cuenta conserva el control administrativo completo.">
      ![Paso Definir permisos administrativos de clave de AWS KMS, que enumera los roles de IAM que pueden administrar la clave.](https://platform.claude.com/docs/images/cmek/aws-admin-permissions.png)
    </Frame>

    <Frame caption="No agregues el ID de cuenta de Anthropic aquí. Este paso del asistente produce una política con permisos excesivos. Deja los permisos de uso vacíos y edita el JSON de Key policy después de la creación (consulta la política de clave anterior).">
      ![Paso Definir permisos de uso de clave de AWS KMS con el ID de cuenta de Anthropic ingresado en la sección Otras cuentas de AWS.](https://platform.claude.com/docs/images/cmek/aws-usage-permissions.png)
    </Frame>
  </Step>
</Steps>

## Registrar la clave con Anthropic

La forma en que registras la clave depende del producto que uses.

<Tabs>
  <Tab title="Claude Platform">
    <Note>
      **Claude Platform on AWS:** El principal, la política de clave y el flujo de registro difieren, y no hay un paso de validación separado. Sigue [Configurar CMEK en Claude Platform on AWS](https://platform.claude.com/docs/es/manage-claude/cmek-aws-kms#claude-platform-on-aws) en lugar de esta pestaña.
    </Note>

    <Note>
      **Encontrar tu ID de compartimento:** Cada workspace tiene un ID de compartimento que delimita sus datos de CMEK. Para encontrarlo en la Claude Console, ve a la página [Data retention](https://platform.claude.com/settings/privacy) (`platform.claude.com/settings/privacy`) y selecciona el workspace en el menú desplegable en la parte superior de la página. El ID está en **Encryption key**, en el campo **Compartment ID**. También puedes leer el campo `compartment_id` devuelto por el endpoint [Get Workspace](https://platform.claude.com/docs/es/api/organization/workspaces/retrieve).
    </Note>

    Puedes configurar la clave en la Claude Console o a través de la Admin API, con el mismo resultado.

    <Tabs>
      <Tab title="Claude Console">
        <Steps>
          <Step title="Registrar la clave con Anthropic">
            En la Claude Console, ve a la página [Data retention](https://platform.claude.com/settings/privacy#encryption-keys) (`platform.claude.com/settings/privacy`). Si no ves **Encryption keys**, selecciona **Organization** en el menú desplegable en la parte superior de la página. En **Encryption keys**, haz clic en **Add key**. Ingresa un nombre para mostrar, elige **AWS KMS** y haz clic en **Continue**. Pega el ARN de la clave en **KMS key ARN** y haz clic en **Add**.

            El paso de detalles de la clave muestra tu ID de organización. Agrégalo a la [política de clave](https://platform.claude.com/docs/es/manage-claude/cmek-aws-kms#key-policy) antes de hacer clic en **Add**.
          </Step>

          <Step title="Validar la clave">
            En la lista **Encryption keys**, haz clic en **Verify** junto a la clave. Aparece **Connected** cuando la verificación se completa correctamente. Si falla, un mensaje indica el motivo.
          </Step>

          <Step title="Adjuntar la clave a un workspace">
            En la Claude Console, ve a la página [Data retention](https://platform.claude.com/settings/privacy) (`platform.claude.com/settings/privacy`) y selecciona el workspace en el menú desplegable en la parte superior de la página. En **Encryption key**, selecciona la clave, haz clic en **Save** y confirma. Adjuntar una clave no se puede deshacer. Para un workspace que ya recibe solicitudes, la clave puede tardar [hasta un día en surtir efecto](https://platform.claude.com/docs/es/manage-claude/cmek#how-it-works).
          </Step>
        </Steps>
      </Tab>

      <Tab title="API">
        <Steps>
          <Step title="Registrar la clave con Anthropic">
            Crea una configuración de clave externa a través de la 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>

            La respuesta contiene el ID de la clave externa:

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

          <Step title="Validar la clave">
            Activa un ciclo de cifrado y descifrado contra tu clave.

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

            Una respuesta exitosa se ve así:

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

            Si la validación falla, las causas comunes son:

            * **Discrepancia de contexto de cifrado:** Si la política tiene una condición `kms:EncryptionContext:anthropic:compartment_uuid`, asegúrate de que enumere el ID de compartimento de cada workspace al que la clave está adjunta. La validación envía el ID de compartimento del workspace que verifica. Una clave más antigua cuya declaración de compartimento todavía permite `kms:Encrypt` se valida con el valor de todos ceros (`00000000-0000-0000-0000-000000000000`) mientras no está adjunta, así que mantén ese valor en su lista.
            * **Políticas de control de recursos (RCP):** Si tu organización de AWS tiene una RCP que deniega operaciones de KMS cuando `aws:PrincipalOrgID` no coincide con tu organización, bloquea el rol entre cuentas de Anthropic. La RCP necesita una excepción para esta clave o para el ARN del rol de Anthropic. Las políticas de control de servicio no se aplican aquí, porque no se evalúan para principales externos que llaman a través de políticas basadas en recursos.
            * **Acceso otorgado a través de IAM en lugar de la política de clave:** El acceso de KMS entre cuentas debe otorgarse en la propia política de clave, no a través de una política de IAM en tu cuenta. Verifica con `aws kms get-key-policy --key-id <id> --policy-name default`.
            * **Discrepancia de región:** Confirma que la región de la clave sea una en la que Anthropic opera para el nivel geográfico que configuraste.
          </Step>

          <Step title="Adjuntar la clave a un workspace">
            Una vez que la clave esté validada, adjúntala a un nuevo workspace antes de enviar cualquier solicitud a ese workspace. Para un workspace que ya recibe solicitudes, la clave puede tardar [hasta un día en surtir efecto](https://platform.claude.com/docs/es/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">
    En [claude.ai > Organization settings > Data and privacy](https://claude.ai/admin-settings/data-privacy-controls), abre **Encryption keys**, luego haz clic en **Add key**. Elige **AWS** y haz clic en **Continue**, luego pega el ARN de la clave del paso anterior y haz clic en **Add**. Anthropic valida la clave con un ciclo de cifrado y descifrado. Una vez que se muestra como verificada, tu organización está protegida por CMEK a partir de ese momento.

    El paso de detalles de la clave de este flujo muestra tu **Organization ID for the key policy** con un botón de copiar. Sustituye ese valor por `<ORGANIZATION_UUID>` en la política de clave. Puedes abrir el flujo para copiar el ID antes de crear la clave.

    En Claude Enterprise, CMEK se aplica a toda la organización, por lo que no hay un paso separado de adjuntar workspace, y una organización solo puede tener una clave.
  </Tab>
</Tabs>

## Configurar CMEK en Claude Platform on AWS

En [Claude Platform on AWS](https://platform.claude.com/docs/es/build-with-claude/claude-platform-on-aws), CMEK usa únicamente claves de AWS KMS, y la configuración difiere de las secciones anteriores de estas maneras:

* **Principal:** Tu política de clave otorga acceso al principal de servicio de AWS `aws-external-anthropic.amazonaws.com`. El rol de IAM y el ID de cuenta de Anthropic no se usan, por lo que el [ARN para Anthropic](https://platform.claude.com/docs/es/manage-claude/cmek-aws-kms#amazon-resource-name-arn-for-anthropic) no aplica.
* **Requisitos de la clave:** La clave debe ser una clave de KMS simétrica con uso de cifrar y descifrar, de región única, y en la misma cuenta y región de AWS que el workspace al que la adjuntas. Las claves entre cuentas no son compatibles: la clave debe estar en la cuenta de AWS que aloja tu organización. Las claves multirregión (IDs de clave que comienzan con `mrk-`) y los ARN de alias se rechazan cuando registras la clave; usa el ARN de la clave.
* **Sin paso de validación separado:** Aparte de esas verificaciones en el ARN de la clave durante el registro, la clave se valida cuando la adjuntas a un workspace. La llamada de adjuntar realiza un ciclo de cifrado/descifrado contra la clave con el ID de compartimento de ese workspace como contexto de cifrado, por lo que un problema de política de clave aparece en el momento de adjuntar en lugar de en el registro. Por lo tanto, una condición `EncryptionContext` no necesita una entrada de todos ceros.
* **Dónde administras las claves:** Registra y adjunta claves en la Claude Console, con sesión iniciada a través de AWS con el rol de administrador. Los endpoints de clave externa también están disponibles en Claude Platform on AWS, autorizados a través de [acciones de IAM](https://platform.claude.com/docs/es/api/claude-platform-on-aws-iam-actions#encryption-keys); allí, una clave se identifica por su ARN de clave de KMS en lugar de un ID `ekey_`.

<Warning>
  Usa únicamente este nombre de principal de servicio publicado. Nunca confíes en un identificador proporcionado por correo electrónico, chat o cualquier canal de incorporación.
</Warning>

### Requisitos previos

* La cuenta de AWS que aloja tu organización de Claude Platform on AWS, con permisos para crear claves de KMS y establecer políticas de clave (`kms:CreateKey` y `kms:PutKeyPolicy`).
* El rol **Admin** en la Claude Console para Claude Platform on AWS. Consulta [Usar la Claude Console](https://platform.claude.com/docs/es/build-with-claude/claude-platform-on-aws#using-the-claude-console).
* Para el principal de IAM con el que inicias sesión en la Claude Console: además de `aws-external-anthropic:AssumeConsole`, las [acciones de IAM](https://platform.claude.com/docs/es/api/claude-platform-on-aws-iam-actions#encryption-keys) para las operaciones que realizas allí, porque registrar, enumerar y adjuntar claves pasa por el gateway de AWS. Registrar una clave es `RegisterKey` (con `ListKeys` y `GetKey` para ver los registros), y adjuntar una es `UpdateWorkspace` o `CreateWorkspace`. Las acciones de claves externas (y `CreateWorkspace`) tienen alcance de cuenta, así que otórgalas en `Resource: "*"`; una política limitada a ARN de workspace no las incluye.
* Para el principal de IAM que adjunta la clave a un workspace (la identidad con la que iniciaste sesión en la Claude Console): `kms:DescribeKey`, `kms:Encrypt` y `kms:Decrypt` en la clave. El acceso de tu principal a la clave se verifica cuando la adjuntas, además del principal de servicio.
* Opcional, para el selector de claves en la Claude Console: `kms:ListKeys` y `kms:DescribeKey` para el principal con el que inicias sesión. Sin ellos, pega el ARN de la clave en su lugar.

### Crear la clave de KMS

La política de clave tiene tres declaraciones: la declaración de administrador raíz de tu cuenta; una declaración que permite al principal de servicio de Claude Platform on AWS cifrar, descifrar y generar claves de datos; y una declaración separada para `kms:DescribeKey`. La declaración criptográfica incluye una condición `EncryptionContext` opcional que vincula la clave a los workspaces que enumeres. `DescribeKey` se otorga por separado porque no tiene un parámetro `EncryptionContext`, por lo que una condición `EncryptionContext` en esa acción siempre denegaría el acceso.

Si planeas usar la condición `EncryptionContext` opcional que se muestra aquí, crea primero el workspace (sin clave), copia su ID de compartimento y sustituye `<compartment-uuid>` por él. Para encontrar el ID en la Claude Console, ve a la página [Data retention](https://platform.claude.com/settings/privacy) (`platform.claude.com/settings/privacy`) y selecciona el workspace en el menú desplegable en la parte superior de la página. El ID está en **Encryption key**, en el campo **Compartment ID**. También puedes leerlo del campo `compartment_id` devuelto por el endpoint [Get Workspace](https://platform.claude.com/docs/es/api/organization/workspaces/retrieve). Si no planeas usar la condición, elimina el bloque `Condition` de esa declaración.

```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\": \"*\"
      }
    ]
  }"
```

Captura `KeyMetadata.Arn` de la salida. Lo necesitas cuando registres la clave.

La condición `EncryptionContext` es opcional. Cada llamada de cifrado, descifrado y clave de datos realizada para un workspace, incluida la comprobación al adjuntar, lleva el ID de compartimento de ese workspace como `anthropic:compartment_uuid`, por lo que la condición enumera el ID de compartimento de cada workspace al que adjuntas la clave y no necesita una entrada de todos ceros. Agregarla también vincula la clave a los workspaces que enumeres en la capa de IAM. Como un ID de compartimento solo existe una vez que existe su workspace, el orden es: crea el workspace, coloca su ID de compartimento en la condición (al crear la clave, o más tarde con `kms:PutKeyPolicy`) y luego adjunta la clave. Antes de adjuntar la clave a cada workspace adicional, agrega el ID de compartimento de ese workspace de la misma manera. Para comenzar sin ella, elimina el bloque `Condition` de la declaración `AllowClaudePlatformOnAWSCrypto`; si la agregas más tarde, incluye el ID de compartimento de cada workspace al que la clave ya está adjunta.

Puedes restringir aún más ambas declaraciones del principal de servicio con una condición `aws:SourceArn`. El servicio pasa el [ARN del workspace](https://platform.claude.com/docs/es/api/claude-platform-on-aws-iam-actions#service-details) (`arn:aws:aws-external-anthropic:<region>:<account-id>:workspace/<workspace-id>`) como ARN de origen en cada llamada que realiza con tu clave, por lo que `"ArnLike": {"aws:SourceArn": "arn:aws:aws-external-anthropic:*:<account-id>:workspace/*"}` limita la concesión a los workspaces de tu propia cuenta de AWS, y una lista de ARN de workspace completos la limita a esos workspaces. Esta condición no es obligatoria; la condición `EncryptionContext` por sí sola vincula la clave a los workspaces que enumeres.

También puedes crear la clave desde la AWS Console: elige una clave simétrica con el uso de clave de cifrar y descifrar, una clave de región única y origen de material de clave de KMS, en la región del workspace. Deja los permisos de uso de clave vacíos en el asistente de creación de clave, luego abre la pestaña **Key policy** de la clave y reemplaza el JSON con la política mostrada aquí.

### Registrar y adjuntar la clave

<Steps>
  <Step title="Registrar la clave">
    En la Claude Console, ve a la página [Data retention](https://platform.claude.com/settings/privacy#encryption-keys) (`platform.claude.com/settings/privacy`). Si no ves **Encryption keys**, selecciona **Organization** en el menú desplegable en la parte superior de la página. En **Encryption keys**, haz clic en **Add key**. Ingresa un nombre para mostrar, luego elige la clave en el selector de claves o elige **Enter ARN manually** y pega el ARN de la clave, y haz clic en **Add**. La clave debe estar en la cuenta de AWS que aloja tu organización; no se admiten claves entre cuentas. El selector enumera las claves habilitadas, administradas por el cliente, simétricas y de una sola región de tu cuenta en una de las regiones de tu organización; para una clave que el selector no enumera, ingresa el ARN. Solo enumera claves si el principal con el que iniciaste sesión puede llamar a `kms:ListKeys` y `kms:DescribeKey`.
  </Step>

  <Step title="Adjuntar la clave a un workspace">
    Adjunta la clave a un workspace nuevo antes de enviar cualquier solicitud a ese workspace. Para un workspace que ya recibe solicitudes, la clave puede tardar [hasta un día en surtir efecto](https://platform.claude.com/docs/es/manage-claude/cmek#how-it-works). En la Claude Console, ve a la página [Data retention](https://platform.claude.com/settings/privacy) (`platform.claude.com/settings/privacy`) y selecciona el workspace en el menú desplegable en la parte superior de la página. En **Encryption key**, selecciona la clave, haz clic en **Save** y confirma. También puedes seleccionar una clave al crear un workspace en la Claude Console, pero solo si tu política de clave aún no nombra workspaces específicos (sin condición `EncryptionContext`), porque el ID de compartimento del workspace se asigna al crearlo. Una vez adjunta, la clave de un workspace no se puede cambiar.

    Este es el momento en que se valida la clave: la llamada de adjuntar verifica el acceso de tu principal a la clave y realiza un ciclo de cifrado/descifrado contra ella con el ID de compartimento del workspace como contexto de cifrado, por lo que un problema con la política de clave o con los permisos de tu principal aparece como un error en esa llamada. Si la adjunción falla con un error de acceso de KMS, verifica lo siguiente:

    * La política de clave nombra el principal de servicio `aws-external-anthropic.amazonaws.com` y otorga `kms:Encrypt`, `kms:Decrypt` y `kms:GenerateDataKey`, más `kms:DescribeKey` en una declaración separada que no tiene condición `EncryptionContext`.
    * Cualquier condición `EncryptionContext` incluye el ID de compartimento de este workspace, y cualquier condición `aws:SourceArn` que hayas agregado coincide con el ARN de este workspace.
    * La clave está habilitada, es de región única y está en la misma cuenta y región de AWS que el workspace.
    * El principal con el que has iniciado sesión tiene `kms:DescribeKey`, `kms:Encrypt` y `kms:Decrypt` en la clave.
    * Ninguna política de control de servicio o política de control de recursos en tu organización de AWS impide que el principal de servicio o tu principal usen la clave.
    * Si la política parece correcta y la adjunción sigue fallando, busca el evento `kms:` denegado en CloudTrail en la cuenta de la clave (muestra el principal que realiza la llamada y, para las llamadas criptográficas, el contexto de cifrado), luego corrige la condición con `kms:PutKeyPolicy` y vuelve a intentarlo.
  </Step>
</Steps>

## Terraform

Para implementaciones de infraestructura como código, los mismos pasos se asignan al proveedor `aws` con los recursos `aws_kms_key` y `aws_kms_alias`.
