Salta al contenuto principale
Okta for AI Agents: Pattern di Accesso in Profondità
  1. Posts/
  2. Blog/

Okta for AI Agents: Pattern di Accesso in Profondità

Fabio Grasso
Autore
Fabio Grasso
Solutions Engineer specializzato in Identity & Access Management (IAM) e cybersecurity.
Indice dei contenuti
O4AA - Okta for AI Agents - Questo articolo fa parte di una serie.
Parte 3: Questo articolo

Dalla Panoramica all’Implementazione
#

Nella Parte 2 di questa serie ho introdotto i quattro pattern di accesso forniti da Okta for AI Agents (O4AA) — XAA, STS, PSK e Service Account — e il framework strategico per scegliere tra loro. Quell’articolo rispondeva a quale pattern e perché.

Questo deep dive risponde al come. Per ogni pattern analizzo il flusso del protocollo, i diagrammi di sequenza, la struttura del token (dove applicabile), i segnali di audit attesi nei system log di Okta, i casi d’uso in cui si adatta meglio e i passi di configurazione concreti nella console di amministrazione Okta. Se sei un architetto o un solution engineer in procinto di implementare uno di questi pattern, questa è la guida di riferimento da tenere aperta in una seconda scheda.

Come leggere questo articolo

Vai direttamente al pattern che stai implementando — ogni sezione è autoconsistente:


Cross App Access (XAA)
#

Cross App Access (XAA) è il pattern di accesso di punta di Okta for AI Agents. Implementa l’accesso delegato dall’utente e consapevole del contesto utente tramite l’Identity Assertion JWT Authorization Grant (ID-JAG), uno standard IETF emergente per la delega sicura1.

Panoramica di Cross App Access

Perché XAA è Importante
#

XAA è il primo pattern di accesso a incorporare il contesto identitario completo a ogni hop in un workflow agente. Ogni token contiene sia:

  • sub: L’identità utente (chi ha autorizzato l’azione)
  • act.sub: L’identità dell’agente (quale agente sta agendo per conto suo)

Questa struttura a doppia identità abilita capacità impossibili con i tradizionali service account:

  • Attribuzione dell’audit per utente: Ogni azione dell’agente è tracciabile fino all’utente specifico che l’ha autorizzata
  • Revoca chirurgica: Disabilita l’accesso di un utente a un agente senza influenzare altri utenti o agenti
  • Riduzione degli scope: I permessi effettivi del token corrispondono all’intersezione più stretta tra ciò che l’agente può fare, ciò a cui l’utente ha diritto e ciò che il task specifico richiede
  • Conformità normativa: Audit trail completi che soddisfano i requisiti di tracciabilità di NIST SP 800-63-42, EU AI Act3, NIS24 e DORA5

Come Funziona XAA: Il Flusso ID-JAG
#

Il flusso XAA prevede una sequenza di scambio token in cui Okta garantisce l’identità dell’utente al server di autorizzazione della risorsa target.

sequenceDiagram
    autonumber
    actor User
    participant Client as 🤖 Client
(AI Agent) box rgba(243, 242, 247,0.3) Okta Cloud participant IdP as 🔐 IdP AS
(Okta Org AS) participant AS as 🛡️ Resource AS
(Custom AS) end participant RS as 📦 Resource Server
(Protected API) Note over User, RS: Step 1: Autenticazione Utente (OIDC SSO) User->>Client: Avvia azione Client->>IdP: Auth Code + PKCE IdP->>User: Autenticazione (MFA) User-->>IdP: Credenziali IdP-->>Client: ID Token + Refresh Token Note left of IdP: sub:user
aud:client Note over User, RS: Step 2: Token Exchange (RFC 8693) Client->>IdP: Token Exchange Request Note right of Client: grant_type:token-exchange
subject_token:ID_Token
requested_token_type:id-jag
audience:Resource AS IdP->>IdP: Validate ID Token Note right of IdP: private_key_jwt
managed connection policy IdP->>IdP: Generate ID-JAG IdP-->>Client: ID-JAG (Identity Assertion) Note left of IdP: sub:user
aud:Resource AS
client_id:agent Note over User, RS: Step 3: JWT Bearer Grant (RFC 7523) Client->>AS: JWT Bearer Request Note right of Client: grant_type:jwt-bearer
assertion:ID-JAG
scope:orders:read AS->>AS: Validate ID-JAG Note left of AS: aud match
client_id match
signature (JWKS) AS->>AS: Apply Authorization Policy AS-->>Client: Access Token Note left of AS: sub + act.sub + scope
ephemeral Note over User, RS: Step 4: API Call Client->>RS: API call (with Access Token) RS->>RS: Validate Token (JWKS) RS-->>Client: Response data

Analisi passo per passo
#

  1. Autenticazione utente (OIDC SSO): L’utente avvia un’azione tramite l’applicazione client. Il client redirige verso l’Org Authorization Server di Okta usando Authorization Code + PKCE. L’utente si autentica (inclusa MFA se configurata), e Okta emette un ID Token e opzionalmente un Refresh Token. Questo ID Token diventa il subject_token per lo step successivo.
  2. Scambio token in Okta (RFC 8693): L’agente si autentica con le proprie credenziali di workload (private_key_jwt) e richiede uno scambio token (grant_type: token-exchange, subject_token: ID Token, requested_token_type: id-jag, audience: Custom AS). Okta valida il token, verifica la policy della managed connection e genera un ID-JAG — un JWT firmato contenente sub (utente), aud (Custom AS) e client_id (agente).
  3. JWT Bearer grant al Custom AS (RFC 7523): L’agente presenta l’ID-JAG all’endpoint token del Custom AS (grant_type: jwt-bearer, assertion: ID-JAG, scope: orders:read). Il Custom AS valida la firma dell’ID-JAG tramite JWKS, conferma che aud e client_id corrispondano, applica la sua policy di autorizzazione locale ed emette un access token effimero con sub + act.sub.
  4. Chiamata API: L’agente chiama la risorsa protetta con l’access token con scope limitato. La risorsa valida il token tramite JWKS e restituisce i dati.
