Claude Platform Docs
Managed AgentsConfigurazione aziendale

Identità e credenziali dell’agente

Fai firmare al tuo server Claude Managed Agents self-hosted un token di breve durata che identifica ciascun agente, conserva le credenziali dei vault nel tuo gestore di segreti e tieni i segreti fuori dalle sandbox con l’egress gateway.

Questa pagina mostra come consentire ai sistemi esterni al tuo server di fidarsi di un agente e dove conservare le credenziali usate dai tuoi agenti:

  • Identità dell’agente: consenti a un server MCP o a un gateway di concedere a ciascun agente il proprio accesso. Il server firma un token di breve durata che identifica l’agente.
  • Gestore di segreti: il server conserva le credenziali dei vault in AWS Secrets Manager, Google Cloud Secret Manager, HashiCorp Vault o Azure Key Vault.
  • Credenziali delle variabili d’ambiente: consenti ai comandi di un agente di chiamare un servizio mentre la sandbox contiene solo un segnaposto. L’“egress gateway” (gateway di uscita) inserisce il valore reale nelle richieste dell’agente.

Identità dell’agente

Il tuo server può firmare un “JSON Web Token” (token web JSON), o JWT, di breve durata che identifica un agente, e inviarlo insieme alle chiamate MCP di quell’agente. Il destinatario, un server MCP o un gateway, verifica il token rispetto alle chiavi pubbliche che pubblichi e può quindi concedere a ciascun agente il proprio accesso.

Configurare l’emittente

  1. Scegli l’URL dell’emittente. Nel passaggio 3 pubblichi le tue chiavi pubbliche a questo URL, e i destinatari le recuperano da lì. Va bene un host web statico. Non usare l’indirizzo del tuo server, perché il server non serve le chiavi ai percorsi da cui i destinatari le recuperano. Usa un URL https:// senza percorso né barra finale, su un nome host che puoi mantenere.

  2. Crea la chiave di firma. Esegui questi comandi nella directory principale dell’archivio estratto:

    mkdir -m 700 agent-identity
    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out agent-identity/signing-key.pem
  3. Pubblica le chiavi pubbliche. Questo comando le scrive in issuer-files/.well-known/. Servi issuer-files alla radice del nome host dell’emittente, con il content type 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. Fornisci la chiave al server.

    1. Se l’archivio ha una directory compose, sposta al suo interno la directory della chiave: mv agent-identity compose/agent-identity.
    2. In docker-compose.yml, elimina la riga volumes: *server_mounts del servizio cma-server e rimuovi il commento dal blocco volumes: sottostante. Se hai modificato l’elenco x-server-mounts, apporta la stessa modifica in quel blocco, perché il servizio cma-server non legge più l’elenco.
    3. Nella directory che contiene agent-identity, esegui sudo chown -R root:root agent-identity, a meno che tu non usi Docker Desktop su macOS o Docker rootless.
  5. Modifica il file delle impostazioni. Elenca il nome host del destinatario in mcp.allowed_hostnames e aggiungi questa sezione:

    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

    Ogni audience identifica un destinatario, come URL https://. I suoi urls sono i prefissi URL dei server MCP che possono ricevere un token per esso.

  6. Riavvia il server. Nello stack Compose, esegui docker compose up -d dalla directory del file Compose invece di un riavvio.

Per tenere la chiave privata fuori dai file, usa key_secret (il tuo gestore dei segreti) oppure kms_key (AWS KMS o Google Cloud KMS). Il riferimento di configurazione descrive entrambe le impostazioni.

Inviare il token a un server MCP

Il connettore MCP descrive i campi della voce del server MCP di un agente. Aggiungi un campo auth a quella voce:

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

Per ogni elenco di strumenti o chiamata a uno strumento, il tuo server firma un nuovo token. Lo invia come Authorization: Bearer <token>, al posto di una credenziale del vault. Né il modello né il worker lo ricevono.

Per inviare sia il token sia una credenziale del vault, sostituisci il campo auth con un 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

La credenziale del vault viene inserita nell’intestazione Authorization, come avviene per una voce senza nessuno dei due campi. Il token viene inserito in un’intestazione Agent-Identity-Token, senza il prefisso Bearer.

L’SDK non dispone dei campi auth e agent_token_header. Nel codice SDK, aggiungi il campo alla voce del server MCP come campo extra, oppure invia la richiesta come JSON semplice.

Queste pagine mostrano come inviare campi extra:

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

Alcune di queste pagine mostrano i campi extra solo al livello superiore di una richiesta, non all’interno di una voce di un elenco. In tal caso, rendi mcp_servers stesso il campo extra. Invia in quel modo l’intero elenco, con auth o agent_token_header nella sua voce.

