Skip to content

A comprehensive OAuth 2.0 authorization server and OpenID Connect provider built from scratch in Go, implementing multiple RFC standards and security best practices

Notifications You must be signed in to change notification settings

sandeepkv93/oauth-from-scratch-in-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

24 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

OAuth 2.0 & OpenID Connect Server Implementation in Go

A comprehensive OAuth 2.0 authorization server and OpenID Connect provider built from scratch in Go, implementing multiple RFC standards and security best practices. This implementation provides a complete OAuth 2.0 authorization server with OpenID Connect capabilities, supports all major grant types, includes advanced security features, and offers enterprise-grade functionality.

πŸ“‹ Table of Contents

πŸ” OAuth 2.0 & OpenID Connect Explained

What is OAuth 2.0?

OAuth 2.0 is an authorization framework that enables applications to obtain limited access to user accounts. It works by delegating user authentication to the service that hosts the user account and authorizing third-party applications to access the user account.

graph TB
    subgraph "OAuth 2.0 Roles"
        RO[Resource Owner<br/>πŸ‘€ User]
        C[Client<br/>πŸ“± Application]
        AS[Authorization Server<br/>πŸ›‘οΈ This Server]
        RS[Resource Server<br/>πŸ—„οΈ API Server]
    end

    RO -.->|"owns resources"| RS
    C -.->|"wants access to"| RS
    AS -.->|"issues tokens for"| RS
    C -->|"requests authorization"| AS
    AS -->|"grants access tokens"| C
    C -->|"accesses with token"| RS
Loading

OAuth 2.0 vs OpenID Connect

graph LR
    subgraph "OAuth 2.0"
        direction TB
        A1[Authorization πŸ”]
        A2["What can you do?"]
        A3[Access Token]
        A4[API Access]
    end

    subgraph "OpenID Connect"
        direction TB
        B1[Authentication πŸ‘€]
        B2["Who are you?"]
        B3[ID Token]
        B4[Identity Info]
    end

    OAuth2 -.->|"built on top of"| OIDC
    A1 --> A2 --> A3 --> A4
    B1 --> B2 --> B3 --> B4
Loading

Token Types Explained

graph TB
    subgraph "Token Ecosystem"
        AT[Access Token<br/>🎫 API Key<br/>Short-lived<br/>15 minutes]
        RT[Refresh Token<br/>πŸ”„ Renewal Ticket<br/>Long-lived<br/>7 days]
        IT[ID Token<br/>πŸ‘€ Identity Card<br/>User info<br/>JWT format]
        AC[Authorization Code<br/>πŸ“ Exchange Voucher<br/>One-time use<br/>10 minutes]
    end

    AC -->|"exchange for"| AT
    AC -->|"exchange for"| RT
    AC -->|"exchange for"| IT
    RT -->|"refresh"| AT
    AT -->|"access"| API[Protected APIs]
    IT -->|"contains"| Claims[User Claims]
Loading

πŸ—οΈ Architecture

System Architecture

graph TB
    subgraph "Client Applications"
        WEB[Web App]
        MOBILE[Mobile App]
        SPA[Single Page App]
        API_CLIENT[API Client]
    end

    subgraph "OAuth Server (This Implementation)"
        LB[Load Balancer]

        subgraph "Application Layer"
            AUTH[Authorization<br/>Endpoint]
            TOKEN[Token<br/>Endpoint]
            USERINFO[UserInfo<br/>Endpoint]
            ADMIN[Admin<br/>Interface]
        end

        subgraph "Business Logic"
            GRANT[Grant<br/>Handlers]
            SCOPE[Scope<br/>Manager]
            JWT_SVC[JWT<br/>Service]
            CLIENT_SVC[Client<br/>Service]
        end

        subgraph "Data Layer"
            CACHE[Redis<br/>Cache]
            DB[(PostgreSQL<br/>Database)]
        end
    end

    subgraph "Protected Resources"
        API1[User API]
        API2[Admin API]
        API3[Business API]
    end

    WEB --> LB
    MOBILE --> LB
    SPA --> LB
    API_CLIENT --> LB

    LB --> AUTH
    LB --> TOKEN
    LB --> USERINFO
    LB --> ADMIN

    AUTH --> GRANT
    TOKEN --> GRANT
    USERINFO --> CLIENT_SVC

    GRANT --> SCOPE
    GRANT --> JWT_SVC
    GRANT --> CLIENT_SVC

    CLIENT_SVC --> DB
    JWT_SVC --> CACHE
    SCOPE --> DB

    WEB -.->|"with access token"| API1
    MOBILE -.->|"with access token"| API2
    API_CLIENT -.->|"with access token"| API3