Nomenclatura IETF e Corrispondenze Okta

Questo diagramma utilizza i nomi dei ruoli della specifica ID-JAG. Ecco come ogni ruolo IETF corrisponde all’implementazione Okta:

Ruolo IETF Corrispondente Okta
Client L’agente IA (o il suo layer di frontend/orchestrazione) — il workload principal registrato in Okta
IdP AS Il server di autorizzazione Org di Okta, basato su Universal Directory e Okta SSO
Resource AS Un Custom Authorization Server in Okta, che protegge le API downstream
Resource Server (RS) La risorsa protetta — un’API interna, un server MCP o un’API di terze parti

In uno scenario reale, il blocco “Client” rappresenta più componenti che lavorano insieme: un’applicazione frontend (chat UI, web app) che gestisce l’autenticazione utente via OIDC, uno strato di orchestrazione che gestisce lo stato della conversazione e le chiamate agli strumenti, e uno o più agenti backend (workload principal) che eseguono gli scambi token. Li ho raggruppati in un unico blocco per mantenere il focus sul flusso protocollare piuttosto che sull’architettura interna.

Presenza Utente e Modello di Consenso
#

Un vantaggio chiave di XAA è l’eliminazione dello step di consenso interattivo presso il Resource Authorization Server. A differenza dei flussi OAuth tradizionali dove ogni risorsa richiede il consenso dell’utente separatamente, in XAA l’IdP valuta le policy definite dall’amministratore e delega l’autorità di autorizzazione. Il Resource AS si fida dell’asserzione dell’IdP senza richiedere conferma all’utente — questo è ciò che oauth.net descrive come accesso “without any user interaction” a livello di risorsa.

Tuttavia, XAA richiede l’autenticazione dell’utente per avviare il flusso. L’utente deve autenticarsi via OIDC SSO (Step 1) affinché l’agente ottenga un ID Token come subject_token per lo scambio token. Ogni azione dell’agente è vincolata all’identità e ai permessi di un utente specifico autenticato.

Operazione Autonoma: Specifica vs. Implementazione

La specifica ID-JAG definisce una capacità opzionale (MAY) che consente alle implementazioni di accettare Refresh Token come subject_token, permettendo agli agenti di ottenere nuovi ID-JAG senza ri-autenticare l’utente. Questo abiliterebbe operazioni completamente autonome per task schedulati o event-driven.

Tuttavia, questa capacità non è ancora documentata nell’implementazione XAA di Okta né su xaa.dev. Oggi, il flusso XAA di Okta richiede un ID Token ottenuto da un’autenticazione utente attiva come subject_token. Per scenari che richiedono operazioni in background senza presenza dell’utente, considera di combinare XAA (quando il contesto utente è disponibile) con altri pattern come PSK o Service Account per le operazioni autonome.

Lo Standard ID-JAG
#

ID-JAG (Identity Assertion JWT Authorization Grant) si basa su diversi standard IETF:

  • RFC 8693: OAuth 2.0 Token Exchange
  • RFC 7523: JWT Profile for OAuth 2.0 Client Authentication
  • IETF ID-JAG Draft: Specifica Identity Assertion JWT Authorization Grant (draft attivo del working group IETF)

Per una panoramica completa di Cross App Access e di come si inserisce nell’ecosistema OAuth, consulta il riferimento Cross App Access su OAuth.net.

L’innovazione chiave è la netta separazione tra identità utente (sub) e identità agente (client_id) come claim distinte e obbligatorie nel token ID-JAG. L’IdP firma un’asserzione che dice “l’utente X ha autorizzato l’agente Y ad agire per suo conto sulla risorsa Z” — tutto in un unico JWT verificabile. A valle, il Resource AS può emettere access token con la claim act (secondo RFC 8693 §4.4) per propagare questa separazione ai resource server, abilitando una chiara audit trail di “per chi è questa azione” rispetto a “quale sistema sta eseguendo l’azione.”

Struttura del Token
#

Il flusso XAA produce due token distinti. Comprendere la differenza è importante per l’implementazione e l’audit.

Il Token ID-JAG (emesso dall’IdP)
#

L’ID-JAG è un JWT firmato emesso dall’IdP Authorization Server durante il token exchange (Step 1). Asserisce l’identità dell’utente e l’autorizzazione dell’agente ad agire per suo conto. L’header JWT deve utilizzare il tipo oauth-id-jag+jwt.

Header: { "typ": "oauth-id-jag+jwt", "alg": "RS256" }
{
  "iss": "https://acme.okta.com",
  "sub": "john@example.com",
  "aud": "https://crm.example.com/oauth2",
  "client_id": "sales-representative-agent",
  "jti": "9e43f81b64a33f20116179",
  "exp": 1735571612,
  "iat": 1735571312,
  "resource": "https://crm.example.com/api",
  "scope": "orders:read accounts:read",
  "auth_time": 1735571200,
  "amr": ["mfa", "pwd"]
}
Claim Stato Scopo
iss REQUIRED Identificatore dell’IdP Authorization Server
sub REQUIRED Identità utente — stesso identificatore utilizzato nel SSO
aud REQUIRED Identificatore del Resource Authorization Server
client_id REQUIRED Identità agente — il client OAuth registrato presso il Resource AS
jti REQUIRED Identificatore univoco del token (per prevenzione replay e correlazione audit)
exp REQUIRED Tempo di scadenza
iat REQUIRED Tempo di emissione
resource OPTIONAL URI del Resource Server target
scope OPTIONAL Scope richiesti (possono essere ridotti dalla policy dell’IdP)
auth_time OPTIONAL Quando l’utente si è autenticato l’ultima volta
amr OPTIONAL Metodi di autenticazione utilizzati (es. mfa, pwd, hwk)
Nota

L’ID-JAG non contiene una claim act. La separazione utente/agente è espressa tramite sub (utente) e client_id (agente). La claim act appare solo nell’access token a valle.

L’Access Token (emesso dal Resource AS)
#