Per interrompere i token di un agente, rimuovi la voce dall’agente oppure archivia l’agente. Un token già inviato rimane valido fino al suo exp, al massimo 5 minuti per impostazione predefinita.

Cosa verifica il destinatario

Fai in modo che il destinatario accetti una richiesta solo se sono soddisfatte tutte queste condizioni:

  • La firma viene verificata con una chiave del tuo set di chiavi, <issuer>/.well-known/jwks.json. La chiave giusta è quella il cui ID corrisponde a kid nell’intestazione del token. Per una chiave RSA, l’algoritmo è RS256.
  • iss è uguale all’URL del tuo emittente e aud è uguale all’audience del destinatario.
  • exp è nel futuro e iat non è nel futuro.
  • typ nell’intestazione del token è agent+jwt e token_use è agent.

Quindi applica queste regole:

  • Basa le regole di accesso di ciascun agente sulla claim agent_id, l’ID dell’agente nell’API.
  • Accetta un jti ripetuto, perché un singolo elenco o una singola chiamata può comportare diverse richieste con lo stesso token.
  • Fai in modo che un gateway chiami ogni strumento con la propria credenziale e non inoltri mai il token.

Con il single sign-on, il token di una chiamata a uno strumento identifica anche il chiamante che ha creato la sessione, nelle claim actor_sub e actor_iss. actor_sub non significa che il chiamante abbia approvato la chiamata. È il modello a scegliere ogni chiamata.

Questi token non hanno actor_sub:

  • Il token di un elenco di strumenti
  • Il token di una chiamata di un subagente
  • Ogni token di una sessione creata dalla chiave API del server

Se una regola dipende dal chiamante, rifiuta una chiamata a uno strumento che non ha actor_sub.

Testare il gateway MCP

Il comando check-gateway invia a un gateway MCP token validi e non validi. Fornisci al comando un file delle impostazioni dedicato, qui check-gateway.yaml:

  1. Copia nel file solo le sezioni mcp e agent_identity delle impostazioni del server, e limits.mcp_call_timeout se il server la imposta.
  2. Nella copia, cambia key_file nel percorso della chiave sulla macchina in cui esegui il comando, ad esempio ./agent-identity/signing-key.pem. Se hai spostato la directory in compose, il percorso è ./compose/agent-identity/signing-key.pem.

Per -agent, fornisci l’ID di un agente che il gateway consente. Se la chiave è di proprietà di root, usa sudo.

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

Il comando stampa una riga per ogni richiesta che invia, con la risposta del gateway. Un’esecuzione riuscita stampa quindi una riga che inizia con check-gateway: PASS ed esce con codice 0. Un’esecuzione non riuscita indica cosa è andato storto, in una riga che inizia con check-gateway:, ed esce con codice 1.

Gestore di segreti

Per impostazione predefinita, il server archivia nel proprio database i segreti delle credenziali dei vault. Con una sezione secret_store, il server scrive il segreto di ogni nuova credenziale del vault nel tuo gestore di segreti, sotto un prefisso di nome che riservi a tale scopo. Il database conserva solo un riferimento.

Aggiungi il blocco per il tuo gestore di segreti al file delle impostazioni:

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

Concedere l’accesso

Assegna al server un’unica identità e limitala al prefisso. La directory iam/ dell’archivio contiene un file per ogni gestore di segreti:

  • AWS Secrets Manager: Sostituisci i segnaposto in aws-secrets-manager-policy.json e associa la policy all’identità con cui viene eseguito il server.
  • Google Cloud Secret Manager: Esegui i comandi presenti nei commenti di gcp-secret-manager-role.yaml.
  • Azure Key Vault: Un ruolo Azure copre un intero key vault, non un prefisso. Quindi assegna al deployment un key vault dedicato, che usi il controllo degli accessi in base al ruolo di Azure. Sostituisci SUBSCRIPTION_ID in azure-key-vault-role.json e crea da esso un ruolo personalizzato. Assegna il ruolo sul key vault all’identità con cui viene eseguito il server.
  • HashiCorp Vault: Sostituisci i segnaposto in hashicorp-vault-policy.hcl e associa la policy all’identità con cui viene eseguito il server.

Verso AWS e Google Cloud, il server si autentica come fa per l’inferenza. Verso Azure Key Vault, si autentica con Microsoft Entra ID, come fa per Microsoft Foundry.

Verificare la configurazione

Esegui validate-store prima del primo avvio e dopo ogni modifica alle policy. Crea, legge ed elimina un secret di test sotto il prefisso, senza avviare il server. Esegui il comando dove viene eseguito il server, con l’ambiente del server:

  • Docker Compose: Eseguilo nel container del server. Su Arm, sostituisci linux_amd64 in questo comando con linux_arm64:

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

    ./cma-server validate-store -config /etc/cma-server/config.yaml
  • Kubernetes: Esegui lo stesso comando come Job con il service account del server.