Loading

Code Architecture

β”œβ”€β”€ cmd/server/          # πŸš€ Application entry point
β”œβ”€β”€ internal/            # 🏠 Core business logic
β”‚   β”œβ”€β”€ auth/           #   πŸ” OAuth 2.0 authentication flows
β”‚   β”œβ”€β”€ client/         #   πŸ‘₯ Client management & validation
β”‚   β”œβ”€β”€ config/         #   βš™οΈ Configuration management
β”‚   β”œβ”€β”€ db/             #   πŸ—„οΈ Database models & operations
β”‚   β”œβ”€β”€ handlers/       #   🌐 HTTP handlers for OAuth endpoints
β”‚   β”œβ”€β”€ middleware/     #   πŸ›‘οΈ Security, logging, CORS, rate limiting
β”‚   β”œβ”€β”€ scope/          #   πŸ“‹ Scope validation & consent management
β”‚   └── token/          #   🎫 Token generation, validation & introspection
β”œβ”€β”€ pkg/                # πŸ“¦ Reusable packages
β”‚   β”œβ”€β”€ jwt/            #   πŸ”‘ JWT token utilities
β”‚   β”œβ”€β”€ crypto/         #   πŸ”’ Cryptographic utilities
β”‚   └── utils/          #   πŸ› οΈ Common utilities
β”œβ”€β”€ scripts/            # πŸ“œ Database setup & testing scripts
β”œβ”€β”€ tests/              # πŸ§ͺ Unit & integration tests
β”œβ”€β”€ docs/               # πŸ“š OpenAPI specification
└── web/                # πŸ–₯️ Static files & templates

πŸ”„ Supported Grant Types

1. Authorization Code Grant (Recommended)

The most secure flow for web applications and mobile apps.

sequenceDiagram
    participant U as User
    participant C as Client App
    participant AS as Auth Server
    participant RS as Resource Server

    Note over U,RS: Authorization Code Grant Flow

    C->>AS: 1. Authorization Request
    AS->>U: 2. Show Login Page
    U->>AS: 3. User Authentication
    AS->>U: 4. Show Consent Page
    U->>AS: 5. User Consent
    AS->>C: 6. Authorization Code
    C->>AS: 7. Token Request (code + credentials)
    AS->>C: 8. Access Token + Refresh Token
    C->>RS: 9. API Request with Access Token
    RS->>C: 10. Protected Resource
Loading

Example Flow:

# 1. Authorization Request
GET /authorize?response_type=code&client_id=web-app&redirect_uri=https://app.com/callback&scope=openid profile&state=xyz123&code_challenge=abc&code_challenge_method=S256

# 2. Token Exchange
POST /token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=AUTH_CODE&redirect_uri=https://app.com/callback&client_id=web-app&client_secret=secret&code_verifier=def

2. Client Credentials Grant

For server-to-server communication where no user is involved.

sequenceDiagram
    participant C as Client App
    participant AS as Auth Server
    participant RS as Resource Server

    Note over C,RS: Client Credentials Grant Flow

    C->>AS: 1. Token Request (client credentials)
    AS->>AS: 2. Validate Client
    AS->>C: 3. Access Token
    C->>RS: 4. API Request with Access Token
    RS->>C: 5. Protected Resource
