BeaconAuth is a modern, secure authentication system for Minecraft servers, featuring a web-based login interface with OAuth support and a companion mod for seamless in-game authentication.
- 🔐 ES256 JWT Authentication - Industry-standard elliptic curve cryptography
- 🌐 Modern Web Interface - React-based login and registration pages
- 🍪 Session Management - Secure HttpOnly cookies with refresh token rotation
- 🔑 OAuth Integration - Support for GitHub and Google authentication
- 🔒 WebAuthn/Passkey Support - Passwordless authentication with biometrics
- 🗄️ SQLite Database - Simple, file-based user storage
- 🐳 Docker Ready - Multi-architecture container images (amd64/arm64)
- ⚡ High Performance - Built with Rust and Actix-web
- 🎮 Automatic Login Flow - Seamless in-game authentication
- 🔒 PKCE Security - Proof Key for Code Exchange protection
- 🌍 Multi-Loader Support - Works with both Fabric and Forge
- 🌐 Internationalization - English and Chinese translations
- ⚙️ Configurable - Server-side TOML configuration
- 🔗 JWT Validation - Secure verification using JWKS
- Quick Start
- Cloudflare Deployment (Workers + Pages)
- Auth Server Deployment
- Mod Installation
- Development Guide
- API Documentation
- Troubleshooting
- Contributing
- License
The easiest way to deploy BeaconAuth is using Docker:
# Pull the latest image
docker pull ghcr.io/summpot/beacon_auth:latest
# Run the server
docker run -d --name beaconauth \
-p 8080:8080 \
-v $(pwd)/data:/app/data \
-e DATABASE_URL=sqlite:///app/data/beacon_auth.db \
ghcr.io/summpot/beacon_auth:latestThe server will be available at http://localhost:8080.
Download the latest release for your platform from the Releases page:
Linux (amd64):
wget https://github.com/Summpot/beacon_auth/releases/latest/download/beaconauth-linux-amd64-musl-v1.0.0.tar.gz
tar -xzf beaconauth-linux-amd64-musl-v1.0.0.tar.gz
chmod +x beacon
./beacon serveWindows (amd64):
# Download and extract the zip file
# Run in PowerShell:
.\beacon.exe servemacOS (Apple Silicon):
wget https://github.com/Summpot/beacon_auth/releases/latest/download/beaconauth-macos-arm64-v1.0.0.tar.gz
tar -xzf beaconauth-macos-arm64-v1.0.0.tar.gz
chmod +x beacon
./beacon serve# Clone the repository
git clone https://github.com/Summpot/beacon_auth.git
cd beacon_auth
# Install frontend dependencies
pnpm install
# Build the project
cargo build --workspace --release
# The binary will be at target/release/beaconThis repository ships a Cloudflare deployment that keeps the browser on a single origin while still separating concerns:
- API Worker:
crates/beacon-worker(Rust/WASM) using D1 + Workers KV. - Frontend (React): deployed to Cloudflare Pages.
To avoid cross-origin headaches, the Pages deployment includes a small dist/_worker.js that proxies these paths to the API Worker:
/api/*/v1/*/.well-known/*
Everything else (SPA routes like /login) is served as static content from Pages.
This repo uses two Wrangler configs at the repo root:
wrangler.workers.jsonc: the API Worker (crates/beacon-worker, D1 + KV, Rust/WASM)wrangler.jsonc: Cloudflare Pages (static UI + a service bindingBACKENDpointing to the API Worker)
This repo is configured for Automatic provisioning:
- D1 binding:
DB(configured withdatabase_name, no hard-codeddatabase_id) - KV binding:
KV(no hard-coded namespace id)
Workflow:
.github/workflows/deploy-cloudflare.yml
Required GitHub Actions secrets:
| Secret | Required | Used for |
|---|---|---|
CLOUDFLARE_API_TOKEN |
Yes | Wrangler authentication (deploy + D1 operations + secrets) |
CLOUDFLARE_ACCOUNT_ID |
Yes | Pin the Cloudflare Account ID in CI so Wrangler does not need to infer it via /memberships |
Recommended / optional secrets:
| Secret | Required | Used for |
|---|---|---|
CLOUDFLARE_WORKER_BASE_URL |
Recommended | Sets BASE_URL for issuer + OAuth redirects + WebAuthn RP origin. If omitted, CI defaults to https://<workerName>.pages.dev. |
CLOUDFLARE_WORKER_JWT_PRIVATE_KEY_DER_B64 |
Strongly recommended | Stable ES256 signing key (base64-encoded PKCS#8 DER P-256 private key) |
CLOUDFLARE_WORKER_GITHUB_CLIENT_ID |
Optional | GitHub OAuth |
CLOUDFLARE_WORKER_GITHUB_CLIENT_SECRET |
Optional | GitHub OAuth |
CLOUDFLARE_WORKER_GOOGLE_CLIENT_ID |
Optional | Google OAuth |
CLOUDFLARE_WORKER_GOOGLE_CLIENT_SECRET |
Optional | Google OAuth |
The workflow will:
- build the frontend (React)
- deploy the API Worker (Automatic provisioning will create/link D1 + KV if needed)
- apply D1 migrations via
wrangler d1 migrations apply(idempotent) - sync Worker secrets (when provided)
- deploy Pages from
dist/(which includesdist/_worker.jsbuilt fromsrc/pages/_worker.tsvia rsbuild)
The workflow runs on pushes to main and can also be triggered manually.
BeaconAuth can be configured using environment variables or command-line arguments. All configuration options can be viewed with:
beacon serve --help| Option | Environment Variable | Default | Description |
|---|---|---|---|
--bind-address |
BIND_ADDRESS |
127.0.0.1:8080 |
Server bind address |
--database-url |
DATABASE_URL |
sqlite://./beacon_auth.db?mode=rwc |
Database connection URL |
--jwt-expiration |
JWT_EXPIRATION |
3600 |
JWT expiration time in seconds |
--cors-origins |
CORS_ORIGINS |
http://localhost:3000,http://localhost:5173 |
Allowed CORS origins |
--github-client-id |
GITHUB_CLIENT_ID |
- | GitHub OAuth client ID |
--github-client-secret |
GITHUB_CLIENT_SECRET |
- | GitHub OAuth client secret |
--google-client-id |
GOOGLE_CLIENT_ID |
- | Google OAuth client ID |
--google-client-secret |
GOOGLE_CLIENT_SECRET |
- | Google OAuth client secret |
--oauth-redirect-base |
OAUTH_REDIRECT_BASE |
http://localhost:8080 |
OAuth redirect base URL |
Create a .env file in your working directory:
DATABASE_URL=sqlite:///app/data/beacon_auth.db
BIND_ADDRESS=0.0.0.0:8080
JWT_EXPIRATION=7200
CORS_ORIGINS=http://localhost:3000
# Optional: OAuth providers
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
OAUTH_REDIRECT_BASE=https://auth.example.comBeaconAuth uses SQLite by default. Initialize the database with:
# Run migrations
beacon migrate --database-url sqlite://./beacon_auth.db
# Create an initial admin user
beacon create-user --username admin --password your_secure_password
# List all users
beacon list-users
# Delete a user
beacon delete-user --username username- Go to GitHub Developer Settings
- Click "New OAuth App"
- Fill in the details:
- Application name: BeaconAuth
- Homepage URL:
http://localhost:8080(or your domain) - Authorization callback URL:
http://localhost:8080/api/v1/oauth/callback
- Copy the Client ID and Client Secret
- Set environment variables:
export GITHUB_CLIENT_ID=your_client_id export GITHUB_CLIENT_SECRET=your_client_secret
- Go to Google Cloud Console
- Create a new project or select an existing one
- Enable the Google+ API
- Go to Credentials → Create Credentials → OAuth Client ID
- Configure the OAuth consent screen
- Create credentials:
- Application type: Web application
- Authorized redirect URIs:
http://localhost:8080/api/v1/oauth/callback
- Copy the Client ID and Client Secret
- Set environment variables:
export GOOGLE_CLIENT_ID=your_client_id export GOOGLE_CLIENT_SECRET=your_client_secret
Create a docker-compose.yml:
version: '3.8'
services:
beaconauth:
image: ghcr.io/summpot/beacon_auth:latest
ports:
- "8080:8080"
volumes:
- ./data:/app/data
environment:
DATABASE_URL: sqlite:///app/data/beacon_auth.db
BIND_ADDRESS: 0.0.0.0:8080
JWT_EXPIRATION: 7200
GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID}
GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET}
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
OAUTH_REDIRECT_BASE: https://auth.example.com
restart: unless-stoppedStart the service:
docker-compose up -dserver {
listen 80;
server_name auth.example.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}For HTTPS, use Let's Encrypt:
certbot --nginx -d auth.example.com-
Download the Mod: Get the latest mod file from the Releases page
- For Fabric:
beaconauth-fabric-1.0.0.jar - For Forge:
beaconauth-forge-1.0.0.jar
- For Fabric:
-
Install the Mod:
- Place the jar file in your server's
mods/directory - Restart the server
- Place the jar file in your server's
-
Configure the Mod: Edit
config/beaconauth-server.toml(see Mod Configuration)
-
Download the Mod: Same mod file as the server version
-
Install the Mod:
- Place the jar file in your client's
mods/directory - The mod will automatically handle the client-side authentication flow
- Place the jar file in your client's
-
Requirements:
- Fabric Loader 0.18.0+ or Forge 47.4.10+
- Minecraft 1.20.1
After the first server startup, a configuration file will be generated at config/beaconauth-server.toml:
# BeaconAuth Server Configuration
# Authentication server base URL
# This should point to your deployed auth server
auth_server_url = "http://localhost:8080"
# JWKS URL for JWT validation
# The mod will fetch the public key from this endpoint
jwks_url = "http://localhost:8080/.well-known/jwks.json"
# JWT validation settings
[jwt]
# Expected issuer claim
issuer = "http://localhost:8080"
# Expected audience claim
audience = "minecraft-client"
# Allow clock skew in seconds (for exp validation)
clock_skew = 60Important: Update auth_server_url and jwks_url to match your deployed auth server's address.
For production deployments:
auth_server_url = "https://auth.example.com"
jwks_url = "https://auth.example.com/.well-known/jwks.json"
[jwt]
issuer = "https://auth.example.com"
audience = "minecraft-client"
clock_skew = 60This is a monorepo containing three distinct projects:
beacon_auth/
├── crates/ # Rust workspace (Auth Server)
│ ├── beacon/ # Main server binary
│ │ ├── src/
│ │ │ ├── main.rs # CLI entry point
│ │ │ ├── server.rs # HTTP server setup
│ │ │ ├── handlers.rs # API handlers
│ │ │ ├── crypto.rs # JWT/ECDSA utilities
│ │ │ ├── config.rs # Configuration
│ │ │ └── ...
│ │ ├── build.rs # Frontend build script
│ │ └── Cargo.toml
│ ├── entity/ # Sea-ORM entities
│ └── migration/ # Database migrations
├── src/ # Frontend (React/Rsbuild)
│ ├── routes/ # TanStack Router pages
│ │ ├── index.tsx # Login page
│ │ ├── register.tsx # Registration page
│ │ └── ...
│ └── ...
├── modSrc/ # Minecraft Mod (Kotlin/Gradle)
│ ├── common/ # Shared code
│ │ └── src/main/kotlin/
│ │ ├── client/ # Client-side code
│ │ │ ├── AuthClient.kt
│ │ │ └── ...
│ │ ├── server/ # Server-side code
│ │ │ ├── AuthServer.kt
│ │ │ └── ...
│ │ ├── network/ # Network packets
│ │ ├── config/ # Configuration
│ │ └── ...
│ ├── fabric/ # Fabric implementation
│ └── forge/ # Forge implementation
├── .github/workflows/ # CI/CD workflows
├── Dockerfile # Docker image definition
├── package.json # Frontend dependencies
└── Cargo.toml # Rust workspace definition
-
Install dependencies:
# Install Rust curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Install Node.js and pnpm curl -fsSL https://get.pnpm.io/install.sh | sh - # Install frontend dependencies pnpm install
-
Run in development mode:
# Terminal 1: Run frontend dev server pnpm dev # Terminal 2: Run backend cargo run --bin beacon serve
-
Access the application:
- Frontend dev server:
http://localhost:5173 - Backend API:
http://localhost:8080
- Frontend dev server:
-
Open in IDE:
- IntelliJ IDEA: Open
modSrc/build.gradle.kts - Eclipse: Import as Gradle project
- IntelliJ IDEA: Open
-
Build the mod:
cd modSrc ./gradlew build -
Run development server:
# Fabric ./gradlew :fabric:runServer # Forge ./gradlew :forge:runServer
-
Run development client:
# Fabric ./gradlew :fabric:runClient # Forge ./gradlew :forge:runClient
# Debug build
cargo build --workspace
# Release build (optimized)
cargo build --workspace --release
# Cross-compile for different targets
cargo install cargo-zigbuild
cargo zigbuild --target x86_64-unknown-linux-musl --releasepnpm buildOutput will be in dist/.
cd modSrc
# Build all loaders
./gradlew build
# Build specific loader
./gradlew :fabric:build
./gradlew :forge:buildArtifacts:
- Fabric:
modSrc/fabric/build/libs/beaconauth-fabric-*.jar - Forge:
modSrc/forge/build/libs/beaconauth-forge-*.jar
# Run all tests
cargo test --workspace
# Run specific package tests
cargo test -p beacon
cargo test -p entity
# Run with logging
RUST_LOG=debug cargo test --workspace -- --nocapturepnpm testcd modSrc
./gradlew testAuthenticate a user with username and password. Sets HttpOnly session cookies.
Request:
{
"username": "player123",
"password": "secure_password"
}Response (200 OK):
{
"success": true
}Cookies Set:
access_token- ES256 JWT valid for 15 minutesrefresh_token- Random token valid for 7 days
Register a new user account. Auto-logs in the user by setting session cookies.
Request:
{
"username": "newplayer",
"password": "secure_password"
}Response (201 Created):
{
"success": true
}Cookies Set:
access_token- ES256 JWT valid for 15 minutesrefresh_token- Random token valid for 7 days
Refresh an expired access token using a valid refresh token.
Request: Requires refresh_token cookie
Response (200 OK):
{
"success": true
}Cookies Set:
access_token- New ES256 JWT valid for 15 minutes
Generate a Minecraft-specific JWT for mod authentication. Requires valid session.
Request:
{
"challenge": "PKCE_challenge_string",
"redirect_port": 38125
}Response (200 OK):
{
"redirectUrl": "http://localhost:38125/auth-callback?jwt=eyJ..."
}Initiate OAuth authentication flow.
Request:
{
"provider": "github",
"challenge": "PKCE_challenge_string",
"redirect_port": 38125
}Response (200 OK):
{
"authorizationUrl": "https://github.com/login/oauth/authorize?..."
}OAuth provider callback endpoint.
Query Parameters:
code: Authorization code from OAuth providerstate: State token for validation
Response: HTTP 302 redirect to mod callback URL with JWT
Retrieve JSON Web Key Set for JWT verification.
Response (200 OK):
{
"keys": [
{
"kty": "EC",
"use": "sig",
"crv": "P-256",
"kid": "beacon-auth-key-1",
"x": "...",
"y": "...",
"alg": "ES256"
}
]
}Problem: Database connection error
Solution:
# Ensure database directory exists
mkdir -p data
# Run migrations
beacon migrate --database-url sqlite://./data/beacon_auth.dbProblem: pnpm: command not found
Solution: The build.rs script automatically handles frontend builds. Ensure pnpm is installed in your system PATH.
Problem: "Failed to validate JWT"
Solutions:
- Check that
jwks_urlin mod config matches your server - Verify server is accessible from client
- Check server logs for JWT validation errors
- Ensure system clocks are synchronized (use NTP)
Problem: "Invalid redirect URI"
Solutions:
- Verify OAuth app callback URL matches exactly:
http://yourserver:8080/api/v1/oauth/callback - Check
OAUTH_REDIRECT_BASEenvironment variable - For production, use HTTPS and proper domain
Enable detailed logging:
Auth Server:
RUST_LOG=debug beacon serveMod (server log):
Look for [BeaconAuth] prefix in server logs.
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
cargo test --workspace && cd modSrc && ./gradlew test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Rust: Follow standard Rust conventions (
cargo fmt,cargo clippy) - TypeScript: Use Biome formatter (
pnpm check) - Kotlin: Follow Kotlin conventions (configured in
.editorconfig)
Use conventional commit format:
feat:New featuresfix:Bug fixesdocs:Documentation changeschore:Maintenance taskstest:Test additions or modifications
This project is licensed under the MIT License - see the LICENSE file for details.
- Actix-web - Rust web framework
- Sea-ORM - Rust ORM
- Architectury - Multi-loader mod framework
- Nimbus JOSE+JWT - JWT library for Java
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made with ❤️ by Summpot