Nederlands
  • cli
  • oauth
  • security
  • ai-tools

CLI-authenticatie goed krijgen: de complete gids voor alle 4 methoden

De 4 CLI-authentificatiemethoden die ertoe doen, hoe GitHub, AWS en AI-tools ze implementeren en de beveiligingsfouten die je wilt vermijden.

Yijun
Yijun
Developer

Stop met weken verspillen aan gebruikersauthenticatie
Lanceer veilige apps sneller met Logto. Integreer gebruikersauthenticatie in minuten en focus op je kernproduct.
Aan de slag
Product screenshot

Elke ontwikkelaars-CLI wordt geleverd met login als eerste commando. En ze lossen allemaal authenticatie anders op.

GitHub toont je een code en opent je browser om deze te verifiëren. AWS opent een browser voor PKCE-gebaseerde SSO. Stripe laat je een koppelingscode in het dashboard bevestigen. De nieuwere AI-tools (Claude Code, OpenAI Codex CLI, Cursor) kozen elk hun eigen benadering.

Als je een CLI bouwt, is authenticatie één van de eerste dingen waar je over na moet denken. Kies je de verkeerde methode, dan hoor je het snel genoeg: gefrustreerde gebruikers, beveiligingsaudits, of allebei. En met de recente golf aan AI-coding-agents die CLI-tools programmatisch aanroepen, zijn de risico's groter: je authenticeert niet alleen meer een mens. Je geeft misschien inloggegevens aan een autonoom proces.

Hier zijn de vier relevante authenticatiemethoden, hoe de grootste tools ze toepassen, en de fouten die je wilt vermijden.

De vier methoden in vogelvlucht

Voordat we de diepte ingaan, hier een snelle vergelijking:

MethodeBest voorBeveiligingBrowser nodig?
OAuth Device Code FlowHeadless omgevingen, SSHHoogNee (op hetzelfde apparaat)
Browser-based OAuth (localhost redirect)Lokale ontwikkelingHoogstJa
API Keys / PATsAutomatisering, CI/CD, snel prototypenMatigNee
Client CredentialsMachine-to-machine, servicesHoogNee

Elke optie heeft zijn eigen voor- en nadelen. Hier is wat je moet weten over elk.

1. OAuth device code flow (RFC 8628)

Dit is die waarbij je CLI je een code toont zoals ABCD-1234 plus een URL, en je vraagt die URL op elk apparaat te openen en de code in te voeren.

Wie gebruikt het: GitHub CLI (standaard), Azure CLI (via --use-device-code), Vercel CLI (sinds kort als standaard), OpenAI Codex CLI (als bètakeuze)

Hoe werkt het

  1. Je voert cli login uit
  2. De CLI vraagt een device code aan bij de authenticatieserver met zijn client_id en gewenste scopes
  3. De server stuurt drie dingen terug: een device_code (interne ID), een user_code (de korte code die je invoert) en een verification_uri (waarheen je moet gaan)
  4. Je CLI toont de code en URL, en begint elke 5+ seconden de server te polsen
  5. Je opent de URL op elk apparaat (telefoon, laptop, andere computer), voert de code in en logt in zoals gewenst (wachtwoord, SSO, passkeys, MFA)
  6. Als je toestemt, geeft de volgende poll een access token en refresh token terug
  7. De CLI slaat deze op en je bent aangemeld

Waarom ontwikkelaars het fijn vinden

Het grote voordeel: het werkt overal. SSH-sessie naar een remote server? Werkt. Draait in een Docker-container? Werkt. Cloud IDE zonder lokale browser? Werkt. De browser hoeft niet op dezelfde machine te draaien als de CLI.

Het ondersteunt ook alle enterprise-authenticatievormen (SAML, OIDC, MFA), want alles gebeurt in de browser en niet in de terminal. Je CLI ziet nooit je wachtwoord.

Het beveiligingsprobleem dat de meeste mensen missen

Device code flow heeft een phishingprobleem. Een aanvaller kan een device code aanvragen, een legitieme gebruikerscode krijgen en je misleiden deze in te voeren, waardoor hij feitelijk de sessie van de aanvaller autoriseert. Dit is geen theorie. Security-onderzoekers hebben deze aanval tegen AWS SSO device code auth beschreven.