Loading

3. Device Authorization Grant (RFC 8628)

For devices with limited input capabilities (smart TVs, IoT devices).

sequenceDiagram
    participant D as Device
    participant U as User
    participant AS as Auth Server
    participant B as User's Browser

    Note over D,B: Device Authorization Grant Flow

    D->>AS: 1. Device Authorization Request
    AS->>D: 2. Device Code + User Code + Verification URI
    D->>U: 3. Display User Code & URI
    U->>B: 4. Navigate to Verification URI
    B->>AS: 5. Enter User Code
    AS->>U: 6. User Authentication & Consent
    loop Polling
        D->>AS: 7. Token Request (device code)
        AS->>D: 8. "authorization_pending" OR Access Token
    end
Loading

4. Token Exchange Grant (RFC 8693)

For token delegation and impersonation scenarios.

sequenceDiagram
    participant C1 as Client 1
    participant AS as Auth Server
    participant C2 as Client 2
    participant RS as Resource Server

    Note over C1,RS: Token Exchange Grant Flow

    C1->>AS: 1. Original Access Token
    C1->>AS: 2. Token Exchange Request
    AS->>AS: 3. Validate & Transform Token
    AS->>C1: 4. New Access Token (different scope/audience)
    C1->>C2: 5. Delegate New Token
    C2->>RS: 6. API Request with New Token
    RS->>C2: 7. Protected Resource
Loading

πŸš€ Features

OAuth 2.0 Grant Types

  • βœ… Authorization Code Grant with PKCE (RFC 7636)
  • βœ… Client Credentials Grant
  • βœ… Refresh Token Grant with rotation
  • βœ… Resource Owner Password Credentials Grant
  • βœ… Implicit Grant (deprecated but supported)
  • βœ… Device Authorization Grant (RFC 8628)
  • βœ… JWT Bearer Grant (RFC 7523)
  • βœ… Token Exchange Grant (RFC 8693)

OpenID Connect Features

  • βœ… ID Token Generation with standard claims
  • βœ… UserInfo Endpoint with scope-based claims
  • βœ… Discovery Endpoints (well-known configurations)
  • βœ… Session Management with logout flows
  • βœ… JWKS Endpoint for public key distribution

Advanced Features

  • βœ… Dynamic Client Registration (RFC 7591)
  • βœ… Token Introspection (RFC 7662) & Revocation (RFC 7009)
  • βœ… Hierarchical Scope Management with consent tracking
  • βœ… JWT Access Tokens with configurable algorithms
  • βœ… Rate Limiting and Security Headers
  • βœ… PostgreSQL Integration with connection pooling
  • βœ… Admin Interface and Monitoring endpoints
  • βœ… Docker & Kubernetes deployment support

πŸ› οΈ Installation & Setup

Prerequisites

  • Go 1.24+
  • PostgreSQL 12+
  • Git
  • Task (for build automation)

Quick Start

# 1. Clone the repository
git clone [email protected]:sandeepkv93/oauth-from-scratch-in-go.git
cd oauth-from-scratch-in-go

# 2. Install Task runner
sh -c "$(curl -ssL https://taskfile.dev/install.sh)"

# 3. Install dependencies
task deps

# 4. Setup environment
cp .env.example .env
# Edit .env with your configuration

# 5. Setup database
createdb oauth_server
task db:setup

# 6. Build and run
task build && task run

The server will start on http://localhost:8080

Development Commands

# Development workflow
task run:dev           # Run with hot reload
task run:watch         # Run with file watching
task test              # Run all tests
task test:coverage     # Run tests with coverage report
task check             # Run all checks (fmt, lint, security, test)

# Database operations
task db:setup          # Setup database with sample data
task db:migrate        # Run migrations
task db:reset          # Reset database

# Docker deployment
task docker:build      # Build Docker image
task docker:run        # Run with Docker

