Claude Platform Docs
Managed AgentsConfiguração empresarial

Identidade e credenciais do agente

Faça seu servidor auto-hospedado do Claude Managed Agents assinar um token de curta duração que nomeia cada agente, mantenha as credenciais de vault no seu gerenciador de segredos e mantenha os segredos fora dos sandboxes com o gateway de saída.

Esta página mostra como permitir que os sistemas fora do seu servidor confiem em um agente e onde manter as credenciais que seus agentes usam:

  • Identidade do agente: Permita que um servidor MCP ou gateway dê a cada agente seu próprio acesso. O servidor assina um token de curta duração que nomeia o agente.
  • Gerenciador de segredos: O servidor mantém as credenciais de vault no AWS Secrets Manager, no Google Cloud Secret Manager, no HashiCorp Vault ou no Azure Key Vault.
  • Credenciais de variável de ambiente: Permita que os comandos de um agente chamem um serviço enquanto o sandbox mantém apenas um placeholder. O “egress gateway” (gateway de saída) coloca o valor real nas solicitações do agente.

Identidade do agente

Seu servidor pode assinar um “JSON Web Token” (token web JSON), ou JWT, de curta duração que nomeia um agente, e enviá-lo com as chamadas MCP desse agente. O receptor, um servidor MCP ou “gateway” (gateway), verifica o token em relação às chaves públicas que você publica e pode então dar a cada agente seu próprio acesso.

Configurar o emissor

  1. Escolha a URL do “issuer” (emissor). Você publica suas chaves públicas nesta URL na etapa 3, e os receptores as buscam nela. Um host web estático funciona. Não use o endereço do seu servidor, porque o servidor não serve as chaves nos caminhos que os receptores buscam. Use uma URL https:// sem caminho nem barra final, em um nome de host que você possa manter.

  2. Crie a chave de assinatura. Execute estes comandos no nível superior do arquivo extraído:

    mkdir -m 700 agent-identity
    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out agent-identity/signing-key.pem
  3. Publique as chaves públicas. Este comando as grava em issuer-files/.well-known/. Sirva issuer-files na raiz do nome de host do emissor, com o tipo de conteúdo application/json.

    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. Dê a chave ao servidor.

    1. Se o arquivo tiver um diretório compose, mova o diretório da chave para dentro dele: mv agent-identity compose/agent-identity.
    2. Em docker-compose.yml, exclua a linha volumes: *server_mounts do serviço cma-server e descomente o bloco volumes: abaixo dela. Se você alterou a lista x-server-mounts, faça a mesma alteração nesse bloco, porque o serviço cma-server não lê mais a lista.
    3. No diretório que contém agent-identity, execute sudo chown -R root:root agent-identity, a menos que você use o Docker Desktop no macOS ou Docker rootless.
  5. Altere o arquivo de configurações. Liste o nome de host do receptor em mcp.allowed_hostnames e adicione esta seção:

    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 nomeia um receptor, como uma URL https://. Seus urls são os prefixos de URL dos servidores MCP que podem receber um token para ele.

  6. Reinicie o servidor. Na stack do Compose, execute docker compose up -d a partir do diretório do arquivo Compose em vez de reiniciar.

Para manter a chave privada fora de arquivos, use key_secret (seu gerenciador de segredos) ou kms_key (AWS KMS ou Google Cloud KMS). A Referência de configuração descreve ambas as configurações.

Enviar o token a um servidor MCP

O conector MCP descreve os campos da entrada de servidor MCP de um agente. Adicione um campo auth a essa entrada:

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 listagem de ferramentas ou chamada de ferramenta, seu servidor assina um novo token. Ele envia o token como Authorization: Bearer <token>, no lugar de uma credencial do vault. Nem o modelo nem o worker o recebem.

Para enviar tanto o token quanto uma credencial de vault, substitua o campo auth por um campo agent_token_header:

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

A credencial de vault vai no cabeçalho Authorization, como acontece em uma entrada sem nenhum dos dois campos. O token vai em um cabeçalho Agent-Identity-Token, sem o prefixo Bearer.

O SDK não tem os campos auth e agent_token_header. No código do SDK, adicione o campo à entrada do servidor MCP como um campo extra ou envie a solicitação como JSON simples.

Estas páginas mostram como enviar campos extras:

SDK Python · SDK TypeScript · SDK Go · SDK Java · SDK PHP · SDK Ruby

Algumas dessas páginas mostram campos extras apenas no nível superior de uma solicitação, não dentro de uma entrada de lista. Nesse caso, torne o próprio mcp_servers o campo extra. Envie toda a lista dessa forma, com auth ou agent_token_header em sua entrada.

