A free & production-ready Single Sign-On (SSO) authentication service built with Go, featuring multiple authentication methods, role-based access control, and comprehensive security features.
- Email/Password Authentication - Traditional username/password login
- OAuth 2.0 Social Login - Google and GitHub integration
- OTP (One-Time Password) - Email-based passwordless authentication
- JWT Token Management - Access and refresh token system with automatic rotation
- End-to-End Encryption - AES-256-GCM encryption for sensitive user data (email, phone, fullname)
- Password Hashing - Bcrypt with cost factor 12
- SHA-256 Hashing - For searchable encrypted fields
- Cookie Encryption - Encrypted HTTP-only cookies for token storage
- Rate Limiting - Global (60 req/min) and endpoint-specific limits
- CORS Protection - Configurable cross-origin resource sharing
- Account Lockout - Failed login attempt tracking and temporary lockouts
- Role-Based Access Control (RBAC) - Flexible role management system
- Built-in Roles - Public, Admin, and SuperAdmin roles
- API Key Authentication - Internal and external API key support
- Middleware Protection - JWT, Role, Internal, and External key middleware
- Application Management - Support for multiple applications
- API Key Management - Per-application API keys with scoped access
- User-App Association - Link users to specific applications
- Comprehensive Audit Logs - Track all user actions (login, create, update, delete, assign, restore)
- Axiom Integration - Structured logging with Axiom for observability
- Request Logging - Detailed HTTP request/response logging with Zerolog
- Health Monitoring - Built-in health check endpoint with Fiber monitor
- Hot Reload - Air for automatic server restart during development
- Type-Safe Database Queries - SQLC for compile-time SQL verification
- Database Migrations - golang-migrate for version-controlled schema changes
- Clean Architecture - Organized codebase with separation of concerns
- Validation - go-playground/validator for request validation
- Go 1.24.0 or higher
- PostgreSQL 12 or higher
- Redis 6 or higher
- golang-migrate CLI tool (for migrations)
- sqlc (optional, for regenerating queries)
git clone <repository-url>
cd sso_be_v1go mod downloadCreate a .env file in the root directory with the following variables:
# Server Configuration
PORT=8181
ENV_PROD=false
APP_DOMAIN=localhost
CLIENT_DOMAIN=http://localhost:3000
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/sso_db?sslmode=disable
# Redis
REDIS_HOST=localhost:6379
REDIS_PASSWORD=
REDIS_DB=0
# Encryption Keys (must be 32 bytes base64 encoded)
ENC_KEY=<your-32-byte-base64-key>
COOKIE_ENC_KEY=<your-32-byte-base64-key>
# JWT Configuration
JWT_SECRET=<your-jwt-secret>
JWT_EXPIRY=15 # minutes
JWT_REFRESH_EXPIRY=4320 # minutes (3 days)
# API Keys
INTERNAL_KEY=<your-internal-key>
# Google OAuth
G_CLIENT_ID=<your-google-client-id>
G_CLIENT_SECRET=<your-google-client-secret>
G_CLIENT_REDIRECT=http://localhost:8181/api/v1/auth/social/google/callback
# GitHub OAuth
GTH_CLIENT_ID=<your-github-client-id>
GTH_CLIENT_SECRET=<your-github-client-secret>
GTH_CLIENT_REDIRECT=http://localhost:8181/api/v1/auth/social/github/callback
# Email/OTP Configuration (Brevo)
BREVO_API_KEY=<your-brevo-api-key>
OTP_SENDER_NAME=Hubku
OTP_SENDER_EMAIL=noreply@hubku.com
OTP_SENDER_SUBJECT=Your Hubku OTP Code
# Axiom Logging
AXIOM_TOKEN=<your-axiom-token>
AXIOM_DATASET=<your-axiom-dataset># Generate 32-byte base64 keys for ENC_KEY and COOKIE_ENC_KEY
openssl rand -base64 32# Apply all migrations
./scripts/migrate.sh up
# Or manually with migrate CLI
migrate -database "${DATABASE_URL}" -path internal/database/migrations upDevelopment mode with hot reload:
airProduction mode:
go build -o bin/server ./cmd/server
./bin/serverThe server will start on http://localhost:8181 (or your configured PORT).
sso_be_v1/
βββ cmd/
β βββ server/
β βββ main.go # Application entry point
βββ internal/
β βββ controllers/ # HTTP request handlers
β β βββ auth.go # Authentication endpoints
β β βββ users.go # User management
β β βββ user_roles.go # Role management
β β βββ apps.go # Application management
β β βββ keys.go # API key management
β β βββ logs.go # Audit log endpoints
β βββ database/
β β βββ migrations/ # SQL migration files
β β βββ queries/ # SQLC query definitions
β β βββ generated/ # SQLC generated code
β β βββ postgres.go # PostgreSQL connection
β β βββ redis.go # Redis connection
β βββ modules/ # Business logic layer
β β βββ auth/ # Authentication service
β β βββ users/ # User service & repository
β β βββ user_roles/ # Role service & repository
β β βββ apps/ # Application service & repository
β β βββ keys/ # API key service & repository
β β βββ auditlogs/ # Audit logging service
β β βββ mails/ # Email service (Brevo)
β β βββ redis/ # Redis service
β βββ routes/
β βββ index.go # Route definitions & middleware
βββ pkg/
β βββ common.go # Utility functions
β βββ type.go # Shared types & constants
βββ scripts/
β βββ migrate.sh # Migration helper script
βββ .air.toml # Air configuration
βββ sqlc.yaml # SQLC configuration
βββ go.mod # Go module dependencies
βββ README.md
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /login |
Email/password login | No |
| POST | /refresh |
Refresh access token | No (refresh token) |
| GET | /session |
Get current session | JWT |
| POST | /otp |
Send OTP to email | No (rate limited) |
| POST | /otp/verify |
Verify OTP code | No |
| GET | /social/google |
Google OAuth redirect | No |
| GET | /social/google/callback |
Google OAuth callback | No |
| GET | /social/github |
GitHub OAuth redirect | No |
| GET | /social/github/callback |
GitHub OAuth callback | No |
Routes for external applications using API keys.
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /auth/refresh |
Refresh token (external) | External Key + JWT |
| GET | /auth/session |
Get session (external) | External Key + JWT |
| GET | /users/me |
Get current user | External Key + JWT |
| POST | /users/list |
Get users in bulk | External Key |
| GET | /users/:id |
Get user by ID | External Key |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /me |
Get current user | Internal Key + JWT |
| PATCH | /me |
Update current user | Internal Key + JWT |
| GET | /list |
List all users | Internal Key + JWT + Admin |
| POST | /create |
Create new user | Internal Key + JWT + Admin |
| GET | /search |
Search users | Internal Key + JWT + Admin |
| GET | /:id |
Get user by ID | Internal Key + JWT + Admin |
| PATCH | /:id |
Update user | Internal Key + JWT + Admin |
| DELETE | /:id |
Soft delete user | Internal Key + JWT + Admin |
| POST | /restore/:id |
Restore deleted user | Internal Key + JWT + Admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /list |
List all roles | Internal Key + JWT + Admin |
| POST | /create |
Create new role | Internal Key + JWT + Admin |
| POST | /assign/:id |
Assign role to user | Internal Key + JWT + Admin |
| GET | /id/:id |
Get role by ID | Internal Key + JWT + Admin |
| GET | /name/:name |
Get role by name | Internal Key + JWT + Admin |
| PUT | /:id |
Update role | Internal Key + JWT + Admin |
| DELETE | /:id |
Delete role | Internal Key + JWT + Admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /list |
List all apps | Internal Key + JWT + Admin |
| POST | /create |
Create new app | Internal Key + JWT + Admin |
| GET | /:id |
Get app by ID | Internal Key + JWT + Admin |
| PATCH | /:id |
Update app | Internal Key + JWT + Admin |
| DELETE | /:id |
Delete app | Internal Key + JWT + Admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /list |
List all keys | Internal Key + JWT + Admin |
| POST | /create |
Create new key | Internal Key + JWT + Admin |
| GET | /:id |
Get key by ID | Internal Key + JWT + Admin |
| DELETE | /:id |
Delete key | Internal Key + JWT + Admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /list |
List audit logs | Internal Key + JWT + Admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /health |
Server health & metrics | No |
POST /api/v1/auth/login
{
"username": "user@example.com",
"password": "securepassword"
}
Response: Sets HTTP-only cookies (__hk_asid, __hk_rsid)
1. GET /api/v1/auth/social/google?redirect=<frontend-url>
2. User authenticates with Google
3. Callback to /api/v1/auth/social/google/callback
4. Sets cookies and redirects to frontend
1. POST /api/v1/auth/otp { "email": "user@example.com" }
2. User receives OTP via email
3. POST /api/v1/auth/otp/verify { "email": "user@example.com", "otp": "123456" }
4. Sets cookies on success
POST /api/v1/auth/refresh
(Automatically uses refresh token from cookie)
Response: New access token set in cookie
- Sensitive fields (email, phone, fullname) are encrypted with AES-256-GCM before storage
- Hash fields (email_hash, phone_hash, fullname_hash) enable searching without decryption
- Encryption keys must be 32 bytes and base64 encoded
- Bcrypt hashing with cost factor 12
- Password change tracking with
password_changed_at - Failed login attempt tracking
- Account lockout after multiple failed attempts
- Short-lived access tokens (15 minutes default)
- Long-lived refresh tokens (3 days default)
- HTTP-only cookies prevent XSS attacks
- Secure flag enabled in production
- SameSite=Lax for CSRF protection
- Separate internal and external keys
- Per-application API keys
- Key-based rate limiting
airCreate a new migration:
./scripts/migrate.sh create migration_nameApply migrations:
./scripts/migrate.sh upRollback one migration:
./scripts/migrate.sh downForce migration version:
./scripts/migrate.sh force <version>sqlc generate- users - User accounts with encrypted PII
- roles - Role definitions
- apps - Application registry
- keys - API keys for applications
- audit_logs - Comprehensive audit trail
- Users belong to a role (many-to-one)
- Users can be associated with an app (many-to-one)
- Keys belong to an app (many-to-one)
| Variable | Description | Required |
|---|---|---|
| PORT | Server port | No (default: 8181) |
| ENV_PROD | Production mode flag | Yes |
| DATABASE_URL | PostgreSQL connection string | Yes |
| REDIS_HOST | Redis host:port | Yes |
| ENC_KEY | 32-byte encryption key (base64) | Yes |
| COOKIE_ENC_KEY | Cookie encryption key (base64) | Yes |
| JWT_SECRET | JWT signing secret | Yes |
| JWT_EXPIRY | Access token expiry (minutes) | Yes |
| JWT_REFRESH_EXPIRY | Refresh token expiry (minutes) | Yes |
| INTERNAL_KEY | Internal API key | Yes |
| G_CLIENT_ID | Google OAuth client ID | No |
| G_CLIENT_SECRET | Google OAuth client secret | No |
| GTH_CLIENT_ID | GitHub OAuth client ID | No |
| GTH_CLIENT_SECRET | GitHub OAuth client secret | No |
| BREVO_API_KEY | Brevo email API key | No |
| AXIOM_TOKEN | Axiom logging token | No |
- Set
ENV_PROD=true - Use strong, unique encryption keys
- Configure CORS with specific origins
- Set up PostgreSQL with SSL
- Configure Redis with authentication
- Set up Axiom for centralized logging
- Configure reverse proxy (Nginx/Caddy)
- Enable HTTPS with valid certificates
- Set up database backups
- Configure monitoring and alerts
go build -o bin/server -ldflags="-s -w" ./cmd/server- Fiber v2 - Fast HTTP web framework
- pgx/v5 - PostgreSQL driver and toolkit
- Redis - Caching and session storage
- golang-jwt/jwt - JWT token handling
- golang.org/x/crypto - Bcrypt password hashing
- golang.org/x/oauth2 - OAuth 2.0 client
- Viper - Configuration management
- Zerolog - Structured logging
- go-playground/validator - Request validation
- SQLC - Type-safe SQL code generation
- Axiom - Observability and logging
- Brevo - Transactional email service
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Mobile endpoints
- Dashboard and complete web UI
- GRPC endpoints