Dit is zo'n groot risico dat AWS hun standaard heeft gewijzigd. Vanaf AWS CLI v2.22.0 is de standaard voor aws sso login nu PKCE-gebaseerde authorization code flow. Device code is nog steeds beschikbaar via --use-device-code, maar het is niet meer de standaard.

Microsofts eigen tenant is gestart met blokkeren van device code flow via conditional access policies, wat aangeeft dat zij dit als een risicovolle authenticatiemethode beschouwen.

We zien dus een interessante splitsing: Vercel adopteerde device code flow als standaard in september 2025, terwijl AWS er juist vanaf stapt. De trend: device code flow is ideaal als je echt geen browser kunt openen, maar kan dat lokaal wél, dan is PKCE veiliger.

Aan de aanbiederskant groeit de vraag duidelijk. Logto bracht onlangs OAuth 2.0 Device Authorization Grant ondersteuning uit voor native apps in v1.38.0 (open source) en Logto Cloud. Zo kun je nu device flow als authorisatiemethode voor iedere native applicatie inschakelen. Dat is belangrijk als je een CLI bouwt. RFC 8628 correct implementeren (code-verval, rate limiting, pollinglogica, sign-in UX op de verificatiepagina) kost meer werk dan de meeste teams denken, en het aan je provider overlaten betekent alleen dat jij de juiste HTTP-calls hoeft te doen.

Technische details uit de RFC

Enkele punten uit RFC 8628:

  • De expires_in waarde voor device codes wordt door de server bepaald. De RFC noemt 1800 seconden (30 minuten) als voorbeeld, maar dat is geen vaste eis.
  • Geeft de server geen polling interval, dan moet de client standaard 5 seconden aanhouden.
  • Krijg je een slow_down error, tel dan 5 seconden bij je interval op.
  • Device codes moeten eenmalig zijn en snel verlopen.
  • Alle tokenuitwisseling moet over HTTPS plaatsvinden.

2. Browser-based OAuth (localhost redirect)

Dit is de meest gebruikte methode voor CLIs die lokaal draaien. Je voert login uit, je browser opent, je authenticeert en de browser redirect terug naar een tijdelijke lokale server die de CLI opzet. Moderne varianten voegen PKCE (spreek uit: "pixie") toe, waardoor de flow veel moeilijker te misbruiken is.

Wie gebruikt het: Claude Code, gcloud CLI, Terraform CLI, AWS CLI v2.22+ (voor SSO, met PKCE als standaard)

