Skip to content

feat: implement OAuth 2.0 Device Authorization Grant (RFC 8628)#42

Merged
ngerakines merged 1 commit into
graze-social:mainfrom
bigmoves:feature/device-grant-flow
Sep 13, 2025
Merged

feat: implement OAuth 2.0 Device Authorization Grant (RFC 8628)#42
ngerakines merged 1 commit into
graze-social:mainfrom
bigmoves:feature/device-grant-flow

Conversation

@bigmoves

Copy link
Copy Markdown
Contributor

OAuth 2.0 Device Authorization Grant Implementation (RFC 8628)

Summary

Implements the OAuth 2.0 Device Authorization Grant flow, allowing CLI tools and other devices without web browsers to authenticate users and obtain ATProtocol sessions.

How the Flow Works

Step 1: Device Authorization Request

CLI tool requests device authorization:

POST /oauth/device
Content-Type: application/x-www-form-urlencoded

client_id=device-flow-cli-example&scope=atproto:atproto

Response:

{
  "device_code": "device_a1b2c3d4e5f6",
  "user_code": "WXYZ-1234", 
  "verification_uri": "https://aip.example.com/device",
  "expires_in": 1800,
  "interval": 5
}

Step 2: User Authorization

CLI displays to user:

📋 User Code: WXYZ-1234
🌐 Verification URL: https://aip.example.com/device

User visits the URL, enters code, and completes ATProtocol OAuth authentication.

Step 3: Device Token Polling

While user is authorizing, CLI polls every 5 seconds:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:device_code
&device_code=device_a1b2c3d4e5f6
&client_id=device-flow-cli-example

Before authorization: {"error": "authorization_pending"}

After authorization:

{
  "access_token": "aip_at_xyz789...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "aip_rt_abc123...",
  "scope": "atproto:atproto"
}

Step 4: Access ATProtocol Session

CLI uses access token to get session data:

GET /api/atprotocol/session
Authorization: Bearer aip_at_xyz789...

Response:

{
  "did": "did:plc:user123...",
  "handle": "user.bsky.social",
  "access_token": "atp_session_token...",
  "pds_endpoint": "https://bsky.social",
}

Key Changes

New Endpoints

  • POST /oauth/device - Device authorization requests
  • GET /device - User verification page
  • Enhanced POST /oauth/token - Added device_code grant type

Database Changes

  • New device_codes table for tracking authorization state
  • Client metadata fields for native app registration
  • Migration scripts for PostgreSQL and SQLite

Core Files Modified

  • src/oauth/auth_server.rs - Added device code grant handling
  • src/oauth/clients/registration.rs - Enhanced for native apps
  • src/storage/traits.rs - New DeviceCodeStore trait
  • src/http/handler_*.rs - New device endpoints

Example Application

  • Complete CLI example in examples/device-flow-cli/
  • Registration script for easy setup
  • Demonstrates full end-to-end flow

Client Registration for Device Flow

Device clients register differently than web apps:

{
  "client_name": "Device Flow CLI Example",
  "grant_types": ["urn:ietf:params:oauth:grant-type:device_code", "refresh_token"],
  "response_types": ["device_code"],
  "token_endpoint_auth_method": "none",
  "application_type": "native"
}

Key differences: no redirect_uris, public client (none auth), device-specific grant types.

Security Features

  • Device codes expire after 30 minutes
  • Single-use device codes (consumed on success)
  • Proper polling intervals (5 seconds minimum)
  • Public client support (no client secrets needed)
  • Full ATProtocol OAuth integration

Testing

Run the example:

cd examples/device-flow-cli
./register-client.sh
cargo run

Backward Compatibility

✅ No breaking changes - purely additive feature that doesn't affect existing OAuth flows.

New Screens

image image image

@bigmoves bigmoves marked this pull request as ready for review August 15, 2025 23:41
@bigmoves bigmoves force-pushed the feature/device-grant-flow branch 5 times, most recently from dce3118 to 5a304b0 Compare September 12, 2025 20:27
Implements the OAuth 2.0 Device Authorization Grant flow according to RFC 8628
for devices with limited input capabilities or lack of web browser access.

Key features:
- Device authorization endpoint (`/oauth/device_authorization`)
- Device code token endpoint integration
- User device verification flow with HTML templates
- Internal device authorization client management
- Support for both SQLite and PostgreSQL storage backends
- Comprehensive test coverage for device flow scenarios

Additional improvements:
- Enhanced OAuth client registration with application metadata
- SQLX offline mode support for both database backends
- OAuth scope validation and configuration
- Client management API enhancements
- Integration with existing private_key_jwt authentication support
@bigmoves bigmoves force-pushed the feature/device-grant-flow branch from 5a304b0 to 69c80cf Compare September 12, 2025 20:32
@ngerakines ngerakines merged commit e360279 into graze-social:main Sep 13, 2025
bigmoves added a commit to bigmoves/aip that referenced this pull request Sep 18, 2025
…e-social#42)

Implements the OAuth 2.0 Device Authorization Grant flow according to RFC 8628
for devices with limited input capabilities or lack of web browser access.

Key features:
- Device authorization endpoint (`/oauth/device_authorization`)
- Device code token endpoint integration
- User device verification flow with HTML templates
- Internal device authorization client management
- Support for both SQLite and PostgreSQL storage backends
- Comprehensive test coverage for device flow scenarios

Additional improvements:
- Enhanced OAuth client registration with application metadata
- SQLX offline mode support for both database backends
- OAuth scope validation and configuration
- Client management API enhancements
- Integration with existing private_key_jwt authentication support
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants