Distribuzione e operazioni del gateway delle app Claude
Registrare il gateway con il vostro IdP, costruire il container, distribuire su Kubernetes o Cloud Run, e gestirlo: controlli di integrità, rotazione dei segreti, aggiornamenti e sicurezza.
Questa pagina copre il lato operativo dell'esecuzione del gateway delle app Claude: registrazione di un client OAuth nel vostro provider di identità (IdP), distribuzione del gateway come container, e gestione quotidiana. Per ogni opzione nel file gateway.yaml che il gateway legge all'avvio, consultare il Riferimento di configurazione.
Una distribuzione in produzione segue quattro passaggi in ordine, e le sezioni sottostanti li corrispondono. I primi due sono dove fate scelte; i secondi due sono materiale di riferimento da consultare una volta che è in esecuzione.
- Configurare il vostro provider di identità: registrare il client OAuth e controllare le note specifiche per IdP per Okta, Entra e Google
- Distribuire il gateway: costruire un'immagine container con versione fissa ed eseguirla su Kubernetes, Cloud Run, o la vostra piattaforma. Questa sezione copre anche decisioni relative a costi, bypass, gateway multipli e serverless
- Configurare le operazioni: log, sonde di integrità, comportamento in caso di interruzione, rotazione dei segreti e aggiornamenti. Riferimento per quando state collegando il monitoraggio e i runbook
- Esaminare la postura di sicurezza: dove fluiscono i dati, il modello di minaccia e le risposte sulla conformità. Riferimento per una revisione della sicurezza
Se un accesso o un avvio fallisce lungo il percorso, andare direttamente a Troubleshooting, che è indicizzato in base all'errore che vedete.
Distribuire sulla vostra rete privata. Claude Code si connette solo a un gateway il cui indirizzo è privato. Questo è un meccanismo di sicurezza, perché un gateway affidabile può inviare impostazioni che eseguono comandi sulle macchine degli sviluppatori. Mettere il gateway dietro un load balancer interno o una VPN e dargli un nome host che si risolve solo in indirizzi IP privati. Se la vostra rete interna è numerata da spazio IPv4 pubblico che la vostra organizzazione possiede, consultare Consentire un gateway su spazio di indirizzi pubblici che possedete.
Configurazione del provider di identità
Registra un'applicazione web OAuth/OpenID Connect (OIDC) confidenziale con un singolo URI di reindirizzamento, https://<gateway>/oauth/callback, e assegnala agli utenti o ai gruppi che dovrebbero avere accesso al gateway.
Qualsiasi IdP conforme a OIDC funziona: Okta, Microsoft Entra ID, Google Workspace, Keycloak, Dex, PingFederate e altri. L'IdP deve soddisfare tre requisiti:
- Serve
/.well-known/openid-configuration, su HTTPS in produzione; il gateway accetta unhttp://issuer, e un issuer loopback richiede inoltreCLAUDE_GATEWAY_ALLOW_LOOPBACK=1 - Supporta il flusso authorization-code. PKCE (Proof Key for Code Exchange) è attivo per impostazione predefinita; disabilitalo con
oidc.use_pkce: falseper IdP che non lo supportano - Restituisce
emaile facoltativamentegroupsnell'id_token, o li serve dall'endpoint userinfo conoidc.userinfo_fallback: true
Per PKI privata, imposta oidc.ca_cert_pem.
Alcuni provider gestiscono i claim di email e gruppo diversamente:
- Okta: il server di autorizzazione dell'organizzazione in
https://example.okta.comrestituisce un id_token sottile che ometteemailegroups, quindi impostaoidc.userinfo_fallback: trueogni volta che lo usi comeissuer. Un server di autorizzazione personalizzato comehttps://example.okta.com/oauth2/defaultche includeemaile facoltativamentegroupsnell'id_token li emette direttamente e non ha bisogno di fallback. Okta emettegroupssolo quando lo scopegroupsè richiesto inoidc.scopese il filtro dei claim dei gruppi dell'app lo consente;userinfo_fallbacknon può riempire un claim per il quale l'IdP non è stato interrogato. - Microsoft Entra ID:
issuer=https://login.microsoftonline.com/<tenant-id>/v2.0. Entra emette Object ID dei gruppi piuttosto che nomi, quindi usa i GUID inmanaged.policies.match.groups, o usa App Roles per nomi leggibili. Se il tuo tenant emette ruoli sottorolesinvece digroups, impostaoidc.groups_claim: roles. - Google Workspace:
issuer=https://accounts.google.com. L'id_token di Google non contiene gruppi. Per usareallowed_groupsbasato su gruppi omanaged.policiescon Google come IdP, configuraoidc.google_groups, che cerca i gruppi di ogni utente tramite l'API Admin SDK Directory usando un account di servizio con delega a livello di dominio. Senza di esso, usaoidc.allowed_email_domainsper il gating dell'appartenenza emanaged.policies.match.email_domainper l'assegnazione della policy. Google ignora anche lo scope standardoffline_access. Per i token di aggiornamento, impostaoidc.scopes: [openid, profile, email]eoidc.extra_auth_params: { access_type: offline, prompt: consent }.
I token di aggiornamento consentono al gateway di rinnovare silenziosamente la sessione di uno sviluppatore, senza inviare lo sviluppatore al browser. Guidano anche il deprovisioning, perché quando l'IdP disabilita un utente, il prossimo aggiornamento fallisce e la sessione termina entro ttl_hours. Il gateway richiede offline_access per impostazione predefinita per ottenere un token di aggiornamento. Se il tuo IdP richiede il consenso esplicito per l'accesso offline, configura il client OAuth per consentirlo.
Se il tuo IdP non può emettere token di aggiornamento affatto, il gateway funziona comunque, ma non c'è rinnovamento silenzioso, quindi gli sviluppatori rieseguono l'accesso al browser quando la loro sessione scade. Per evitare che ciò accada ogni ora, aumenta session.ttl_hours a 8 o 12. Il compromesso è la latenza di deprovisioning, perché senza token di aggiornamento un utente disabilitato mantiene l'accesso fino a quando il TTL più lungo non scade.
Distribuzione
Il gateway è un singolo binario Linux senza stato che si coordina attraverso Postgres, quindi distribuiscilo come distribuisci qualsiasi altro servizio senza stato nel tuo ambiente. Mantienilo all'interno della tua rete, dove i tuoi sviluppatori e il tuo IdP possono raggiungerlo su HTTPS, e trattalo come qualsiasi servizio che contiene una credenziale di produzione.
Alcune decisioni modellano la distribuzione oltre a dove viene eseguito:
- Costo: nessuna licenza separata o tassa per posto. Il gateway fa parte del binario
claude, quindi paghi per l'inferenza attraverso il tuo impegno esistente, più il calcolo su cui viene eseguito. - Bypass: il gateway non applica che l'unica rotta a un modello passi attraverso di esso. Uno sviluppatore con la propria credenziale può comunque chiamare il provider direttamente, quindi chiudere quel percorso è una decisione di policy di rete, ad esempio bloccando l'uscita verso
api.anthropic.comtranne dal gateway. Bloccare anche quell'uscita interrompe il controllo di sicurezza del dominio WebFetch, che chiamaapi.anthropic.comda ogni macchina dello sviluppatore. ImpostaskipWebFetchPreflight: truenella policy gestita per disabilitarlo. - Gateway multipli: ogni gateway è una distribuzione separata con la sua configurazione, e il CLI memorizza la fiducia e le credenziali per nome host del gateway, quindi i team possono utilizzare gateway diversi senza conflitto. Per servire più emittenti OIDC, esegui istanze separate.
- Serverless: Cloud Run funziona se imposti
min-instances: 1per evitare il cold start della scoperta OIDC. Lambda e Cloud Functions non funzionano, perché il gateway è un server HTTP a lunga durata.
Ogni topologia di produzione qui mette un proxy L7, come un Ingress, il front-end di Cloud Run, o un ALB, davanti alle repliche HTTP semplici. Imposta listen.trusted_proxies agli intervalli di origine del proxy in modo che il gateway legga gli IP client da X-Forwarded-For. Il gateway onora l'intestazione solo quando il peer TCP è affidabile. Gli esempi elaborati di Google Cloud e AWS hanno valori concreti per topologia. Senza proxy affidabili, ogni richiesta sembra provenire dall'IP del proxy, il che comprime i limiti di velocità per IP in un bucket condiviso e registra l'IP del proxy negli eventi di audit.
Non reindirizzare le richieste agli endpoint di autorizzazione del dispositivo e token del gateway, ad esempio con una riscrittura HTTP-to-HTTPS o di canonicalizzazione dell'host all'ingress. Claude Code non segue i reindirizzamenti su quelle richieste, quindi una regola di ingress che le reindirizza interrompe l'accesso e l'aggiornamento del token.
Dai al proxy un timeout di inattività più lungo dell'intervallo di keepalive del gateway, che dipende dall'upstream:
- Su ogni upstream tranne
provider: anthropic, il gateway scrive unpingSSE una volta che un flusso è stato silenzioso per circa 15 secondi. - Su
provider: anthropic, il gateway passa la risposta invariata, inclusi i ping dell'API Anthropic.
Un valore predefinito come i 60 secondi dell'ALB è sufficiente per mantenere aperto un flusso silenzioso. L'esempio elaborato di AWS lo aumenta a un'ora comunque, e la sua riga di troubleshooting copre i gateway più vecchi di v2.1.229, che non hanno inviato nulla durante i periodi silenziosi sugli upstream che ora ricevono ping.
Immagine del container
Costruisci la tua immagine attorno al binario claude nativo dalla versione standard di Claude Code:
- Scarica la build Linux per l'architettura della tua immagine da una versione fissa; consulta Installa una versione specifica per l'URL di download.
- Verificalo rispetto al
manifest.jsonfirmato con GPG della versione come descritto in Integrità binaria e firma del codice. - Copialo nel contesto di build.
Specchia la versione nel tuo registro interno se le tue build non possono raggiungere l'host della versione, e fissa la versione che la tua flotta esegue.
Oltre al binario, l'immagine ha bisogno di:
- Un'immagine basata su glibc: la build glibc ha solo dipendenze dinamiche dalle librerie glibc. Le immagini basate su Musl hanno bisogno della build
linux-x64-muslolinux-arm64-muslpiù pacchetti aggiuntivi; consulta Configurazione di Alpine Linux. - Una directory di stato scrivibile: il gateway funziona come qualsiasi utente, ma le immagini minime non hanno home scrivibile. Imposta
CLAUDE_CONFIG_DIRa un percorso scrivibile come/tmp/.claude. - Il comando del container:
claude gateway --config /etc/claude/gateway.yaml, con il file di configurazione montato in sola lettura e i segreti forniti come variabili di ambiente; il gateway ascolta sulisten.port, predefinito8080.
Kubernetes
Esegui il gateway come Deployment, come qualsiasi servizio senza stato:
- Monta la configurazione da una ConfigMap e i segreti da un Secret; fai riferimento ai segreti nel YAML tramite
${file:/path/to/secret}o come variabili di ambiente - Termina TLS all'Ingress e imposta
listen.public_urlal nome host dell'Ingress - Punta la sonda di readiness a
GET /readyze la sonda di liveness aGET /healthz
Per un esempio elaborato completo su AWS, che copre ECS Fargate o EKS, Amazon RDS e AWS Secrets Manager, consulta Distribuisci su AWS.
Preferisci l'identità del workload della piattaforma rispetto alle chiavi statiche; il riferimento upstreams ha dettagli di configurazione per piattaforma. Per un accoppiamento cross-cloud, come un upstream Bedrock su GKE, imposta credenziali esplicite nel blocco auth dell'upstream.
Cloud Run
Configura il servizio come segue:
- Lascia
listen.portal suo predefinito di8080, che corrisponde alPORTpredefinito di Cloud Run, o impostaport: ${PORT} - Imposta
public_urlall'origine esternamente raggiungibile. Per la produzione questo è normalmente il nome host di un load balancer interno, perché/loginrifiuta gli indirizzi pubblici e l'URL*.run.appsi risolve in uno, quindi l'URL di Cloud Run da solo funziona solo per un test di fumocurlo browser. L'eccezione è una rete dove*.run.appsi risolve privatamente tramite Private Service Connect e una zona privata di Cloud DNS; in quella topologia l'URL di Cloud Run è unpublic_urlvalido. L'esempio elaborato di Google Cloud copre entrambi. - Monta la configurazione come volume segreto
- Imposta
min-instances: 1per evitare il cold start della scoperta OIDC alla prima richiesta
Per un esempio elaborato completo su Google Cloud, che copre Cloud Run o GKE, Cloud SQL e Secret Manager, consulta Distribuisci su Google Cloud.
Invia l'URL del gateway alle macchine degli sviluppatori
Una volta che il gateway è in servizio, invia forceLoginMethod, forceLoginGatewayUrl e parentSettingsBehavior: "merge" a ogni macchina dello sviluppatore tramite impostazioni gestite, tramite MDM o scrivendo direttamente il managed-settings.json per OS. Senza questo, /login mostra il selettore di account standard senza opzione gateway.
Una volta che distribuisci le chiavi, Claude Code smette di utilizzare una chiave API rimasta o un accesso a claude.ai sulla macchina, quindi pianifica il push insieme alle tue istruzioni di accesso. La policy dell'amministratore richiede un accesso al gateway Cloud descrive i messaggi che gli sviluppatori vedono.
Consulta dove ogni meccanismo memorizza la policy per i percorsi dei file, e Impostazioni gestite lato client per l'equivalente bootstrapUrl di Claude Desktop.
Rollout su larga scala
L'accesso è limitato per indirizzo IP client, e i valori predefiniti si adattano a un piccolo team. Ogni indirizzo ottiene 30 avvii di accesso e 10 invii di codice ogni 10 minuti. Un rollout a migliaia di sviluppatori può raggiungere questi limiti la prima mattina, per uno di due motivi:
- Il gateway non può vedere oltre il tuo load balancer. Senza
listen.trusted_proxies, ogni sviluppatore sembra provenire dall'indirizzo del load balancer e condivide un limite. Impostalo prima di qualsiasi altra cosa. Il gateway registra un avviso la prima volta che ignora un'intestazioneX-Forwarded-For. - Molti sviluppatori condividono pochi indirizzi di uscita NAT o VPN. Condividono i limiti di quegli indirizzi anche quando
trusted_proxiesè corretto. Aumentarate_limitsper adattarsi.
Per dimensionare max, dividi gli sviluppatori per gli indirizzi di uscita che condividono. Stima quanti di loro accedono entro un periodo window_seconds, che è 10 minuti per impostazione predefinita. Quindi raddoppialo per coprire i tentativi e gli sviluppatori che accedono sia a Claude Code che a Claude Desktop.
Ad esempio, 10.000 sviluppatori dietro 4 indirizzi di uscita accedono uniformemente in un'ora. Cioè 2.500 sviluppatori per indirizzo e circa 420 di loro in ogni 10 minuti, che raddoppi e arrotondi a 1.000. L'esempio seguente imposta entrambi i limiti a 1.000:
rate_limits:
device_authorization: { max: 1000, window_seconds: 600 }
device_verify: { max: 1000, window_seconds: 600 }
device_verify è quello che impedisce a qualcuno di indovinare il codice di accesso di un altro sviluppatore, quindi aumentalo solo quanto la tua stima ha bisogno. Anche a questi limiti, un codice è 8 caratteri da un alfabeto di 20 caratteri e scade dopo 10 minuti, quindi indovinare rimane impraticabile; consulta Resistenza al brute-force del codice utente.
Quando il tuo IdP emette token di aggiornamento, Claude Code rinnova le sessioni silenziosamente, quindi puoi rimettere il limite dopo il rollout. Senza token di aggiornamento, gli sviluppatori accedono di nuovo ogni session.ttl_hours. Dimensiona entrambi i limiti anche per quel tasso costante e lasciali aumentati.
Quando un limite viene raggiunto, Claude Code v2.1.274 o successivo mostra The gateway is limiting sign-in attempts right now. Un gateway su v2.1.274 o successivo mostra Too many attempts came from your network address sulla pagina di verifica, con le impostazioni da controllare. Scrive anche una riga di log sign-in refused che nomina l'impostazione da modificare.
Operazioni
Una volta che il gateway sta servendo il traffico, l'operazione quotidiana consiste nel leggere i suoi log, sondare la sua salute e ruotare i suoi segreti secondo il tuo programma. Le sottosezioni coprono ciascuno, più quello che Postgres contiene e come gli aggiornamenti e i rollback si comportano.
Log
Il gateway scrive due flussi su stderr, entrambi JSON-friendly:
-
Eventi di audit: JSON a riga singola per evento rilevante per la sicurezza. Invia stderr al tuo aggregatore di log.
Gli eventi emessi includono
config.load,session.mint,session.refresh,device.authorize,device.verify,device.callback,auth.denied,access.denied,access.public_client,inference,managed.serve,desktop_bootstrap.serve,desktop_bootstrap.denied,spend.blocked,admin.denied,admin.limit.upsert, eadmin.limit.delete. I campi variano per evento:- Gli eventi di mint e refresh riusciti portano
sub,email,client_ip, e il risultato auth.deniedeaccess.deniedportano il motivo e l'IP client, più il percorso della richiesta perauth.denied, poiché nessuna identità utente esiste in quelle negazioni. Due motivi diaccess.deniedcambiano quello che l'evento porta:xff_unparseable: l'evento porta anche la voceX-Forwarded-Forche non poteva essere lettaclient_ip_unknown: l'evento non porta alcun IP client, perché la connessione non aveva un indirizzo peer mentre era impostato un elencoaccess_control
access.public_clientporta l'IP client della prima richiesta per processo che arriva da un indirizzo pubblico mentreaccess_control.allow_cidrsè vuoto. Il gateway serve la richiesta come al solito; l'evento segnala che il gateway potrebbe essere raggiungibile da internet pubblico. Vedi il riferimentoaccess_controlper quello che conta come pubblico e per l'elenco di autorizzazione consigliato.inferenceregistra quale upstream ha servito la richiesta e lo stato della rispostadesktop_bootstrap.deniedregistra un fetch di bootstrap di Claude Desktop rifiutato con il motivo (not_configured,policy_not_opted_in, ono_policy_matched) e l'identità dell'utenteadmin.deniedregistra un tentativo di autenticazione dell'API admin rifiutato con l'IP client, il metodo, il percorso e un motivo, senza il materiale della chiave presentato:invalid_keyquando è stato presentato unx-api-keyma non ha corrisposto a nessuna chiave configurata,bearer_rejectedquando è stato presentato solo un headerAuthorizatione non si è verificato come una sessione gateway inadmin.admin_groups, ono_credentialsquando nessun header è stato presentato
- Gli eventi di mint e refresh riusciti portano
-
Log operazionali: righe leggibili con prefisso
[gateway]per avvio, avvertimenti e errori upstream. La variabile di ambienteCLAUDE_GATEWAY_LOG_LEVELcontrolla la verbosità e accettadebug,info,warn, oerror, coninfocome predefinito. Adebug, ogni accesso e aggiornamento registra anche i nomi, non i valori, dei claim nell'id_token, più i nomi dei claim userinfo quandouserinfo_fallbackha fornito qualcosa, così puoi diagnosticare le impostazioniemail_claimegroups_claimsenza registrare PII. Non influisce sugli eventi di audit, che sono sempre emessi.
Salute
Il gateway serve GET /healthz come sonda di liveness e GET /readyz come sonda di readiness; /readyz verifica che lo store sia raggiungibile. Entrambi sono esenti da access_control.allow_cidrs, quindi le sonde continuano a funzionare su un listener bloccato.
Il documento di scoperta OAuth in /.well-known/oauth-authorization-server restituisce anche 200 solo dopo il caricamento della configurazione, la scoperta OIDC, la costruzione del client upstream e la migrazione di Postgres, quindi funge anche da controllo di avvio end-to-end.
Richieste upstream concorrenti
Per impostazione predefinita, ogni replica del gateway invia al massimo 256 richieste upstream contemporaneamente. Una risposta in streaming conta rispetto al limite fino al termine dello stream.
Una richiesta che arriva mentre una replica è al limite attende all'interno del gateway per uno slot libero. Lo sviluppatore vede una risposta che è lenta a iniziare o sembra bloccarsi. Su un upstream provider: anthropic, una richiesta che attende più a lungo di timeouts.upstream_ttfb_ms rinuncia a quell'upstream e fallisce con un 502 quando nessun upstream successivo lo serve.
La riga di log di avvio che contiene upstream requests: mostra il limite in vigore. Mentre una replica ha più richieste aperte rispetto al limite, registra anche un avvertimento che contiene client requests are open, al massimo una volta al minuto.
Per servire più richieste contemporaneamente, hai due opzioni:
- Aggiungi repliche.
- Aumenta il limite su ogni replica. Imposta la variabile di ambiente
BUN_CONFIG_MAX_HTTP_REQUESTSsul contenitore del gateway su un numero intero da 1 a 65535, quindi riavvia il contenitore.
Una replica riempie il suo limite a una velocità di richiesta di circa il limite diviso per il numero medio di secondi che una richiesta rimane aperta. Ad esempio, se le richieste rimangono aperte per 10 secondi in media, una replica al limite predefinito di 256 lo riempie a circa 26 richieste al secondo.
Se autoscali su CPU, una replica al limite mette in coda le richieste senza attivare uno scale-out, quindi imposta l'obiettivo al di sotto del livello di CPU che le tue repliche mostrano quando registrano l'avvertimento client requests are open.
Ogni richiesta aperta contiene memoria nel processo del gateway mentre esegue lo streaming e mentre attende uno slot. Se mantieni il limite a 256, la memoria su una replica sovraccarica continua a crescere, perché le richieste in attesa mantengono i loro corpi di richiesta. Dimensiona la memoria del contenitore per il numero di richieste aperte al picco e osserva la memoria quando cambi il limite. Una replica che esaurisce la memoria viene uccisa e interrompe ogni stream che contiene.
Comportamento in caso di interruzione
Se Postgres si arresta, il gateway stesso continua a servire gli sviluppatori che hanno effettuato l'accesso e i nuovi accessi falliscono. Se gli sviluppatori effettivamente continuano a lavorare dipende da come il tuo orchestrator gestisce la readiness:
- Sessioni esistenti: i bearer token si convalidano localmente con il segreto JWT, gli aggiornamenti della sessione non toccano lo store, e il processo del gateway può comunque servire l'inferenza
- Nuovi accessi: falliscono fino al recupero di Postgres, perché il flusso del dispositivo e i suoi contatori di limite di velocità vivono in Postgres
- Applicazione del limite di spesa: fallisce aperto per impostazione predefinita durante l'interruzione, quindi l'inferenza continua a fluire; capovolgilo per fallire chiuso se preferisci bloccare piuttosto che eseguire senza misurazione
- Readiness:
/readyzsegnala non-ready durante l'interruzione, quindi gli orchestrator che controllano il traffico sulla readiness rimuovono ogni replica dalla rotazione contemporaneamente. In quella topologia tutto il traffico, inclusa l'inferenza che il gateway potrebbe comunque servire, fallisce al load balancer fino al recupero di Postgres. La sonda di liveness su/healthzcontinua a passare, quindi le repliche non vengono riavviate. Punta la sonda di readiness a/healthzinvece se preferisci che gli sviluppatori che hanno effettuato l'accesso continuino a lavorare attraverso un'interruzione dello store; il costo è che i nuovi accessi falliscono contro una replica che ancora segnala ready.
Se il tuo IdP si arresta, le sessioni esistenti funzionano fino a ttl_hours, i nuovi accessi falliscono, e un aggiornamento della sessione riceve una risposta di riprovare e continua una volta che l'IdP è di nuovo disponibile. Imposta un ttl_hours più lungo se il tuo IdP ha frequenti finestre di manutenzione.
Rotazione del segreto JWT
Ruota il segreto di firma in tre passaggi in modo che le sessioni esistenti rimangono valide:
- Genera un nuovo segreto. Anteponi l'array
session.jwt_secret. - Esegui il rollout della distribuzione. I nuovi token firmano con il nuovo segreto; i vecchi token si convalidano comunque.
- Dopo
ttl_hourspiù un margine, rimuovi il vecchio segreto ed esegui di nuovo il rollout.
La rotazione è anche l'unico modo per forzare le sessioni prima che scadano: i bearer token si convalidano localmente rispetto al segreto JWT, quindi non c'è revoca per sessione. Sostituire il segreto completamente, senza mantenere il vecchio nell'array, invalida ogni sessione in sospeso contemporaneamente. Per l'offboarding individuale, esegui il deprovisioning dell'utente nel tuo IdP; la loro sessione termina entro ttl_hours.
Postgres
Il gateway contiene cinque tabelle di dati più una tabella _migrations, tutte create dalle sue migrazioni al momento dell'avvio:
| Tabella | Contenuti | Conservazione |
|---|---|---|
kv |
Concessioni di dispositivi (TTL di 10 minuti) e contatori di limite di velocità | TTL per riga |
spend |
Contatori di spesa da inizio periodo per principale, in centesimi | admin.spend_retention_months, predefinito 13 |
spend_limits |
Limiti di spesa configurati | Fino all'eliminazione tramite l'API |
admin_audit |
Traccia di mutazione dell'API admin | admin.audit_retention_days, predefinito 365 |
principal_emails |
Email dell'ultimo accesso di ogni principale, nome visualizzato e gruppi IdP. Contiene PII. | admin.identity_retention_days dall'ultima attività, predefinito 90 |
Un ciclo di 30 secondi scade le righe kv oltre il loro TTL, e una pulizia oraria applica le finestre di conservazione sulle tabelle di spesa, quindi nulla cresce senza limiti. Senza limiti di spesa configurati, solo kv viene scritto. Il gateway applica le sue proprie migrazioni dello schema all'avvio e ad ogni aggiornamento, quindi il suo ruolo di database ha bisogno di diritti per creare e alterare le tabelle. Puntalo a un database o schema dedicato al gateway per mantenere quel grant stretto.
Con limiti di spesa in uso, un database perso significa perdita di tracciamento della spesa e limiti, non solo re-accessi degli sviluppatori, quindi esegui backup regolari. Per cancellare immediatamente uno sviluppatore partito piuttosto che aspettare la conservazione, esegui DELETE FROM principal_emails WHERE principal = '<sub>' direttamente; questo rimuove l'unica tabella che contiene la loro email, nome e gruppi. Le righe spend e admin_audit fanno riferimento solo allo pseudonimo OIDC sub.
Aggiornamenti
Le repliche sono senza stato, quindi un riavvio rolling non perde alcuno stato del gateway. Il gateway esegue migrazioni dello schema all'avvio, il che significa che distribuire il nuovo binario auto-migra il database. Le repliche concorrenti si serializzano su un lock consigliato di Postgres, quindi solo una applica ogni migrazione.
Quando il tuo orchestrator arresta una replica con SIGTERM, come in un riavvio rolling o uno scale-in, il gateway smette di accettare nuove connessioni e lascia che le richieste e gli stream già in volo finiscano prima di uscire. Attende fino a 25 secondi, chiamato la finestra di drenaggio, quindi chiude tutto ciò che è ancora aperto. Un SIGINT, come Ctrl+C in un terminale, avvia lo stesso drenaggio, e un secondo segnale durante il drenaggio chiude le richieste aperte ed esce subito. Il drenaggio richiede gateway v2.1.274 o successivo.
Le generazioni lunghe possono eseguire lo streaming per minuti. Su Kubernetes e Amazon ECS, aumenta entrambi questi insieme per dare a quegli stream più tempo:
- La finestra di drenaggio: imposta la variabile di ambiente
CLAUDE_GATEWAY_DRAIN_TIMEOUT_MSsul contenitore del gateway su un numero intero positivo di millisecondi, come120000. Il gateway ignora un valore in qualsiasi altra forma, come120s, e mantiene il predefinito di 25 secondi - Il periodo di grazia del tuo orchestrator:
terminationGracePeriodSecondssu Kubernetes, ostopTimeoutsu Amazon ECS
Il periodo di grazia predefinito è 30 secondi su entrambe le piattaforme. Mantienilo almeno 5 secondi più lungo della finestra di drenaggio, o l'orchestrator uccide il gateway prima che il drenaggio finisca. Su Kubernetes, aggiungi anche la durata di qualsiasi hook preStop, perché il periodo di grazia inizia a contare prima che l'hook venga eseguito piuttosto che quando il gateway riceve SIGTERM.
La tua piattaforma potrebbe anche limitare quanto a lungo il drenaggio può eseguire:
- Amazon ECS su Fargate:
stopTimeoutconsente al massimo 120 secondi - Cloud Run: arresta un'istanza 10 secondi dopo
SIGTERM, quindi gli stream aperti ottengono al massimo 10 secondi lì, qualunque sia la finestra di drenaggio
Quando la finestra di drenaggio termina con richieste ancora aperte, il gateway registra un avvertimento che contiene drain window over after, conta le richieste che ha tagliato e nomina entrambe le impostazioni da aumentare.
Le migrazioni sono append-only, quindi il rollback a un binario precedente che conosce meno migrazioni è sicuro; ignora le righe extra. Il rollback ri-convalida anche il YAML rispetto allo schema del binario più vecchio, quindi una configurazione che ha adottato una chiave introdotta dalla versione più recente fallisce l'avvio su quella più vecchia. Rimuovi la nuova chiave prima di eseguire il rollback.
Poiché fissi la versione del gateway nella tua immagine, le correzioni nelle nuove versioni di Claude Code, incluse le correzioni di sicurezza, raggiungono la tua distribuzione solo quando aggiorni il pin e ridistribuisci. Includi il gateway nello stesso ciclo di patching che usi per altri servizi che contengono credenziali di produzione.
Sicurezza
Questa sezione risponde alle domande che una revisione di sicurezza pone: quali dati fluiscono attraverso il gateway e dove vanno, quali attacchi il design difende, e quali risposte appartengono a un questionario di conformità.
Flusso di dati
| Dati | Percorso | Inviato ad Anthropic dal gateway |
|---|---|---|
| Inferenza (prompt, completamenti) | CLI → gateway → il tuo upstream | Solo se l'API Anthropic è un upstream configurato |
| Telemetria (metriche OTLP, più log e tracce opt-in) | CLI → gateway → il tuo collettore | Mai |
| Identità (email, gruppi, sub) | IdP → gateway → JWT → CLI; il CLI lo marca sulle esportazioni OTLP. Se attivi forward_user_identity, il gateway invia anche l'email dello sviluppatore e il soggetto IdP come intestazioni al tuo proxy |
Mai |
| Impostazioni gestite | Il tuo gateway YAML → CLI | Mai |
| Log di audit | Gateway stderr → il tuo aggregatore | Mai |
Riepilogo del modello di minaccia
Il gateway si trova all'interno del perimetro della tua rete, ma i singoli laptop degli sviluppatori non sono considerati affidabili. Il design tiene conto di questo in tre modi:
-
Gli sviluppatori detengono JWT di breve durata invece di chiavi upstream grezze. La gamba CLI-to-gateway utilizza la concessione del dispositivo RFC 8628, e lo scambio di autorizzazione del gateway con l'IdP esegue PKCE nella configurazione predefinita, quindi un codice di autorizzazione IdP intercettato è inutile.
-
La pagina di verifica del dispositivo applica POST della stessa origine e un limite di velocità per IP per RFC 8628 §5.1. Consulta Resistenza al brute-force del codice utente.
-
Le richieste del gateway al tuo IdP, ai tuoi collettori OTLP e agli upstream
provider: anthropicpassano attraverso una guardia SSRF (Server-Side Request Forgery) che risolve DNS, blocca gli indirizzi link-local e cloud-metadata più loopback per impostazione predefinita, e fissa la connessione all'IP risolto, quindi gli URL influenzati dall'operatore non possono essere reindirizzati agli endpoint dei metadati cloud. Gli intervalli privati RFC 1918 sono deliberatamente consentiti, perché gli IdP e i collettori OTLP comunemente vivono su IP privati. Per gli altri provider, il gateway rifiuta unbase_urlche nomina uno di quegli indirizzi o un nome host di metadati quando carica la configurazione, e l'SDK del provider si connette quindi senza il controllo DNS.Se attivi egress solo proxy, quel controllo di indirizzo si sposta al tuo proxy in avanti: il gateway consegna i nomi host e la lista di consentiti del proxy deve rifiutare quelle destinazioni.
Imposta
CLAUDE_GATEWAY_ALLOW_LOOPBACK=1nell'ambiente del gateway solo quando qualcosa che il gateway deve raggiungere legittimamente vive su loopback, come un IdP di sviluppo locale o un collettore OTLP sidecar sulocalhost. La variabile rilassa il blocco loopback per ogni URL configurato dall'operatore e salta anche l'avviso al momento dell'avvio che controlla se il pod può raggiungere l'endpoint dei metadati cloud, quindi preferisci dare al collettore il suo indirizzo interno.
Se aggiungi i tuoi controlli di uscita, il gateway deve raggiungere il server dei metadati ogni volta che utilizza credenziali di metadati dell'istanza come workload identity.
Due minacce sono fuori ambito perché sono la tua infrastruttura da proteggere:
- Un host gateway compromesso: l'host sia contiene la credenziale upstream che distribuisce impostazioni gestite a ogni sviluppatore connesso, quindi il controllo sulla configurazione del gateway è paragonabile al controllo sul tuo MDM. La finestra di dialogo di approvazione del CLI per le impostazioni in grado di shell limita i cambiamenti silenziosi ma non sostituisce la sicurezza dell'host.
- Un provider OIDC malintenzionato: il provider firma gli id_token che il gateway si fida, quindi può asserire qualsiasi identità. Il vetting e la protezione del tuo IdP è tua responsabilità.
Resistenza al brute-force del codice utente
Il user_code che uno sviluppatore digita nella pagina di verifica /device è di 8 caratteri tratti da un alfabeto di 20 caratteri, che produce 20⁸ o circa 2,56×10¹⁰ combinazioni, e scade dopo 10 minuti.
Il gateway applica limiti di velocità per IP sugli endpoint di concessione del dispositivo, configurabili tramite rate_limits. Aumenta i limiti se molti sviluppatori accedono da un singolo indirizzo NAT aziendale condiviso. I rollout su larga scala mostra come dimensionarli. I limiti si applicano solo al flusso di accesso, non all'inferenza.
Postura di conformità
- Residenza dei dati: il piano dati del gateway stesso non invia nulla ad Anthropic a meno che l'API Anthropic non sia un upstream configurato; quando lo è, il tuo accordo di gestione dei dati esistente si applica al percorso di inferenza. Telemetria, audit, identità e impostazioni vanno solo alle destinazioni che configuri.
- Traffico del processo host: il processo host è il Claude Code CLI. Il
claude gatewayviene eseguito secondo le stesse regole di terze parti delle distribuzioni Amazon Bedrock e Google Cloud's Agent Platform e non invia nulla ad Anthropic. Prima della v2.1.227, il processo host inviava telemetria di avvio come versione del prodotto e piattaforma, che l'impostazione diCLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1nell'ambiente del container disattivava. Quelle versioni inviavano anche una richiestaHEADall'avvio, senza corpo o credenziali, a/api/hellosuhttps://api.anthropic.com, o suANTHROPIC_BASE_URLquando l'ambiente lo impostava, a meno che l'ambiente non impostasse anche una variabile proxy comeHTTPS_PROXYo un certificato client mTLS. Ignoravano la risposta, quindi bloccare quella richiesta al firewall di uscita non influenzava il gateway. - Analitiche client: il CLI disabilita la sua stessa analittica di utilizzo e segnalazione degli errori mentre è connesso a un gateway. Prima del primo accesso, il CLI invia comunque eventi di avvio ad Anthropic, incluso su macchine le cui impostazioni gestite forzano l'accesso al gateway. Per disattivare anche quelli, fornisci
DISABLE_TELEMETRYnelle stesse impostazioni gestite lato client che forzano l'accesso al gateway. - Segnalazione degli errori: il CLI disattiva la segnalazione degli errori ogni volta che le sue richieste di modello vanno a qualsiasi endpoint diverso dall'API di prima parte di Anthropic, come Amazon Bedrock o un
ANTHROPIC_BASE_URLpersonalizzato. - Macchine client: i CLI degli sviluppatori inviano comunque controlli del nome host WebFetch e controlli della versione ad Anthropic a meno che
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1eskipWebFetchPreflight: truenon siano impostati. Consulta utilizzo dei dati. - Valutazioni del sondaggio: mentre è connesso a un gateway, il CLI disabilita il caricamento della valutazione legato ad Anthropic insieme ai flussi di analitiche, quindi non invia valutazioni ad Anthropic.
- Condivisione della trascrizione: scegliere Sì su un prompt di condivisione della trascrizione di un sondaggio scrive un file locale sotto
~/.claude/feedback-bundles/invece di caricare su Anthropic. - Aggiornamenti client: i controlli di aggiornamento sono separati dal traffico del gateway. Fissa le versioni attraverso la tua distribuzione e imposta
DISABLE_UPDATESse i laptop non devono recuperare le versioni.DISABLE_AUTOUPDATERinterrompe solo gli aggiornamenti in background mentreclaude updatefunziona ancora. - TLS: servi
public_urlsu HTTPS in produzione, sia dal listener proprio del gateway tramitelisten.tlsche da un ingress che termina TLS davanti alle repliche HTTP semplici, conlisten.public_urlimpostato in entrambi i casi. Il gateway non rifiuta HTTP semplice. L'IdP deve servire HTTPS in produzione, e Postgres supporta?sslmode=require. ImpostaStrict-Transport-Securityal tuo ingress. - Divulgazione di vulnerabilità: segui Segnalazione di problemi di sicurezza
Troubleshooting
Per domande e feedback, utilizza il supporto Claude Code, oppure apri un problema nel repository GitHub di Claude Code. Quando segnali un problema, includi:
- Gateway issue: lo stderr del gateway per la finestra rilevante, il tuo
gateway.yamlcon i segreti oscurati, la versione del gateway, mostrata nella pagina di destinazione in/e nell'intestazione della rispostax-cc-gateway-versionin/managed/settings, e cosa è cambiato di recente - Login issue: lo sviluppatore esegue
claude --debug-file ./claude-debug.txt, riproduce il problema e invia quel file più il log di audit del gateway per la stessa finestra - Inference issue: il modello richiesto, gli upstream configurati e il log di audit del gateway per la richiesta, che registra quale upstream l'ha servita e lo stato della risposta
Lo stderr del gateway include il flusso di eventi di audit, il log di audit registra le identità degli sviluppatori e il file di debug registra l'output di hook e MCP server dalla macchina dello sviluppatore. Rivedi e oscura questi elementi prima di pubblicare su un problema pubblico.
| Sintomo | Causa | Soluzione |
|---|---|---|
La /login di uno sviluppatore mostra il selettore di account standard invece della schermata Cloud gateway |
forceLoginMethod o forceLoginGatewayUrl non è impostato nelle impostazioni gestite su quella macchina |
Distribuisci il file delle impostazioni gestite al dispositivo; /login legge l'URL del gateway da lì |
Le richieste di uno sviluppatore falliscono con Not signed in to the Cloud gateway — run /login. |
Le impostazioni gestite della macchina impostano forceLoginMethod: "gateway" o forceLoginGatewayUrl, e la sessione non ha un accesso al gateway. Un accesso a claude.ai residuo non soddisfa il requisito. |
Chiedi allo sviluppatore di eseguire /login e completare l'accesso al gateway. Vedi anche Administrator policy requires a Cloud gateway sign-in. |
| Claude Desktop segnala che la sua configurazione di bootstrap non poteva essere recuperata | /user/bootstrap ha restituito 404: il criterio che corrisponde all'utente non contiene una chiave desktop, oppure nessun criterio corrisponde. Il log di audit del gateway registra ogni rifiuto come desktop_bootstrap.denied con il motivo. |
Aggiungi un blocco desktop al criterio che corrisponde all'utente, oppure al livello base match: {}; un desktop: {} vuoto è sufficiente. Vedi Claude Desktop overlay. |
L'avvio mostra Gateway login is configured in managed settings, but this Claude Code build does not include Cloud gateway support. |
La build di Claude Code installata precede il supporto del gateway | Chiedi allo sviluppatore di aggiornare Claude Code a una versione che include il supporto Cloud gateway |
L'avvio esce con Administrator policy requires a Cloud gateway sign-in on this machine |
L'ambiente dello sviluppatore imposta ANTHROPIC_API_KEY o ANTHROPIC_AUTH_TOKEN, le loro impostazioni configurano un apiKeyHelper, oppure una chiave API da un accesso precedente a Claude Console è ancora salvata |
Chiedi allo sviluppatore di cancellare ciascuno che si applica: annulla l'impostazione della variabile, rimuovi la voce apiKeyHelper, oppure esegui claude auth logout per rimuovere la chiave salvata. Quindi chiedigli di avviare claude e accedere con /login. Vedi anche Administrator policy requires a Cloud gateway sign-in. |
L'avvio o /login segnala Claude Code may not be enabled for your organization dopo un 403 al caricamento delle impostazioni gestite |
Il gateway, o qualcosa davanti ad esso, ha risposto alla richiesta /managed/settings con 403. La rotta delle impostazioni del gateway stesso non risponde mai con 403. Lo stato proviene dai controlli IP access_control o da un proxy o WAF davanti al gateway. Il log di audit registra un rifiuto del controllo IP come access.denied con il motivo. Lo sviluppatore rimane connesso. |
Controlla il log di audit per access.denied al momento dell'errore e correggi gli elenchi access_control o il front end, quindi chiedi allo sviluppatore di avviare claude di nuovo |
CLI /login: The gateway is limiting sign-in attempts right now, oppure Request failed with status code 429 nelle versioni precedenti. La pagina /device potrebbe mostrare Too many attempts agli sviluppatori che non hanno mai provato prima |
È stato raggiunto il limite di velocità di accesso per IP. O listen.trusted_proxies non copre il bilanciatore di carico, quindi ogni sviluppatore condivide il suo indirizzo, oppure molti sviluppatori condividono un indirizzo di uscita NAT o VPN. Gli eventi di audit con result: rate_limited mostrano lo stesso uno o pochi valori client_ip. |
Imposta prima listen.trusted_proxies agli intervalli di origine del bilanciatore di carico, quindi aumenta rate_limits se gli sviluppatori condividono ancora indirizzi. Vedi Large rollouts. |
CLI /login: Gateway hosts must be on your organization's private network; <host> resolves to the public (or unrecognized) address <ip> |
Il nome host del gateway si risolve in almeno un indirizzo IP pubblico. Claude Code controlla ogni indirizzo risolto e richiede che tutti siano privati. Una causa comune è un nome dual-stack in cui una famiglia si risolve in un indirizzo pubblico, inclusi i bilanciatori di carico dual-stack interni di AWS, che restituiscono indirizzi AAAA in intervallo pubblico. | Fai in modo che il nome del gateway si risolva solo in indirizzi privati sulle macchine degli sviluppatori. Per un nome dual-stack, elimina il record in intervallo pubblico o servi un nome DNS solo interno separato. Vedi il prerequisito di rete privata. Se l'indirizzo è spazio pubblico che la tua organizzazione possiede e utilizza internamente, dichiara quel blocco invece. |
CLI /login: Gateway login would go through proxy <proxy>, which is not on a private network |
Un HTTPS_PROXY o HTTP_PROXY si applica all'host del gateway e il nome host del proxy si risolve in un indirizzo pubblico. Un proxy il cui host si risolve solo in indirizzi privati è consentito e non attiva questo errore |
Aggiungi l'host del gateway a NO_PROXY sulla macchina dello sviluppatore in modo che la connessione sia diretta, oppure utilizza un proxy il cui nome host si risolve in indirizzi privati. Il messaggio nomina la voce esatta NO_PROXY da aggiungere |
CLI /login: Claude Code only signs in to <host> from inside its declared network <block> (managed settings), and this machine is connecting from <ip>, outside it |
Il gateway è su un blocco dichiarato in gatewayInternalNetworks, e la macchina dello sviluppatore l'ha raggiunto da un indirizzo al di fuori di quel blocco: un pool di indirizzi VPN, un segmento NAT di container o WSL2, oppure una rete che non è la tua |
Chiedi allo sviluppatore di eseguire /login dal sistema operativo host sulla tua rete. Se l'indirizzo mostrato è anche lo spazio pubblico della tua organizzazione, sostituisci la voce del gateway con un blocco che copra entrambi, fino a /8; una seconda voce sovrapposta è rifiutata |
CLI /login: Every address for gateway host <host> must be inside its declared network <block>, and it also resolves to <ip> |
Il nome del gateway si risolve in un indirizzo al di fuori del blocco dichiarato in gatewayInternalNetworks: un secondo sito, oppure un record IPv6 su un nome dual-stack. Sotto un blocco dichiarato ogni record deve essere all'interno di quel blocco IPv4, indirizzi privati e IPv6 inclusi |
Pubblica solo record all'interno del blocco per il nome del gateway sulle macchine degli sviluppatori, oppure servi un nome solo interno separato |
CLI /login: <host> is on the declared network <block>, which Claude Code checks over a direct connection, not through an HTTP proxy |
Un HTTPS_PROXY o HTTP_PROXY si applica a un gateway su un blocco dichiarato |
Sulla macchina dello sviluppatore, aggiungi la voce NO_PROXY che il messaggio nomina |
CLI /login: un messaggio che inizia con gatewayInternalNetworks in managed settings |
Il valore viola una delle regole di convalida, e il messaggio nomina quale. Fino a quando non lo correggi, Claude Code rifiuta ogni nuovo /login del gateway sulla macchina, gateway su indirizzi privati inclusi; gli accessi esistenti continuano a funzionare |
Nella fonte delle impostazioni gestite che distribuisci, correggi la voce che il messaggio nomina, quindi esegui di nuovo /login |
CLI /login: Could not resolve the configured HTTP proxy |
Il nome host in HTTPS_PROXY o HTTP_PROXY non si risolve dalla macchina dello sviluppatore, tipicamente perché non è connesso alla rete aziendale |
Chiedi allo sviluppatore di connettersi alla tua rete o VPN e riprovare, oppure correggi l'URL del proxy |
CLI /login: Could not resolve gateway host <host> |
La macchina non può risolvere il nome DNS interno del gateway, tipicamente perché non è sulla rete aziendale | Chiedi allo sviluppatore di connettersi alla tua rete o VPN, quindi riprova /login |
L'avvio esce con un errore di convalida della configurazione che nomina store.postgres_url |
Nessun Postgres configurato; il gateway richiede Postgres | Imposta store.postgres_url. Per lo sviluppo locale, utilizza un container usa e getta: docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres. |
L'avvio esce: requires the native binary |
In esecuzione sotto Node invece del binario nativo | Installa Claude Code con uno dei metodi di installazione standalone |
L'avvio esce con un errore di scoperta OIDC dopo config.load |
oidc.issuer non raggiungibile, oppure la catena TLS non è attendibile |
Controlla che l'emittente sia raggiungibile dal pod e serva /.well-known/openid-configuration. Imposta ca_cert_pem per PKI privata. Se il pod raggiunge l'IdP solo attraverso un proxy forward, imposta oidc.use_proxy: true; nelle versioni precedenti a v2.1.227, fornisci al pod una rotta diretta a ciascuno degli endpoint dell'IdP invece. Se il pod inoltre non può risolvere il nome host dell'IdP, oppure il proxy rifiuta CONNECT a un indirizzo IP, vedi Proxy-only egress, che richiede v2.1.277 o successivo. |
| L'avvio esce con un errore di autorizzazione Postgres | Il ruolo del database manca dei diritti DDL sul suo schema | Concedi al ruolo CREATE sullo schema del gateway in modo che possa creare e alterare le sue tabelle all'avvio |
Log: could not connect to Postgres at boot, attempt 1 of 3 |
Il database non era raggiungibile quando il gateway è stato avviato, ad esempio su un'istanza fredda la cui rete è ancora in fase di avvio | Se il gateway finisce di avviarsi, non è necessaria alcuna azione. Quando il database non è raggiungibile, il gateway tenta la connessione tre volte, due secondi di distanza, prima di uscire. Se esce con could not connect to Postgres, controlla store.postgres_url e il percorso di rete al database. Se i tentativi scadono piuttosto che essere rifiutati, aumenta store.connect_timeout_seconds per dare a ciascuno più tempo. |
/oauth/callback mostra "Sign-in could not be completed" |
Dominio email rifiutato, convalida id_token non riuscita, oppure email_verified è esplicitamente false, che il gateway rifiuta sempre senza override |
Controlla allowed_email_domains e che l'IdP restituisca un'attestazione email verificata. Per email_verified: false, correggi la verifica lato IdP. Se il tuo IdP emette email con un nome di attestazione diverso, imposta oidc.email_claim. |
Log: token exchange failed request_id=<id>: id_token missing email claim |
L'IdP non include email nell'id_token per impostazione predefinita. Questo rifiuto si attiva solo quando allowed_email_domains è impostato; senza di esso, un'email mancante conia una sessione senza email |
Configura l'IdP per emettere email nell'id_token. Okta: aggiungi email alle attestazioni del token ID di un server di autorizzazione personalizzato. Entra: aggiungi email come attestazione facoltativa sulla registrazione dell'app. PingFederate: abilita una Politica OpenID Connect che emette email. Se l'IdP serve email dall'endpoint userinfo ma non lo includerà nell'id_token, come il server di autorizzazione dell'organizzazione Okta, imposta oidc.userinfo_fallback: true. |
Log: refresh failed request_id=<id>: invalid_token (…) (at userinfo_no_id_token, …), e gli sviluppatori vedono Cloud gateway session expired ogni session.ttl_hours |
L'IdP ha accettato il token di aggiornamento ma non ha restituito alcun id_token con esso, quindi il gateway ha chiesto all'endpoint userinfo dell'IdP le attestazioni dell'utente. L'IdP ha rifiutato il token di accesso aggiornato lì. Il gateway risponde temporarily_unavailable, quindi Claude Code mantiene il token di aggiornamento ma non può rinnovare la sessione. Le versioni del gateway precedenti a v2.1.260 registrano la stessa riga senza il dettaglio (at …). |
Imposta oidc.scope_on_refresh: true, disponibile nel gateway v2.1.260 o successivo, in modo che la richiesta di aggiornamento chieda di nuovo openid. Alcuni IdP, come Okta, restituiscono un id_token all'aggiornamento solo quando richiesto. Su PingFederate, abilita Return ID Token On Refresh Grant in Applications > OAuth > OpenID Connect Policy Management invece. La chiave non cambia il comportamento di PingFederate. Per altri IdP che ancora lo omettono, controlla se l'endpoint userinfo accetta token di accesso emessi da un aggiornamento. Come misura temporanea, aumenta session.ttl_hours. Vedi Identity provider setup per il compromesso di deprovisioning. |
Ogni richiesta Amazon Bedrock restituisce 502; il log mostra Could not load credentials from any providers |
Su EC2, il limite di hop predefinito di IMDSv2 di 1 blocca la richiesta di metadati dell'istanza dall'interno del container. L'avvio e /readyz passano comunque perché l'AWS SDK risolve le credenziali dell'istanza sulla prima richiesta, non alla costruzione del client |
Aumenta il limite di hop con aws ec2 modify-instance-metadata-options --instance-id <id> --http-put-response-hop-limit 2, oppure impostalo nel modello di lancio. La modifica si applica a ogni container sull'istanza. Preferisci i ruoli delle attività ECS dove disponibili, che leggono le credenziali dall'endpoint delle credenziali del container ECS ed evitano completamente la modifica, oppure applica la modifica su un'istanza del gateway dedicata per limitare l'esposizione. |
Al carico di picco, le risposte sono lente a iniziare o sembrano bloccarsi, oppure falliscono con un 502 all upstreams failed mentre l'upstream è integro |
Una replica ha più richieste aperte di quante ne invia upstream contemporaneamente, quindi le richieste extra attendono all'interno del gateway. Su un upstream provider: anthropic, una richiesta che attende più a lungo di timeouts.upstream_ttfb_ms rinuncia a quel upstream, che produce il 502 quando nessun upstream successivo lo serve. Il log mostra un avviso che contiene client requests are open. |
Aggiungi repliche, oppure aumenta il limite su ogni replica. Vedi Concurrent upstream requests. |
| Errore IdP: unknown or unsupported scope | L'IdP rifiuta gli ambiti che non riconosce | Imposta oidc.scopes esattamente all'elenco che il tuo IdP accetta; deve includere openid. L'impostazione predefinita è openid profile email offline_access. |
Le sessioni non si rinnovano silenziosamente dopo l'impostazione di oidc.scopes |
offline_access è stato eliminato dall'override |
Aggiungi di nuovo offline_access se il tuo IdP lo supporta. Senza un token di aggiornamento, gli sviluppatori rieseguono l'accesso del browser ogni session.ttl_hours. |
| Il browser mostra "This request came from another site and was blocked" | POST di modulo cross-site, bloccato come protezione CSRF. Previsto per pagine incorporate o proxy | Apri il collegamento di verifica direttamente |
| Chrome blocca il pulsante Approve con "Refused to send form data … violates … Content Security Policy directive: form-action", ma la stessa pagina funziona in Safari o Firefox | Chrome applica form-action all'intera catena di reindirizzamento. Il tuo IdP reindirizza ulteriormente a un secondo host che non è nella lista di autorizzazione. |
Aggiungi ogni origine aggiuntiva nella catena di reindirizzamento a oidc.form_action_origins. Apri Chrome DevTools → Console nella pagina Approve per vedere quale origine è stata bloccata. |
| L'accesso si completa presso l'IdP ma il callback fallisce, con un errore CSP in Chrome o "this sign-in link has expired" in Safari | L'IdP ha restituito il codice tramite response_mode=form_post, che lo invia automaticamente cross-origin tramite POST a /oauth/callback. Chrome lo blocca sotto una CSP ristretta; Safari consente l'invio ma il callback legge solo la stringa di query. |
Assicurati che il tuo IdP onori response_mode=query, che il gateway richiede esplicitamente in modo che il callback sia un reindirizzamento semplice |
| L'accesso funziona localmente ma fallisce dietro un ALB | public_url nomina ancora l'origine locale o interna http://, quindi l'IdP ottiene l'redirect_uri sbagliato |
Imposta listen.public_url all'origine esterna https:// e registra <public_url>/oauth/callback con l'IdP |
| Lo sviluppatore vede il prompt di fiducia ripetutamente | Il certificato TLS ruota per replica o per richiesta | Utilizza un certificato stabile all'ingresso, oppure termina TLS una volta ed esegui le repliche su HTTP semplice internamente |
CLI /login: "Could not verify the gateway's TLS certificate" o SELF_SIGNED_CERT_IN_CHAIN |
La catena TLS del gateway è firmata da una CA privata non nell'archivio di fiducia dell'host CLI | Claude Code legge l'archivio di fiducia del sistema operativo per impostazione predefinita sul binario nativo e su Node 22.15 o successivo; CLAUDE_CODE_CERT_STORE controlla questo comportamento. Se la CA è installata nell'archivio di fiducia del sistema operativo, assicurati che gli sviluppatori siano su un runtime attuale. Altrimenti imposta NODE_EXTRA_CA_CERTS al PEM del certificato CA prima del lancio. Il prompt dell'impronta digitale della prima connessione si applica comunque. |
CLI /login completa l'accesso del browser, quindi la sessione termina con Cloud gateway sign-in was not completed e una mancata corrispondenza del certificato TLS |
Sulla prima richiesta dopo l'accesso, il gateway ha presentato un certificato che non corrisponde all'impronta digitale che Claude Code ha fissato, quindi Claude Code non ha mantenuto alcuna credenziale del gateway. Le cause comuni sono repliche dietro un indirizzo che servono certificati diversi, oppure qualcosa sul percorso di rete che intercetta TLS. | Servi un certificato per il nome host, ad esempio terminando TLS una volta all'ingresso, quindi chiedi allo sviluppatore di eseguire di nuovo /login. Se quel certificato differisce da quello fissato, Claude Code mostra di nuovo il prompt di fiducia con un avviso che il certificato è cambiato. |
CLI /login si ferma con The gateway's TLS certificate changed during sign-in: it no longer matches the one you trusted |
Una richiesta di accesso ha raggiunto un server il cui certificato non corrisponde a quello che lo sviluppatore ha accettato quando /login è iniziato: repliche dietro un indirizzo che servono certificati diversi, intercettazione TLS sul percorso, oppure una rotazione del certificato mentre l'accesso era in corso. |
Servi un certificato per il nome host, quindi chiedi allo sviluppatore di avviare di nuovo l'accesso e rivedere il nuovo certificato al prompt di fiducia. |
Il messaggio Cloud gateway sign-in was not completed nomina il nome host del gateway. Quando Claude Code ha sia l'impronta digitale fissata che quella presentata, il messaggio mostra anche i primi 16 caratteri di ciascuna.
Se Claude Code segnala couldn't load your organization's managed settings dopo un accesso al gateway, Claude Code nomina il motivo, si riavvia sul posto e riprende la conversazione. Se Claude Code non può riavviarsi, ad esempio in una sessione in background, Claude Code termina la sessione e mantiene l'accesso.
Correlati
- Panoramica del gateway delle app Claude: quickstart e connessione dello sviluppatore
- Riferimento di configurazione: ogni opzione di
gateway.yaml