README
ยถ
๐ tiny-auth
The Most Lightweight Traefik ForwardAuth Service Ever! ๐
One config file to rule them all, never worry about API security again!
English | ็ฎไฝไธญๆ
โจ Why tiny-auth?
๐ก TL;DR: If you're using Traefik as a reverse proxy and struggling with authentication, tiny-auth is your lifesaver!
๐ฏ Key Features
- ๐ชถ Ultra Lightweight: Single binary, zero dependencies, under 5MB
- โก Blazingly Fast: Powered by Fiber framework, easily handles 1000+ req/s
- ๐ Security First: Constant-time comparison prevents timing attacks, config file permission checks
- ๐จ Flexible Config: TOML format, environment variable support, hot reload without restart
- ๐ Multiple Auth Methods: Basic Auth / Bearer Token / API Key / JWT all-in-one
- ๐ฏ Fine-grained Control: Route-based policies by host/path/method, play it your way
- ๐ Header Injection: Client uses Basic Auth, upstream receives Bearer Token? No problem!
- ๐ Out-of-the-box: Health checks, debug endpoints, config validation, everything you need
๐ Comparison
| Feature | tiny-auth | Traefik BasicAuth | OAuth2 Proxy | Authelia |
|---|---|---|---|---|
| Binary Size | ~5MB | N/A | ~20MB | ~30MB |
| Multiple Auth | โ | โ | โ | โ |
| Route Policies | โ | โ | โ | โ |
| Header Transform | โ | โ | โ ๏ธ | โ |
| Hot Reload | โ | โ | โ | โ |
| Env Vars | โ | โ | โ | โ |
| Complexity | โญ | โญ | โญโญโญ | โญโญโญโญ |
๐ฆ Docker Images
tiny-auth is available from two registries for fast access worldwide:
| Registry | Address | Recommended For |
|---|---|---|
| ๐ณ Docker Hub | nerdneils/tiny-auth:latest |
๐ International |
| ๐ฆ GitHub CR | ghcr.io/nerdneilsfield/tiny-auth:latest |
๐ Asia (may be slower) |
Supported Architectures:
linux/amd64- x86_64linux/arm64- ARM64 / Apple Siliconlinux/arm/v7- ARMv7
๐ Quick Start
Option 1: Docker (Recommended)
# 1. Create config file
cat > config.toml << 'EOF'
[server]
port = "8080"
[[basic_auth]]
name = "admin"
user = "admin"
pass = "supersecret"
roles = ["admin"]
EOF
# 2. Run (Choose one registry)
# Docker Hub
docker run -d \
--name tiny-auth \
-p 8080:8080 \
-v $(pwd)/config.toml:/root/config.toml:ro \
nerdneils/tiny-auth:latest
# Or use GitHub Container Registry
docker run -d \
--name tiny-auth \
-p 8080:8080 \
-v $(pwd)/config.toml:/root/config.toml:ro \
ghcr.io/nerdneilsfield/tiny-auth:latest
# 3. Test
curl -u admin:supersecret http://localhost:8080/auth
# โ 200 OK โ
Option 2: Binary Download
# Download latest release
wget https://github.com/nerdneilsfield/tiny-auth/releases/latest/download/tiny-auth_linux_amd64.tar.gz
tar -xzf tiny-auth_linux_amd64.tar.gz
# Run
./tiny-auth server --config config.toml
Option 3: Build from Source
git clone https://github.com/nerdneilsfield/tiny-auth.git
cd tiny-auth
just build # or make build
./tiny-auth server
๐จ Configuration Examples
๐ Complete Configuration Example (Click to expand)
# ===== Server Configuration =====
[server]
port = "8080"
auth_path = "/auth"
health_path = "/health"
# ===== Logging Configuration =====
[logging]
format = "json" # or "text"
level = "info" # debug/info/warn/error
# ===== Basic Auth =====
[[basic_auth]]
name = "admin-user"
user = "admin"
pass = "supersecret" # Supports env:PASSWORD to read from environment
roles = ["admin", "user"]
# ===== Bearer Token =====
[[bearer_token]]
name = "api-token"
token = "env:API_TOKEN" # Read from environment variable
roles = ["api", "service"]
# ===== API Key =====
[[api_key]]
name = "prod-key"
key = "ak_prod_xxx"
roles = ["admin"]
# ===== JWT Validation =====
[jwt]
secret = "your-256-bit-secret-key-must-be-32-chars"
issuer = "auth-service"
audience = "api"
# ===== Route Policies =====
# Public API allows anonymous access
[[route_policy]]
name = "public"
path_prefix = "/public"
allow_anonymous = true
# Admin panel requires admin role
[[route_policy]]
name = "admin"
host = "admin.example.com"
allowed_basic_names = ["admin-user"]
require_all_roles = ["admin"]
# Webhook endpoint with header injection
[[route_policy]]
name = "webhook"
host = "hooks.example.com"
path_prefix = "/webhook"
allowed_bearer_names = ["api-token"]
inject_authorization = "Bearer upstream-token-123"
๐ Environment Variable Syntax
Use env:VAR_NAME in config to read sensitive data from environment:
[[basic_auth]]
pass = "env:ADMIN_PASSWORD"
[jwt]
secret = "env:JWT_SECRET"
Set environment variables when starting:
export ADMIN_PASSWORD="my-secure-password"
export JWT_SECRET="my-jwt-secret-key-32-chars-long"
./tiny-auth server
๐ Traefik Integration
Complete Docker Compose Example
version: '3.8'
services:
# tiny-auth authentication service
tiny-auth:
image: nerdneils/tiny-auth:latest # Or use ghcr.io/nerdneilsfield/tiny-auth:latest
volumes:
- ./config.toml:/root/config.toml:ro
networks:
- traefik
# Traefik reverse proxy
traefik:
image: traefik:v3.2
ports:
- "80:80"
command:
- --providers.docker=true
- --entrypoints.web.address=:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- traefik
# Protected service (example)
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
# Configure ForwardAuth middleware
- "traefik.http.middlewares.auth.forwardauth.address=http://tiny-auth:8080/auth"
- "traefik.http.middlewares.auth.forwardauth.authResponseHeaders=X-Auth-User,X-Auth-Role,X-Auth-Method"
# Apply middleware
- "traefik.http.routers.whoami.middlewares=auth@docker"
networks:
- traefik
networks:
traefik:
Key Configuration Settings
| Setting | Description | Example |
|---|---|---|
address |
tiny-auth's /auth endpoint | http://tiny-auth:8080/auth |
authResponseHeaders |
Headers to inject to upstream | X-Auth-User,X-Auth-Role |
trustForwardHeader |
Trust X-Forwarded-* headers | false (recommended) |
โ ๏ธ Important: Never enable forwardBody=true, it breaks SSE/WebSocket!
๐ฏ Use Cases
Case 1: Multi-environment API Authentication
# Development environment uses Basic Auth
[[basic_auth]]
name = "dev"
user = "dev"
pass = "dev123"
roles = ["developer"]
# Production environment uses Bearer Token
[[bearer_token]]
name = "prod"
token = "env:PROD_TOKEN"
roles = ["admin", "service"]
# Route policies
[[route_policy]]
name = "dev-api"
host = "dev-api.example.com"
allowed_basic_names = ["dev"]
[[route_policy]]
name = "prod-api"
host = "api.example.com"
allowed_bearer_names = ["prod"]
Case 2: Auth Transformation (Client Basic โ Upstream Bearer)
[[basic_auth]]
name = "user"
user = "client"
pass = "clientpass"
roles = ["user"]
[[route_policy]]
name = "transform"
host = "api.example.com"
allowed_basic_names = ["user"]
inject_authorization = "Bearer upstream-internal-token-abc123"
Client uses Basic Auth, upstream service receives Bearer Token!
Case 3: Microservices Internal Authentication
# Service-to-service communication with API Keys
[[api_key]]
name = "service-a"
key = "env:SERVICE_A_KEY"
roles = ["internal"]
[[api_key]]
name = "service-b"
key = "env:SERVICE_B_KEY"
roles = ["internal"]
[[route_policy]]
name = "internal"
host = "internal.example.com"
require_any_role = ["internal"]
๐ณ Docker Usage Guide
๐ Quick Start Full Environment
Use our complete example (includes Traefik + tiny-auth + 5 demo services):
# 1. Clone repository
git clone https://github.com/nerdneilsfield/tiny-auth.git
cd tiny-auth/examples
# 2. Prepare configuration
cp config-full.toml config.toml
cp .env.example .env
# Edit .env file to set your passwords
# 3. Start services
docker-compose -f docker-compose-full.yml up -d
# 4. Test
curl -u admin:your-password http://whoami-basic.localhost/
curl http://public.localhost/public/
curl -H "Authorization: Bearer your-token" http://api.localhost/
# 5. View logs
docker-compose -f docker-compose-full.yml logs -f tiny-auth
# 6. Stop services
docker-compose -f docker-compose-full.yml down
๐ง Custom Docker Compose
Integrate tiny-auth in your project:
version: '3.8'
services:
tiny-auth:
image: nerdneils/tiny-auth:latest
volumes:
- ./your-config.toml:/root/config.toml:ro
environment:
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
- JWT_SECRET=${JWT_SECRET}
networks:
- traefik
your-service:
image: your-app:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
- "traefik.http.middlewares.auth.forwardauth.address=http://tiny-auth:8080/auth"
- "traefik.http.middlewares.auth.forwardauth.authResponseHeaders=X-Auth-User,X-Auth-Role"
- "traefik.http.routers.app.middlewares=auth@docker"
networks:
- traefik
๐ Hot Reload Configuration
After modifying config file, no container restart needed:
# Method 1: Send SIGHUP signal
docker kill --signal=SIGHUP tiny-auth
# Method 2: Use docker-compose
docker-compose kill -s SIGHUP tiny-auth
# View reload logs
docker logs tiny-auth --tail 20
# โ "โป๏ธ Configuration reloaded"
๐๏ธ Build from Source
# Clone repository
git clone https://github.com/nerdneilsfield/tiny-auth.git
cd tiny-auth
# Build image
docker build -t my-tiny-auth:latest .
# Or use justfile
just docker-build
# Run
docker run -d -p 8080:8080 \
-v $(pwd)/config.toml:/root/config.toml:ro \
my-tiny-auth:latest
๐ Operations
Hot Reload Configuration
# Send SIGHUP signal to reload config
kill -HUP $(pidof tiny-auth)
# Or with Docker
docker kill --signal=SIGHUP tiny-auth
No restart needed, config takes effect immediately! โจ
Configuration Validation
# Validate config file
tiny-auth validate config.toml
# Output example
โ
Configuration is valid
๐ Configuration Summary:
โ Server: port 8080
โ Basic Auth: 2 users configured
โ Bearer Tokens: 1 tokens configured
โ Route Policies: 3 policies configured
โ Warning: config.toml has insecure permissions 644
โ Recommendation: chmod 0600 config.toml
Health Check
curl http://localhost:8080/health
{
"status": "ok",
"basic_count": 2,
"bearer_count": 1,
"apikey_count": 1,
"jwt_enabled": true,
"policy_count": 3
}
Debug Endpoint (Optional)
Enable in config first:
[server]
enable_debug = true
curl http://localhost:8080/debug/config
{
"server": {
"port": "8080",
"auth_path": "/auth"
},
"authentication": {
"basic_auth": ["admin", "dev"],
"bearer_tokens": ["prod-token"],
"jwt_enabled": true
},
"policies": ["public", "admin-only"]
}
โ ๏ธ Do not expose this endpoint publicly. Restrict it to trusted networks only.
Audit Logging (Recommended for Production)
tiny-auth can emit a separate structured audit log stream (JSON Lines) for compliance and traceability.
[audit]
enabled = true
output = "./audit.log" # or "stdout" / "stderr"
Each line is a JSON event including request_id, client_ip, host/uri, auth_method, policy, result, status, and latency.
๐ Security Best Practices
โ Must Do
-
โ ๏ธ Configure Trusted Proxies (CRITICAL!)
Why: Prevents attackers from spoofing
X-Forwarded-*headers to bypass policies.Important: Your reverse proxy/load balancer MUST strip or overwrite any client-supplied
X-Forwarded-*headers.
If it doesn't,trusted_proxiescan still be bypassed.[server] # โ PRODUCTION: Only trust your reverse proxy trusted_proxies = ["172.16.0.0/12"] # Docker network # โ INSECURE: Empty list accepts headers from ANY source # trusted_proxies = []Examples:
- Docker Compose:
["172.16.0.0/12"] - Kubernetes:
["10.0.0.0/8"] - Specific IP:
["192.168.1.100"] - Multiple:
["172.16.0.0/12", "192.168.1.0/24"]
Without it:
# Attacker can fake host to bypass policies curl -H "X-Forwarded-Host: admin.internal.com" \ http://your-tiny-auth:8080/auth # Without trusted_proxies: โ Allowed (bypass!) # With trusted_proxies: โ Denied (headers ignored) - Docker Compose:
-
Config File Permissions
chmod 0600 config.toml # Owner read/write only -
Use Environment Variables for Secrets
pass = "env:ADMIN_PASSWORD" # โ pass = "plaintext123" # โ -
Strong Password Policy
- At least 12 characters
- Mix of uppercase, lowercase, numbers, special chars
-
JWT Secret Length
- At least 32 characters (256 bits)
-
Enable JSON Logging for Production
[logging] format = "json" # Structured, searchable level = "info"Structured logs include:
request_id: Trace across servicesclient_ip: Real client IP (validated via trusted_proxies)auth_method: Which authentication succeededlatency: Performance monitoringreason: Why authentication failed
โ ๏ธ Warnings
- Don't expose
/debug/configendpoint publicly - Rotate tokens and API keys regularly
- Use HTTPS (configure TLS in Traefik)
- Review auth logs, monitor suspicious access
๐ ๏ธ Development Guide
๐จ Local Development
Prerequisites
- Go 1.23+
- just or make
Common Commands
# Clone repository
git clone https://github.com/nerdneilsfield/tiny-auth.git
cd tiny-auth
# Install dependencies
just deps
# Build
just build
# Run tests
just test
# Lint
just lint
# Format code
just fmt
# Full check (test + lint)
just check
# List all commands
just --list
Project Structure
tiny-auth/
โโโ cmd/ # CLI commands
โ โโโ root.go # Root command
โ โโโ server.go # Server command
โ โโโ validate.go # Config validation
โ โโโ version.go # Version info
โโโ internal/ # Internal packages
โ โโโ config/ # Config management
โ โโโ auth/ # Authentication logic
โ โโโ policy/ # Policy matching
โ โโโ server/ # HTTP server
โโโ openspec/ # OpenSpec specification
โโโ main.go # Entry point
๐งช Testing
# Run all tests
just test
# Generate coverage report
just test-coverage
open coverage.html
# Race detection
go test -race ./...
Current coverage target: >80%
๐ Documentation
- Complete Configuration Reference
- Authentication Methods
- Route Policies
- Header Injection
- Technical Design
๐ค Contributing
All contributions are welcome!
- Fork this repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Before committing:
just pre-commit # Format + check
๐ Changelog
See CHANGELOG.md for version history.
๐ License
This project is licensed under the MIT License.
๐ Acknowledgments
- Fiber - High-performance web framework
- Traefik - Modern reverse proxy
- golang-jwt - JWT implementation
- BurntSushi/toml - TOML parser
๐ฌ Community & Support
- ๐ Report Issues
- ๐ก Feature Requests
- ๐ง Contact: dengqi935@gmail.com
โญ Star this repo if you find it useful! โญ
Made with โค๏ธ by dengqi
Documentation
ยถ
There is no documentation for this package.