Skip to content

go-rbac is a lightweight and scalable library for implementing Role-Scope Based Access Control (RBAC) in Go applications. It provides an intuitive and flexible way to define roles, permissions, and access scopes to secure your APIs and application resources.

License

Notifications You must be signed in to change notification settings

DoWithLogic/go-rbac

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Go-RBAC: Role and Scope Based Access Control Implementation

This repository demonstrates how to implement Role and Scope-Based Access Control (RBAC) in a Go application using Redis, MySQL, and the Echo framework.

rbac


Features πŸš€

  • 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.

Prerequisites πŸ“‹

  • Go: Version 1.21 or higher
  • MySQL: For storing user data
  • Redis: For caching role and scope data
  • Docker: For containerization (optional)

Project Structure πŸ“‚

β”œβ”€β”€ 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

Endpoints and Access Requirements 🌐

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.

Installation & Setup πŸ› οΈ

Clone the Repository

git clone https://github.com/DoWithLogic/go-rbac.git
cd go-rbac

Run the Application

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

Example Implementation πŸ§‘β€πŸ’»

Middleware for Role Validation

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
}

Middleware for Scope Validation

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
}

Assign Middleware to Endpoints

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))
}

Configuration βš™οΈ

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

API Documentation πŸ“‘

Overview

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.

Explore Swagger Documentation

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.

License πŸ“„

This project is licensed under the MIT License. See the LICENSE file for details.

Contributing 🀝

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!

About

go-rbac is a lightweight and scalable library for implementing Role-Scope Based Access Control (RBAC) in Go applications. It provides an intuitive and flexible way to define roles, permissions, and access scopes to secure your APIs and application resources.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published