Skip to content

Commit a7aae56

Browse files
committed
docs: revise and expand authentication documentation for clarity
- Rewrite and expand introduction for greater clarity about CLI usage and token handling - Add a new overview section detailing automatic browser launch, local server callback, and token storage/reuse - Enhance security documentation, specifying defaults and mitigations for PKCE, state parameter, TLS, and token file permissions - Introduce explicit prerequisites and a sample `.env.example` file for easier setup - Make configuration options more prominent, clarifying precedence among flags, environment variables, and defaults - Add detailed sample terminal output for both first and subsequent authentication runs - Improve explanation of client modes, including a clear table for use case selection - Expand token lifecycle information, including a visual decision tree to show reuse, refresh, and re-auth flow - Clarify multi-client token storage and recommend adding token files to `.gitignore` - Replace a list of security practices with a mitigation table for easier reference - Add section dividers throughout for improved readability and navigation Signed-off-by: appleboy <appleboy.tw@gmail.com>
1 parent 6dfd1ff commit a7aae56

1 file changed

Lines changed: 149 additions & 22 deletions

File tree

README.md

Lines changed: 149 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,33 @@
33
[![Lint and Testing](https://github.com/go-authgate/oauth-cli/actions/workflows/testing.yml/badge.svg)](https://github.com/go-authgate/oauth-cli/actions/workflows/testing.yml)
44
[![Trivy Security Scan](https://github.com/go-authgate/oauth-cli/actions/workflows/security.yml/badge.svg)](https://github.com/go-authgate/oauth-cli/actions/workflows/security.yml)
55

6-
A command-line tool that demonstrates the **OAuth 2.0 Authorization Code Flow** (RFC 6749 §4.1) with **PKCE** (RFC 7636) against an AuthGate server.
6+
A CLI tool that authenticates with an AuthGate server by opening your browser, then manages OAuth 2.0 tokens locally — no manual code copying required.
77

8-
Unlike the Device Code Flow (which shows a user code to enter manually), this flow opens a browser window and receives the authorization code via a local HTTP callback server.
8+
**What it does:**
99

10-
## Which Client Mode Should I Use?
10+
- Opens your browser at the AuthGate authorization page automatically
11+
- Spins up a local HTTP server to receive the OAuth callback
12+
- Exchanges the authorization code for tokens and saves them to disk
13+
- On subsequent runs, reuses valid tokens or refreshes them silently
1114

12-
| Scenario | Mode | `CLIENT_SECRET` |
13-
| ------------------------- | ----------------------- | --------------- |
14-
| SPA, mobile app, CLI tool | **Public + PKCE** | Leave empty |
15-
| Server-side web app | **Confidential + PKCE** | Set the secret |
15+
**Security defaults:**
16+
17+
- PKCE (RFC 7636) always enabled — for both public and confidential clients
18+
- State parameter validated on every callback to prevent CSRF
19+
- TLS 1.2+ enforced for all HTTPS connections
20+
- Token file written with `0600` permissions and atomic rename
21+
22+
---
23+
24+
## Prerequisites
25+
26+
- **Go 1.24+**
27+
- A running [AuthGate](https://github.com/go-authgate) server
28+
- An OAuth client registered in AuthGate Admin with:
29+
- Grant type: **Authorization Code**
30+
- Redirect URI: `http://localhost:8888/callback`
31+
32+
---
1633

1734
## Quick Start
1835

@@ -21,14 +38,42 @@ Unlike the Device Code Flow (which shows a user code to enter manually), this fl
2138
Navigate to **Admin → OAuth Clients → Create New Client** and configure:
2239

2340
- **Grant Types**: Authorization Code Flow (RFC 6749)
24-
- **Client Type**: `Public` (no secret) or `Confidential`
2541
- **Redirect URIs**: `http://localhost:8888/callback`
42+
- **Client Type**: choose based on your use case:
43+
44+
| Scenario | Client Type | `CLIENT_SECRET` |
45+
| ------------------------- | ----------------------- | --------------- |
46+
| SPA, mobile app, CLI tool | **Public + PKCE** | Leave empty |
47+
| Server-side web app | **Confidential + PKCE** | Set the secret |
2648

2749
### 2. Configure
2850

2951
```bash
3052
cp .env.example .env
31-
# Edit .env with your CLIENT_ID (and CLIENT_SECRET for confidential clients)
53+
# Edit .env — set at minimum CLIENT_ID
54+
```
55+
56+
`.env.example`:
57+
58+
```ini
59+
# Required
60+
CLIENT_ID=your-client-id-here
61+
62+
# Optional: leave empty for public client (PKCE mode), set for confidential client
63+
CLIENT_SECRET=
64+
65+
# Server configuration
66+
SERVER_URL=http://localhost:8080
67+
68+
# Callback server (must match the Redirect URI registered in AuthGate)
69+
CALLBACK_PORT=8888
70+
REDIRECT_URI=http://localhost:8888/callback
71+
72+
# OAuth scopes (space-separated)
73+
SCOPE=read write
74+
75+
# Token storage
76+
TOKEN_FILE=.authgate-tokens.json
3277
```
3378

3479
### 3. Run
@@ -39,16 +84,64 @@ go run .
3984
go build -o authgate-oauth-cli && ./authgate-oauth-cli
4085
```
4186

42-
The tool will:
87+
---
88+
89+
## Terminal Output
90+
91+
**First run** — browser opens, you log in and approve access:
92+
93+
```
94+
=== OAuth 2.0 Authorization Code Flow CLI Demo ===
95+
Client mode : public (PKCE)
96+
Server URL : http://localhost:8080
97+
Client ID : 550e8400-e29b-41d4-a716-446655440000
98+
99+
No existing tokens found, starting Authorization Code Flow...
100+
Step 1: Opening authorization URL in your browser...
101+
102+
http://localhost:8080/oauth/authorize?client_id=...&code_challenge=...
103+
104+
Browser opened. Please complete authorization in your browser.
105+
Step 2: Waiting for callback on http://localhost:8888/callback ...
106+
Authorization code received!
107+
Step 3: Exchanging authorization code for tokens...
108+
Tokens saved to .authgate-tokens.json
109+
110+
========================================
111+
Current Token Info:
112+
Access Token : eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
113+
Token Type : Bearer
114+
Expires In : 59m59s
115+
========================================
116+
117+
Verifying token with server...
118+
Token Info: {"sub":"user@example.com","scope":"read write","exp":1740048000}
119+
Token verified successfully.
120+
121+
Demonstrating automatic refresh on API call...
122+
API call successful!
123+
```
124+
125+
**Subsequent runs** — tokens are reused without opening the browser:
43126

44-
1. Open your browser at the AuthGate authorization page
45-
2. After you log in and approve access, the browser redirects to `localhost:8888/callback`
46-
3. The CLI receives the authorization code, exchanges it for tokens, and saves them locally
47-
4. On subsequent runs the saved tokens are reused (or refreshed automatically)
127+
```
128+
=== OAuth 2.0 Authorization Code Flow CLI Demo ===
129+
Client mode : public (PKCE)
130+
Server URL : http://localhost:8080
131+
Client ID : 550e8400-e29b-41d4-a716-446655440000
132+
133+
Found existing tokens.
134+
Access token is still valid, using it.
135+
...
136+
```
137+
138+
---
48139

49140
## Configuration
50141

51-
All settings can be provided as flags, environment variables, or in a `.env` file (flag > env > default).
142+
All settings can be provided as flags, environment variables, or in a `.env` file.
143+
144+
**Precedence:** flag > environment variable > default
52145

53146
| Flag | Environment Variable | Default | Description |
54147
| ---------------- | -------------------- | -------------------------------- | -------------------------------------------- |
@@ -76,8 +169,12 @@ go run . -client-id=550e8400-... \
76169
-redirect-uri=http://localhost:9000/callback
77170
```
78171

172+
---
173+
79174
## How It Works
80175

176+
The CLI acts as an OAuth 2.0 client: it builds an authorization URL, opens the browser, then waits on a local HTTP server for the callback carrying the authorization code. Once received, it exchanges the code for tokens and saves them locally.
177+
81178
```mermaid
82179
sequenceDiagram
83180
participant CLI as CLI Tool
@@ -107,15 +204,35 @@ sequenceDiagram
107204

108205
PKCE (Proof Key for Code Exchange) is used for all clients — including confidential ones — for defence in depth. The CLI generates a fresh `code_verifier` and `code_challenge` on every authorization attempt.
109206

110-
### Token Lifecycle
207+
---
208+
209+
## Token Lifecycle
210+
211+
On every run the CLI follows this decision tree:
212+
213+
```
214+
Load token from disk
215+
216+
├─ Not found ──────────────► Full Authorization Code Flow
217+
218+
├─ Found, still valid ─────► Use immediately
219+
220+
└─ Found, expired
221+
222+
├─ Refresh succeeds ► Use refreshed token
223+
224+
└─ Refresh fails ──► Full Authorization Code Flow
225+
```
111226

112227
- **Reuse**: Valid tokens are loaded from disk and used immediately.
113228
- **Refresh**: Expired access tokens are refreshed silently using the stored refresh token.
114229
- **Re-auth**: If the refresh token is also expired or invalid, the full Authorization Code Flow restarts.
115230

231+
---
232+
116233
## Token Storage
117234

118-
Tokens are saved to `.authgate-tokens.json` (configurable). The file supports multiple client IDs:
235+
Tokens are saved to `.authgate-tokens.json` (configurable). The file supports multiple client IDs so you can authenticate against several clients without conflicts:
119236

120237
```json
121238
{
@@ -133,13 +250,21 @@ Tokens are saved to `.authgate-tokens.json` (configurable). The file supports mu
133250

134251
The file is written with `0600` permissions and uses atomic rename to prevent corruption.
135252

253+
> **Tip:** Add `.authgate-tokens.json` to your `.gitignore` to avoid accidentally committing tokens.
254+
255+
---
256+
136257
## Security Notes
137258

138-
- **PKCE** prevents authorization code interception attacks (RFC 7636).
139-
- **State** parameter prevents CSRF attacks; the callback server validates it.
140-
- **TLS 1.2+** is enforced for all HTTPS connections.
141-
- **HTTP warning** is printed when the server URL uses plain HTTP.
142-
- Add `.authgate-tokens.json` to `.gitignore`.
259+
| Concern | Mitigation |
260+
| ------------------------------- | ----------------------------------------------------------- |
261+
| Authorization code interception | PKCE (RFC 7636) — `code_verifier` never leaves the client |
262+
| CSRF on callback | `state` parameter validated before code is accepted |
263+
| Token in transit | TLS 1.2+ enforced for all HTTPS connections |
264+
| Accidental plaintext exposure | Warning printed when `SERVER_URL` uses plain HTTP |
265+
| Token file permissions | Written as `0600`; uses atomic rename to prevent corruption |
266+
267+
---
143268

144269
## Troubleshooting
145270

@@ -153,6 +278,8 @@ The file is written with `0600` permissions and uses atomic rename to prevent co
153278

154279
**Token verification failed** — The token may have been revoked. Delete `.authgate-tokens.json` and re-authenticate.
155280

281+
---
282+
156283
## Learn More
157284

158285
- [RFC 6749 — The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749)

0 commit comments

Comments
 (0)