---
title: Identidad y credenciales del agente
url: https://platform.claude.com/docs/es/managed-agents/self-hosted/agent-identity
description: Haz que tu servidor autoalojado de Claude Managed Agents firme un token de corta duración que nombre a cada agente, guarda las credenciales de vault en tu gestor de secretos y mantén los secretos fuera de los sandboxes con el gateway de salida.
---

<Note>
  Para solicitar acceso a Claude Managed Agents autoalojado, ponte en contacto con el equipo de tu cuenta de Anthropic.
</Note>

Esta página muestra cómo permitir que los sistemas fuera de tu servidor confíen en un agente y dónde guardar las credenciales que usan tus agentes:

* [Identidad del agente](https://platform.claude.com/docs/es/managed-agents/self-hosted/agent-identity#agent-identity): Permite que un servidor MCP o un gateway le dé a cada agente su propio acceso. El servidor firma un token de corta duración que nombra al agente.
* [Gestor de secretos](https://platform.claude.com/docs/es/managed-agents/self-hosted/agent-identity#secret-manager): El servidor guarda las credenciales de vault en AWS Secrets Manager, Google Cloud Secret Manager, HashiCorp Vault o Azure Key Vault.
* [Credenciales de variables de entorno](https://platform.claude.com/docs/es/managed-agents/self-hosted/agent-identity#environment-variable-credentials): Permite que los comandos de un agente llamen a un servicio mientras el sandbox contiene solo un marcador de posición. El “egress gateway” (gateway de salida) coloca el valor real en las solicitudes del agente.

## Identidad del agente

Tu servidor puede firmar un “JSON Web Token” (token web JSON), o JWT, de corta duración que nombre a un agente, y enviarlo con las llamadas MCP de ese agente. El receptor, un servidor MCP o un “gateway” (puerta de enlace), verifica el token con las claves públicas que publicas y, a continuación, puede darle a cada agente su propio acceso.

### Configura el emisor

1. **Elige la URL del emisor.** Publicas tus claves públicas en esta URL en el paso 3, y los receptores las obtienen desde ella. Un host web estático funciona. No uses la dirección de tu servidor, porque el servidor no sirve las claves en las rutas que obtienen los receptores. Usa una URL `https://` sin ruta ni barra final, en un nombre de host que puedas conservar.

2. **Crea la clave de firma.** Ejecuta estos comandos en el directorio superior del archivo extraído:

   ```bash
   mkdir -m 700 agent-identity
   openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out agent-identity/signing-key.pem
   ```

3. **Publica las claves públicas.** Este comando las escribe en `issuer-files/.well-known/`. Sirve `issuer-files` en la raíz del nombre de host del emisor, con el tipo de contenido `application/json`.

   ```bash
   CMA_AGENT_IDENTITY__ISSUER=https://agents.example.com \
   CMA_AGENT_IDENTITY__KEY_FILE=./agent-identity/signing-key.pem \
     ./cma-server export-issuer -out issuer-files
   ```

4. **Dale la clave al servidor.**

   <Tabs>
     <Tab title="Docker Compose">
       1. Si el archivo tiene un directorio `compose`, mueve el directorio de la clave dentro de él: `mv agent-identity compose/agent-identity`.
       2. En `docker-compose.yml`, elimina la línea `volumes: *server_mounts` del servicio `cma-server` y quita el comentario del bloque `volumes:` que está debajo. Si cambiaste la lista `x-server-mounts`, haz el mismo cambio en ese bloque, porque el servicio `cma-server` ya no lee la lista.
       3. En el directorio que contiene `agent-identity`, ejecuta `sudo chown -R root:root agent-identity`, a menos que uses Docker Desktop en macOS o Docker sin root.
     </Tab>

     <Tab title="Kubernetes">
       Ejecuta `kubectl -n cma-server create secret generic cma-agent-identity --from-file=agent-identity/signing-key.pem`. Luego establece `server.agentIdentity.secretName` en `cma-agent-identity` en el archivo de valores del chart del servidor.
     </Tab>
   </Tabs>

5. **Modifica el [archivo de configuración](https://platform.claude.com/docs/es/managed-agents/self-hosted/configuration-reference#where-settings-go).** Incluye el nombre de host del receptor en [`mcp.allowed_hostnames`](https://platform.claude.com/docs/es/managed-agents/self-hosted/differences#mcp-servers-need-an-allowlist-entry) y agrega esta sección:

   ```yaml
   agent_identity:
     issuer: https://agents.example.com
     key_file: /run/cma-server/agent-identity/signing-key.pem
     direct:
       audiences:
         - audience: https://mcp-gateway.example.com
           urls:
             - https://mcp-gateway.example.com
   ```

   Cada `audience` nombra a un receptor, como una URL `https://`. Sus `urls` son los prefijos de URL de los servidores MCP que pueden recibir un token para él.

6. **Reinicia el servidor.** En el stack de Compose, ejecuta `docker compose up -d` desde el directorio del archivo de Compose en lugar de reiniciar.

Para mantener la clave privada fuera de los archivos, usa `key_secret` (tu [gestor de secretos](https://platform.claude.com/docs/es/managed-agents/self-hosted/agent-identity#secret-manager)) o `kms_key` (AWS KMS o Google Cloud KMS). [Referencia de configuración](https://platform.claude.com/docs/es/managed-agents/self-hosted/configuration-reference#agent-identity) describe ambas configuraciones.

### Envía el token a un servidor MCP

[Conector MCP](https://platform.claude.com/docs/es/managed-agents/mcp-connector) describe los campos de la entrada del servidor MCP de un agente. Agrega un campo `auth` a esa entrada:

```yaml
mcp_servers:
  - type: url
    name: tickets
    url: https://mcp-gateway.example.com/tickets
    auth:
      type: agent_token
      audience: https://mcp-gateway.example.com
```

Para cada listado de herramientas o llamada a herramienta, tu servidor firma un token nuevo. Envía el token como `Authorization: Bearer <token>`, en lugar de una credencial del vault. Ni el modelo ni el worker lo reciben.

Para enviar tanto el token como una [credencial de bóveda](https://platform.claude.com/docs/es/managed-agents/vaults), reemplaza el campo `auth` por un campo `agent_token_header`:

```yaml
mcp_servers:
  - type: url
    name: tickets
    url: https://mcp-gateway.example.com/tickets
    agent_token_header:
      audience: https://mcp-gateway.example.com
```

La credencial de bóveda va en el encabezado `Authorization`, como ocurre con una entrada que no tiene ninguno de los dos campos. El token va en un encabezado `Agent-Identity-Token`, sin el prefijo `Bearer`.

El SDK no tiene los campos `auth` y `agent_token_header`. En el código del SDK, agrega el campo a la entrada del servidor MCP como un campo adicional, o envía la solicitud como JSON simple.

Estas páginas muestran cómo enviar campos adicionales:

[SDK de Python](https://platform.claude.com/docs/es/cli-sdks-libraries/sdks/python#undocumented-request-params) · [SDK de TypeScript](https://platform.claude.com/docs/es/cli-sdks-libraries/sdks/typescript#undocumented-request-params) · [SDK de Go](https://platform.claude.com/docs/es/cli-sdks-libraries/sdks/go#request-fields) · [SDK de Java](https://platform.claude.com/docs/es/cli-sdks-libraries/sdks/java#undocumented-parameters) · [SDK de PHP](https://platform.claude.com/docs/es/cli-sdks-libraries/sdks/php#undocumented-request-parameters) · [SDK de Ruby](https://platform.claude.com/docs/es/cli-sdks-libraries/sdks/ruby#undocumented-request-params)

Algunas de esas páginas muestran campos adicionales solo en el nivel superior de una solicitud, no dentro de una entrada de lista. En ese caso, haz que `mcp_servers` sea el campo adicional. Envía toda la lista de esa forma, con `auth` o `agent_token_header` en su entrada.

Para detener los tokens de un agente, elimina la entrada del agente o archiva el agente. Un token ya enviado sigue siendo válido hasta su `exp`, como máximo 5 minutos de forma predeterminada.

### Qué verifica el receptor

Haz que el receptor acepte una solicitud solo si se cumplen todas estas condiciones:

* La firma se verifica con una clave de tu conjunto de claves, `<issuer>/.well-known/jwks.json`. La clave correcta es aquella cuyo ID coincide con `kid` en el encabezado del token. Para una clave RSA, el algoritmo es `RS256`.
* `iss` es igual a la URL de tu emisor, y `aud` es igual a la audiencia del receptor.
* `exp` está en el futuro, y `iat` no está en el futuro.
* `typ` en el encabezado del token es `agent+jwt`, y `token_use` es `agent`.

Luego aplica estas reglas:

* Basa las reglas de acceso de cada agente en el claim `agent_id`, el ID del agente en la API.
* Acepta un `jti` repetido, porque un listado o una llamada puede requerir varias solicitudes con el mismo token.
* Haz que un gateway llame a cada herramienta con su propia credencial y que nunca reenvíe el token.

Con el [inicio de sesión único](https://platform.claude.com/docs/es/managed-agents/self-hosted/configure#single-sign-on), el token de una llamada a herramienta también nombra al autor de la llamada que creó la sesión, en los claims `actor_sub` y `actor_iss`. `actor_sub` no significa que el autor de la llamada haya aprobado la llamada. El modelo elige cada llamada.

Estos tokens no tienen `actor_sub`:

* El token de un listado de herramientas
* El token de una llamada de un subagente
* Todos los tokens de una sesión creada con la clave de API del servidor

Si una regla depende del autor de la llamada, rechaza una llamada a herramienta que no tenga `actor_sub`.

### Prueba el gateway MCP

El comando `check-gateway` envía a un gateway MCP tokens válidos e inválidos. Dale al comando un archivo de configuración propio, aquí `check-gateway.yaml`:

1. Copia en el archivo solo las secciones `mcp` y `agent_identity` de la configuración del servidor, y `limits.mcp_call_timeout` si el servidor lo establece.
2. En la copia, cambia `key_file` a la ruta de la clave en la máquina donde ejecutas el comando, como `./agent-identity/signing-key.pem`. Si moviste el directorio dentro de `compose`, la ruta es `./compose/agent-identity/signing-key.pem`.

Para `-agent`, indica el ID de un agente que el gateway permita. Si root es el propietario de la clave, usa `sudo`.

```bash
./cma-server check-gateway -config check-gateway.yaml -agent agent_011CYm1BLqPXpQRk5khsSXrs \
  -url https://mcp-gateway.example.com/tickets
```

El comando imprime una línea por cada solicitud que envía, con la respuesta del gateway. Una ejecución correcta imprime luego una línea que comienza con `check-gateway: PASS` y sale con el código `0`. Una ejecución fallida indica qué salió mal, en una línea que comienza con `check-gateway:`, y sale con el código `1`.

## Gestor de secretos

De forma predeterminada, el servidor almacena los secretos de las [credenciales de vault](https://platform.claude.com/docs/es/managed-agents/vaults) en su base de datos. Con una sección `secret_store`, el servidor escribe el secreto de cada nueva credencial de vault en tu gestor de secretos, con un prefijo de nombre que reservas para ello. La base de datos guarda solo una referencia.

Agrega el bloque de tu gestor de secretos al [archivo de configuración](https://platform.claude.com/docs/es/managed-agents/self-hosted/configuration-reference#where-settings-go):

<Tabs>
  <Tab title="AWS Secrets Manager">
    ```yaml
    secret_store:
      type: aws_secrets_manager
      region: us-east-1
      prefix: cma-server/prod/
    ```
  </Tab>

  <Tab title="Google Cloud Secret Manager">
    ```yaml
    secret_store:
      type: gcp_secret_manager
      project: my-project        # the project ID, not its number
      prefix: cma-server-prod--
    ```
  </Tab>

  <Tab title="Azure Key Vault">
    ```yaml
    secret_store:
      type: azure_key_vault
      vault_url: https://my-vault.vault.azure.net
      prefix: cma-server-prod--
    ```
  </Tab>

  <Tab title="HashiCorp Vault">
    ```yaml
    secret_store:
      type: hashicorp_vault
      address: https://vault.internal:8200
      prefix: cma-server/prod/
      approle:
        role_id: <role-id>
        secret_id_file: /run/vault/secret-id
      #kubernetes: { role: cma-server }
      #token_file: /run/vault/token
    ```

    Establece exactamente uno de los tres métodos de inicio de sesión:

    * **`approle`:** Úsalo con Docker Compose, en un host o con el chart de Helm del servidor. El servidor inicia sesión con un ID de rol y con un ID secreto que lee de un archivo.
    * **`kubernetes`:** Úsalo solo en una instalación de Kubernetes propia, cuyo pod del servidor tenga un token de cuenta de servicio. El servidor inicia sesión con ese token. El chart de Helm del servidor no les da ese token a los pods del servidor, así que este método no funciona con el chart.
    * **`token_file`:** Úsalo para cualquier otro método de inicio de sesión de Vault. Ejecuta Vault Agent junto al servidor y haz que escriba su token en este archivo.

    Con el chart de Helm del servidor, dale al servidor el ID secreto en un Secret:

    1. Coloca el ID secreto en un Secret en el namespace del servidor e indica el nombre de ese Secret en `server.extensionFiles.secretName` del chart.
    2. Establece `approle.secret_id_file` en la ruta del ID secreto. El chart monta cada clave de ese Secret como un archivo en `/run/cma-server/extension-files/`, así que una clave llamada `secret-id` está en `/run/cma-server/extension-files/secret-id`.

    Para el método `kubernetes`, vincula el rol de Kubernetes de Vault al namespace y a la cuenta de servicio del servidor, no al namespace de los sandboxes, `cma`.
  </Tab>
</Tabs>

### Conceder acceso

Dale al servidor una identidad y limítala al prefijo. El directorio `iam/` del archivo tiene un archivo para cada gestor de secretos:

* **AWS Secrets Manager:** Reemplaza los marcadores de posición en `aws-secrets-manager-policy.json` y adjunta la política a la identidad con la que se ejecuta el servidor.
* **Google Cloud Secret Manager:** Ejecuta los comandos de los comentarios de `gcp-secret-manager-role.yaml`.
* **Azure Key Vault:** Un rol de Azure abarca todo un key vault, no un prefijo. Así que dale a la implementación un key vault propio, uno que use el control de acceso basado en roles de Azure. Reemplaza `SUBSCRIPTION_ID` en `azure-key-vault-role.json` y crea un rol personalizado a partir de él. Asigna el rol en el key vault a la identidad con la que se ejecuta el servidor.
* **HashiCorp Vault:** Reemplaza los marcadores de posición en `hashicorp-vault-policy.hcl` y adjunta la política a la identidad con la que se ejecuta el servidor.

Ante AWS y Google Cloud, el servidor se autentica igual que para la inferencia. Ante Azure Key Vault, se autentica con Microsoft Entra ID, igual que para [Microsoft Foundry](https://platform.claude.com/docs/es/managed-agents/self-hosted/inference-provider#microsoft-foundry).

### Comprobar la configuración

Ejecuta `validate-store` antes del primer inicio y después de cualquier cambio de política. Crea, lee y elimina un secreto de prueba bajo el prefijo, sin iniciar el servidor. Ejecuta el comando donde se ejecuta el servidor, con el entorno del servidor:

* **Docker Compose:** Ejecútalo en el contenedor del servidor. En Arm, reemplaza `linux_amd64` en este comando por `linux_arm64`:

  ```bash
  docker compose exec cma-server /opt/cma-server/bin/linux_amd64/cma-server validate-store -config /etc/cma-server/config.yaml
  ```

* **En un host:**

  ```bash
  ./cma-server validate-store -config /etc/cma-server/config.yaml
  ```

* **Kubernetes:** Ejecuta el mismo comando como un Job con la cuenta de servicio del servidor.

Una ejecución correcta termina con una línea que dice `pass` y sale con el código `0`.

Con Azure Key Vault, ejecuta esta comprobación contra tu key vault antes de confiar en él.

### Límites del gestor de secretos

* **Elige la configuración una sola vez.** Después de cualquiera de estos cambios, el servidor deja de encontrar los secretos que escribió antes del cambio:

  * Eliminas la sección `secret_store`.
  * Cambias `type`, `prefix`, `region`, `project`, `vault_url`, `mount` o `namespace`. Los dos últimos son configuraciones opcionales de HashiCorp Vault.
  * Diriges `address` a otro Vault.

  El servidor vuelve a encontrar esos secretos solo cuando restauras los valores anteriores.

* **Una identidad lee todo el prefijo.** Si dos grupos no deben poder acceder a las credenciales del otro, dale a cada grupo su propia implementación. Cada implementación necesita su propio prefijo o key vault y su propia identidad.

## Credenciales de variables de entorno

Con una [credencial de variable de entorno](https://platform.claude.com/docs/es/managed-agents/vaults#add-a-credential), los comandos de un agente pueden llamar a un servicio mientras el sandbox contiene solo un marcador de posición para el secreto. El gateway de salida coloca el valor real en las solicitudes a los hosts que la credencial enumera.

El gateway, `cma-egress`, es un proxy incluido en el archivo de la versión que se sitúa entre tus sandboxes e internet. Está desactivado de forma predeterminada, y tu servidor acepta estas credenciales solo con el gateway activado.

Con el gateway activado, se aplican dos límites a tus sandboxes:

* Los sandboxes llegan a internet solo a través del gateway.
* El gateway se conecta solo a los hosts que enumeras en la configuración `egress.allowed_hostnames` del servidor.

Enumera nombres de host públicos exactos, sin comodines. Incluye todos los hosts desde los que descargan los comandos de tus agentes.

Si creaste tu propia imagen de sandbox, inicia el worker mediante `cma-with-egress`, como se muestra en [Crea tu propia imagen de sandbox](https://platform.claude.com/docs/es/managed-agents/self-hosted/call-the-api#what-an-image-of-your-own-needs).

### Activa el gateway en el stack de Compose

Desde el directorio que contiene `docker-compose.yml`, agrega dos líneas a `.env`. La primera enumera los hosts a los que se conecta el gateway, separados por comas. La segunda carga el archivo de Compose del gateway. Luego inicia el stack:

```bash
echo 'CMA_EGRESS__ALLOWED_HOSTNAMES=api.github.com' >> .env
echo 'COMPOSE_FILE=docker-compose.yml:docker-compose.egress.yml' >> .env
docker compose up --build -d
```

Si también usas otro archivo de Compose, agrégalo a la línea `COMPOSE_FILE`. Una variable `COMPOSE_FILE` en tu shell anula la de `.env`, así que elimina la variable del shell.

El archivo del gateway establece las demás configuraciones `egress` del servidor, así que no agregues una sección `egress` a `compose.config.yaml`.

### Activa el gateway en Kubernetes

Estos pasos parten de la implementación de [Implementa en Kubernetes](https://platform.claude.com/docs/es/managed-agents/self-hosted/kubernetes). Usan las variables `REGISTRY`, `TAG` y `PLATFORM` de esa página y sus dos archivos de valores. Ejecuta los comandos desde el directorio superior del archivo, con OpenSSL 3.0 o posterior. El chart del sandbox no ofrece el gateway en Azure Kubernetes Service (AKS).

La actualización del chart del servidor en estos pasos también agrega una política de red sobre los pods de los servidores. Revisa dos de los puertos que cubre antes de empezar:

* **Puerto 9464, el puerto de métricas:** La política lo cierra. Si Prometheus recopila métricas de ese puerto, establece `server.telemetry.prometheus.scraper.namespace` en `cma-server-values.yaml` en el namespace en el que se ejecuta Prometheus.
* **Puerto 8400, el puerto de la API:** La política admite cualquier origen. Si una política propia limita quién llega al puerto 8400, ese límite deja de funcionar. Las políticas de red se suman, así que una conexión pasa si cualquier política la admite.

<Steps>
  <Step title="Compila y sube la imagen del gateway">
    ```bash
    docker buildx build --platform "$PLATFORM" -f kubernetes/egress/Dockerfile -t "$REGISTRY/cma-egress:$TAG" --push .
    ```
  </Step>

  <Step title="Crea la autoridad de certificación y la clave del gateway">
    ```bash
    (umask 077 && openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -days 825 \
      -subj "/CN=cma-server egress gateway" \
      -addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
      -addext "keyUsage=critical,keyCertSign,cRLSign" \
      -keyout egress-ca.key -out egress-ca.crt)
    kubectl -n cma create secret tls cma-egress-ca --cert=egress-ca.crt --key=egress-ca.key
    kubectl -n cma-server create configmap cma-egress-ca --from-file=ca.crt=egress-ca.crt
    GATEWAY_KEY=$(openssl rand -hex 32)
    printf %s "$GATEWAY_KEY" | kubectl -n cma create secret generic cma-egress-gateway-key --from-file=gateway-key=/dev/stdin
    printf %s "$GATEWAY_KEY" | kubectl -n cma-server create secret generic cma-egress-gateway-key --from-file=gateway-key=/dev/stdin
    unset GATEWAY_KEY
    ```

    Luego elimina `egress-ca.key`, la clave privada de la autoridad de certificación. Cualquiera que la tenga puede suplantar cualquier sitio web ante tus sandboxes. El certificado es válido durante 825 días. Consulta [Renueva el certificado](https://platform.claude.com/docs/es/managed-agents/self-hosted/agent-identity#renew-the-certificate).
  </Step>

  <Step title="Elimina los sandboxes de sesiones anteriores">
    Si el entorno no ha ejecutado ninguna sesión, omite este paso. Un sandbox de antes del cambio no puede iniciar su worker después. Estos comandos también eliminan el espacio de trabajo de cada sandbox:

    ```bash
    kubectl -n cma scale deployment cma-dispatcher --replicas=0
    kubectl -n cma delete sandboxwarmpool cma-sandbox
    kubectl -n cma delete sandboxclaims --all
    ```

    En Google Kubernetes Engine (GKE), ejecuta también este comando:

    ```bash
    kubectl -n cma delete sandboxes --all
    ```

    Repite `kubectl -n cma get sandboxes,pods,pvc` hasta que no encuentre nada. El `helm upgrade` del paso “Activa el lado de los sandboxes” vuelve a iniciar el dispatcher.
  </Step>

  <Step title="Activa el lado del servidor">
    Elige una dirección IPv4 libre en el rango de Service del clúster para el gateway. La columna `CLUSTER-IP` de `kubectl get svc -A` muestra direcciones de ese rango. Agrega esto a `cma-server-values.yaml`. Si el archivo ya tiene un bloque `server`, combina estas líneas en él:

    ```yaml
    egressGateway:
      enabled: true
      proxyAddress: 34.118.224.53:3128   # the address that you chose, and port 3128
    server:
      config:
        egress:
          allowed_hostnames:
            - api.github.com
    ```

    Luego ejecuta la actualización:

    ```bash
    helm upgrade cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait
    ```
  </Step>

  <Step title="Activa el lado de los sandboxes">
    Ejecuta `kubectl -n cma-server get svc` para enumerar los dos Services del servidor. En una instalación nueva, se llaman `cma-server` y `cma-server-egress`.

    En `cma-values.yaml`, cambia `egress.mode` a `gateway` y agrega un bloque `gateway` debajo de `egress`. Indica en el bloque los dos nombres que enumeró el comando:

    ```yaml
    egress:
      mode: gateway
      gateway:
        serviceIP: 34.118.224.53   # the address that you chose
        serverService: cma-server
        serverEgressService: cma-server-egress
        apiServerCIDRs:
          - 203.0.113.10/32        # the cluster's API endpoint
    ```

    Conserva los demás valores `egress` del archivo. Para imprimir las direcciones y el puerto del endpoint de la API, ejecuta `kubectl get endpoints kubernetes -n default`. Si el puerto no es 443, establece también `egress.gateway.apiServerPort`.

    ```bash
    helm upgrade cma kubernetes/chart --namespace cma -f cma-values.yaml --wait
    ```

    Si la actualización se detiene por un conflicto sobre `.spec.replicas`, ejecuta `kubectl -n cma scale deployment cma-dispatcher --replicas=1` y luego vuelve a ejecutar la actualización.
  </Step>
</Steps>

### Agrega una credencial

Crea una credencial de variable de entorno como se muestra en [Agrega una credencial](https://platform.claude.com/docs/es/managed-agents/vaults#add-a-credential). Las guías del servicio alojado indican que estas credenciales no son compatibles con sandboxes autoalojados. Eso describe el servicio alojado, no tu servidor.

Tu servidor agrega reglas propias. Rechaza una solicitud que incumpla alguna con un error `400` que nombra el campo. A continuación se indican dos de esas reglas:

* `networking` (csharp, go: `Networking`) debe tener el tipo `limited`, y cada host en `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) debe estar en la lista `egress.allowed_hostnames` del servidor.
* `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) debe ser `{"header": true}` en JSON, y no se puede omitir.

Después de agregar un host a la lista del servidor, aplica el cambio. En Docker Compose, ejecuta `docker compose up -d`. En Kubernetes, ejecuta el comando `helm upgrade` del servidor y `kubectl -n cma-server rollout restart deployment -l anthropic.com/role=server`.

### Verifica el gateway de salida

Crea una sesión con el vault de la credencial y pídele al agente que ejecute dos comandos. Este ejemplo es para una credencial llamada `GITHUB_TOKEN` que enumera `api.github.com`:

```bash
printenv GITHUB_TOKEN
curl -sS -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/user
```

El primer comando imprime un marcador de posición que comienza con `cma_ph_`. El segundo imprime el perfil de la cuenta de GitHub del token, porque el gateway reemplazó el marcador de posición por el token. El gateway rechaza una solicitud a un host que no está en tu lista con un error `403`.

En Kubernetes, si todas las solicitudes reciben un error `503`, probablemente la red de tu clúster reescribe las direcciones de los pods, como lo hace la opción `--masquerade-all` de kube-proxy. El gateway distingue los sandboxes por las direcciones de sus pods, así que esas direcciones deben llegarle sin cambios.

### Renueva el certificado

En Kubernetes, renueva el certificado mientras no se ejecute ninguna sesión. Repite todo el paso “Crea la autoridad de certificación y la clave del gateway” de [Activa el gateway en Kubernetes](https://platform.claude.com/docs/es/managed-agents/self-hosted/agent-identity#turn-on-the-gateway-on-kubernetes). Ese paso vuelve a crear la autoridad de certificación y la clave del gateway, así que no necesitas el archivo `egress-ca.key` que eliminaste. Haz un cambio: agrega `--dry-run=client -o yaml | kubectl apply -f -` al final de cada una de las cuatro líneas que ejecutan `kubectl create`. Por ejemplo, una línea que termina en `--from-file=gateway-key=/dev/stdin` termina entonces en `--from-file=gateway-key=/dev/stdin --dry-run=client -o yaml | kubectl apply -f -`.

Luego reinicia los servidores y el gateway:

```bash
kubectl -n cma-server rollout restart deployment -l anthropic.com/role=server
kubectl -n cma rollout restart deployment/cma-egress
```

### Límites del gateway de salida

* **Encabezados:** El gateway coloca un valor solo en un encabezado de solicitud, nunca en una URL ni en un cuerpo. De forma predeterminada, el único encabezado es `Authorization`. Para permitir otros, enuméralos junto con `Authorization` en `egress.swap_header_names`, o en `CMA_EGRESS__SWAP_HEADER_NAMES` en `.env` para el stack de Compose.
* **Programas que ignoran las variables de proxy:** Los sandboxes encuentran el gateway mediante `HTTPS_PROXY` y variables relacionadas. Las herramientas de Java como Maven y Gradle no leen esas variables, así que no llegan a nada.
