Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Access control, roles, and permissions (RBAC + Policy/Ability) for Go APIs — maximum performance, flexibility, and decoupling.

NotificationsYou must be signed in to change notification settings

Casagrande-Lucas/go-acl

Repository files navigation

Descrição da imagem

Access control, roles, and permissions (RBAC + Policy/Ability) for Go APIs — maximum performance, flexibility, and decoupling.

Go Reference


Features

  • RBAC (Role-Based Access Control): Define roles, permissions, and users dynamically.
  • Policy/Ability Pattern: Advanced authorization logic for complex business requirements.
  • Fully Decoupled: Pure Go, zero framework dependencies. Compatible with any HTTP stack (Gin, Gorilla, Fiber, Echo, Chi, etc.).
  • Native Middlewares: Ready-to-use withnet/http, easily adaptable for any framework.
  • Extensible: Implement your own Store (in-memory, SQL, Redis, etc) and plug it in easily.

Installation

go get github.com/Casagrande-Lucas/go-acl

Overview

go-acl provides everything you need for robust, scalable, and reusable access control in any Go API—from monoliths to microservices.


Quick Start — Pure Go (net/http)

package mainimport ("net/http""github.com/Casagrande-Lucas/go-acl")funcmain() {store:=acl.NewMemoryStore()// Create roles and usersadminRole:=&acl.Role{Name:"admin",Permissions:map[string]struct{}{"user:create": {},"user:delete": {}}}store.AddRole(adminRole)user:=&acl.User{ID:"1",Roles: []*acl.Role{adminRole}}// Directly populate the user mapstore.Users()["1"]=userauthz:=acl.NewAuthorizer(store)// RBAC-protected routehttp.Handle("/admin",acl.RBACMiddleware(authz,"user:create",func(r*http.Request)*acl.User {id:=r.Header.Get("X-User-ID")u,_:=store.GetUser(id)returnu    })(http.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {w.Write([]byte("admin area"))    })))http.ListenAndServe(":8080",nil)}

Advanced Example — Policy/Ability

authz.RegisterPolicy("edit_post",func(user*acl.User,resourceany)bool {post,ok:=resource.(map[string]any)if!ok {returnfalse }returnpost["owner_id"]==user.ID})http.Handle("/post/edit",acl.PolicyMiddleware(authz,"edit_post",func(r*http.Request)*acl.User {id:=r.Header.Get("X-User-ID")u,_:=store.GetUser(id)returnu    },func(r*http.Request)any {// Simulated resource fetchreturnmap[string]any{"owner_id":r.Header.Get("X-User-ID")}    },)(http.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {w.Write([]byte("edit permitted"))})))

Using with Frameworks (Gin, Gorilla, etc)

go-acl is pure Go and hasno direct dependencies on any web framework.
To integrate with frameworks like Gin or Gorilla, simply create adapters in your application.

Example: RBAC Middleware for Gin

import ("github.com/gin-gonic/gin""github.com/Casagrande-Lucas/go-acl")funcRBACGinMiddleware(authz*acl.Authorizer,permstring,userFromContextfunc(*gin.Context)*acl.User) gin.HandlerFunc {returnfunc(c*gin.Context) {user:=userFromContext(c)ifuser==nil||!authz.HasPermission(user,perm) {c.AbortWithStatusJSON(403, gin.H{"error":"forbidden"})return        }c.Next()    }}// Usager:=gin.Default()r.GET("/admin",RBACGinMiddleware(authz,"user:create",func(c*gin.Context)*acl.User {id:=c.GetHeader("X-User-ID")u,_:=store.GetUser(id)returnu}),func(c*gin.Context) {c.JSON(200, gin.H{"status":"admin ok"})})

Example: Policy Middleware for Gin

funcPolicyGinMiddleware(authz*acl.Authorizer,actionstring,userFromContextfunc(*gin.Context)*acl.User,resourceFromContextfunc(*gin.Context)any) gin.HandlerFunc {returnfunc(c*gin.Context) {user:=userFromContext(c)resource:=resourceFromContext(c)ifuser==nil||!authz.Can(user,action,resource) {c.AbortWithStatusJSON(403, gin.H{"error":"forbidden"})return        }c.Next()    }}// Usage for editing a post (only owner can edit)r.PUT("/post/:id/edit",PolicyGinMiddleware(authz,"edit_post",func(c*gin.Context)*acl.User {id:=c.GetHeader("X-User-ID")u,_:=store.GetUser(id)returnu    },func(c*gin.Context)any {// Simulate resource loadreturnmap[string]any{"owner_id":c.GetHeader("X-User-ID")}    },),func(c*gin.Context) {c.JSON(200, gin.H{"status":"edit permitted"})})

Example: Using with Gorilla Mux

With Gorilla Mux, you can use the middleware as-is, since it follows the standardhttp.Handler interface:

import ("github.com/gorilla/mux""github.com/Casagrande-Lucas/go-acl""net/http")r:=mux.NewRouter()r.Handle("/admin",acl.RBACMiddleware(authz,"user:create",userFromRequest)(http.HandlerFunc(adminHandler),)).Methods("GET")

Note:
Middleware adapters for Gin, Echo, Fiber, etc.are not provided in the core library — this keeps the core decoupled, lightweight, and framework-agnostic.
Implement adapters in your application as needed.


Extending: Using Custom Stores (e.g., GORM/SQL)

You can implement your own Store (SQL, Redis, etc.) by following theStore interface:

typeStoreinterface {GetUser(userIDstring) (*User,error)GetRole(roleNamestring) (*Role,error)AddRole(role*Role)errorAssignRoleToUser(userID,roleNamestring)errorAddPermissionToRole(roleName,permNamestring)error}

Quick Example: Store with GORM

import ("gorm.io/gorm""github.com/Casagrande-Lucas/go-acl")// GORM ModelstypeUserstruct {IDstring`gorm:"primaryKey"`Roles []Role`gorm:"many2many:user_roles;"`}typeRolestruct {IDstring`gorm:"primaryKey"`NamestringPermissions []Permission`gorm:"many2many:role_permissions;"`}typePermissionstruct {IDstring`gorm:"primaryKey"`Namestring}// Implementation (minimal)typeGormStorestruct {db*gorm.DB }func (s*GormStore)GetUser(userIDstring) (*acl.User,error) {vardbUserUseriferr:=s.db.Preload("Roles.Permissions").First(&dbUser,"id = ?",userID).Error;err!=nil {returnnil,err    }roles:=make([]*acl.Role,0)for_,r:=rangedbUser.Roles {perms:=map[string]struct{}{}for_,p:=ranger.Permissions {perms[p.Name]=struct{}{}        }roles=append(roles,&acl.Role{Name:r.Name,Permissions:perms})    }return&acl.User{ID:dbUser.ID,Roles:roles},nil}

Usage with GORM (but works with PostgreSQL, MySQL, etc):

import"gorm.io/driver/sqlite"funcmain() {db,_:=gorm.Open(sqlite.Open("acl.db"),&gorm.Config{})db.AutoMigrate(&User{},&Role{},&Permission{})store:=&GormStore{db:db}authz:=acl.NewAuthorizer(store)// Use authz as in the other examples}

Testing

To run unit tests (with coverage):

gotest -cover ./...

To generate a coverage HTML report:

gotest -coverprofile=coverage.out ./...go tool cover -html=coverage.out

Roadmap

  • Native support for SQL/NoSQL stores
  • Official adapters for Gin, Echo, Fiber, and other frameworks
  • Auditing/logging hooks
  • Advanced documentation for policies and abilities
  • Multi-tenant support

Contributions

Contributions are welcome!
Please open an issue, submit a pull request, or share your feedback.


Contact

Questions, suggestions, or corporate proposals?
Contact LinkedInLucas Casagrande.

About

Access control, roles, and permissions (RBAC + Policy/Ability) for Go APIs — maximum performance, flexibility, and decoupling.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp