This repository demonstrates how to implement Role and Scope-Based Access Control (RBAC) in a Go application using Redis, MySQL, and the Echo framework.
- Role-Based Access Control: Restricts access to resources based on user roles (e.g., Admin, Employee, Customer).
- Scope-Based Permissions: Adds granular permissions for specific operations (e.g.,
users:read
,users:create
). - Redis Integration: Caches user roles, scopes and blacklisted access.
- MySQL Integration: Stores user and role data persistently.
- Secure Authentication: Includes endpoints for user registration and login.
- Go: Version 1.21 or higher
- MySQL: For storing user data
- Redis: For caching role and scope data
- Docker: For containerization (optional)
βββ cmd
β βββ main.go # Application entry point
βββ config
β βββ config.go # Configuration loader and management logic
β βββ config.yaml # Configuration file for environment variables and application settings
βββ internal
β βββ {sub_domain} # Grouped by subdomains or modules
β β βββ usecase # Application-specific business logic
β β β βββ usecase.go # Implementation of use cases for the subdomain
β β βββ entities # Core domain entities
β β β βββ entity.go # Definitions of core domain entities
β β βββ dtos # Data Transfer Objects for request/response payloads
β β β βββ dtos.go # DTO definitions for input/output operations
β β βββ repository # Persistence and database layer
β β β βββ repository.go # Implementation of repository interfaces
β β βββ delivery # Delivery layer (e.g., HTTP handlers, routes)
β β β βββ handlers.go # Request/response handlers for the subdomain
β β β βββ routes.go # Route definitions for the subdomain
β β βββ usecase.go # Interface for the use case layer
β β βββ repository.go # Interface for the repository layer
β β βββ delivery.go # Interface for the delivery layer
βββ middleware # Custom middleware (e.g., RBAC, logging, authentication)
βββ pkg # Shared libraries or utility functions
β βββ redis # Utilities for Redis interactions
β βββ constants # Application-wide constants and enumerations
β βββ utils # General utility functions and helpers
β βββ datasources # Data source configuration and initialization (e.g., MySQL, Redis)
β βββ rbac # Role-based access control utilities and logic
βββ migrations # Database migration files
βββ infrastructure # Infrastructure setup and configurations
β βββ docker-compose.yml # Docker Compose configuration for service orchestration
βββ docs # Documentation (e.g., API specifications, design documents)
βββ tests # Testing suite for various layers
β βββ e2e # End-to-end tests
β βββ unit # Unit tests
β βββ integration # Integration tests
βββ README.md # Project documentation
βββ Makefile # Build and automation instructions for the project
Endpoint | HTTP Method | Scope | Roles with Access | Description |
---|---|---|---|---|
/users |
GET |
users:read |
Admin , Employee |
Retrieve the list of users. |
/users/:id |
PUT |
users:update |
Admin , Employee |
Update user details. |
/users |
POST |
users:create |
Admin |
Create a new user. |
/users/:id |
DELETE |
users:delete |
Admin |
Delete a user. |
/profile |
GET |
profile:read |
Customer , Employee |
Retrieve the authenticated user's profile. |
/profile |
PUT |
profile:update |
Customer , Employee |
Update the authenticated user's profile. |
git clone https://github.com/DoWithLogic/go-rbac.git
cd go-rbac
The make run command will:
- Start the Docker containers for Redis and the database (if not already running).
- Apply any pending database migrations.
- Start the application.
make run
func (m *Middleware) RolesMiddleware(roles ...constants.UserRole) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
jwtData, ok := c.Get(constants.AuthCredentialContextKey.String()).(*security.JWTClaims)
if !ok {
return response.ErrorBuilder(app_errors.Forbidden(app_errors.ErrAccessDenied)).Send(c)
}
if !m.hasRequiredRole(jwtData.Role, roles) {
return response.ErrorBuilder(app_errors.Forbidden(app_errors.ErrAccessDenied)).Send(c)
}
// Store the token claims in the request context for later use
c.Set(constants.AuthCredentialContextKey.String(), jwtData)
return next(c)
}
}
}
func (m *Middleware) hasRequiredRole(userRole constants.UserRole, roles []constants.UserRole) bool {
for _, r := range roles {
if r == userRole {
return true
}
}
return false
}
func (m *Middleware) PermissionsMiddleware(permissions ...constants.Permission) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
jwtData, ok := c.Get(constants.AuthCredentialContextKey.String()).(*security.JWTClaims)
if !ok {
return response.ErrorBuilder(app_errors.Forbidden(app_errors.ErrAccessDenied)).Send(c)
}
if !m.hasRequiredPermission(jwtData.Permissions, permissions) {
return response.ErrorBuilder(app_errors.Forbidden(app_errors.ErrAccessDenied)).Send(c)
}
c.Set(constants.AuthCredentialContextKey.String(), jwtData)
return next(c)
}
}
}
func (m *Middleware) hasRequiredPermission(userPermissions, requiredPermissions []constants.Permission) bool {
requiredPermissionsMap := make(map[constants.Permission]bool)
for _, permission := range requiredPermissions {
requiredPermissionsMap[permission] = true
}
for _, permission := range userPermissions {
if requiredPermissionsMap[permission] {
return true
}
}
return false
}
func MapUserRoutes(g echo.Group, h users.Handlers, mw *middlewares.Middleware) {
users := g.Group("/users", mw.JWTMiddleware())
users.POST("", h.CreateUserHandler, mw.RolesMiddleware(constants.AdminUserRole), mw.PermissionsMiddleware(constants.UsersCreatePermission))
}
App:
Name: "go-rbac"
Version: "0.0.1"
Scheme: "http"
Host: "localhost:3002"
Environment: local #local,development,staging,production
Server:
Port: "3002"
Debug: true
TimeZone: "Asia/Jakarta"
Database:
Host: "127.0.0.1"
Port: "3306"
DBName: "go_rbac"
UserName: "root"
Password: "pwd"
Debug: true
Security:
JWT:
Key: "95476ff7-c7b2-49d7-853e-322b6f983914"
ExpiredInSecond: 3600
This repository provides a set of API endpoints for managing roles, permissions, and user access. The API allows you to create, update, retrieve, and delete roles, permissions, and role-permission mappings. It also supports secure JWT-based authentication to enforce role-based access control.
For a detailed description of all the available API endpoints, request/response formats, and examples, explore our Swagger documentation at the following link:
The Swagger documentation will provide detailed information on:
- Available Endpoints: All API routes for managing users, roles, permissions, and access control.
- Request/Response Formats: Detailed format for the expected input and output of each API endpoint.
- Authentication: How to authenticate requests using JWT tokens.
- Role and Permission Validation: How roles and permissions are validated for each endpoint.
This project is licensed under the MIT License. See the LICENSE file for details.
Feel free to submit pull requests or open issues to improve this project. Contributions are always welcome!
This `README.md` file includes the project overview, structure, setup instructions, endpoint details, and example implementations. Let me know if you'd like to add or modify any sections!