Un’esecuzione riuscita termina con una riga che riporta pass ed esce con codice 0.

Con Azure Key Vault, esegui questa verifica sul tuo key vault prima di farvi affidamento.

Limitazioni del gestore di segreti

  • Scegli le impostazioni una sola volta. Dopo una qualsiasi di queste modifiche, il server non trova più i secret che ha scritto prima della modifica:

    • Rimuovi la sezione secret_store.
    • Modifichi type, prefix, region, project, vault_url, mount o namespace. Gli ultimi due sono impostazioni facoltative di HashiCorp Vault.
    • Punti address a un altro Vault.

    Il server ritrova quei secret solo quando ripristini i vecchi valori.

  • Un’unica identità legge l’intero prefisso. Se due gruppi non devono poter accedere alle credenziali l’uno dell’altro, assegna a ciascun gruppo un proprio deployment. Ogni deployment necessita di un proprio prefisso o key vault e di una propria identità.

Credenziali delle variabili d’ambiente

Con una credenziale di variabile d’ambiente, i comandi di un agente possono chiamare un servizio mentre la sandbox contiene solo un segnaposto per il segreto. L’egress gateway inserisce il valore reale nelle richieste dirette agli host elencati dalla credenziale.

Il gateway, cma-egress, è un proxy incluso nell’archivio della release che si trova tra le tue sandbox e internet. È disattivato per impostazione predefinita, e il tuo server accetta queste credenziali solo con il gateway attivo.

Con il gateway attivo, alle tue sandbox si applicano due limitazioni:

  • Le sandbox raggiungono internet solo attraverso il gateway.
  • Il gateway si connette solo agli host che elenchi nell’impostazione egress.allowed_hostnames del server.

Elenca nomi host pubblici esatti, senza caratteri jolly. Includi ogni host da cui i comandi dei tuoi agenti scaricano contenuti.

Se hai creato la tua immagine sandbox, avvia il worker tramite cma-with-egress, come mostrato in Creare la tua immagine sandbox.

Attivare il gateway nello stack Compose

Dalla directory che contiene docker-compose.yml, aggiungi due righe a .env. La prima elenca gli host a cui si connette il gateway, separati da virgole. La seconda carica il file Compose del gateway. Quindi avvia lo 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 usi anche un altro file Compose, aggiungilo alla riga COMPOSE_FILE. Una variabile COMPOSE_FILE nella tua shell ha la precedenza su quella in .env, quindi annulla l’impostazione della variabile della shell.

Il file del gateway imposta le altre impostazioni egress del server, quindi non aggiungere una sezione egress a compose.config.yaml.

Attivare il gateway su Kubernetes

Questi passaggi partono dal deployment descritto in Distribuire su Kubernetes. Usano le variabili REGISTRY, TAG e PLATFORM di quella pagina e i suoi due file di valori. Esegui i comandi dalla directory principale dell’archivio, con OpenSSL 3.0 o versione successiva. Il chart della sandbox non offre il gateway su Azure Kubernetes Service (AKS).

L’upgrade del chart del server in questi passaggi aggiunge anche una network policy sui pod dei server. Prima di iniziare, verifica due delle porte che copre:

  • Porta 9464, la porta delle metriche: La policy la chiude. Se Prometheus esegue lo scraping di quella porta, imposta server.telemetry.prometheus.scraper.namespace in cma-server-values.yaml sul namespace in cui viene eseguito Prometheus.
  • Porta 8400, la porta dell’API: La policy ammette qualsiasi origine. Se una tua policy limita chi raggiunge la porta 8400, quel limite smette di funzionare. Le network policy si sommano, quindi una connessione passa se una qualsiasi policy la ammette.
  1. Crea ed esegui il push dell’immagine del gateway

    docker buildx build --platform "$PLATFORM" -f kubernetes/egress/Dockerfile -t "$REGISTRY/cma-egress:$TAG" --push .
  2. Crea l’autorità di certificazione e la chiave del 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

    Quindi elimina egress-ca.key, la chiave privata dell’autorità di certificazione. Chiunque la detenga può impersonare qualsiasi sito web nei confronti delle tue sandbox. Il certificato è valido per 825 giorni. Consulta Rinnovare il certificato.

  3. Rimuovi le sandbox delle sessioni precedenti

    Se l’ambiente non ha eseguito sessioni, salta questo passaggio. Una sandbox precedente alla modifica non può avviare il proprio worker dopo di essa. Questi comandi eliminano anche lo spazio di lavoro di ciascuna sandbox:

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

    Su Google Kubernetes Engine (GKE), esegui anche questo comando:

    kubectl -n cma delete sandboxes --all

    Ripeti kubectl -n cma get sandboxes,pods,pvc finché non trova più nulla. Il helm upgrade nel passaggio “Attiva il lato delle sandbox” riavvia il dispatcher.

  4. Attiva il lato del server

    Scegli per il gateway un indirizzo IPv4 libero nell’intervallo dei Service del cluster. La colonna CLUSTER-IP di kubectl get svc -A mostra gli indirizzi in quell’intervallo. Aggiungi quanto segue a cma-server-values.yaml. Se il file ha già un blocco server, unisci queste righe al suo interno:

    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

    Quindi esegui l’upgrade:

    helm upgrade cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait
  5. Attiva il lato delle sandbox

    Esegui kubectl -n cma-server get svc per elencare i due Service del server. In una nuova installazione, sono denominati cma-server e cma-server-egress.

    In cma-values.yaml, cambia egress.mode in gateway e aggiungi un blocco gateway sotto egress. Inserisci nel blocco i due nomi elencati dal comando:

    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

    Mantieni gli altri valori egress del file. Per stampare gli indirizzi e la porta dell’endpoint API, esegui kubectl get endpoints kubernetes -n default. Se la porta non è 443, imposta anche egress.gateway.apiServerPort.

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

    Se l’upgrade si interrompe per un conflitto su .spec.replicas, esegui kubectl -n cma scale deployment cma-dispatcher --replicas=1, quindi esegui di nuovo l’upgrade.