# Kubernetes deployment
task k8s:deploy        # Deploy to Kubernetes
task k8s:status        # Check deployment status

🌐 OAuth 2.0 Flow Examples

Complete Authorization Code Flow

# Step 1: Get authorization code
curl "http://localhost:8080/authorize?response_type=code&client_id=web-app&redirect_uri=http://localhost:3000/callback&scope=openid+profile+email&state=random123"

# Step 2: Exchange code for tokens
curl -X POST http://localhost:8080/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=CODE_FROM_STEP1&redirect_uri=http://localhost:3000/callback&client_id=web-app&client_secret=web-secret"

# Response:
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "refresh_token": "rt_abc123...",
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "openid profile email"
}

Client Credentials Flow

curl -X POST http://localhost:8080/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=api-client&client_secret=api-secret&scope=api:read api:write"

Device Flow

# Step 1: Start device flow
curl -X POST http://localhost:8080/device/authorize \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=tv-app&scope=profile"

# Response:
{
  "device_code": "device_abc123",
  "user_code": "QWER-TYUI",
  "verification_uri": "http://localhost:8080/device",
  "expires_in": 600,
  "interval": 5
}

# Step 2: Poll for token
curl -X POST http://localhost:8080/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=device_abc123&client_id=tv-app"

Using Access Tokens

# Get user information
curl -H "Authorization: Bearer ACCESS_TOKEN" \
  http://localhost:8080/userinfo

# Introspect token
curl -X POST http://localhost:8080/introspect \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=ACCESS_TOKEN&client_id=web-app&client_secret=web-secret"

πŸ“š API Documentation

OAuth 2.0 Endpoints

Endpoint Method Description RFC
/authorize GET Authorization endpoint RFC 6749
/token POST Token endpoint RFC 6749
/device/authorize POST Device authorization RFC 8628
/introspect POST Token introspection RFC 7662
/revoke POST Token revocation RFC 7009
/userinfo GET User information OIDC Core

OpenID Connect Endpoints

Endpoint Method Description
/.well-known/openid-configuration GET OpenID Provider configuration
/.well-known/oauth-authorization-server GET OAuth Server metadata
/.well-known/jwks.json GET JSON Web Key Set
/logout GET End session endpoint

Management API

Endpoint Method Description
/api/clients POST Create OAuth client
/api/clients GET List OAuth clients
/api/clients/{id} PUT Update OAuth client
/api/users POST Create user account
/api/users GET List users

System Endpoints

Endpoint Method Description
/health GET Health check
/metrics GET Prometheus metrics
/admin GET Admin dashboard

πŸ”’ Security Features

Token Security

graph TB
    subgraph "Token Security Layers"
        TG[Token Generation<br/>🎲 Crypto Random]
        TS[Token Signing<br/>πŸ” HMAC-SHA256]
        TE[Token Encryption<br/>πŸ”’ AES-256]
        TV[Token Validation<br/>βœ… Signature Check]
    end

    subgraph "Storage Security"
        TH[Token Hashing<br/>πŸ—‚οΈ SHA-256]
        RT[Rate Limiting<br/>⏱️ Per-IP Limits]
        AL[Audit Logging<br/>πŸ“ Security Events]
    end

    TG --> TS --> TE --> TV
    TV --> TH --> RT --> AL
Loading

Authentication Security

  • πŸ” Password Hashing: bcrypt with configurable cost factor
  • πŸ›‘οΈ PKCE Required: Mandatory for public clients
  • ⏱️ Rate Limiting: Configurable per-IP and per-client limits
  • πŸ” Input Validation: Comprehensive parameter validation
  • 🚫 SQL Injection Protection: Parameterized queries only

Application Security

  • πŸ”’ Security Headers: HSTS, CSP, X-Frame-Options, X-Content-Type-Options
  • 🌐 CORS Protection: Configurable allowed origins
  • πŸ“ Request Limits: Size and rate limiting
  • πŸ•°οΈ Timing Attack Protection: Constant-time comparisons
  • πŸ” TLS Enforcement: HTTPS-only mode available

