Proteggere l'agente Amazon Bedrock con Microsoft Entra Agent ID

Questa guida illustra come proteggere un agente Amazon Bedrock usando Microsoft Entra ID Auth SDK (sidecar) per eseguire l'autenticazione alle API downstream. Il sidecar viene eseguito come contenitore separato e gestisce tutte le credenziali e lo scambio di token con Microsoft Entra ID. L'agente richiede un'intestazione di autorizzazione dal sidecar e il sidecar gestisce lo scambio OAuth 2.0 con Microsoft Entra ID.

Prerequisiti

Prima di iniziare, assicurarsi di avere:

Clonare il repository di esempio:

  1. Clonare il repository e passare alla directory di esempio aws:

    git clone https://github.com/microsoft/entra-agentid-samples.git
    cd entra-agentid-samples/sidecar/aws
    

Architettura

L'SDK di autenticazione di Microsoft Entra ID (sidecar) si colloca tra l'agente e Microsoft Entra ID. L'agente non comunica mai con Microsoft Entra ID direttamente e non gestisce mai le credenziali. Chiede al sidecar di un'intestazione Authorization di chiamare un'API downstream. Amazon Bedrock gestisce separatamente l'inferenza LLM, senza doversi preoccupare dell'identità.

Diagramma che mostra il flusso del token tra l'agente Bedrock, sidecar, Microsoft Entra ID e l'API Meteo.

L'esempio esegue tre contenitori in una rete Docker bridge:

  • llm-agent-aws: App Flask con un'interfaccia utente per chat e un agente LangGraph ReAct che utilizza Amazon Bedrock (Claude) per svolgere il ragionamento. Esposto sulla porta 3001.
  • agent-id-sidecar-aws: Il contenitore sidecar ufficiale di Microsoft Entra ID Auth SDK. Acquisisce e memorizza nella cache i token. Nessuna porta host raggiungibile solo dall'interno della rete Docker.
  • weather-api-aws: API downstream che convalida il token JWT dell'agente (firma, autorità di certificazione, scadenza, gruppo di destinatari) su ogni richiesta e restituisce i dati meteo.

La richiesta scorre attraverso questi passaggi:

  1. Digitare una query nell'interfaccia utente della chat all'indirizzo http://localhost:3001.
  2. L'app Flask invia la query a AWS Bedrock (Claude) tramite l'agente LangGraph ReAct.
  3. Quando Claude decide di avere bisogno di dati meteo, chiama lo get_weather strumento.
  4. Lo strumento richiede al sidecar un'intestazione di autorizzazione chiamando GET /AuthorizationHeader?AgentIdentity={agentId}.
  5. Il sidecar esegue l'autenticazione per Microsoft Entra ID usando lo scambio OAuth 2.0 (credenziali client o OBO).
  6. Microsoft Entra ID restituisce il token richiesto (TR) al sidecar.
  7. L'agente chiama l'API meteo con Authorization: Bearer TR.
  8. L'API meteo convalida TR e restituisce la risposta JSON meteo.

Comprendere il flusso del token

Tre token sono coinvolti nello scambio di identità:

Token Rilasciato a Quando Come
Tc Utente connesso Solo flusso OBO MSAL.js nel browser
T1 App progetto Entrambi i flussi Sidecar (credenziali del cliente)
TR Agente (API downstream) Entrambi i flussi Sidecar-app-only (autonomo) oppure scambio OBO

Nel flusso autonomo, il sidecar utilizza le credenziali client per ottenere T1, quindi lo scambia con TR con ambito definito sull'API downstream. Nel flusso OBO, il sidecar riceve anche Tc (token dell'utente) ed esegue uno scambio OBO per ottenere TR, che opera per conto dell'utente autenticato.

In questa configurazione, solo l'interfaccia utente della chat (porta 3001) viene esposta all'host. L'API sidecar e meteo è raggiungibile solo all'interno della rete Docker, che stabilisce un limite di sicurezza chiaro.

Scegliere una modalità di esecuzione e un flusso di identità