Il Resource AS valida l’ID-JAG (Step 2) ed emette un access token con scope limitato. Questo token propaga la delega tramite la claim act (RFC 8693 §4.4), rendendo entrambe le identità visibili al resource server:

{
  "sub": "john@example.com",
  "act": {
    "sub": "sales-representative-agent",
    "aud": "okta.com"
  },
  "aud": "crm-orders-api",
  "scope": "orders:read accounts:read",
  "jti": "s2r3d4x3m6a0q1l",
  "iat": 1735571312,
  "nbf": 1735571312,
  "exp": 1735571468
}
Claim Scopo Valore Audit/Conformità
sub Identità utente Risponde a: “Quale utente ha autorizzato questa azione?”
act.sub Identità agente Risponde a: “Quale agente ha eseguito questa azione?”
aud Risorsa target Risponde a: “A quale sistema è stato effettuato l’accesso?”
scope Permessi concessi Risponde a: “Quali operazioni erano consentite?”
jti ID transazione Identificatore univoco per la correlazione tra sistemi
exp Scadenza Garantisce accesso effimero; limita il blast radius

Durata del Token
#

La specifica ID-JAG richiede le claim exp (scadenza) e iat (emesso il) in ogni token, ma non impone una durata specifica. Il valore "expires_in": 300 (5 minuti) che appare nella specifica è contrassegnato come RECOMMENDED nella risposta di token exchange — è un esempio, non un requisito fisso.

In pratica, l’amministratore dell’IdP configura la durata del token in base alla postura di sicurezza del deployment. Una durata più breve (es. 5 minuti) limita il blast radius in caso di compromissione del token; una durata più lunga riduce la frequenza degli scambi token per agenti che eseguono workflow multi-step. Il valore corretto dipende dal profilo di rischio, ma l’intento progettuale è chiaro: i token ID-JAG devono essere di breve durata e riemessi frequentemente, non conservati in cache per ore.

Riduzione degli Scope in Azione

Un agente che opera per un sales manager potrebbe avere accesso a orders:read, orders:write e accounts:read. Ma quando elabora un task specifico (“elenca le mie trattative aperte”), la richiesta può essere ridotta al solo orders:read. Il permesso effettivo è sempre l’intersezione di ciò che l’agente può fare, di ciò che l’utente può fare e di ciò che questa specifica richiesta richiede.

Benefici per Audit e Conformità
#

Con XAA, i log di sistema di Okta catturano un contesto ricco per ogni evento di accesso, incluse le identità di utente e agente, gli scope richiesti, la risorsa target e un ID transazione univoco per la correlazione. L’EventType app.oauth2.token.grant.id_jag indica specificamente quando si è verificato uno scambio ID-JAG, fornendo una chiara audit trail per le azioni degli agenti.

Vediamo un esempio di una voce di log di un evento XAA reale dai log di sistema di Okta:

Voce completa del log di sistema Okta per uno scambio ID-JAG (clicca per espandere)
{
  "actor": {
    "id": "wlpxnnu00000B6vxs1d7",
    "type": "PublicClientApp",
    "alternateId": "unknown",
    "displayName": "Pricing Agent",
    "detailEntry": null
  },
  "client": {
    "userAgent": {
      "rawUserAgent": "python-requests/2.33.1",
      "os": "Unknown",
      "browser": "UNKNOWN"
    },
    "zone": "null",
    "device": "Unknown",
    "id": null,
    "ipAddress": "x.x.x.x",
    "geographicalContext": {
      "city": "Ashburn",
      "state": "Virginia",
      "country": "United States",
      "postalCode": "20149",
      "geolocation": {
        "lat": 39.0469,
        "lon": -77.4903
      }
    }
  },
  "displayMessage": "OAuth 2.0 Identity Assertion Authorization Grant is granted",
  "eventType": "app.oauth2.token.grant.id_jag",
  "outcome": {
    "result": "SUCCESS",
    "reason": null
  },
  "published": "2026-04-16T19:27:49.919Z",
  "securityContext": {
    "asNumber": 14618,
    "asOrg": "amazon.com  inc.",
    "isp": "amazon.com  inc.",
    "domain": "amazonaws.com",
    "isProxy": false,
    "ipDetails": {
      "asNumber": 14618,
      "asOrg": "amazon.com  inc.",
      "isp": "amazon.com  inc.",
      "domain": "amazonaws.com"
    }
  },
  "severity": "INFO",
  "debugContext": {
    "debugData": {
      "clientAuthType": "private_key_jwt",
      "grantedScopes": "pricing:margin",
      "subjectTokenIssuer": "https://xxx.oktapreview.com",
      "subjectTokenType": "urn:ietf:params:oauth:token-type:id_token",
      "clientId": "wlpxnnu00000B6vxs1d7",
      "responseTime": "213",
      "requestedTokenType": "urn:ietf:params:oauth:token-type:id-jag",
      "authorizationServerAudience": "https://xxx.oktapreview.com/oauth2/ausxnnacdm60nV7vv1d7",
      "requestUri": "/oauth2/v1/token",
      "requestedScopes": "pricing:margin",
      "tokenExchangeType": "Agent ID Assertion",
      "url": "/oauth2/v1/token?",
      "managedConnectionId": "mcnxnodu9t2FRZO5R1d7",
      "subjectTokenId": "ID.kiJ9Ch3aBer2ftX2CobkLuSSPqBMdMsZaxwRMZQjr44",
      "subjectTokenClientId": "0oaxnnekviMmWpyBK2d3",
      "requestId": "5eaf3d96ff3dbb684e1099bf8cecdd53",
      "dtHash": "96dec87ffaebc55e64ab62eca30303c555d589e0f9686d55827963c51032ef7f",
      "threatSuspected": "false",
      "grantType": "urn:ietf:params:oauth:grant-type:token-exchange"
    }
  },
  "legacyEventType": null,
  "transaction": {
    "type": "WEB",
    "id": "5eaf3d96ff3dbb684e1099bf8cecdd53",
    "detail": {}
  },
  "uuid": "5b10a39b-39ca-11f1-bbfb-f341db467931",
  "version": "0",
  "request": {
    "ipChain": [
      {
        "ip": "x.x.x.x",
        "geographicalContext": {
          "city": "Ashburn",
          "state": "Virginia",
          "country": "United States",
          "postalCode": "20149",
          "geolocation": {
            "lat": 39.0469,
            "lon": -77.4903
          }
        },
        "version": "V4",
        "source": null,
        "ipDetails": {
          "asNumber": 14618,
          "asOrg": "amazon.com  inc.",
          "isp": "amazon.com  inc.",
          "domain": "amazonaws.com"
        }
      }
    ]
  },
  "target": [
    {
      "id": "ID.kiJ9Ch3aBer2ftX2CobkLuSSPqBMdMsZaxwRMZQjr44",
      "type": "id_token",
      "alternateId": null,
      "displayName": "ID Token",
      "detailEntry": {
        "audience": "0oaxnnekviMmWpyBK2d3",
        "expires": "2026-04-16T20:07:29.000Z",
        "subject": "00uxnn7b13YEcYj2V6a7",
        "hash": "iMQM1uCzsH07nFhkRPUNvg"
      }
    },
    {
      "id": "00uxnn7b13YEcYj2V6a7",
      "type": "User",
      "alternateId": "fabio.grasso@example.com",
      "displayName": "Fabio Grasso",
      "detailEntry": null
    },
    {
      "id": "IDAAG.5ZazR5P-fmm8zuG1CwuqT3EenUx1pFfN00jToEE0s6A",
      "type": "id_jag",
      "alternateId": null,
      "displayName": "Identity Assertion JWT Authorization Grant",
      "detailEntry": {
        "audience": "https://xxx.oktapreview.com/oauth2/ausxnnacdm60nV7vv1d7",
        "expires": "2026-04-16T19:32:49.000Z",
        "subject": "00uxnn7b13YEcYj2V6a7",
        "scope": "pricing:margin",
        "hash": "Tq7wccRtqpRvZvEXKYK9nA"
      }
    }
  ]
}

