Skip to content

AuthGate is an authorization server built on the OAuth 2.0 Device Authorization Grant (RFC 8628) standard, developed using Go and the Gin framework.

License

Notifications You must be signed in to change notification settings

appleboy/authgate

Repository files navigation

AuthGate

A lightweight OAuth 2.0 Device Authorization Grant server for CLI tools and browserless devices

Security Scanning Lint and Testing License

Table of Contents


Why 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

✨ Key Features

  • 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

🚀 Quick Start

Prerequisites

  • Go 1.24 or higher
  • Make (optional, but recommended)

Installation

# 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

Run the Server

# 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:latest

Server starts on http://localhost:8080

Important: Note the client_id printed in startup logs - you'll need this for the CLI example.

Test with Example CLI

cd _example/authgate-cli

# Configure client
cp .env.example .env
nano .env  # Add CLIENT_ID from server logs

# Run the CLI
go run main.go

The CLI demonstrates the complete device authorization flow with automatic token refresh.


📖 Documentation

Getting Started

Development

Operations

Advanced Topics


🎯 How It Works

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
Loading

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)

Full API Reference →


🎨 User Interface

AuthGate provides a clean, modern web interface:

Login & Authorization Flow

Login Page Simple username/password authentication

Device Authorization Enter the code from your CLI tool

Success Confirmation and return to CLI

Session Management

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

⚙️ Configuration

Basic Configuration (.env)

# 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

Complete Configuration Guide →

Advanced Features

  • 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

Advanced Configuration →


🏗️ Architecture

Technology Stack

  • 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

Project Structure

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

Architecture Deep Dive →


🚀 Deployment

Docker Deployment

# 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

Production Deployment

  • 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

Complete Deployment Guide →


🔒 Security

Production Checklist

  • 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

Full Security Guide →

What AuthGate Protects

  • ✅ 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)

📊 Performance

Benchmarks (Reference)

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

Scalability

  • 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

Performance Guide →


🔧 Development

Build from Source

# Build binary
make build

# Run tests
make test

# Run linter
make lint

# Cross-compile for Linux
make build_linux_amd64
make build_linux_arm64

Extending AuthGate

  • Add custom OAuth clients
  • Implement custom authentication providers
  • Add new endpoints
  • Customize web UI templates

Development Guide →


❓ FAQ

Q: Why not use OAuth password grant?

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.

Q: Can I use this in production?

Yes! Follow the Security Checklist and harden your deployment. AuthGate includes production features like audit logging, rate limiting, and health checks.

Q: How do I add user registration?

Implement custom registration handlers. See Development Guide.

Q: Does it support refresh tokens?

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

Q: How do users revoke device access?

  • Web UI: Visit /account/sessions
  • CLI/API: Call POST /oauth/revoke
  • Bulk action: "Revoke All" button

More FAQs →


🤝 Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for new features
  4. Run make fmt && make lint && make test
  5. Submit a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


📚 References


🙏 Acknowledgments

Built with:


Need Help? Check the Troubleshooting Guide or open an issue on GitHub.

Ready to Deploy? Start with the Deployment Guide.

About

AuthGate is an authorization server built on the OAuth 2.0 Device Authorization Grant (RFC 8628) standard, developed using Go and the Gin framework.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors 3

  •  
  •  
  •