A lightweight OAuth 2.0 Device Authorization Grant server for CLI tools and browserless devices
- AuthGate
Modern CLI tools and IoT devices need secure user authentication, but traditional OAuth flows don't work well for devices without browsers or keyboards. AuthGate implements the OAuth 2.0 Device Authorization Grant (RFC 8628), allowing users to authenticate on a separate device while keeping credentials secure.
Perfect for:
- 🖥️ CLI tools (like
gh,aws-cli) - 📺 Smart TVs and streaming devices
- 🏠 IoT devices without input capabilities
- 🤖 CI/CD pipelines and automation scripts
- 🎮 Gaming consoles
- OAuth 2.0 Compliance: Full implementation of Device Authorization Grant (RFC 8628), Refresh Tokens (RFC 6749), and Token Revocation (RFC 7009)
- Security First: Rate limiting, audit logging, CSRF protection, and session management built-in
- Production Ready: Built-in monitoring, health checks, and comprehensive audit trails
- Zero Dependencies: Single static binary with SQLite embedded, or use PostgreSQL for scale
- Multi-Auth Support: Local authentication, external HTTP API, OAuth providers (GitHub, Gitea, Microsoft)
- Flexible Deployment: Docker-ready, cloud-friendly, runs anywhere
- Token Management: Fixed and rotation refresh token modes, web UI for session management
- Go 1.24 or higher
- Make (optional, but recommended)
# Clone repository
git clone <repository-url>
cd authgate
# Copy environment configuration
cp .env.example .env
# Generate strong secrets
echo "JWT_SECRET=$(openssl rand -hex 32)" >> .env
echo "SESSION_SECRET=$(openssl rand -hex 32)" >> .env
# Build the server
make build# Start server
./bin/authgate server
# Or with Docker
docker run -d \
--name authgate \
-p 8080:8080 \
-v authgate-data:/app/data \
-e JWT_SECRET=$(openssl rand -hex 32) \
-e SESSION_SECRET=$(openssl rand -hex 32) \
-e BASE_URL=http://localhost:8080 \
authgate:latestServer starts on http://localhost:8080
Important: Note the client_id printed in startup logs - you'll need this for the CLI example.
cd _example/authgate-cli
# Configure client
cp .env.example .env
nano .env # Add CLIENT_ID from server logs
# Run the CLI
go run main.goThe CLI demonstrates the complete device authorization flow with automatic token refresh.
- Quick Start - Get up and running in 5 minutes
- Configuration Guide - Environment variables, secrets, OAuth setup, rate limiting
- Deployment Guide - Production deployment with Docker, systemd, Nginx, cloud platforms
- Architecture Guide - System design, flow diagrams, database schema
- Development Guide - Building, testing, and extending AuthGate
- Monitoring Guide - Health checks, metrics, audit logging, alerting
- Security Guide - Production checklist, threat model, secrets management
- Troubleshooting - Common issues, debug mode, FAQ
- OAuth Setup Guide - GitHub, Gitea, Microsoft Entra ID integration
- Rate Limiting Guide - Protect against brute force and API abuse
- Performance Guide - Scalability, optimization, benchmarks
- Use Cases - Real-world examples and code samples
sequenceDiagram
participant CLI as CLI Tool
participant AuthGate as AuthGate Server
participant User as User (Browser)
CLI->>AuthGate: 1. Request device code
AuthGate-->>CLI: device_code + user_code + URL
Note over CLI: Display: "Visit URL, Enter code"
User->>AuthGate: 2. Visit URL in browser
User->>AuthGate: 3. Login + Enter code
AuthGate-->>User: Success!
CLI->>AuthGate: 4. Poll for token
AuthGate-->>CLI: access_token + refresh_token
Key Endpoints:
| Endpoint | Method | Purpose |
|---|---|---|
/oauth/device/code |
POST | Request device code (CLI) |
/oauth/token |
POST | Get or refresh tokens |
/oauth/tokeninfo |
GET | Verify token validity |
/oauth/revoke |
POST | Revoke tokens (RFC 7009) |
/device |
GET | User authorization page (browser) |
/device/verify |
POST | Complete authorization |
/account/sessions |
GET | View and manage active sessions |
/login |
POST | User login |
/health |
GET | Health check (monitoring) |
AuthGate provides a clean, modern web interface:
Simple username/password authentication
Enter the code from your CLI tool
Confirmation and return to CLI
Users can view and revoke active sessions at /account/sessions:
- View all authorized devices
- See client information and authorization times
- Revoke specific devices or all at once
- Monitor active vs expired sessions
# Server
SERVER_ADDR=:8080
BASE_URL=http://localhost:8080
# Security (REQUIRED - use openssl rand -hex 32)
JWT_SECRET=your-256-bit-secret-change-in-production
SESSION_SECRET=your-session-secret-change-in-production
# Database
DATABASE_DRIVER=sqlite # or postgres
DATABASE_DSN=oauth.db
# Admin Password (REQUIRED in production)
DEFAULT_ADMIN_PASSWORD=your-secure-password
# Features
ENABLE_RATE_LIMIT=true # Brute force protection
ENABLE_AUDIT_LOGGING=true # Comprehensive audit trailsComplete Configuration Guide →
- OAuth Third-Party Login: GitHub, Gitea, Microsoft Entra ID
- External Authentication: Integrate with existing auth systems
- Pluggable Token Providers: Use external token services
- Service-to-Service Auth: HMAC or simple header authentication
- HTTP Retry with Backoff: Resilient external API calls
- Rate Limiting: Memory or Redis store for distributed deployments
- Web Framework: Gin - Fast HTTP router
- Templates: templ - Type-safe HTML templating
- ORM: GORM - Database abstraction
- Database: SQLite (default) / PostgreSQL
- Sessions: Encrypted cookies with gin-contrib/sessions
- JWT: golang-jwt/jwt
authgate/
├── config/ # Configuration management
├── handlers/ # HTTP request handlers
├── middleware/ # Auth, CSRF, rate limiting
├── models/ # Database models
├── auth/ # Authentication providers
├── token/ # Token providers
├── services/ # Business logic
├── store/ # Database layer (SQLite/PostgreSQL)
├── templates/ # Type-safe templ templates
├── docs/ # Documentation
├── docker/ # Docker configuration
└── _example/ # Example CLI client# Build image
docker build -f docker/Dockerfile -t authgate .
# Run container
docker run -d \
--name authgate \
--restart unless-stopped \
-p 8080:8080 \
-v authgate-data:/app/data \
-e JWT_SECRET=$(openssl rand -hex 32) \
-e SESSION_SECRET=$(openssl rand -hex 32) \
-e BASE_URL=https://auth.yourdomain.com \
authgate:latest- Binary Deployment: Systemd service with security hardening
- Docker Compose: Multi-container setup with health checks
- Reverse Proxy: Nginx/Caddy with SSL/TLS
- Cloud Platforms: Fly.io, AWS, GCP, Azure
- Generate strong JWT and session secrets (32+ bytes)
- Set secure admin password
- Enable HTTPS (use reverse proxy)
- Configure rate limiting
- Enable audit logging
- Set up regular database backups
- Review security best practices
- ✅ Client secret exposure in distributed apps
- ✅ Phishing attacks (authorization on trusted domain)
- ✅ Replay attacks (single-use device codes)
- ✅ Token tampering (JWT signature verification)
- ✅ Brute force attacks (rate limiting)
- ✅ Session hijacking (encrypted cookies, CSRF protection)
Hardware: 2-core CPU, 4GB RAM, SSD
| Metric | SQLite | PostgreSQL |
|---|---|---|
| Requests/sec | ~500 | ~2000 |
| Avg Response Time | 20ms | 5ms |
| P95 Response Time | 50ms | 15ms |
| Concurrent Devices | < 1000 | > 1000 |
- SQLite: Suitable for < 1000 concurrent devices, single-instance deployments
- PostgreSQL: Recommended for production, supports horizontal scaling
- Multi-Pod: Use PostgreSQL + Redis for rate limiting across pods
# Build binary
make build
# Run tests
make test
# Run linter
make lint
# Cross-compile for Linux
make build_linux_amd64
make build_linux_arm64- Add custom OAuth clients
- Implement custom authentication providers
- Add new endpoints
- Customize web UI templates
Password grant requires users to enter credentials directly into your app, training users to trust third parties with passwords (security anti-pattern). Device flow keeps credentials on the trusted authorization server.
Yes! Follow the Security Checklist and harden your deployment. AuthGate includes production features like audit logging, rate limiting, and health checks.
Implement custom registration handlers. See Development Guide.
Yes! AuthGate fully supports RFC 6749 refresh tokens with two modes:
- Fixed Mode (default): Reusable tokens, perfect for multi-device
- Rotation Mode: High-security one-time-use tokens
- Web UI: Visit
/account/sessions - CLI/API: Call
POST /oauth/revoke - Bulk action: "Revoke All" button
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Write tests for new features
- Run
make fmt && make lint && make test - Submit a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- RFC 8628 - OAuth 2.0 Device Authorization Grant
- RFC 6749 - OAuth 2.0 Framework (Refresh Tokens)
- RFC 7009 - OAuth 2.0 Token Revocation
- RFC 8725 - JWT Best Practices
Built with:
Need Help? Check the Troubleshooting Guide or open an issue on GitHub.
Ready to Deploy? Start with the Deployment Guide.