Come puoi vedere, vengono registrati non solo l’agente che ha effettuato la richiesta (Pricing Agent) ma anche l’utente che ha autorizzato l’azione (fabio.grasso@example.com). Il campo grantedScopes mostra i permessi effettivi concessi all’agente per questa richiesta, ovvero l’intersezione di ciò che l’agente può fare e di ciò a cui l’utente ha diritto. La claim jti nel token diventa il transaction.id nei log, permettendoti di correlare questo evento con gli eventi downstream nei log della tua risorsa, se anch’essa registra l’ID transazione.

Casi d’Uso XAA
#

Vediamo alcuni esempi concreti di come XAA può essere utilizzato per proteggere diversi tipi di risorse:

  1. API interna tramite MCP Server — Un agente di supporto clienti deve accedere al database interno degli ordini per rispondere alle richieste dei clienti.
    • Agente registrato nell’Okta Universal Directory
    • MCP Server protetto da un Okta Custom Authorization Server
    • Flusso XAA: l’agente scambia l’ID Token dell’utente per un accesso con scope limitato a orders:read
    • Audit: ogni query registrata con ID utente, ID agente e ID transazione
  2. SaaS First-Party (ISV-Enabled) — Un agente assistente alle vendite accede alle opportunità Salesforce per conto di un commerciale.
    • Salesforce implementa la validazione ID-JAG
    • L’agente presenta l’ID-JAG all’endpoint di autorizzazione Salesforce
    • Salesforce emette un token con scope limitato ai soli dati dell’utente
    • Nessuna credenziale statica; nessun service account condiviso
  3. Workflow agente multi-step — Un agente finanziario esegue un workflow di approvazione:
    • Step 1: Legge la nota spese (scope read:expenses)
    • Step 2: Verifica la disponibilità di budget (scope read:budgets)
    • Step 3: Invia l’approvazione (scope write:approvals)
    • Ogni step può richiedere scope diversi. Se l’agente viene compromesso a metà workflow, la revoca blocca solo la sessione di quell’utente senza influenzare gli altri.
Adozione ISV in Corso

XAA è completamente funzionale oggi per gli Okta Custom Authorization Server (tipo di connessione: “Authorization Server”) e i MCP Server (tipo di connessione: “MCP Server”). L’adozione ISV per le integrazioni SaaS di terze parti è attualmente in corso. I principali vendor stanno lavorando attivamente al supporto ID-JAG.

Inizia a costruire su XAA ora per essere pronto ad estendere le integrazioni SaaS non appena gli ISV completano le loro implementazioni. Nel frattempo, usa STS (tipo di connessione: “Application”) per i SaaS di terze parti che supportano OAuth ma non ancora ID-JAG.

Testare XAA: Il Playground xaa.dev
#

Okta mette a disposizione un ambiente di test interattivo su xaa.dev dove puoi sperimentare i flussi XAA senza configurare infrastruttura6.

Funzionalità:

  • Test nel browser (nessun Docker o configurazione locale)
  • Componenti preconfigurati: Requesting App, Resource App, IdP
  • Avvio in meno di 60 secondi
  • Registrazione di client personalizzati per i test

Il playground include un flusso di esempio in cui “Bob Tables” crea e gestisce task tramite un agente IA, dimostrando l’intero scambio ID-JAG.

ID-JAG e XAA: Una Nota sulla Terminologia
#

Probabilmente hai incontrato entrambi i termini — “ID-JAG” e “XAA” — usati quasi in modo intercambiabile in documentazione, blog post e conferenze. Sono strettamente correlati, ma si collocano a livelli di astrazione diversi, e nessuno dei due è un termine esclusivo di Okta.

Cross-App Access (XAA) è il nome informale dell’estensione OAuth nel suo complesso — il pattern end-to-end in cui un IdP enterprise fa da broker tra due applicazioni e sostituisce lo step di approvazione manuale dell’utente con uno scambio token. È documentato su oauth.net/cross-app-access/ e in fase di standardizzazione attraverso l’IETF.