Security Headers Applied

Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin

βš™οΈ Configuration

Environment Variables

Variable Description Default Required
Server Configuration
SERVER_HOST Server bind address localhost No
SERVER_PORT Server port 8080 No
SERVER_READ_TIMEOUT Request read timeout 10s No
SERVER_WRITE_TIMEOUT Response write timeout 10s No
Database Configuration
DB_HOST PostgreSQL host localhost No
DB_PORT PostgreSQL port 5432 No
DB_USER Database user postgres No
DB_PASSWORD Database password Yes
DB_NAME Database name oauth_server No
DB_SSL_MODE SSL mode disable No
DB_MAX_OPEN_CONNS Max open connections 25 No
DB_MAX_IDLE_CONNS Max idle connections 25 No
Authentication Configuration
JWT_SECRET JWT signing secret Yes
JWT_ALGORITHM JWT algorithm HS256 No
ACCESS_TOKEN_TTL Access token lifetime 15m No
REFRESH_TOKEN_TTL Refresh token lifetime 168h No
ID_TOKEN_TTL ID token lifetime 1h No
AUTHORIZATION_CODE_TTL Authorization code lifetime 10m No
Security Configuration
BCRYPT_COST bcrypt cost factor 12 No
RATE_LIMIT_REQUESTS Rate limit per window 100 No
RATE_LIMIT_WINDOW Rate limit window 1m No
ALLOWED_ORIGINS CORS allowed origins * No
SECURE_COOKIES Enable secure cookies false No

Sample Configuration

# .env file
SERVER_HOST=0.0.0.0
SERVER_PORT=8080

# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=oauth_user
DB_PASSWORD=secure_password
DB_NAME=oauth_server
DB_SSL_MODE=require

# JWT Configuration
JWT_SECRET=your-super-secure-secret-key-at-least-32-characters-long
JWT_ALGORITHM=HS256
ACCESS_TOKEN_TTL=15m
REFRESH_TOKEN_TTL=168h

# Security
BCRYPT_COST=12
RATE_LIMIT_REQUESTS=1000
RATE_LIMIT_WINDOW=1m
ALLOWED_ORIGINS=https://yourdomain.com,https://app.yourdomain.com
SECURE_COOKIES=true

πŸ§ͺ Testing

Test Coverage Overview

graph LR
    subgraph "Test Types"
        UT[Unit Tests<br/>πŸ“‹ 85% Coverage]
        IT[Integration Tests<br/>πŸ”„ OAuth Flows]
        ST[Security Tests<br/>πŸ›‘οΈ Vulnerability Scans]
        PT[Performance Tests<br/>⚑ Load Testing]
    end

    UT --> TF[Test Fixtures]
    IT --> TD[Test Database]
    ST --> SC[Security Checks]
    PT --> LT[Load Tests]
Loading

Running Tests

# Run all tests
task test

# Run with coverage
task test:coverage

# Run specific test suites
task test:unit              # Unit tests only
task test:integration       # Integration tests only
task test:security          # Security vulnerability scan

# Test OAuth flows end-to-end
task test:oauth

# Performance testing
task test:load

Test OAuth Flows

The repository includes comprehensive test scripts that demonstrate all OAuth flows:

# Test all grant types
./scripts/test-oauth-flows.sh

# Test specific flows
./scripts/test-authorization-code.sh
./scripts/test-client-credentials.sh
./scripts/test-device-flow.sh

Example test output:

βœ… Authorization Code Grant: PASSED
βœ… Client Credentials Grant: PASSED
βœ… Refresh Token Grant: PASSED
βœ… Device Authorization Grant: PASSED
βœ… Token Introspection: PASSED
βœ… Token Revocation: PASSED
βœ… OIDC UserInfo: PASSED

πŸš€ Production Deployment

Security Checklist