L'esempio supporta due modalità di esecuzione e due flussi di identità che è possibile combinare:

Autonomo (solo per app) OBO (per conto dell'utente)
Diretto (assenza di LLM) Percorso demo rapido. Il token è stato recuperato e l'API meteo è stata richiamata direttamente. Stesso, ma usa l'endpoint sidecar autenticato con il token utente.
Bedrock + LangChain L'agente LangGraph ReAct decide quando chiamare get_weather. Stesso, ma l'agente passa il token utente attraverso quando viene eseguito lo strumento.

Usare la modalità diretta per verificare il flusso di token end-to-end senza dover accedere a AWS Bedrock. Passare alla modalità Bedrock per l'esperienza completa dell'agente.

Scegliere un livello di autenticazione AWS

L'esempio supporta tre modi per eseguire l'autenticazione ad Amazon Bedrock. Scegliere il livello corrispondente all'ambiente:

  • Credenziali STS temporanee: Ideali per lo sviluppo locale con AWS SSO. Impostare AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYe AWS_SESSION_TOKEN nel .env file. Queste credenziali scadono dopo circa un'ora.
  • Chiave API Bedrock: Ideale per demo e workshop. Impostare AWS_BEARER_TOKEN_BEDROCK nel .env file. Limitato esclusivamente a Bedrock con una durata configurabile.
  • OIDC federation: Ideale per distribuzioni di produzione su Servizio app di Azure. AWS_ROLE_ARN e AWS_WEB_IDENTITY_TOKEN_FILE impostati dalla piattaforma. Nessun segreto archiviato ovunque.

Tip

Per le distribuzioni di produzione, vedere la guida alla distribuzione Servizio app di Azure per istruzioni dettagliate sulla configurazione della federazione OIDC tra Azure e AWS con zero segreti archiviati.

Selezionare un modello Bedrock

L'esempio usa per impostazione predefinita us.anthropic.claude-3-haiku-20240307-v1:0 perché è il modello di Anthropic più economico su Bedrock e supporta la chiamata agli strumenti. Il us. prefisso indica un profilo di inferenza tra aree che instrada tra aree degli Stati Uniti per una maggiore disponibilità.

Altri modelli supportati:

ID modello Costo per 1000 token di input Notes
us.anthropic.claude-3-haiku-20240307-v1:0 $ 0,00025 Predefinito. Veloce, più economico, supporta le chiamate di strumenti.
us.anthropic.claude-3-5-haiku-20241022-v1:0 $ 0,0008 Più recente, più intelligente, ancora conveniente.
us.anthropic.claude-3-5-sonnet-20241022-v2:0 $ 0,003 Migliore rapporto qualità/costo.

Eseguire l'override dell'impostazione predefinita impostando BEDROCK_MODEL_ID nel .env file. È necessario abilitare ogni modellonell'accesso al modello della > AWS Bedrock prima di poterlo richiamare.

Creare gli oggetti Microsoft Entra (configurazione per la prima volta)

Se si dispone già di un .env file di un'esecuzione precedente con BLUEPRINT_APP_ID popolato, passare a Configurare le variabili di ambiente.

Eseguire i comandi seguenti una volta per ogni tenant per creare l'app Blueprint, l'ID agente e l'app SPA usata per l'accesso OBO.

  1. Creare l'app Blueprint e l'ID agente per il flusso autonomo seguendo il flusso di lavoro di PowerShell in Creare un progetto di identità agente e Creare identità agente. Alla fine hai:

    • TENANT_ID: tenant Microsoft Entra.
    • BLUEPRINT_APP_ID: registrazione dell'app Blueprint.
    • BLUEPRINT_CLIENT_SECRET: Segreto cliente per il Blueprint.
    • AGENT_CLIENT_ID: ID agente creato dal progetto.
  2. (Facoltativo) Creare l'app SPA e configurare OBO. Questo passaggio è obbligatorio solo se si vuole usare il flusso di identità OBO:

    Esegui gli script seguenti per creare la registrazione dell'applicazione SPA e configurare le autorizzazioni OBO nel Blueprint. Gli script registrano l'URI di reindirizzamento spa e concedono le autorizzazioni delegate necessarie.

    Bash:

    bash ../../scripts/setup-obo-client-app.sh
    bash ../../scripts/setup-obo-blueprint.sh
    

    PowerShell:

    pwsh ../../scripts/setup-obo-client-app.ps1
    pwsh ../../scripts/setup-obo-blueprint.ps1 `
        -TenantId        '<TENANT_ID>' `
        -BlueprintAppId  '<BLUEPRINT_APP_ID>' `
        -AgentAppId      '<AGENT_CLIENT_ID>' `
        -ClientSpaAppId  '<CLIENT_SPA_APP_ID>'
    

L'URI di reindirizzamento spa per questo esempio è http://localhost:3001 (porta 3001, non 3003). Assicurarsi che questo URI sia registrato.

Configurare le variabili di ambiente

Il sidecar supporta più tipi di credenziali tramite l'impostazione AzureAd__ClientCredentials__0__SourceType in docker-compose.yml:

  • ClientSecret: solo sviluppo locale. L'esempio include questo tipo.
  • SignedAssertionFromManagedIdentity: Distribuito in Azure. Zero segreti, consigliato per la produzione.
  • KeyVault: Certificato da Azure Key Vault.
  • StoreWithThumbprint: Certificato dall'archivio del computer locale.
  1. Creare un file di configurazione locale .env dal modello incluso. Questo file archivia le credenziali del tenant, dell'app e di AWS:

Bash:

cp .env.example .env

PowerShell:

Copy-Item .env.example .env
  1. Impostare le variabili seguenti nel .env file:

    • TENANT_ID: Il tuo ID del tenant Microsoft Entra.
    • BLUEPRINT_APP_ID: registrazione dell'app Blueprint. Il sidecar esegue l'autenticazione come questa app.
    • BLUEPRINT_CLIENT_SECRET: segreto client del progetto (solo sviluppo locale).
    • AGENT_CLIENT_ID: Il tuo ID agente. Viene visualizzato come parametro di AgentIdentity query.
    • CLIENT_SPA_APP_ID: ID app SPA usato da MSAL.js per l'accesso al browser (solo OBO).
    • AWS_REGION: regione AWS, ad esempio us-east-2, per Bedrock.
    • BEDROCK_MODEL_ID: ID modello. Impostazione predefinita: us.anthropic.claude-3-haiku-20240307-v1:0.
    • VALIDATE_TOKEN_SIGNATURE: valore predefinito true. Impostare su false per ignorare la convalida della firma JWKS nell'API meteo (solo debug).
  2. Aggiungere le credenziali AWS in base al livello scelto:

    • Livello A (STS): Impostare AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYe AWS_SESSION_TOKEN.
    • Livello B (chiave API): Impostare AWS_BEARER_TOKEN_BEDROCK.
    • Livello C (OIDC): Configurato tramite le impostazioni dell'app della piattaforma, non in .env.

Tip

Se si ha già un oggetto .env di una sessione precedente, è sufficiente aggiornare le credenziali AWS (token STS scadono dopo circa un'ora). Vai direttamente a Avvia lo stack.

Avvia lo stack

  1. Verificare che Docker Desktop (o il motore Docker) sia in esecuzione nel computer.

  2. Compilare le immagini del contenitore e avviare tutti e tre i servizi (agente, sidecar e API meteo) in modalità scollegata:

    docker compose up --build -d
    
  3. Verificare che tutti i contenitori siano stati avviati correttamente interrogando l'endpoint di stato. La risposta segnala se l'agente può raggiungere AWS Bedrock:

    Bash:

    curl http://localhost:3001/api/status
    

    PowerShell:

    Invoke-RestMethod http://localhost:3001/api/status
    

    Viene visualizzata una risposta che indica bedrock_available: true (o false se si usa la modalità diretta senza credenziali AWS).

Important

Quando si aggiorna .env (ad esempio, per aggiornare le credenziali stS scadute), docker compose restart non ricarica le variabili di ambiente. Utilizzare invece docker compose up -d --force-recreate llm-agent-aws.

Inviare una query tramite l'interfaccia utente della chat

  1. Aprire http://localhost:3001 nel browser.

  2. Usare la barra di intestazione per configurare la demo:

    • Modalità di esecuzione:Direct (ignorare LLM) o Bedrock (agente LangChain ReAct su Claude).
    • Flusso di identità:Autonomous (token solo app) o OBO (agisce per un utente autenticato).
  3. Se si seleziona OBO, selezionare Accedi per eseguire l'autenticazione tramite il popup MSAL.js.

  4. Digitare una query come "Weather in Dallas?" e selezionare Invia.

  5. Guarda il pannello Identity Trace, Traccia identità, a destra per una suddivisione dettagliata, passo per passo, di ogni scambio di token e chiamata API. Il pannello mostra schede JWT codificate a colori per ogni token (Tc, T1, TR) con attestazioni decodificate.

Risolvere i problemi comuni

Se qualcosa non funziona come previsto, controllare la tabella seguente per individuare i problemi e le correzioni comuni:

Sintomo Causa possibile Correzione
/api/status Mostra bedrock_available: false Credenziali AWS mancanti o scadute o accesso al modello non concesso. Controllare docker logs llm-agent-aws. Aggiornare le credenziali STS con aws sso login. Abilitare il modello nella console Bedrock.
ExpiredTokenException da Bedrock Token di sessione STS (livello A) scaduto. Incollare le credenziali nuove in .env, quindi eseguire docker compose up -d --force-recreate llm-agent-aws.
AccessDeniedException su InvokeModel L'entità IAM non dispone dell'autorizzazione bedrock:InvokeModel o l'accesso al modello non risulta abilitato. Concedere bedrock:InvokeModel gli APN del modello e del profilo di inferenza.
ValidationException: invalid model identifier L'area non ospita il modello, oppure è stato usato un ID modello semplice anziché il us. profilo di inferenza. Usare l'ID us.del profilo di inferenza con prefisso , ad esempio us.anthropic.claude-3-haiku-20240307-v1:0.
L'API meteo restituisce 401 Unauthorized Mancata corrispondenza del tenant del token, segreto scaduto o verifica della firma non riuscita. Verificare TENANT_ID corrisponda al tenant del Blueprint. Controllare i log sidecar.
LLM risponde senza chiamare lo strumento La query non era chiaramente a forma di strumento o il modello non supporta la chiamata agli strumenti. Usa Claude 3 Haiku o versione successiva. Formula la richiesta come "Com'è il tempo a <città>?".
Popup di accesso OBO bloccato Blocco popup del browser. Consenti popup per localhost:3001.
4xx dal sidecar durante OBO CLIENT_SPA_APP_ID mancata corrispondenza dell'URI di reindirizzamento o SPA mancante. Rieseguire setup-obo-client-app. Assicurarsi che http://localhost:3001 sia presente negli URI di reindirizzamento della SPA.

Se un problema persiste anche dopo aver eseguito la procedura di risoluzione dei problemi, esaminare direttamente i log del contenitore. Ogni servizio scrive i log nel proprio container:

docker logs llm-agent-aws          # Agent app: Bedrock calls, tool invocations
docker logs agent-id-sidecar-aws   # Sidecar: token acquisition, credential errors
docker logs weather-api-aws        # Weather API: JWT validation, request handling

Pulire le risorse

Al termine del test, arrestare i contenitori locali per liberare le risorse di sistema. Scegliere una delle opzioni di pulizia seguenti in base alla possibilità di mantenere le immagini per riavvii più veloci.

Important

docker compose down rimuove solo i contenitori Docker locali. Gli oggetti Microsoft Entra (blueprint dell'agente, ID dell'agente, registrazione dell'app SPA) costituiscono lo stato lato tenant e persistono. Eliminarli manualmente nel Interfaccia di amministrazione di Microsoft Entra se non sono più necessari.

# Stop containers but keep volumes and images for faster restarts
docker compose down

# Remove everything including volumes and images
docker compose down -v --rmi all