Autenticazione CLI fatta bene: la guida completa ai 4 metodi
I 4 metodi di autenticazione CLI che contano, come li implementano GitHub, AWS e gli strumenti di IA, e gli errori di sicurezza da evitare assolutamente.
I 4 metodi di autenticazione CLI che contano, come li implementano GitHub, AWS e gli strumenti di IA, e gli errori di sicurezza da evitare assolutamente.
Ogni CLI per sviluppatori include login come prima comando. E ognuna risolve l'autenticazione in modo diverso.
GitHub ti mostra un codice e apre il browser per verificarlo. AWS apre un browser per l'SSO basato su PKCE. Stripe ti fa confermare un codice di abbinamento nella dashboard. I nuovi strumenti di IA (Claude Code, OpenAI Codex CLI, Cursor) hanno tutti scelto strategie proprie.
Se stai costruendo una CLI, l’autenticazione è una delle prime cose da risolvere. Scegli il metodo sbagliato e ne sentirai parlare: utenti frustrati, audit di sicurezza, o entrambi. E con la recente ondata di agenti AI per il coding che chiamano strumenti CLI in modo programmato, la posta in gioco è ancora più alta: non stai più autenticando solo un umano. Potresti consegnare credenziali a un processo autonomo.
Ecco i quattro metodi di autenticazione che contano, come li implementano i principali strumenti, e gli errori da evitare.
Prima di approfondire, ecco un rapido confronto:
| Metodo | Ideale per | Sicurezza | Serve il browser? |
|---|---|---|---|
| Flusso del codice dispositivo OAuth | Ambienti headless, SSH | Alta | No (sulla stessa macchina) |
| OAuth via browser (redirect su localhost) | Sviluppo locale | Massima | Sì |
| API Key / PATs | Automazione, CI/CD, prototipi rapidi | Moderata | No |
| Credenziali client | Macchina-a-macchina, servizi | Alta | No |
Ciascuno ha i suoi compromessi. Ecco cosa sapere su ognuno.
Qui la CLI ti mostra un codice come ABCD-1234 e un URL, e ti chiede di aprire quell’URL su qualsiasi dispositivo e inserire il codice.
Chi lo usa: GitHub CLI (default), Azure CLI (tramite --use-device-code), Vercel CLI (passato da poco come default), OpenAI Codex CLI (opzione beta)
cli loginclient_id e gli scope richiestidevice_code (identificatore interno), un user_code (il codice breve da digitare), e una verification_uri (dove andare)Il vantaggio principale: funziona ovunque. Sessione SSH su un server remoto? Ok. Dentro un container Docker? Ok. Cloud IDE senza browser locale? Ok. Il browser non deve essere sulla stessa macchina della CLI.
Supporta tutta l’autenticazione enterprise (SAML, OIDC, MFA) perché tutto accade nel browser, non nel terminale. La CLI non vede mai la tua password.
Il flusso device code ha un problema di phishing. Un attaccante può avviare una richiesta di codice dispositivo, ottenere un user code legittimo e ingannarti facendoti inserirlo, autorizzando di fatto la sessione dell’attaccante. Non è teoria. Analisti di sicurezza hanno documentato questo attacco sulla device code auth di AWS SSO.
La questione è seria al punto che AWS ha cambiato il default. Da AWS CLI v2.22.0 in poi, il default per aws sso login è passato dal flusso device code al flusso di autorizzazione con PKCE. Device code è ancora disponibile con --use-device-code, ma non è più la strada principale.
Nel frattempo, il tenant di Microsoft ha iniziato a bloccare del tutto il device code flow tramite policy di accesso condizionale, segno che viene considerato un metodo a rischio elevato.
Quindi c'è una spaccatura interessante: Vercel ha adottato il device code flow come predefinito a settembre 2025, mentre AWS si è allontanata da esso. Sembra che il device code flow sia ottimo negli ambienti dove davvero non puoi aprire un browser, ma se puoi, PKCE è più sicuro.
Dal lato dei provider di autenticazione, la domanda sta crescendo. Logto ha appena introdotto il supporto OAuth 2.0 Device Authorization Grant per app native dalla v1.38.0 (open source) e Logto Cloud, così puoi abilitare il device flow come metodo per qualsiasi applicazione nativa. Conta se stai costruendo una CLI. Implementare bene RFC 8628 (scadenza dei codici, rate limiting, polling, UX per il login) è più lavoro di quanto ci si aspetta e lasciare al provider il compito significa solo fare le giuste chiamate HTTP.
Alcuni punti da sapere su RFC 8628:
expires_in è impostato dal server di auth; l’RFC suggerisce 1800 secondi (30 minuti) come esempio, ma non è obbligatorio.slow_down, aggiungi 5 secondi all’intervallo.Il metodo più comune per CLI su macchina di sviluppo. Esegui login, si apre il browser, ti autentichi e il browser fa redirect su un server locale avviato dalla CLI. Le implementazioni moderne usano anche PKCE (si pronuncia "pixie"), che rende il flusso difficile da sfruttare.
Chi lo usa: Claude Code, gcloud CLI, Terraform CLI, AWS CLI v2.22+ (per SSO, PKCE è default)
cli loginhttp://127.0.0.1:8742)http://127.0.0.1:8742/callback?code=XXXX&state=YYYYL’esperienza per l’utente è fluida. Nessun codice da copiare, nessun URL da digitare. Solo una scheda che si apre e si chiude.
Funziona solo se la CLI può aprire un browser e attivare il binding su localhost. Sono quindi esclusi:
Per questo quasi tutti gli strumenti che usano di default OAuth via browser supportano anche un'alternativa, tipicamente device code flow o API key.
Errore 1: binding a 0.0.0.0 invece che a 127.0.0.1
L’errore più comune (e grave). Se il server di callback ascolta su tutte le interfacce, chiunque sulla rete può intercettare il codice di autorizzazione.
Si vede spesso anche in CLI in produzione. Un errore facile, perché molte librerie di server HTTP usano 0.0.0.0 di default.
Errore 2: mancata validazione del parametro state
Il parametro state è la protezione CSRF. Senza di esso, un attaccante può far accettare alla tua CLI un codice di autorizzazione da una sessione malevola.
Errore 3: non usare PKCE
Se il tuo flusso OAuth non usa PKCE (Proof Key for Code Exchange), il codice di autorizzazione può essere intercettato e riutilizzato.
Nel flusso standard, se un attaccante intercetta il codice (tramite rete, oppure leggendo la URL del redirect), può scambiarlo per i token. PKCE impedisce tutto ciò richiedendo una prova cryptografica che lo scambio venga iniziato dallo stesso client che ha avviato la richiesta.
Ecco cosa aggiunge PKCE:
code_verifier random (stringa ad alta entropia)code_challenge hashando il verifier con SHA-256code_verifier originaleUn attaccante che intercetta il codice non ha il code_verifier, quindi non può completare lo scambio.
Ecco perché AWS CLI v2.22+ ha reso PKCE il default per SSO, abbandonando il device code flow. Se la CLI può aprire un browser sulla stessa macchina, OAuth via browser con PKCE è la scelta migliore: stessa UX, più sicurezza, nessun rischio phishing. Il device code resta la scelta giusta solo dove non si può aprire il browser (SSH, container, ambienti remoti), ma questo non è il caso comune nello sviluppo locale.
L’approccio più semplice. Generi un token dalla dashboard web, lo incolli nella config della CLI o in una variabile d’ambiente e hai finito.
Chi lo usa: Stripe CLI (come opzione login), npm, pip, la maggior parte degli strumenti AI come fallback (Claude Code tramite ANTHROPIC_API_KEY, strumenti OpenAI tramite OPENAI_API_KEY, Aider)
sk_live_, ghp_, npm_)~/.config/stripe/config.toml, ~/.aws/credentials) o in una variabile d’ambienteLa CLI la legge all’avvio e la include in tutte le richieste API, di solito come token Bearer nell’header Authorization.
Per l’automazione, le API key sono imbattibili. Funzionano in CI/CD, container, script, cron job. Ovunque si possa leggere un env var. Nessun browser. Nessun prompt. Nessun rinnovo di token.
Soprattutto nei workflow agent AI, le API key sono la strada più semplice. Quando Claude Code o Cursor deve chiamare una API, una variabile d’ambiente con una API key è il punto di integrazione più immediato.
La scelta intelligente: usare le API key solo per ottenere token a breve scadenza runtime.
AWS è stata pioniera con STS (Security Token Service). Le credenziali long-lived servono solo per richiedere credenziali temporanee con scadenza (1 ora). Strumenti come aws-vault automatizzano tutto.
Anche se parti con API key, valuta di aggiungere questo schema. Limita la finestra di rischio da "finché qualcuno se ne accorge" a "un'ora".
Questo flusso OAuth 2.0 è progettato per l’autenticazione macchina-a-macchina: servizi che parlano con servizi, senza coinvolgimento umano.
Usato in: pipeline CI/CD, servizi in background, strumenti automatizzati
Il servizio invia client_id e client_secret direttamente al server di auth e riceve un access token a breve scadenza. Niente browser, niente utenti, nessun redirect.
Usa client credentials quando:
Non usarlo per autenticare persone. Non supporta MFA, SSO, né altri controlli interattivi.
Ecco un riepilogo corretto basato su doc e codice sorgente attuali. Molti articoli sono imprecisi perché gli strumenti cambiano default frequentemente.
| CLI Tool | Auth predefinita | Opzioni fallback | Dove salva i token |
|---|---|---|---|
GitHub CLI (gh) | Device code flow via browser | PAT (--with-token), env var (GH_TOKEN) | OS keychain (fallback: file di testo) |
| AWS CLI v2 | PKCE auth code flow (SSO) | Device code (--use-device-code), credential files | ~/.aws/sso/cache/ |
Azure CLI (az) | WAM su Windows; oauth code via browser su Linux/macOS | Device code (--use-device-code) | ~/.azure/msal_token_cache.* |
| Vercel CLI | Device code flow (nuovo default, Set 2025) | API token (--token, env var) | ~/.local/share/com.vercel.cli/auth.json |
| Stripe CLI | Pairing via browser | API key (--interactive, --api-key, o env var) | ~/.config/stripe/config.toml |
| gcloud CLI | Browser OAuth | manual flow --no-browser | ~/.config/gcloud/ |
| Claude Code | Browser OAuth | API key (env var, apiKeyHelper) | OS keychain / ~/.claude/.credentials.json |
| OpenAI Codex CLI | Browser OAuth | Device code (beta), API key | ~/.codex/auth.json / OS keyring |
| Terraform CLI | Browser OAuth | Token da incollare | ~/.terraform.d/credentials.tfrc.json |
La tendenza è chiara: OAuth via browser è il default per lo sviluppo locale, device code flow come fallback headless e API key per l’automazione. PKCE è sempre più diffuso come opzione sicura quando un browser è disponibile.
L’autenticazione è inutile se i token sono conservati male.
Tutti i principali OS hanno uno store sicuro:
Danno crittografia, controllo accessi e sicurezza hardware. La tua CLI non deve gestire crittografia.
Quando il keychain non è disponibile (container o Linux minimal), usa file criptati con permessi restrittivi:
File in chiaro. Dovrebbe essere ovvio, ma molti strumenti ancora lo fanno. Un file token in chiaro può essere letto da ogni processo user, ogni tool di backup, chiunque abbia accesso temporaneo.
Environment variable per storage a lungo termine. Gli environment var sono visibili nei processi, talvolta loggati dai crash reporter, ereditati dai processi figli. Ok per CI/CD (il CI gestisce il segreto), ma rischiosi in sviluppo locale.
Browser localStorage. Se la CLI ha una parte web, evitare di salvare token nel localStorage. Basta una XSS e perdi tutto.
Tenerli a breve durata. Un’ora è la norma. Quando scade, la CLI deve fare refresh trasparente. L’utente non dovrebbe dover fare login per ogni operazione.
I refresh token sono le credenziali long-lived che permettono di ottenere nuovi access token senza autenticarsi di nuovo. Sono preziosi per gli attaccanti perché durano giorni/mesi.
I moderni sistemi di autenticazione ruotano il refresh token ad ogni uso:
Così si limita il danno: se un attaccante usa un refresh token già usato dalla CLI, il server rileva l’uso multiplo e invalida tutta la famiglia di token. Sia il token dell’attaccante che quello legittimo smettono di funzionare: forzando il re-login ma impedendo accesso persistente a chi ha rubato il token.
Già detto sopra: bind sempre su 127.0.0.1, mai su 0.0.0.0.
Succede più spesso di quanto si ammetta. Un log debug, un error handler che stampa tutti gli header, una verbose mode che mostra tutto.
Le immagini Docker non sono archivi sicuri. Ogni layer è estraibile.
Se un token scade durante un'operazione, non crashare con 401. Prova il refresh e solo se anche il refresh token è scaduto chiedi il login.
Non richiedere scope admin:* se ti serve solo repo:read. Vale per scope OAuth e permessi API key.
Quando un agente AI usa la tua CLI, è fondamentale. Probabilmente non vuoi dare a un assistente AI i permessi di delete-repo solo perché deve leggere il codice.
Ecco cosa rende il 2026 diverso dal 2023: le CLI non sono più solo per umani che digitano comandi. Agenti AI come Claude Code, Codex e Cursor in modalità agente chiamano le CLI in modo programmato. Questo aggiunge nuove sfide:
Permessi delegati. Quando Claude Code esegue gh pr create per te, usa le tue credenziali GitHub. Ma un agente AI dovrebbe avere i tuoi stessi permessi? Il principio del minimo privilegio dice di no, ma quasi nessuno strumento permette di limitarli.
Esposizione delle credenziali. Se la tua chiave API è in un env var, ogni processo può leggerla, inclusi i sottoprocessi dell’agente AI. Strumenti come Claude Code usano già apiKeyHelper per generare token temporanei, ma non è uno standard.
Autenticazione headless per agenti. Un agente AI in ambiente sandbox non può aprire un browser. Device code flow va benissimo (l’utente approva su un altro device), ma le API key sono più usate perché non richiedono interazione.
Audit trail. Se un agente AI chiama le API con le tue credenziali, nell’audit log risulti tu. Non c’è modo standard di distinguere "l’umano ha fatto questo" da "l’agente agisce per conto dell’umano."
È uno scenario in evoluzione. Il meglio che puoi fare oggi:
Scegliere il metodo di auth? Ecco la sintesi:
"I miei utenti sono sviluppatori sulle loro macchine" → OAuth via browser con PKCE (massima sicurezza + UX fluida)
"La mia CLI deve funzionare in SSH o container" → Device code flow come fallback, OAuth via browser come primaria
"Gira in CI/CD senza intervento umano" → Client credentials flow o API key con scope limitati
"Mi serve la soluzione più veloce" → API key (ma aggiungi la rotazione token dopo)
"I clienti enterprise vogliono SSO e MFA" → Qualsiasi flusso OAuth (device code o browser), supportano tutto lo stack auth enterprise
"Agenti AI useranno questa CLI" → Supporta sia API key (per integrazione agenti) sia OAuth via browser (per umani), con permessi limitati e token a vita breve
Sicuro contro la maggior parte degli attacchi, ma presenta un noto rischio di phishing. Un attaccante può generare un codice dispositivo e ingannare utenti ad approvarlo. Per questo AWS è passata a PKCE di default per il login SSO. Dove PKCE non va bene (ambiente headless), il device code resta la miglior soluzione. Va solo considerato il rischio di phishing.
Per CI/CD: sì, il sistema CI li cripta a riposo e li passa runtime. Per sviluppo locale: no. Usa il keychain OS. Gli env var sono visibili nei processi e possono venir loggati o ereditati.
Poca. Entrambi sono credenziali long-lived per autenticare le richieste API. La differenza è organizzativa: le API key spesso sono legate ad app/progetti, i PAT a un account utente. Alcuni servizi li usano come sinonimi.
Access token: ogni ora o meno (il refresh flow lo gestisce automaticamente). Refresh token: rotazione a ogni uso (gestita dal server). API key: almeno ogni 90 giorni o subito se sospetti una fuga. In pratica la maggior parte dei team le ruota solo dopo un incidente, troppo tardi.
Tre opzioni, in ordine:
docker run -e API_KEY=${API_KEY}) per CI/CDdocker run -v ~/.config/tool:/root/.config/tool:ro) per sviluppo localeMai inserire le credenziali nell’immagine. Mai.
MCP è lo standard emergente affinché gli agenti AI si connettano a strumenti e servizi esterni. Porta una nuova dimensione: l’agente ha bisogno di credenziali per il server MCP, che poi ha bisogno di credenziali per le API downstream. È tutto in evoluzione. Adesso quasi tutti gli MCP usano API key o token OAuth passati via config. Aspettati grandi cambiamenti a breve.
L’autenticazione CLI sta cambiando rapidamente. Quello che era best practice due anni fa (device code di default, file credential in chiaro) sta già venendo sostituito. Se oggi aggiungi auth a una CLI, parti da OAuth via browser + PKCE per gli umani, API key per automazione, e preparati al giorno in cui i tuoi utenti principali saranno agenti AI.