Para interromper os tokens de um agente, remova a entrada do agente ou arquive o agente. Um token já enviado permanece válido até seu exp, no máximo 5 minutos por padrão.

O que o receptor verifica

Faça o receptor aceitar uma solicitação somente se todas estas condições forem atendidas:

  • A assinatura é verificada com uma chave do seu conjunto de chaves, <issuer>/.well-known/jwks.json. A chave correta é aquela cujo ID corresponde ao kid no cabeçalho do token. Para uma chave RSA, o algoritmo é RS256.
  • iss é igual à URL do seu emissor, e aud é igual ao audience do receptor.
  • exp está no futuro, e iat não está no futuro.
  • typ no cabeçalho do token é agent+jwt, e token_use é agent.

Em seguida, aplique estas regras:

  • Baseie as regras de acesso de cada agente na claim agent_id, o ID do agente na API.
  • Aceite um jti repetido, porque uma listagem ou chamada pode exigir várias solicitações com o mesmo token.
  • Faça um gateway chamar cada ferramenta com sua própria credencial e nunca repassar o token.

Com single sign-on, o token de uma chamada de ferramenta também nomeia o chamador que criou a sessão, nas claims actor_sub e actor_iss. actor_sub não significa que o chamador aprovou a chamada. O modelo escolhe cada chamada.

Estes tokens não têm actor_sub:

  • O token de uma listagem de ferramentas
  • O token de uma chamada de um subagente
  • Todos os tokens de uma sessão criada pela chave de API do servidor

Se uma regra depender do chamador, recuse uma chamada de ferramenta que não tenha actor_sub.

Testar o gateway MCP

O comando check-gateway envia tokens válidos e inválidos a um gateway MCP. Forneça ao comando um arquivo de configurações próprio, aqui check-gateway.yaml:

  1. Copie para o arquivo apenas as seções mcp e agent_identity das configurações do servidor, e limits.mcp_call_timeout se o servidor a definir.
  2. Na cópia, altere key_file para o caminho da chave na máquina em que você executa o comando, como ./agent-identity/signing-key.pem. Se você moveu o diretório para compose, esse caminho é ./compose/agent-identity/signing-key.pem.

Para -agent, forneça o ID de um agente que o gateway permite. Se a chave pertencer ao root, use sudo.

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

O comando imprime uma linha para cada solicitação que envia, com a resposta do gateway. Uma execução bem-sucedida imprime então uma linha que começa com check-gateway: PASS e sai com o código 0. Uma execução com falha informa o que deu errado, em uma linha que começa com check-gateway:, e sai com o código 1.

Gerenciador de segredos

Por padrão, o servidor armazena os segredos das credenciais de vault em seu banco de dados. Com uma seção secret_store, o servidor grava o segredo de cada nova credencial de vault no seu gerenciador de segredos, sob um prefixo de nome que você reserva para isso. O banco de dados mantém apenas uma referência.

Adicione o bloco do seu gerenciador de segredos ao arquivo de configurações:

secret_store:
  type: aws_secrets_manager
  region: us-east-1
  prefix: cma-server/prod/

Conceda acesso

Dê ao servidor uma identidade e restrinja-a ao prefixo. O diretório iam/ do arquivo tem um arquivo para cada gerenciador de segredos:

  • AWS Secrets Manager: Substitua os placeholders em aws-secrets-manager-policy.json e anexe a política à identidade com a qual o servidor é executado.
  • Google Cloud Secret Manager: Execute os comandos que estão nos comentários de gcp-secret-manager-role.yaml.
  • Azure Key Vault: Uma função do Azure abrange um key vault inteiro, não um prefixo. Portanto, dê à implantação um key vault próprio, que use o controle de acesso baseado em funções do Azure. Substitua SUBSCRIPTION_ID em azure-key-vault-role.json e crie uma função personalizada a partir dele. Atribua a função no key vault à identidade com a qual o servidor é executado.
  • HashiCorp Vault: Substitua os placeholders em hashicorp-vault-policy.hcl e anexe a política à identidade com a qual o servidor é executado.

Na AWS e no Google Cloud, o servidor se autentica da mesma forma que faz para inferência. No Azure Key Vault, ele se autentica com o Microsoft Entra ID, da mesma forma que faz para o Microsoft Foundry.

Verifique a configuração