ID-JAG (Identity Assertion JWT Authorization Grant) è il nome formale della specifica IETF. Più precisamente, si riferisce all’asserzione JWT firmata che viaggia tra domini all’interno di un flusso XAA. XAA si basa sul draft più ampio Identity and Authorization Chaining Across Domains e lo profila per un uso enterprise interoperabile.

XAA è un’estensione aperta e multi-vendor. Le implementazioni elencate oggi su oauth.net includono Okta (early access), Auth0, Athenz e Keycloak (in corso), con client come Claude Code già in fase di adozione. Okta è stata una forza trainante sia per lo sforzo di standardizzazione IETF sia per l’adozione iniziale nell’industria — ed è per questo che “XAA” è il termine che molti incontrano per primo in contesti Okta — ma l’estensione in sé non è un nome di prodotto Okta.

Il punto pratico: quando leggi documentazione Okta, “XAA” descrive l’implementazione Okta dell’estensione. Quando leggi il draft IETF o una guida di integrazione di terze parti, “ID-JAG” si riferisce al grant di asserzione sottostante che qualsiasi organizzazione può implementare.

Limitazioni di XAA
#

  • Adozione ISV in corso: XAA è GA lato Okta, ma le integrazioni SaaS di terze parti richiedono il supporto degli ISV. I principali vendor stanno implementando attivamente ID-JAG; costruire su XAA ora garantisce che tu sia pronto quando lo rilasciano.

  • Durata del token vs. sessioni lunghe: I token sono intenzionalmente di breve durata (la durata è configurabile dall’amministratore dell’IdP, non fissata dalla specifica). Gli agenti che eseguono workflow multi-step devono ri-scambiare i token alla scadenza. È una scelta progettuale (limita il blast radius) ma richiede che gli agenti gestiscano il refresh dei token in modo appropriato.

  • Non adatto per: Agenti che devono operare offline o mettere in cache le credenziali a tempo indeterminato. Per questi scenari, considera STS con un’attenta gestione del ciclo di vita delle credenziali.


Secure Token Service (STS)
#

Secure Token Service (STS) consente agli agenti di accedere ad applicazioni SaaS di terze parti che supportano OAuth ma non hanno ancora adottato XAA. Okta agisce come un broker sicuro, conservando in vault i token consentiti dall’utente in Okta Privileged Access (OPA) e fornendo accesso federato a breve scadenza a runtime.

Quando Usare STS
#

  • SaaS di terze parti con supporto OAuth ma senza supporto ID-JAG (ad es. oggi: GitHub, Google Workspace, Slack)
  • Il contesto a livello utente è richiesto per audit e conformità
Suggerimento

Verifica regolarmente con i tuoi vendor SaaS la loro roadmap per il supporto ID-JAG. STS è un ponte, non una destinazione. L’obiettivo è migrare a XAA non appena il vendor lo supporta.

Come Funziona STS
#

sequenceDiagram
    autonumber
    actor User
    participant Client as 🤖 Client