Aggiungere una credenziale

Crea una credenziale di variabile d’ambiente come mostrato in Aggiungere una credenziale. Le guide del servizio ospitato indicano che queste credenziali non sono supportate con le sandbox self-hosted. Ciò descrive il servizio ospitato, non il tuo server.

Il tuo server aggiunge regole proprie. Rifiuta una richiesta che ne viola una con un errore 400 che indica il campo. Due di queste regole sono le seguenti:

  • networking deve avere il tipo limited e ogni host in allowed_hosts deve trovarsi nell’elenco egress.allowed_hostnames del server.
  • injection_location deve essere {"header": true} in JSON e non può essere omesso.

Dopo aver aggiunto un host all’elenco del server, applica la modifica. Su Docker Compose, esegui docker compose up -d. Su Kubernetes, esegui il comando helm upgrade del server e kubectl -n cma-server rollout restart deployment -l anthropic.com/role=server.

Verificare l’egress gateway

Crea una sessione con il vault della credenziale e chiedi all’agente di eseguire due comandi. Questo esempio riguarda una credenziale denominata GITHUB_TOKEN che elenca api.github.com:

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

Il primo comando stampa un segnaposto che inizia con cma_ph_. Il secondo stampa il profilo dell’account GitHub del token, perché il gateway ha sostituito il segnaposto con il token. Il gateway rifiuta una richiesta verso un host che non è nel tuo elenco con un errore 403.

Su Kubernetes, se ogni richiesta riceve un errore 503, la rete del tuo cluster probabilmente riscrive gli indirizzi dei pod, come fa l’opzione --masquerade-all di kube-proxy. Il gateway distingue le sandbox in base agli indirizzi dei loro pod, quindi tali indirizzi devono raggiungerlo invariati.

Rinnovare il certificato

Su Kubernetes, rinnova il certificato mentre non è in esecuzione alcuna sessione. Ripeti l’intero passaggio “Crea l’autorità di certificazione e la chiave del gateway” in Attivare il gateway su Kubernetes. Crea di nuovo l’autorità di certificazione e la chiave del gateway, quindi non ti serve il file egress-ca.key che hai eliminato. Apporta una sola modifica: aggiungi --dry-run=client -o yaml | kubectl apply -f - alla fine di ciascuna delle quattro righe che eseguono kubectl create. Una riga che termina con --from-file=gateway-key=/dev/stdin, ad esempio, termina quindi con --from-file=gateway-key=/dev/stdin --dry-run=client -o yaml | kubectl apply -f -.

Quindi riavvia i server e il gateway:

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

Limitazioni dell’egress gateway

  • Intestazioni: Il gateway inserisce un valore solo in un’intestazione di richiesta, mai in un URL o in un body. Per impostazione predefinita, l’unica intestazione è Authorization. Per consentirne altre, elencale insieme ad Authorization in egress.swap_header_names, oppure in CMA_EGRESS__SWAP_HEADER_NAMES in .env per lo stack Compose.
  • Programmi che ignorano le variabili proxy: Le sandbox trovano il gateway tramite HTTPS_PROXY e variabili correlate. Strumenti Java come Maven e Gradle non leggono quelle variabili, quindi non raggiungono nulla.

Questa pagina ti è stata utile?