Execute validate-store antes da primeira inicialização e após qualquer alteração de política. Ele cria, lê e exclui um segredo de teste sob o prefixo, sem iniciar o servidor. Execute o comando onde o servidor é executado, com o ambiente do servidor:

  • Docker Compose: Execute-o no contêiner do servidor. Em Arm, substitua linux_amd64 neste comando por linux_arm64:

    docker compose exec cma-server /opt/cma-server/bin/linux_amd64/cma-server validate-store -config /etc/cma-server/config.yaml
  • Em um host:

    ./cma-server validate-store -config /etc/cma-server/config.yaml
  • Kubernetes: Execute o mesmo comando como um Job sob a service account do servidor.

Uma execução bem-sucedida termina com uma linha que diz pass e sai com o código 0.

Com o Azure Key Vault, execute esta verificação no seu key vault antes de depender dele.

Limites do gerenciador de segredos

  • Escolha as configurações uma única vez. Após qualquer uma destas alterações, o servidor deixa de encontrar os segredos que gravou antes da alteração:

    • Você remove a seção secret_store.
    • Você altera type, prefix, region, project, vault_url, mount ou namespace. Os dois últimos são configurações opcionais do HashiCorp Vault.
    • Você aponta address para outro Vault.

    O servidor só volta a encontrar esses segredos quando você restaura os valores antigos.

  • Uma única identidade lê todo o prefixo. Se dois grupos não puderem acessar as credenciais um do outro, dê a cada grupo sua própria implantação. Cada implantação precisa de seu próprio prefixo ou key vault e de sua própria identidade.

Credenciais de variável de ambiente

Com uma credencial de variável de ambiente, os comandos de um agente podem chamar um serviço enquanto o sandbox mantém apenas um placeholder para o segredo. O gateway de saída coloca o valor real nas solicitações aos hosts que a credencial lista.

O gateway, cma-egress, é um proxy no arquivo da versão que fica entre seus sandboxes e a internet. Ele fica desativado por padrão, e seu servidor aceita essas credenciais somente com o gateway ativado.

Com o gateway ativado, dois limites se aplicam aos seus sandboxes:

  • Os sandboxes acessam a internet somente por meio do gateway.
  • O gateway se conecta apenas aos hosts que você lista na configuração egress.allowed_hostnames do servidor.

Liste nomes de host públicos exatos, sem curingas. Inclua todos os hosts dos quais os comandos dos seus agentes fazem downloads.

Se você criou sua própria imagem de sandbox, inicie o worker por meio de cma-with-egress, como Criar sua própria imagem de sandbox mostra.

Ativar o gateway na stack do Compose

No diretório que contém docker-compose.yml, adicione duas linhas a .env. A primeira lista os hosts aos quais o gateway se conecta, separados por vírgulas. A segunda carrega o arquivo Compose do gateway. Em seguida, inicie a stack:

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

Se você também usar outro arquivo Compose, adicione-o à linha COMPOSE_FILE. Uma variável COMPOSE_FILE no seu shell substitui a de .env, então remova a definição da variável do shell.

O arquivo do gateway define as outras configurações egress do servidor, portanto não adicione uma seção egress a compose.config.yaml.

Ativar o gateway no Kubernetes

Estas etapas partem da implantação em Implantar no Kubernetes. Elas usam as variáveis REGISTRY, TAG e PLATFORM dessa página e seus dois arquivos de valores. Execute os comandos a partir do diretório principal do arquivo, com OpenSSL 3.0 ou posterior. O chart do sandbox não oferece o gateway no Azure Kubernetes Service (AKS).

