OAuth Device Flows
A specialized Rust library that implements the OAuth 2.0 Device Authorization Grant (RFC 8628), commonly known as the "device flow" or "device code flow". This authentication flow is particularly useful for:
- 🖥️ CLI applications and command-line tools
- 📱 Devices with limited input capabilities (smart TVs, IoT devices)
- 🖱️ Headless systems where opening a browser is impractical
- 🔒 Secure authentication without embedding client secrets
Features
- ✅ Complete RFC 8628 implementation with all error handling
- 🏢 Multiple OAuth providers: Microsoft, Google, GitHub, GitLab, and generic providers
- ⚡ Async/await support with Tokio
- 🔄 Token refresh and lifecycle management
- 📱 QR code generation for easy mobile authentication (optional)
- 🛡️ Secure token handling using the
secrecy
crate - 🎯 Strong typing for all OAuth request/response structures
- 📦 Minimal dependencies suitable for embedded use
- ⚙️ Configurable polling strategies with exponential backoff
- 🔧 Builder pattern for easy configuration
Quick Start
Add to your Cargo.toml
:
[]
= "0.1"
= { = "1.0", = ["full"] }
Basic Example
use ;
use Duration;
async
Supported Providers
Provider | Status | Client Secret Required | Refresh Tokens | Notes |
---|---|---|---|---|
Microsoft | ✅ | No | Yes | Azure AD / Microsoft Entra |
✅ | Yes | Yes | Google Cloud / Workspace | |
GitHub | ✅ | No | No | GitHub Apps |
GitLab | ✅ | Yes | Yes | GitLab.com and self-hosted |
Generic | ✅ | Configurable | Configurable | Custom OAuth providers |
Advanced Usage
With QR Codes
Enable the qr-codes
feature (enabled by default):
if let Ok = auth_response.generate_qr_code
Token Management and Refresh
use TokenManager;
// Create token manager
let mut token_manager = new?;
// Check if token is expired
if token_manager.is_expired
// Get a valid token (automatically refreshes if needed)
let valid_token = token_manager.get_valid_token.await?;
// Use in HTTP requests
let auth_header = token_manager.authorization_header;
Custom Provider Configuration
use ;
use Url;
let custom_config = new
.with_default_scopes
.with_client_secret_required;
let config = new
.client_id
.client_secret
.generic_provider;
let device_flow = new?;
Error Handling
match device_flow.poll_for_token.await
Examples
The repository includes comprehensive examples for each supported provider:
microsoft_device_flow.rs
- Microsoft/Azure AD authenticationgoogle_device_flow.rs
- Google OAuth with refresh tokensgithub_device_flow.rs
- GitHub App authentication
Run an example:
Configuration Options
Option | Description | Default |
---|---|---|
client_id |
OAuth client identifier | Required |
client_secret |
OAuth client secret (if required) | None |
scopes |
Requested OAuth scopes | Provider defaults |
poll_interval |
How often to poll for token | 5 seconds |
max_attempts |
Maximum polling attempts | 60 (5 minutes) |
backoff_multiplier |
Exponential backoff factor | 1.1 |
max_poll_interval |
Maximum poll interval | 30 seconds |
request_timeout |
HTTP request timeout | 30 seconds |
use_pkce |
Enable PKCE (when supported) | Auto-detect |
Cargo Features
Feature | Description | Default |
---|---|---|
qr-codes |
QR code generation support | Enabled |
Disable QR codes to reduce dependencies:
[]
= { = "0.1", = false }
Security Considerations
- 🔐 Secrets are protected using the
secrecy
crate - 🛡️ No logging of sensitive data (tokens, client secrets)
- 🔒 Secure HTTP client with rustls (no OpenSSL dependency)
- ⏰ Proper timeout handling prevents hanging requests
- ✅ Input validation for all OAuth server responses
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development
# Clone the repository
# Run tests
# Run examples
# Check documentation
License
This project is dual-licensed under either:
at your option.
Acknowledgments
- RFC 8628 - OAuth 2.0 Device Authorization Grant
- The Rust community for excellent HTTP and async libraries
Note: This library is not affiliated with any OAuth provider. Provider names and trademarks are the property of their respective owners.