A minimal example of OAuth2 authentication for CLI applications using the browser.
sequenceDiagram
participant CLI
participant Browser
participant OAuth Server
CLI->>CLI: 1. Start local callback server
CLI->>Browser: 2. Open browser to /authorize
Browser->>OAuth Server: 3. User logs in
OAuth Server->>Browser: 4. Redirect to localhost/callback<br/>with ?code=AUTH_CODE
Browser->>CLI: 4. Callback received
CLI->>OAuth Server: 5. Exchange code for token
OAuth Server->>CLI: 6. Return access_token
CLI->>OAuth Server: 7. Make authenticated API requests
- Docker
- Python 3.8+
# Start the mock OAuth2 server
docker compose up -d
# Run the CLI
cd cli
pip install -r requirements.txt
python cli.pyYour browser opens automatically. Log in with any username and the flow completes.
CLI OAuth2 Demo
========================================
1. Opening browser for authentication...
URL: http://localhost:8080/default/authorize?client_id=cli-app&...
2. Waiting for authentication callback...
Received authorization code: wPW2uEjQekhUNWQzNBxg...
3. Exchanging code for access token...
Received access token: eyJraWQiOiJkZWZhdWx0...
4. Fetching user info with access token...
========================================
Authentication successful!
========================================
User Info:
sub: demouser
azp: cli-app
iss: http://localhost:8080/default
The CLI (cli/cli.py) implements OAuth2 Authorization Code flow with PKCE:
- Generate PKCE pair:
code_verifier(random secret) andcode_challenge(SHA256 hash) - Generate state: random string to prevent CSRF attacks
- Start local HTTP server: listens on
localhost:8085for the callback - Open browser: navigates to
/authorizewith client_id, redirect_uri, PKCE challenge, and state - User authenticates: logs in via the OAuth provider
- Receive callback: server redirects to
localhost:8085/callback?code=...&state=... - Validate state: ensures state matches to prevent CSRF
- Exchange code for token: POST to
/tokenwith code and PKCE verifier - Make authenticated requests: use access token to call protected APIs
- PKCE (RFC 7636): prevents authorization code interception attacks
- State parameter: prevents CSRF attacks
- Localhost callback: only accepts callbacks on
127.0.0.1
cd cli && pytest tests/ -vTo use with Google, GitHub, Okta, Auth0, etc.:
- Register your application with the provider
- Set
http://localhost:8085/callbackas an allowed redirect URI - Update
OAUTH_SERVERandCLIENT_IDincli.py - Add any required scopes