O upgrade do chart do servidor nestas etapas também adiciona uma política de rede sobre os pods dos servidores. Verifique duas das portas que ela abrange antes de começar:

  • Porta 9464, a porta de métricas: A política a fecha. Se o Prometheus coletar métricas dessa porta, defina server.telemetry.prometheus.scraper.namespace em cma-server-values.yaml como o namespace em que o Prometheus é executado.
  • Porta 8400, a porta da API: A política admite qualquer origem. Se uma política sua limitar quem acessa a porta 8400, esse limite deixa de funcionar. As políticas de rede se somam, portanto uma conexão passa se qualquer uma das políticas a admitir.
  1. Compilar e enviar a imagem do gateway

    docker buildx build --platform "$PLATFORM" -f kubernetes/egress/Dockerfile -t "$REGISTRY/cma-egress:$TAG" --push .
  2. Criar a autoridade certificadora e a chave do gateway

    (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

    Em seguida, exclua egress-ca.key, a chave privada da autoridade certificadora. Qualquer pessoa que a detenha pode se passar por qualquer site perante seus sandboxes. O certificado é válido por 825 dias. Consulte Renovar o certificado.

  3. Remover os sandboxes de sessões anteriores

    Se o ambiente não executou nenhuma sessão, pule esta etapa. Um sandbox de antes da alteração não consegue iniciar seu worker depois dela. Estes comandos também excluem o workspace de cada sandbox:

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

    No Google Kubernetes Engine (GKE), execute também este comando:

    kubectl -n cma delete sandboxes --all

    Repita kubectl -n cma get sandboxes,pods,pvc até que ele não encontre nada. O helm upgrade da etapa “Ativar o lado dos sandboxes” inicia o dispatcher novamente.

  4. Ativar o lado do servidor

    Escolha um endereço IPv4 livre no intervalo de Services do cluster para o gateway. A coluna CLUSTER-IP de kubectl get svc -A mostra endereços nesse intervalo. Adicione isto a cma-server-values.yaml. Se o arquivo já tiver um bloco server, mescle estas linhas nele:

    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

    Em seguida, execute o upgrade:

    helm upgrade cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait
  5. Ativar o lado dos sandboxes

    Execute kubectl -n cma-server get svc para listar os dois Services do servidor. Em uma nova instalação, eles se chamam cma-server e cma-server-egress.

    Em cma-values.yaml, altere egress.mode para gateway e adicione um bloco gateway sob egress. Dê ao bloco os dois nomes que o comando listou:

    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

    Mantenha os outros valores egress do arquivo. Para imprimir os endereços e a porta do endpoint da API, execute kubectl get endpoints kubernetes -n default. Se a porta não for 443, defina também egress.gateway.apiServerPort.

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

    Se o upgrade parar em um conflito sobre .spec.replicas, execute kubectl -n cma scale deployment cma-dispatcher --replicas=1 e, em seguida, execute o upgrade novamente.

Adicionar uma credencial

Crie uma credencial de variável de ambiente como Adicionar uma credencial mostra. Os guias do serviço hospedado dizem que essas credenciais não são suportadas com sandboxes auto-hospedados. Isso descreve o serviço hospedado, não o seu servidor.

Seu servidor adiciona regras próprias. Ele recusa uma solicitação que viole uma delas com um erro 400 que nomeia o campo. Duas dessas regras são:

  • networking deve ter o tipo limited, e todos os hosts em allowed_hosts devem estar na lista egress.allowed_hostnames do servidor.
  • injection_location deve ser {"header": true} em JSON e não pode ser omitido.

Depois de adicionar um host à lista do servidor, aplique a alteração. No Docker Compose, execute docker compose up -d. No Kubernetes, execute o comando helm upgrade do servidor e kubectl -n cma-server rollout restart deployment -l anthropic.com/role=server.

Verificar o gateway de saída

Crie uma sessão com o vault da credencial e peça ao agente para executar dois comandos. Este exemplo é para uma credencial chamada GITHUB_TOKEN que lista api.github.com:

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

O primeiro comando imprime um placeholder que começa com cma_ph_. O segundo imprime o perfil da conta do GitHub do token, porque o gateway substituiu o placeholder pelo token. O gateway recusa uma solicitação a um host que não está na sua lista com um erro 403.

No Kubernetes, se todas as solicitações receberem um erro 503, a rede do seu cluster provavelmente reescreve os endereços dos pods, como faz a opção --masquerade-all do kube-proxy. O gateway distingue os sandboxes pelos endereços de seus pods, portanto esses endereços devem chegar a ele inalterados.

Renovar o certificado

No Kubernetes, renove o certificado enquanto nenhuma sessão estiver em execução. Repita toda a etapa “Criar a autoridade certificadora e a chave do gateway” em Ativar o gateway no Kubernetes. Ela cria a autoridade certificadora e a chave do gateway novamente, portanto você não precisa do arquivo egress-ca.key que excluiu. Faça uma alteração: adicione --dry-run=client -o yaml | kubectl apply -f - ao final de cada uma das quatro linhas que executam kubectl create. Uma linha que termina em --from-file=gateway-key=/dev/stdin, por exemplo, passa então a terminar em --from-file=gateway-key=/dev/stdin --dry-run=client -o yaml | kubectl apply -f -.

Em seguida, reinicie os servidores e o gateway:

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

Limites do gateway de saída

  • Cabeçalhos: O gateway coloca um valor apenas em um cabeçalho de solicitação, nunca em uma URL ou em um corpo. Por padrão, o único cabeçalho é Authorization. Para permitir outros, liste-os junto com Authorization em egress.swap_header_names, ou em CMA_EGRESS__SWAP_HEADER_NAMES em .env para a stack do Compose.
  • Programas que ignoram variáveis de proxy: Os sandboxes encontram o gateway por meio de HTTPS_PROXY e variáveis relacionadas. Ferramentas Java como Maven e Gradle não leem essas variáveis, portanto não alcançam nada.

Esta página foi útil?