(AI Agent) box rgba(243, 242, 247,0.3) Okta Cloud participant IdP as 🔐 IdP AS
(Okta Org AS) participant Vault as 🔑 OPA
(Token Vault) end participant SaaS as 📱 Third-Party SaaS Note over User, SaaS: Fase 1 — Consenso Una Tantum (avviato dall'utente) Note over User, SaaS: Step 1: SSO Authentication User->>Client: Login via SSO (OIDC) Client->>IdP: OIDC authentication IdP-->>Client: ID Token (sub: user@example.com) Note over User, SaaS: Step 2: OAuth Consent Client->>IdP: Request managed connection token IdP-->>Client: Consent URL (SaaS OAuth) Client-->>User: Redirect to SaaS consent User->>SaaS: Login and approve access Note over User, SaaS: Step 3: Token Vaulting SaaS-->>IdP: Authorization Code (callback) IdP->>SaaS: Exchange code for tokens SaaS-->>IdP: Access + Refresh Tokens IdP->>Vault: Store tokens (bound to user context) Note over Client, SaaS: Fase 2 — Accesso Runtime (agente autonomo, RFC 8693) Note over Client, SaaS: Step 4: Token Exchange (RFC 8693) Client->>IdP: Token Exchange Request Note right of Client: grant_type:token-exchange
subject_token: (vaulted user token)
actor: workload identity
audience: Third-Party SaaS
auth: private_key_jwt IdP->>IdP: Validate managed connection policy IdP->>Vault: Retrieve user-consented tokens Vault-->>IdP: Access + Refresh Tokens IdP->>SaaS: Refresh token if expired SaaS-->>IdP: Fresh Access Token IdP-->>Client: Short-lived federated token Note left of IdP: scope: connection-scoped
token_type: Bearer
expires_in: short-lived Note over Client, SaaS: Step 5: API Call Client->>SaaS: API call with token SaaS-->>Client: Response

Analisi passo per passo
#

  1. Autenticazione utente (SSO): L’utente effettua il login attraverso il Client via OIDC. Okta emette un ID Token con l’identità utente (sub: user@example.com).
  2. Redirect al consenso: Il Client richiede un token di managed connection. Okta restituisce un URL di consenso; il Client reindirizza l’utente alla schermata OAuth standard del SaaS.
  3. Approvazione utente: L’utente effettua il login al SaaS di terze parti e approva gli scope richiesti. Il SaaS restituisce un authorization code all’endpoint callback di Okta.
  4. Vault dei token: Okta scambia l’authorization code per access e refresh token e li conserva in Okta Privileged Access (OPA), legati al contesto di identità dell’utente.
  5. Accesso runtime (agente autonomo — nessuna sessione utente attiva necessaria): L’agente si autentica a Okta con la sua workload identity (private_key_jwt) e richiede accesso tramite la managed connection policy.
  6. Recupero token: Okta recupera i token conservati in OPA, li rinnova con il SaaS se scaduti, ed emette un token federato a breve scadenza per l’agente.
  7. Chiamata API: L’agente chiama il SaaS di terze parti con il token a breve scadenza. Le credenziali utente non toccano mai l’agente.
Presenza dell’Utente e Operatività Autonoma

L’Utente appare nella Fase 1 perché STS richiede il consenso esplicito dell’utente — l’utente deve autenticarsi al SaaS di terze parti e approvare gli scope OAuth. Si tratta di un’operazione una tantum. Una volta concesso il consenso e conservati i token, la Fase 2 opera in modo completamente autonomo: l’agente recupera e utilizza i token senza alcuna interazione utente. L’utente potrebbe non essere nemmeno online quando l’agente accede al SaaS.

Casi d’Uso STS
#

  1. GitHub — Un agente assistente di sviluppo legge repository e crea pull request per conto degli sviluppatori. Lo sviluppatore dà il consenso una volta tramite la schermata OAuth di GitHub; Okta mette in vault i token risultanti. A runtime, l’agente riceve un token federato a breve scadenza per chiamare l’API GitHub — non detiene mai credenziali GitHub a lunga scadenza.
  2. Google Workspace — Un agente di pianificazione gestisce eventi del calendario e bozze di email per un utente. Il contesto utente viene preservato tramite il flusso di consenso, così i log di audit di Google catturano quale utente ha autorizzato le azioni dell’agente.
  3. Jira/Confluence — Un agente di project management crea ticket da conversazioni Slack e aggiorna pagine di documentazione. L’agente si autentica tramite il token intermediato da Okta, senza mai memorizzare direttamente le credenziali Atlassian.

Differenza Chiave con XAA
#

  • Flusso di consenso: STS richiede che l’utente passi per la schermata di consenso OAuth del servizio di terze parti; Okta poi archivia e gestisce quei token per conto dell’agente. XAA salta del tutto la schermata di consenso. La delega avviene al momento della registrazione dell’agente in Okta.
  • Audit trail: STS cattura il consenso utente e l’accesso dell’agente nei log Okta, ma il servizio di terze parti potrebbe vedere solo l’identità dell’agente. XAA fornisce il contesto completo utente+agente alla risorsa.
  • Durata del token: Il token federato emesso all’agente è a breve scadenza (minuti) per limitare il rischio, ma gli access/refresh token sottostanti in Okta potrebbero avere scadenze più lunghe a seconda delle policy del servizio di terze parti.
  • Revoca: Revocare l’accesso richiede l’eliminazione della voce nel vault in Okta, il che può influenzare tutti gli agenti che usano quella connessione. Nessuna revoca per utente all’interno del servizio di terze parti.
  • Riduzione degli scope: L’agente riceve gli scope a cui l’utente ha acconsentito durante il flusso OAuth. Okta non può ridurre dinamicamente gli scope per richiesta come XAA.
Contesto Utente Preservato

A differenza di Pre-Shared Key, STS preserva il contesto utente tramite il flusso di consenso. I log di audit catturano sia l’utente che ha dato il consenso sia l’agente che ha acceduto alla risorsa.

Direzione Strategica

STS è esplicitamente un pattern di transizione. Non appena un ISV o un vendor SaaS introduce il supporto ID-JAG, puoi aggiornare quella connessione da STS a XAA senza rearchitetturare. Nel frattempo, STS ti dà il contesto a livello utente che Pre-Shared Key e Service Account semplicemente non possono fornire.


Pre-Shared Key (PSK) o Segreto in Vault
#

Pre-Shared Key (PSK) archivia credenziali statiche (chiavi API, bearer token, segreti webhook) in Okta Privileged Access (OPA). L’agente recupera i segreti a runtime invece di incorporarli nel codice o nella configurazione.

Quando Usare Pre-Shared Key
#

  • API REST legacy che supportano solo l’autenticazione con chiave API
  • Endpoint webhook che richiedono bearer token
  • Integrazioni di terze parti con autenticazione tramite token statico
  • Servizi in fase iniziale che aggiungeranno OAuth in futuro

Come Funziona Pre-Shared Key
#

sequenceDiagram
    autonumber
    actor Admin as Admin
    participant Client as 🤖 Client
(AI Agent) box rgba(243, 242, 247,0.3) Okta Cloud participant IdP as 🔐 IdP AS
(Okta Org AS) participant Vault as 🔑 OPA
(Secret Vault) end participant RS as 📦 Resource Server
(Protected API) Note over Admin, Vault: Fase 1 — Configurazione (avviata dall'admin) Admin->>Vault: Create & vault secret (API key) Admin->>IdP: Create managed connection on agent (type: Secret) Note over Client, RS: Fase 2 — Accesso Runtime (agente autonomo) Client->>IdP: Authenticate (workload identity) Note right of Client: private_key_jwt
managed connection policy IdP->>IdP: Validate managed connection policy IdP->>Vault: Retrieve vaulted secret Vault-->>IdP: API key / bearer token IdP-->>Client: Release secret Client->>RS: API call with secret RS-->>Client: Response

Analisi passo per passo
#

  1. L’admin mette in vault il segreto: Un amministratore archivia la chiave API o il bearer token in Okta Privileged Access e crea una managed connection sull’agente (tipo: Secret)
  2. L’agente si autentica: A runtime, l’agente si autentica a Okta con la sua identità di workload principal
  3. Verifica della policy: Okta valida l’identità dell’agente e verifica la policy della managed connection
  4. Segreto rilasciato: Okta rilascia la credenziale in vault all’agente
  5. Accesso diretto alla risorsa: L’agente utilizza la credenziale statica per chiamare la risorsa downstream direttamente — nessuno scambio token, nessun contesto utente
Rotazione delle Password

Quando possibile (cioè per i servizi SaaS supportati), configura il vault per ruotare automaticamente le credenziali. Questo riduce il rischio in caso di compromissione di una credenziale, ma richiede che il servizio downstream supporti gli aggiornamenti delle credenziali senza downtime.

Limitazioni di Pre-Shared Key
#

  • Nessun contesto utente: La risorsa vede solo l’identità dell’agente, non l’utente
  • Nessuna riduzione degli scope: L’agente ha accesso completo concesso alla credenziale
  • Audit trail limitata: I log mostrano l’accesso dell’agente, senza attribuzione utente
Pianifica la Migrazione

Pre-Shared Key ha una audit trail limitata e nessun contesto utente. Pianifica la migrazione a XAA o STS non appena i servizi downstream aggiungono il supporto OAuth. Questo pattern deve essere trattato come temporaneo per le integrazioni legacy.


Service Account
#

Service Account utilizza credenziali username e password collegate a un’identità di servizio condivisa. È il pattern legacy da cui Okta raccomanda esplicitamente di migrare.

Come Funziona Service Account
#

sequenceDiagram
    autonumber
    actor Admin as Admin
    participant ClientA as 🤖 Client A
(AI Agent) participant ClientB as 🤖 Client B
(AI Agent) box rgba(243, 242, 247,0.3) Okta Cloud participant IdP as 🔐 IdP AS
(Okta Org AS) participant Vault as 🔑 OPA
(Credential Vault) end participant RS as 📦 Resource Server
(Protected API) Note over Admin, RS: Phase 1 — Configuration (admin-initiated) Admin->>Vault: Create service account (svc_agent@example) Admin->>ClientA: Register with managed connection Admin->>ClientB: Register with managed connection Note over ClientA, RS: Phase 2 — Runtime Access (agent-autonomous) ClientA->>IdP: Request credentials ClientB->>IdP: Request credentials Note right of ClientA: private_key_jwt
managed connection IdP->>IdP: Validate managed connection policy IdP->>Vault: Retrieve vaulted credentials Vault-->>IdP: Username/Password (svc_agent@example) IdP-->>ClientA: Username/Password IdP-->>ClientB: Username/Password ClientA->>RS: Authenticate as svc_agent@example ClientB->>RS: Authenticate as svc_agent@example Note over RS: Entrambi appaiono con la stessa identità!

Analisi passo per passo
#

  1. L’admin provisiona il service account: Un amministratore crea un service account in OPA (Credential Vault) e registra le managed connection su uno o più agenti
  2. Gli agenti richiedono le credenziali: A runtime, ogni agente si autentica all’IdP AS con la sua workload identity (private_key_jwt) e richiede le credenziali del service account tramite la managed connection
  3. Okta rilascia username/password: L’IdP AS recupera le credenziali conservate in OPA, valida l’identità dell’agente, verifica la policy e consegna le credenziali condivise
  4. L’agente si autentica alla risorsa: L’agente accede al Resource Server come service account — indistinguibile da qualsiasi altro agente che usa le stesse credenziali

Limitazioni dei Service Account
#

I Service Account presentano quattro lacune di sicurezza critiche:

  1. Agenti invisibili: Più agenti condividono una singola identità, rendendo impossibile capire quale ha eseguito un’azione
  2. Permessi eccessivi: I service account portano tipicamente privilegi ampi e statici che superano di gran lunga ciò che un singolo task richiede
  3. Attribuzione utente assente: Gli audit di conformità non possono rispondere a “quale utente ha innescato questo accesso ai dati?”
  4. Revoca tutto o niente: Disattivare il service account taglia l’accesso a tutti gli agenti e sistemi che ne dipendono
Non Raccomandato

I Service Account non sono sicuri quanto i tipi di risorsa authorization server o vaulted secret. Le nuove integrazioni non dovrebbero mai ricorrere a questo pattern per default.

Quando il Service Account è Inevitabile
#

  • Sistemi legacy che richiedono autenticazione username/password (database on-prem, mainframe, servizi LDAP)
  • Elaborazioni batch senza contesto utente finale
  • Sistemi che non hanno adottato alcun metodo di autenticazione moderno

Il Service Account è accettabile solo per processi batch senza contesto utente, con un piano di dismissione documentato.

Service Account vs Pre-Shared Key — La distinzione concettuale chiave

Entrambi i pattern mancano di contesto utente e di riduzione degli scope, ma differiscono nel tipo di credenziale archiviata e nella postura di sicurezza:

  • PSK mette in vault una credenziale machine-native (chiave API) che è tipicamente univoca per integrazione, così la rotazione e la revoca rimangono chirurgiche. Le credenziali sono limitate a un’integrazione, quindi puoi avere più PSK per agenti diversi, garantendo almeno attribuzione a livello di agente (audit) e isolamento (per la revoca). Okta Privileged Access può ruotare automaticamente le PSK se il servizio downstream lo supporta, il che è un enorme vantaggio di sicurezza.

  • Service Account prende in prestito una credenziale a forma umana (username/password) per impersonare un’identità condivisa: più agenti condividono lo stesso login, il che è esattamente ciò che rompe l’attribuzione per agente e impone la revoca tutto o niente. Le password hanno tipicamente una lunga durata di vita e richiedono rotazione manuale, il che è un rischio se la credenziale viene compromessa. I service account sono spesso sovra-provisionati con permessi ampi per evitare di rompere gli agenti dipendenti, il che amplifica ulteriormente il rischio.

Ecco perché passare da Service Account a PSK è il primo passo difendibile sulla scala di migrazione, anche se nessuno dei due pattern porta contesto utente.


Dalla Teoria alla Pratica: Configurare i Pattern di Accesso in Okta
#

Nell’Okta Universal Directory, puoi registrare agenti IA come identità di workload e creare Managed Connection che definiscono come accedono alle risorse downstream. Ogni tipo di connessione corrisponde a uno dei pattern di accesso discussi sopra.

Lista Agenti IA Dettaglio Agente IA
Okta Universal Directory - Lista Agenti IA
Okta Universal Directory - Dettaglio Agente IA

Quando crei una managed connection, vedrai cinque tipi di risorsa. Corrispondono ai quattro pattern di accesso trattati in questo articolo:

O4AA Connection Options
Tipo di Connessione Pattern di Accesso Cosa Fa
Authorization Server XAA (Cross App Access) L’agente ottiene token con scope limitato da un Okta Custom Authorization Server tramite scambio ID-JAG
Secret Pre-Shared Key (PSK) L’agente recupera una chiave API o bearer token in vault da Okta Privileged Access
Service Account Service Account L’agente recupera le credenziali username/password di un’identità di servizio in vault in Okta Privileged Access
Application STS (Secure Token Service) L’agente accede a un’app OIN o resource server personalizzato tramite scambio token OAuth intermediato da Okta
MCP Server XAA (Cross App Access) Stesso scambio ID-JAG di Authorization Server, specializzato per la superficie del protocollo MCP
MCP Server = XAA per MCP

Il tipo di connessione MCP Server non è un pattern di accesso separato: è XAA applicato specificamente ai server Model Context Protocol. Si applicano lo stesso modello di delega ID-JAG, la stessa struttura del token (sub + act.sub) e lo stesso enforcement delle policy. Okta fornisce un tipo di connessione dedicato per semplificare la configurazione specifica di MCP.

Panoramica della Configurazione XAA
#

Implementare XAA richiede:

  1. Registrare l’agente nell’Okta Universal Directory come workload principal
  2. Creare una Managed Connection e selezionare “Authorization Server” (per API personalizzate) o “MCP Server” (per endpoint MCP). Entrambi usano lo stesso scambio ID-JAG internamente.
  3. Configurare il Custom Authorization Server che protegge la tua risorsa
  4. Definire policy RBAC che valutino sia gli attributi utente che quelli dell’agente

Esempio di logica di policy, per garantire che l’agente possa accedere ai dati di vendita solo quando l’utente è membro del team commerciale:

IF (act.sub == "sales-representative-agent")
AND (sub IN groups["sales-team"])
AND (requested_scope IN ["sales:read", "accounts:read"])
THEN issue_token_with_scope
ELSE deny

Questo è un esempio in pseudo-codice. Nella console di amministrazione Okta, le access policy del Custom Authorization Server usano un modello a policy + regola — non un linguaggio di scripting. Per seguire l’esempio puoi:

  1. Creare una Access Policy assegnata all’agente IA (cioè sales-representative-agent). Questo limita implicitamente la policy a quell’agente specifico (act.sub).
  2. Creare una Regola all’interno di quella policy:
    • Grant type: JWT Bearer (il grant dello scambio ID-JAG)
    • Idoneità utente: Utenti membri del gruppo: sales-team — questo garantisce che solo i membri del team commerciale possano delegare l’accesso tramite questo agente
    • Scope: Allowlist di orders:read e accounts:read — l’agente non può richiedere scope più ampi anche se l’utente li possiede
    • Durata del token: 5 minuti (effimero)
    • Valutazione: Le policy e le regole vengono valutate in ordine di priorità. Vince il primo match. Se nessuna regola corrisponde (ad es. un utente fuori dal sales-team prova a usare questo agente), la richiesta viene rifiutata.

Il risultato: l’agente può accedere ai dati di vendita solo quando l’utente che sta dietro alla richiesta è membro del team commerciale. I permessi effettivi sono l’intersezione della allowlist di scope della policy, dell’appartenenza al gruppo dell’utente e della managed connection dell’agente.

Configurazione STS
#

Nella console di amministrazione Okta, si configura STS creando una managed connection con il tipo di risorsa “Application”, selezionando un’integrazione OIN app o un resource server personalizzato7. Okta fa quindi da broker per lo scambio token OAuth tra l’agente e il servizio di terze parti.

Configurazione PSK
#

Nella console di amministrazione Okta, si configura PSK creando una managed connection con il tipo di risorsa “Secret”. La chiave API o il bearer token devono essere prima archiviati in Okta Privileged Access; la managed connection fa poi riferimento a quel segreto in vault. A runtime, l’agente recupera la credenziale su richiesta — non è mai incorporata nel codice o nella configurazione dell’agente.

Configurazione Service Account
#

Nella console di amministrazione Okta, si configura una connessione Service Account creando una managed connection con il tipo di risorsa “Service Account”, collegandola a un’identità di servizio archiviata in Okta Privileged Access. Poiché più agenti possono fare riferimento allo stesso service account, va trattato come ultima risorsa, documentando un piano di dismissione prima di utilizzarlo.


E Adesso?
#

Hai ora il toolkit a livello di protocollo per ogni pattern di Okta for AI Agents. Due tappe naturali:

  • Torna alla vista strategica: rileggi la Parte 2 — Pattern di Accesso con i dettagli implementativi freschi in mente. Il framework decisionale e la scala di migrazione assumono molto più senso dopo aver visto i claim dei token e i diagrammi di sequenza.
  • Avanti verso la conformità: nella Parte 4 — Conformità EU AI Act mappo ciascun pattern ai requisiti normativi (EU AI Act, NIST AI RMF, NIS2, DORA), mostrando come i campi di audit che hai appena imparato a leggere si traducono direttamente in evidenze di conformità.

Provare Subito
#

Esplora il playground XAA interattivo su xaa.dev — senza configurazione necessaria. Crea agenti, esegui scambi ID-JAG e ispeziona i token risultanti direttamente nel browser.

Risorse di Riferimento
#

Parliamone
#

Quale pattern stai implementando per primo? Hai incontrato ostacoli sullo scambio ID-JAG o sulle policy delle managed connection? Lascia una nota nei commenti qui sotto o contattami su LinkedIn.


  1. Identity JWT Authorization Grant, IETF OAuth Working Group, 2025 ↩︎

  2. NIST SP 800-63-4: Digital Identity Guidelines, NIST, 2024 ↩︎

  3. EU Artificial Intelligence Act, European Union, 2024 ↩︎

  4. NIS2 Directive, European Commission, 2024 ↩︎

  5. DORA: Digital Operational Resilience Act, European Commission, 2024 ↩︎

  6. XAA Developer Playground, Okta Developer Blog, January 2026 ↩︎

  7. Secure AI agent access to resources, Okta Help Center ↩︎

O4AA - Okta for AI Agents - Questo articolo fa parte di una serie.
Parte 3: Questo articolo

Powered by Hugo Streamline Icon: https://streamlinehq.com Hugo Hugo & Blowfish