graph TB
    subgraph "Production Security"
        SSL[πŸ”’ HTTPS/TLS<br/>Certificate Setup]
        SEC[πŸ” Strong Secrets<br/>32+ character JWT secret]
        DB[πŸ—„οΈ Database Security<br/>SSL, firewall, backups]
        MON[πŸ“Š Monitoring<br/>Logs, metrics, alerts]
    end

    subgraph "Infrastructure Security"
        FW[πŸ›‘οΈ Firewall Rules<br/>Restrict access]
        UP[πŸ”„ Updates<br/>Regular security patches]
        BAK[πŸ’Ύ Backups<br/>Database + secrets]
        NET[🌐 Network Security<br/>VPC, private subnets]
    end

    SSL --> SEC --> DB --> MON
    FW --> UP --> BAK --> NET
Loading

Production Environment Variables

# Strong, random secrets (minimum 32 characters)
JWT_SECRET=a-very-secure-random-secret-key-for-jwt-signing-at-least-32-chars
DB_PASSWORD=ultra-secure-database-password-with-special-chars

# Security settings
ALLOWED_ORIGINS=https://yourdomain.com,https://app.yourdomain.com
SECURE_COOKIES=true
DB_SSL_MODE=require

# Performance settings
RATE_LIMIT_REQUESTS=5000
RATE_LIMIT_WINDOW=1m
DB_MAX_OPEN_CONNS=100
DB_MAX_IDLE_CONNS=50

# Monitoring
LOG_LEVEL=info
METRICS_ENABLED=true

Docker Deployment

# Build production image
task docker:build

# Run with production config
task docker:run:prod

# Docker Compose for full stack
docker-compose -f docker-compose.prod.yml up -d

Kubernetes Deployment

# Deploy to Kubernetes
task k8s:deploy

# Scale deployment
kubectl scale deployment oauth-server --replicas=3

# Check status
task k8s:status

Monitoring & Observability

graph TB
    subgraph "Observability Stack"
        APP[OAuth Server<br/>πŸ“Š Metrics Export]
        PROM[Prometheus<br/>πŸ“ˆ Metrics Collection]
        GRAF[Grafana<br/>πŸ“Š Dashboards]
        ALERT[AlertManager<br/>🚨 Notifications]
    end

    subgraph "Logging Stack"
        LOGS[Application Logs<br/>πŸ“ Structured JSON]
        ELK[ELK Stack<br/>πŸ” Log Analysis]
        DASH[Log Dashboard<br/>πŸ“Š Visualization]
    end

    APP --> PROM --> GRAF
    PROM --> ALERT
    APP --> LOGS --> ELK --> DASH
Loading

πŸ“œ Standards Compliance

This implementation follows these RFCs and standards:

OAuth 2.0 Core Standards

  • RFC 6749: The OAuth 2.0 Authorization Framework
  • RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage
  • RFC 7519: JSON Web Token (JWT)

OAuth 2.0 Extensions

  • RFC 7636: Proof Key for Code Exchange by OAuth Public Clients (PKCE)
  • RFC 7662: OAuth 2.0 Token Introspection
  • RFC 7009: OAuth 2.0 Token Revocation
  • RFC 8414: OAuth 2.0 Authorization Server Metadata
  • RFC 8628: OAuth 2.0 Device Authorization Grant
  • RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
  • RFC 8693: OAuth 2.0 Token Exchange
  • RFC 7591: OAuth 2.0 Dynamic Client Registration Protocol

OpenID Connect

Security Standards

⚠️ Important Note: This is a reference implementation for educational and production use. Always conduct a thorough security review before deploying to production environments. For critical applications, consider additional security measures and regular penetration testing.

🎯 Perfect for: Learning OAuth 2.0/OIDC, prototyping, startups, internal tools, and educational purposes.

About

A comprehensive OAuth 2.0 authorization server and OpenID Connect provider built from scratch in Go, implementing multiple RFC standards and security best practices

Resources

Stars

Watchers

Forks