A robust Role-Based Access Control (RBAC) service built with Go, providing comprehensive user, group, member, and role management with fine-grained permissions.
- 🔐 JWT Authentication: Secure token-based authentication with HS256
- 🛡️ Casbin RBAC: Flexible policy-based authorization
- 👥 User Management: Complete CRUD operations for user accounts
- 📦 Group Management: Organize users into logical groups
- 👤 Member Management: Control group membership and relationships
- 🎭 Role Management: Define and assign fine-grained permissions
- ⚡ Redis Caching: High-performance caching with token denylist
- 🗄️ MySQL/TiDB: Reliable persistent data storage
- 🌐 Multi-tier API: Public, Internal, and Private endpoints
- 📱 CLI Clients: Admin, App, and Anonymous command-line interfaces
- Go 1.25.5 or higher
- MySQL 8.0+ or TiDB
- Redis 6.0+
- Docker & Docker Compose (optional)
# Clone the repository
git clone https://github.com/ryo-arima/locky.git
cd locky
# Start dependencies with Docker Compose
docker compose up -d
# Copy configuration
cp etc/app.dev.yaml etc/app.yaml
# Build the server
go build -o .bin/locky-server ./cmd/server/main.go
# Start the server
./.bin/locky-serverThe server will start on http://localhost:8080.
# Register a user
curl -X POST http://localhost:8080/v1/public/user \
-H "Content-Type: application/json" \
-d '{"name":"Test User","email":"[email protected]","password":"password123"}'
# Login
curl -X POST http://localhost:8080/v1/public/token \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"password123"}'
# Use the JWT token from the response for authenticated requestsLocky follows a clean, layered architecture:
┌─────────────────────────────────────────────────────────────┐
│ Client Layer │
│ (Admin CLI, App CLI, Anonymous CLI) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ API Layer │
│ (Gin Router, JWT Auth, Casbin RBAC, Logger) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Controller Layer │
│ (Public, Internal, Private Controllers) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Business Logic Layer │
│ (User, Group, Member, Role Usecases) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Repository Layer │
│ (User, Group, Member, Role Repositories) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Data Layer │
│ (MySQL/TiDB, Redis, Casbin Policies) │
└─────────────────────────────────────────────────────────────┘
View detailed architecture diagram →
Comprehensive documentation is available at https://ryo-arima.github.io/locky/
- Getting Started - Installation and setup
- Architecture - System design and components
- API Reference - REST API documentation
- Configuration - Configuration guide
- Swagger UI - Interactive API documentation
- GoDoc - Go package documentation
POST /v1/public/user- Register a new userPOST /v1/public/token- Authenticate and get JWT tokenGET /health- Health check
POST /v1/share/token/refresh- Refresh JWT tokenDELETE /v1/share/token- Logout and invalidate tokenGET /v1/share/token/validate- Validate JWT tokenGET /v1/share/token/user- Get user info from token
GET /v1/internal/users- List usersGET /v1/internal/groups- List groupsGET /v1/internal/members- List membersGET /v1/internal/roles- List rolesGET /v1/internal/resources- List resources
PUT /v1/private/user/{id}- Update userDELETE /v1/private/user/{id}- Delete userPOST /v1/private/group- Create groupPOST /v1/private/role- Create rolePOST /v1/private/resource- Create resource
Create etc/app.yaml from the template:
cp etc/app.yaml.example etc/app.yamlEdit the configuration with your settings:
Server:
host: "0.0.0.0"
port: 8080
jwt_secret: "your-secure-secret-256-bits"
Redis:
JWTCache: true # Enable JWT token caching
CacheTTL: 3600 # Cache TTL in seconds
MySQL:
host: "localhost"
user: "locky"
pass: "password"
db: "locky"
Redis:
host: "localhost"
port: 6379
db: 0
Casbin:
app_model: "etc/casbin/locky/model.conf"
app_policy: "etc/casbin/locky/policy.csv"# Build all binaries
make build
# Or build individually
go build -o .bin/locky-server ./cmd/server/main.go
go build -o .bin/locky-client-admin ./cmd/client/admin/main.go
go build -o .bin/locky-client-app ./cmd/client/app/main.go
go build -o .bin/locky-client-anonymous ./cmd/client/anonymous/main.go# Run tests
make test
# Run with coverage
go test -v -cover ./...E2E tests verify the entire system including server, database, Redis, and CLI clients.
Prerequisites:
- Docker & Docker Compose
- Go 1.25.5+
Platform Configuration:
For Apple Silicon (M1/M2/M3) Macs:
# Create .env.local (ignored by git)
echo "DOCKER_PLATFORM=linux/arm64" > .env.localFor Intel Macs and Linux x86_64:
# Create .env.local (ignored by git)
echo "DOCKER_PLATFORM=linux/amd64" > .env.localRun E2E Tests:
# 1. Start dependencies (MySQL and Redis)
docker compose up -d mysql redis
# 2. Wait for services to be ready (about 10 seconds)
sleep 10
# 3. Build CLI binaries
mkdir -p bin
go build -o bin/locky-admin ./cmd/client/admin
go build -o bin/locky-app ./cmd/client/app
go build -o bin/locky-anonymous ./cmd/client/anonymous
# 4. Run E2E tests
go test -v -timeout 15m ./test/e2e/testcase/
# 5. Cleanup
docker compose down -vTest Coverage:
- ✅ Anonymous User Registration
- ⏭️ Authentication Flow (Login, Token validation, Refresh, Logout) - Endpoints need implementation
- ⏭️ App User Group CRUD - Requires authentication implementation
- ⏭️ User/Role Read Operations - Requires authentication implementation
- ⏭️ Admin operations - Requires admin role assignment
Note: Most E2E tests are currently skipped pending full authentication and authorization implementation.
GitHub Actions:
E2E tests run automatically on pull requests and pushes to dev branch using linux/amd64 platform.
An internal mail sandbox (Postfix/Dovecot via docker-mailserver + dnsmasq + Roundcube) can be fully recreated for browser‑based tests. All data is ephemeral.
# Full teardown & rebuild (containers, network, volumes) + account provisioning
./scripts/main.sh env recreate
# Access Roundcube (webmail)
open http://localhost:3005 # or manually open in browser
# Example login
# user: [email protected]
# pass: TestPassword123!Send a test message from test1 to test2 and verify it appears in test2's inbox after switching accounts. Logs:
# Postfix / Dovecot logs (mailserver container)
docker compose logs -f mailserverTo iterate after config changes always use force recreate:
docker compose up -d --force-recreate mailserver roundcubeIf authentication fails, rerun the full recreate script to ensure accounts are re-applied cleanly.
# Build documentation
./scripts/main.sh docs build
# Serve documentation locally
cd docs/dist && python3 -m http.server 8000To make your package available on pkg.go.dev, you have two options:
Manual trigger:
- Go to Actions tab in GitHub
- Select "Create Release Tag" workflow
- Click "Run workflow"
- Enter version (e.g.,
v0.1.0) - Add release notes (optional)
- Click "Run workflow"
Automatic trigger:
- Update the
VERSIONfile with new version (e.g.,0.2.0) - Commit and push to main branch
- GitHub Actions will automatically create the tag
# Publish with default version (v0.1.0)
./scripts/publish-to-pkggodev.sh
# Or specify a version
./scripts/publish-to-pkggodev.sh v0.2.0After publishing (either method), your package will be available at:
- https://pkg.go.dev/github.com/ryo-arima/locky
- https://pkg.go.dev/github.com/ryo-arima/locky/pkg/server
- https://pkg.go.dev/github.com/ryo-arima/locky/pkg/client
Note: It may take 5-10 minutes for pkg.go.dev to index the package after tag creation.
Administrative operations with elevated privileges:
./.bin/locky-client-admin --helpApplication-level operations for authenticated users:
./.bin/locky-client-app --helpPublic operations without authentication:
./.bin/locky-client-anonymous --helplocky/
├── cmd/ # Command-line applications
│ ├── server/ # HTTP server
│ └── client/ # CLI clients (admin, app, anonymous)
├── pkg/ # Shared packages
│ ├── server/ # Server implementation
│ │ ├── controller/ # HTTP handlers
│ │ ├── middleware/ # Middleware components
│ │ └── repository/ # Data access layer
│ ├── client/ # Client implementation
│ ├── config/ # Configuration management
│ └── entity/ # Data models and DTOs
├── etc/ # Configuration files
│ ├── casbin/ # Casbin policy files
│ └── app.yaml.example # Configuration template
├── docs/ # Documentation
│ ├── books/ # mdBook source
│ ├── dist/ # Built documentation (GitHub Pages)
│ ├── architecture/ # Architecture diagrams
│ └── swagger/ # OpenAPI specification
├── scripts/ # Build and utility scripts
└── test/ # Test files
- Language: Go 1.25.5+
- Web Framework: Gin
- ORM: GORM
- Authentication: JWT with golang-jwt
- Authorization: Casbin (Group-based RBAC)
- Database: MySQL 8.0+ / TiDB
- Cache: Redis 6.0+ (JWT token caching, session management)
- Documentation: mdBook, Swagger/OpenAPI
Contributions are welcome! Please read our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
End-to-end tests are located in test/e2e/testcase/ and test the complete application stack.
1. Start required services (MySQL and Redis only):
# For ARM64 (Mac M1/M2/M3, etc.)
docker compose up -d mysql redis
# For AMD64 (GitHub Actions, x86_64 Linux, etc.)
DOCKER_PLATFORM=linux/amd64 docker compose up -d mysql redis2. Build CLI binaries:
make build3. Run E2E tests:
# Run all E2E tests
go test -v ./test/e2e/testcase/
# Run specific test
go test -v ./test/e2e/testcase/ -run TestAuthenticationFlow4. Stop services:
docker compose downCurrently implemented E2E tests:
- ✅ TestMain - Test environment initialization
- ⏭️ All other tests - Pending authentication and authorization implementation
Note: E2E test implementation is in progress. Most test cases are currently disabled pending full system integration.
E2E tests run automatically on GitHub Actions for every pull request and push to main branch. See .github/workflows/e2e-test.yml for details.
- Documentation: https://ryo-arima.github.io/locky/
- API Documentation: https://ryo-arima.github.io/locky/swagger/index.html
- GoDoc: https://ryo-arima.github.io/locky/godoc/index.html (or pkg.go.dev when published)
- Issue Tracker: https://github.com/ryo-arima/locky/issues
- Discussions: https://github.com/ryo-arima/locky/discussions
Made with ❤️ by Ryo ARIMA