Hoe werkt het

  1. Je voert cli login uit
  2. De CLI start een tijdelijke HTTP-server op een willekeurige lokale poort (bijvoorbeeld http://127.0.0.1:8742)
  3. Het opent je standaardbrowser op het authorisatie-endpoint van de provider, en geeft die localhost-url als redirect URI door
  4. Je authenticeert in de browser (SSO, wachtwoord, passkeys, etc.)
  5. De provider redirect je browser naar http://127.0.0.1:8742/callback?code=XXXX&state=YYYY
  6. De lokale server vangt de authorisatiecode op en wisselt die om voor tokens via een back-channel HTTPS request
  7. In de browser krijg je "Succes! Je kunt dit tabblad sluiten"
  8. De CLI slaat de tokens op en sluit de server

De gebruikerservaring is soepel. Geen codes overtypen, geen URL's overnemen. Gewoon een tab opent en weer sluit.

Wanneer werkt dit niet

Dit werkt alleen als de CLI een browser kan openen én aan localhost kan binden. Niet bruikbaar voor:

  • SSH-sessies naar remote servers
  • Docker-containers (tenzij je lastige port forwarding toepast)
  • CI/CD pipelines
  • Headless servers
  • Sommige streng beveiligde bedrijfsomgevingen

Daarom bieden de meeste tools die standaard browser OAuth gebruiken ook een fallback, meestal device code flow of API keys.

Drie bekende beveiligingsvalkuilen

Val 1: Binden aan 0.0.0.0 i.p.v. 127.0.0.1

Dit is de meest gemaakte fout, en erg ernstig. Luistert je callback-server op alle interfaces, kan iedereen op het netwerk de code onderscheppen.

Ik heb dit in production-CLIs gezien. Veel HTTP-serverbibliotheken gebruiken standaard 0.0.0.0, dus je maakt deze fout snel.

Val 2: Ontbrekende state-parametervalidatie

De state-parameter beschermt tegen CSRF. Zonder dit kan een aanvaller je CLI misleiden een code van een kwaadwillende sessie te accepteren.

Val 3: PKCE niet gebruiken

Gebruik je geen PKCE (Proof Key for Code Exchange), kan een onderschepte code opnieuw worden gebruikt.

In een standaard authorization code flow kan een aanvaller de code onderscheppen (via het netwerk of de redirect-URL) en die zelf voor tokens inwisselen. PKCE voorkomt dat door bewijs te eisen dat degene die de code inwisselt, dezelfde client is als degene die de authorisatie aanvroeg.

PKCE voegt dit toe aan de flow:

  1. Voor de flow start, genereert de CLI een willekeurige code_verifier (een lange, willekeurige string)
  2. Die wordt met SHA-256 gehasht tot een code_challenge
  3. De challenge gaat mee in het eerste request
  4. Bij het inwisselen van de code stuurt de CLI de oorspronkelijke code_verifier mee
  5. De server controleert of deze klopt bij de challenge

De aanvaller heeft de code_verifier niet, dus die kan de code niet inwisselen.

Daarom heeft AWS CLI v2.22+ PKCE de standaard gemaakt voor SSO, en stappen ze af van device code flow. Kan de CLI een browser op dezelfde machine openen, dan is browser OAuth met PKCE gewoon beter dan device code flow: zelfde UX, sterkere beveiliging, geen phishingrisico. Device code flow is nog steeds geschikt als een browser op de machine niet mogelijk is (SSH, containers, remote development), maar voor lokaal gebruik is het niet meer de beste keuze.

3. API keys en personal access tokens

De simpelste aanpak. Je maakt een API-key aan in het dashboard, plakt hem in je CLI-configuratie of environment variable, en klaar.

Wie gebruikt het: Stripe CLI (als login-optie), npm, pip, de meeste AI-codingtools als fallback (Claude Code via ANTHROPIC_API_KEY, OpenAI-tools via OPENAI_API_KEY, Aider)

Hoe werkt het

  1. Log in op het dashboard van de dienst
  2. Ga naar instellingen → API keys (of personal access tokens, developer tokens)
  3. Maak een nieuwe key aan, meestal een lange willekeurige string met prefix (zoals sk_live_, ghp_, npm_)
  4. Sla deze op in een configbestand (~/.config/stripe/config.toml, ~/.aws/credentials) of een environment variable

De CLI leest die bij het opstarten uit en stuurt hem mee in API-requests, meestal als Bearer token in de Authorization-header.

Waarom het nog steeds populair is ondanks de risico's

Voor automatisering zijn API-keys ongeëvenaard. Ze werken in CI/CD, containers, scripts, cronjobs. Alles wat een environment variable kan lezen. Geen browser nodig, geen interactieve prompts, geen tokenrefresh.

Voor AI-agent-workflows zijn API-keys de makkelijkste manier. Als Claude Code of Cursor een API moet aanroepen, is een env variable met een API-key de snelste optie.

De risico's zijn echt

  • Lekken. API-keys belanden in git, logbestanden, foutmeldingen en CI-output. GitHub scant op gelekte tokens, en ontdekt er jaarlijks meer dan een miljoen.
  • Te veel rechten. De meeste API-keys geven brede toegang. Als ze lekken is de impact groot.
  • Geen MFA. API-keys omzeilen je zorgvuldig geconfigureerde MFA.
  • Moeilijk te roteren. Bij elke keyrotatie moet je overal de key vervangen. Met teams is dat helemaal een vraagstuk.

Modern toegevoegd: tijdelijke tokenuitwisseling

Slim omgaan met API-keys? Wissel ze runtime om voor tokens met beperkte geldigheid.

AWS was hierop een voorloper met STS (Security Token Service). Je langlevende credentials zijn er alleen om tijdelijke credentials aan te vragen die binnen een uur verlopen. Tools als aws-vault automatiseren dit volledig.

Zelfs als je met API-keys begint, kun je dit patroon toevoegen. Dat beperkt de schade van een gelekte key van "tot iemand het merkt" tot "één uur".

4. Client credentials flow

Deze OAuth 2.0-flow is bedoeld voor machine-to-machine authenticatie: services die zonder menselijke interactie communiceren.

Gebruikt in: CI/CD pipelines, achtergrondservices, geautomatiseerde tools

Hoe werkt het

De service stuurt zijn client_id en client_secret direct naar de authenticatieserver en krijgt een tijdelijke access token terug. Geen browser, geen interactie, geen redirect.

Wanneer te gebruiken

Gebruik client credentials wanneer:

  • Een service of bot moet authenticeren, geen mens
  • Je zit in een CI/CD pipeline
  • Je geautomatiseerde, onbeheerde toegang nodig hebt
  • De "gebruiker" de applicatie zelf is

Gebruik het niet voor menselijke authenticatie. Het ondersteunt geen MFA, SSO of interactieve verificatie.

Wat echte CLI's tegenwoordig gebruiken

Hier is een bijgewerkt overzicht obv documentatie en code. Veel artikelen zitten ernaast omdat tools hun standaardinstellingen regelmatig wijzigen.

CLI-toolStandaard authenticatieFallback-optiesTokenopslag
GitHub CLI (gh)Device code flow via browserPAT (--with-token), env (GH_TOKEN)OS keychain (fallback: tekstbestand)
AWS CLI v2PKCE auth code flow (SSO)Device code (--use-device-code), credential-bestanden~/.aws/sso/cache/
Azure CLI (az)WAM op Windows; browserauth flow op Linux/macOSDevice code (--use-device-code)~/.azure/msal_token_cache.*
Vercel CLIDevice code flow (nieuw standaard, sep 2025)API-token (--token, env variable)~/.local/share/com.vercel.cli/auth.json
Stripe CLIBrowser-based pairing flowAPI-key (--interactive, --api-key, of env)~/.config/stripe/config.toml
gcloud CLIBrowser OAuth--no-browser handmatig~/.config/gcloud/
Claude CodeBrowser OAuthAPI-key (env var, apiKeyHelper)OS keychain / ~/.claude/.credentials.json
OpenAI Codex CLIBrowser OAuthDevice code (beta), API-key~/.codex/auth.json / OS keyring
Terraform CLIBrowser OAuthToken plakken~/.terraform.d/credentials.tfrc.json

De trend is duidelijk: browser-gebaseerde OAuth is de standaard voor lokale ontwikkeling, device code flow als fallback voor headless, en API-keys voor automatisering. PKCE wordt veel gebruikt als veiligste optie waar een browser beschikbaar is.

Tokenopslag: wat wel en niet te doen

Authenticatie juist regelen heeft geen zin als je tokens verkeerd opslaat.

De juiste manier: OS keychains

Elk groot besturingssysteem heeft een ingebouwde versleutelde credential store:

  • macOS: Keychain (gebruikt door GitHub CLI, Claude Code)
  • Windows: Credential Manager
  • Linux: Secret Service API (GNOME Keyring, KDE Wallet)

Deze bieden OS-encryptie, toegangscontrole en eventueel hardware-integratie. Je CLI hoeft zelf geen kryptografie toe te voegen.

Fallback: versleutelde config-bestanden

Is een keychain niet beschikbaar (containers, minimalistische Linux installs), gebruik dan versleutelde configfiles met restrictieve permissies:

Wat te vermijden

Platte tekstbestanden. Dat zou duidelijk moeten zijn, maar veel tools doen dit nog. Een plaintext tokenbestand is toegankelijk voor ieder proces onder je gebruiker, elke backuptool en wie even toegang krijgt tot je machine.

Environment variables voor langdurige opslag. Env vars zijn zichtbaar in processen, worden soms gelogd in crash reports, en doorgegeven aan child-processen. Voor CI/CD (waar het platform de secret beheert) kan het, maar voor lokaal is het riskant.

Browser localStorage. Heeft je CLI een webcomponent, gebruik dan geen localStorage voor tokens. Eén XSS-lek en alles ligt op straat.

Token lifecycle management

Access tokens

Maak deze kortlevend. Eén uur is gangbaar. Als een access token vervalt, moet de CLI hem stilletjes vernieuwen. De gebruiker hoeft daarvoor normaal niet opnieuw in te loggen.

Refresh tokens

Refresh tokens zijn de langdurige aanmeldgegevens waarmee je nieuwe access tokens kunt krijgen zonder opnieuw te authenticeren. Ze zijn gewilde doelwitten voor aanvallers, omdat ze dagen tot maanden geldig blijven.

Refresh token-rotatie

Moderne systemen wisselen refresh tokens bij elk gebruik:

  1. CLI stuurt refresh token om een nieuwe access token te krijgen
  2. Auth-server stuurt een nieuwe access token en een nieuwe refresh token terug
  3. De oude refresh token is direct ongeldig
  4. CLI slaat beide nieuwe tokens op

Dit beperkt de schade van een gestolen refresh token. Probeert een aanvaller een refresh token te hergebruiken die de legitieme CLI al gebruikte, raakt de hele tokenfamilie ongeldig. Zowel de token van de aanvaller als die van de gebruiker werken dan niet meer — je moet opnieuw inloggen, maar de aanvaller blijft buiten.

Veelgemaakte fouten (met code)

1. Callback-server aan alle interfaces binden

Al eerder genoemd, maar het blijft belangrijk: bind altijd aan 127.0.0.1, nooit aan 0.0.0.0.

2. Tokens loggen

Dit gebeurt vaker dan mensen toegeven. Een debuglog, een error-handler die headers dumpt, een verbose-modus die alles print.

3. Credentials in containerimages stoppen

Docker images zijn geen geheime kluis. Elke laag is uitleesbaar.

4. Tokenverval niet netjes afhandelen

Verloopt een token halverwege een operatie, crasht dan niet met een 401-error. Probeer ze te verversen, en vraag pas opnieuw in te loggen als ook de refresh token verlopen is.

5. Geen Least Privilege toepassen

Vraag niet om admin:* scope als je alleen repo:read nodig hebt. Dit geldt voor zowel OAuth scopes als API key-permissies.

Gebruik je CLI door een AI-agent, dan is dit nog belangrijker. Je wilt meestal niet dat een AI-assistent rechten krijgt om een repo te verwijderen, alleen maar omdat hij code mag lezen.

De AI-agent-uitdaging

Wat 2026 anders maakt dan 2023: CLI's zijn niet alleen meer voor mensen die commando's typen. AI-coding-agents zoals Claude Code, Codex en Cursor's agent-modus roepen CLI-tools programmatisch aan. Dit geeft nieuwe authenticatie-uitdagingen:

Gedelegeerde machtigingen. Als Claude Code gh pr create uitvoert namens jou, gebruikt hij jouw GitHub-credentials. Maar hoort een AI-agent dezelfde rechten te hebben als jij? Volgens het principle of least privilege niet, maar de meeste tools bieden geen manier om agent-toegang te beperken.

Credential-exposure. Staat je API-key in een env variable, dan kan ieder proces hem lezen — ook het subprocess van de AI-agent. Tools als Claude Code lossen dit deels op met apiKeyHelper-scripts die tijdelijk geldige tokens genereren, maar universeel is dat nog niet.

Headless authenticatie voor agents. Een AI-agent in een sandbox-omgeving kan geen browser openen. Device code flow werkt (de gebruiker keurt goed op een ander apparaat), maar API-keys zijn de gewoonlijke oplossing omdat ze geen interactie vragen.

Audittrails. Doet een AI-agent API-calls met jouw credentials, dan lijkt het auditlog te tonen dat jij die acties uitvoerde. Er is nog geen standaard om "de mens deed dit" te onderscheiden van "de agent deed dit namens de mens".

Dit ontwikkelt zich snel. Beste wat je nu kunt doen:

  • Gebruik tokens met minimale rechten voor agent-workflows
  • Geef de voorkeur aan kortlevende credentials (tijdelijke tokens i.p.v. permanent geldige API-keys)
  • Gebruik aparte agent-credentials, los van je eigen
  • Monitor API-gebruik op ongebruikelijke patronen

Keuzehulp

Authenticatiemethode kiezen? Hier de korte versie:

"Mijn gebruikers zijn ontwikkelaars op hun lokale machine" → Browsergebaseerde OAuth met PKCE (beste beveiliging + soepelste UX)

"Mijn CLI moet werken in SSH-sessies en containers" → Device code flow als fallback, browser OAuth als primaire optie

"Dit draait in CI/CD zonder mens erbij" → Client credentials flow of gescope API-keys

"Ik wil de snelste implementatie" → API-keys (maar voeg tokenrotatie later toe)

"Enterprise-klanten willen SSO en MFA" → Elke OAuth-flow (device code of browser), want die ondersteunt alle enterprise-authenticatie

"AI-agents gaan deze CLI gebruiken" → Ondersteun API-keys (makkelijk voor agents) + browser OAuth (voor menselijke gebruikers), met beperkte rechten en kortlevende tokens

FAQ

Is device code flow veilig?

Tegen de meeste aanvallen wel, maar er is een bekende phishing-kwetsbaarheid. Een aanvaller kan een device code genereren en gebruikers misleiden die goed te keuren. Daarom maakte AWS PKCE standaard voor SSO-login. Voor headless omgevingen waar PKCE niet kan, blijft device code flow de beste keus — wees alleen alert op phishing.

Moet ik tokens in environment variables opslaan?

Voor CI/CD: ja, want het platform slaat ze versleuteld op en injecteert ze bij runtime. Voor lokaal: niet doen. Gebruik OS keychain. Env variables zijn zichtbaar in processen, kunnen per ongeluk gelogd/gelekt worden naar child-processen.

Wat is het verschil tussen een API-key en een personal access token?

Functioneel weinig. Beide zijn langlevende credentials voor API-aanroepen. Het verschil is vooral organisatorisch: API-keys zijn vaak per project/app gescope, personal access tokens zijn gelinkt aan een gebruikersaccount. Sommige diensten gebruiken de termen door elkaar.

Hoe vaak moet ik credentials roteren?

Access tokens: elk uur of minder (gaat automatisch via refreshflow). Refresh tokens: roteren bij elk gebruik (de auth-server zou dit moeten doen). API-keys: minstens elke 90 dagen, of direct bij vermoeden van lek. In de praktijk vervangen de meeste teams hun API-keys pas na een incident — dat is te laat.

Hoe regel ik authenticatie in Docker-containers?

Drie opties, in volgorde van voorkeur:

  1. Device code flow voor interactief gebruik (werkt omdat de browser op een ander apparaat mag draaien)
  2. Environment variables bij runtime meegeven (docker run -e API_KEY=${API_KEY}) voor CI/CD
  3. Credentials als volume mounten (docker run -v ~/.config/tool:/root/.config/tool:ro) voor lokaal

Nooit credentials in het image bakken. Nooit.

Hoe zit het met MCP (Model Context Protocol) authenticatie?

MCP is de opkomende standaard voor AI-agents die connectie maken met externe tools en diensten. Het introduceert een extra auth-laag: de agent heeft credentials nodig voor de MCP-server, die op zijn beurt weer credentials nodig heeft voor achterliggende APIs. Dit wordt nog gestandaardiseerd. Voor nu gebruiken de meeste MCP-implementaties API-keys of OAuth-tokens die via de MCP-configuratie meegestuurd worden. Verwacht snelle evolutie hierin.


CLI-authenticatie verandert snel. Wat twee jaar geleden best practice was (device code flow als standaard, platte tekst-bestanden voor credentials) is nu al achterhaald. Voeg je vandaag authenticatie toe aan een CLI, begin dan met browser OAuth + PKCE voor mensen, API-keys voor automatisering, en bedenk dat straks AI-agents je belangrijkste gebruikers kunnen zijn.