ZenAuth is a lightweight yet complete OAuth 2.0 authorization server implemented in Go. It supports multiple OAuth 2.0 flows and provides a simple and secure solution for managing authentication and authorization for your applications.
- ZenAuth - OAuth 2.0 Authorization Server in Go
-
Multiple OAuth 2.0 Flows:
- Authorization Code flow with PKCE support
- Client Credentials flow
- Refresh Token flow
-
External Authentication:
- Support for popular identity providers (Microsoft, Google, GitHub)
- Streamlined login experience with social sign-in buttons
-
Security Features:
- PKCE (Proof Key for Code Exchange) support
- JWT-based access tokens
- Secure password hashing with bcrypt
- CORS protection
- Single-use authorization codes
-
PostgreSQL Storage:
- Persistent storage for users, clients, authorization codes, and refresh tokens
-
Role-Based Access Control:
- User roles and groups management
- Role inclusion in JWT tokens
-
Integration Flexibility:
- Standalone mode with internal database
- Hybrid mode with external user authentication and roles
- Support for custom database schemas
-
Admin Console:
- Web-based admin interface
- Manage users, clients, and auth providers
- Role and group assignment
- Go 1.20+
- Docker and Docker Compose (for PostgreSQL)
- Make (optional, for running commands)
-
Clone the repository:
git clone https://github.com/yourusername/zenauth.git cd zenauth -
Start the PostgreSQL database:
make up
-
Initialize the database and create a test user:
make init-db seed
-
Run the ZenAuth server:
make run
-
In a separate terminal, start the test client:
make client
-
Visit http://localhost:3000 and click on "Login with Mini OAuth"
- Use the test credentials:
- Username:
demo - Password:
demo123
- Username:
- Or use one of the configured external authentication providers
- Microsoft
- GitHub
- Use the test credentials:
-
Access the admin console at http://localhost:8080/admin/
Create a .env file in the root directory with the following variables:
# Base Configuration
SERVER_PORT=8080
DATABASE_URL=postgres://oauth_user:oauth_pass@localhost:5432/oauth?sslmode=disable
JWT_SECRET=supersecretkey
FRONTEND_ORIGIN=http://localhost:3000
# User Provider Configuration
USER_PROVIDER_TYPE=default # options: default, sql
USER_PROVIDER_SQL_CONN=postgres://user:pass@host:port/db?sslmode=disable
USER_PROVIDER_SQL_TABLE=users
USER_PROVIDER_SQL_ID_FIELD=id
USER_PROVIDER_SQL_USER_FIELD=username
USER_PROVIDER_SQL_PASS_FIELD=password_hash
USER_PROVIDER_SQL_EMAIL_FIELD=email
# Role Manager Configuration
ROLE_MANAGER_TYPE=default # options: default, external
ROLE_MANAGER_INCLUDE_IN_JWT=true
ROLE_MANAGER_EXTERNAL_CONN=postgres://user:pass@host:port/db?sslmode=disable
ROLE_MANAGER_ROLE_TABLE=roles
ROLE_MANAGER_GROUP_TABLE=groups
| Method | Path | Description |
|---|---|---|
| GET | /authorize |
Starts the Authorization Code flow |
| POST | /token |
Exchanges code or client credentials |
| GET | /userinfo |
Returns user information from token |
| GET | /admin/ |
Admin console to manage users, clients, and authentication providers |
| GET | /auth/external |
Starts external authentication flow |
| GET | /auth/callback |
Callback URL for external authentication providers |
graph TD;
A[Client App] -->|Redirect with code_challenge| B[ZenAuth /authorize];
B --> C[Login Form];
C --> D[Authorization Code];
D -->|Redirect to client| A;
A -->|POST /token with code & verifier| E[ZenAuth /token];
E --> F[Access Token + Refresh Token];
graph TD;
A[Client App] -->|POST /token with credentials| B[ZenAuth];
B --> C[Access Token + Refresh Token];
graph TD;
A[Client App] -->|POST /token with refresh_token| B[ZenAuth];
B --> C[New Access Token];
graph TD;
A[Client App] -->|Redirect to| B[ZenAuth /authorize];
B --> C[Login Form with External Providers];
C -->|Select External Provider| D[/auth/external];
D -->|Redirect to Provider| E[Identity Provider];
E -->|Authentication| F[/auth/callback/];
F -->|Authorization Code| A;
A -->|POST /token| G[Access Token + Refresh Token];
curl -X POST http://localhost:8080/token -u demo-client:demo-secret -d "grant_type=client_credentials"export CODE_VERIFIER=demo123
export CODE_CHALLENGE=demo123Visit:
http://localhost:8080/authorize?client_id=demo-client&redirect_uri=http://localhost:3000&response_type=code&code_challenge=$CODE_CHALLENGE&code_challenge_method=plain
Then exchange the code:
curl -X POST http://localhost:8080/token -d "grant_type=authorization_code" -d "code=xxx" -d "redirect_uri=http://localhost:3000" -d "code_verifier=$CODE_VERIFIER"curl -X POST http://localhost:8080/token -d "grant_type=refresh_token" -d "refresh_token=xxx" -d "client_id=demo-client" -d "client_secret=demo-secret"ZenAuth can be used in different modes depending on your needs.
In this mode, ZenAuth manages both user authentication and OAuth data in its own PostgreSQL database.
USER_PROVIDER_TYPE=default
ROLE_MANAGER_TYPE=default
ZenAuth manages OAuth data (clients, authorization codes, tokens) in its own database, but uses an external database for user authentication and roles.
DATABASE_URL=postgres://oauth_user:oauth_pass@localhost:5432/oauth?sslmode=disable
USER_PROVIDER_TYPE=sql
USER_PROVIDER_SQL_CONN=postgres://user:pass@external-db:5432/app_db?sslmode=disable
ROLE_MANAGER_TYPE=external
ROLE_MANAGER_EXTERNAL_CONN=postgres://user:pass@external-db:5432/app_db?sslmode=disable
Example configuration for using an existing database:
# Connection to an external database for users
USER_PROVIDER_TYPE=sql
USER_PROVIDER_SQL_CONN=postgres://postgres:password@192.168.1.10:5432/app_db?sslmode=disable
USER_PROVIDER_SQL_TABLE=users
USER_PROVIDER_SQL_ID_FIELD=uuid
USER_PROVIDER_SQL_USER_FIELD=username
USER_PROVIDER_SQL_PASS_FIELD=password
USER_PROVIDER_SQL_EMAIL_FIELD=email
# Connection to an external database for roles
ROLE_MANAGER_TYPE=external
ROLE_MANAGER_INCLUDE_IN_JWT=true
ROLE_MANAGER_EXTERNAL_CONN=postgres://postgres:password@192.168.1.10:5432/app_db?sslmode=disable
ROLE_MANAGER_ROLE_TABLE=roles
ROLE_MANAGER_GROUP_TABLE=groups
ZenAuth supports integration with popular identity providers to enable social login and enterprise authentication.
- Microsoft: Use Microsoft accounts for authentication.
- Google: Authenticate users with their Google accounts.
- GitHub: Allow users to sign in using their GitHub accounts.
External authentication providers can be configured via the admin console at /admin/ in the "Auth Providers" section.
For each provider, you will need:
- Provider Name (display name)
- Provider Type (microsoft, google, github)
- Client ID (from the provider's developer console)
- Client Secret (from the provider's developer console)
- Tenant ID (only for Microsoft, optional)
make up- Start the PostgreSQL containermake init-db- Initialize the database schemamake seed- Create a test usermake run- Start the ZenAuth servermake client- Start the test clientmake logs- Show PostgreSQL logsmake down- Stop all containers
MIT License
Contributions are welcome! Feel free to submit a Pull Request.
