A lightweight OAuth 2.0 Authorization Server supporting Device Authorization Grant (RFC 8628) and Authorization Code Flow with PKCE (RFC 6749 + RFC 7636)
- 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) — Device Code Flow - 📺 Smart TVs, IoT devices, gaming consoles — Device Code Flow
- 🌐 Web applications with server-side backends — Authorization Code Flow (confidential)
- 📱 Single-page apps and mobile apps — Authorization Code Flow + PKCE (public)
- 🤖 CI/CD pipelines and automation scripts — Device Code Flow
- Dual OAuth 2.0 Flows: Device Authorization Grant (RFC 8628) for CLI/IoT tools, and Authorization Code Flow with PKCE (RFC 6749 + RFC 7636) for web and mobile apps
- User Consent Management: Users can review and revoke per-app access at
/account/authorizations; admins can force re-authentication for all users of any client - Security First: Rate limiting, audit logging, CSRF protection, PKCE enforcement, and session management built-in
- Production Ready: Built-in monitoring with Prometheus metrics, 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.25 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.
Three example CLIs are provided in _example/. Each demonstrates a different OAuth 2.0 flow.
Device Code Flow (_example/authgate-device-cli/) — for headless environments:
cd _example/authgate-device-cli
# Configure client
cp .env.example .env
nano .env # Add CLIENT_ID from server logs
# Run the CLI
go run main.goAuthorization Code Flow (_example/authgate-oauth-cli/) — for apps that can open a browser:
cd _example/authgate-oauth-cli
# Configure client
cp .env.example .env
nano .env # Add CLIENT_ID (and CLIENT_SECRET for confidential clients)
# Run the CLI
go run .The Authorization Code Flow CLI starts a local callback server, opens your browser at the consent page, and exchanges the returned code for tokens automatically. It supports both public clients (PKCE) and confidential clients.
Hybrid Flow (github.com/go-authgate/cli) — auto-detects the environment and picks the right flow. On a local machine the CLI opens a browser (Authorization Code Flow + PKCE). In an SSH session or headless environment it automatically falls back to Device Code Flow.
- 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
- Prometheus Metrics - Metrics endpoint, authentication, Grafana dashboards
- Security Guide - Production checklist, threat model, secrets management
- Troubleshooting - Common issues, debug mode, FAQ
- Authorization Code Flow Guide - Auth Code Flow, PKCE, user consent, admin controls
- 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
AuthGate supports two OAuth 2.0 authorization flows.
Device Code Flow (RFC 8628) — for CLI / IoT
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, login, enter code
AuthGate-->>User: ✅ Success
CLI->>AuthGate: 3. Poll for token
AuthGate-->>CLI: access_token + refresh_token
Authorization Code Flow (RFC 6749) — for Web / Mobile
sequenceDiagram
participant App as Web/Mobile App
participant Browser as Browser
participant AuthGate as AuthGate Server
App->>Browser: 1. Redirect to /oauth/authorize
Browser->>AuthGate: Login + Consent page
AuthGate->>Browser: 302 redirect_uri?code=XXXXX
Browser->>App: code delivered to callback
App->>AuthGate: 2. POST /oauth/token (code + secret or PKCE)
AuthGate-->>App: access_token + refresh_token
Authorization Code Flow Guide →
Key Endpoints:
| Endpoint | Method | Purpose |
|---|---|---|
/oauth/device/code |
POST | Request device code (CLI) |
/oauth/authorize |
GET | Authorization consent page (web apps) |
/oauth/authorize |
POST | Submit consent decision |
/oauth/token |
POST | Exchange code / device code / refresh token |
/oauth/tokeninfo |
GET | Verify token validity |
/oauth/revoke |
POST | Revoke tokens (RFC 7009) |
/device |
GET | Device code entry page (browser) |
/account/sessions |
GET | Manage active token sessions |
/account/authorizations |
GET | Manage per-app consent grants |
/admin/clients/:id/authorizations |
GET | Admin: view all authorized users for a client |
/admin/clients/:id/revoke-all |
POST | Admin: force re-auth for all users |
/health |
GET | Health check |
/metrics |
GET | Prometheus metrics (optional auth) |
Full API Reference → | Metrics Documentation →
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
Users can manage per-app consent grants at /account/authorizations:
- See which web/mobile apps have been granted access
- View the approved scopes per app
- Revoke access for any individual app (revokes all associated tokens)
# 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 trails
# Monitoring (Optional - disabled by default)
# METRICS_ENABLED=true # Enable Prometheus metrics endpoint
# METRICS_TOKEN=your-bearer-token # Bearer token for /metrics (optional)Complete 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/
├── authgate-device-cli/ # Device Code Flow CLI (RFC 8628)
└── authgate-oauth-cli/ # Authorization Code Flow CLI (RFC 6749 + PKCE)# 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
Yes. Enable it per-client in Admin → OAuth Clients. Public clients (SPAs, mobile apps) use PKCE instead of a client secret.
Authorization Code Flow Guide →
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 Authorization Framework
- RFC 7636 - PKCE for OAuth Public Clients
- 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.