goRBAC provides a lightweight role-based access control implementation in Golang.
For the purposes of this package:
* an identity has one or more roles. * a role requests access to a permission. * a permission is given to a role. Thus, RBAC has the following model:
* many to many relationship between identities and roles. * many to many relationship between roles and permissions. * roles can have parent roles (inheriting permissions). The current version of goRBAC uses Go generics (Go 1.18+) and is under active development.
Install the package:
$ go get github.com/mikespook/gorbac/v3Although you can adjust the RBAC instance anytime and it's absolutely safe, the library is designed for use with two phases:
Preparing
Checking
Import the library:
import"github.com/mikespook/gorbac/v3"Get a new instance of RBAC (using string as the ID type):
rbac:=gorbac.New[string]()Get some new roles:
rA:=gorbac.NewRole("role-a") rB:=gorbac.NewRole("role-b") rC:=gorbac.NewRole("role-c") rD:=gorbac.NewRole("role-d") rE:=gorbac.NewRole("role-e")Get some new permissions:
pA:=gorbac.NewPermission("permission-a") pB:=gorbac.NewPermission("permission-b") pC:=gorbac.NewPermission("permission-c") pD:=gorbac.NewPermission("permission-d") pE:=gorbac.NewPermission("permission-e")Add the permissions to roles:
rA.Assign(pA) rB.Assign(pB) rC.Assign(pC) rD.Assign(pD) rE.Assign(pE)Also, you can implement gorbac.Permission for your own data structure.
After initialization, add the roles to the RBAC instance:
rbac.Add(rA) rbac.Add(rB) rbac.Add(rC) rbac.Add(rD) rbac.Add(rE)And set the inheritance:
rbac.SetParent("role-a", "role-b") rbac.SetParents("role-b", []string{"role-c", "role-d"}) rbac.SetParent("role-e", "role-d")Checking the permission is easy:
ifrbac.IsGranted("role-a", pA, nil) &&rbac.IsGranted("role-a", pB, nil) &&rbac.IsGranted("role-a", pC, nil) &&rbac.IsGranted("role-a", pD, nil){fmt.Println("The role-a has been granted permis-a, b, c and d.") }You can also use assertion functions for more fine-grained permission controls:
assertion:=func(rbac*gorbac.RBAC[string], idstring, p gorbac.Permission[string]) bool{// Custom logic to determine if permission should be grantedreturntrue// or false based on your logic } ifrbac.IsGranted("role-a", pA, assertion){fmt.Println("The role-a has been granted permission-a based on the assertion.") }goRBAC provides several built-in utility functions:
Detects circular inheritance in the role hierarchy:
rbac.SetParent("role-c", "role-a") iferr:=gorbac.InherCircle(rbac); err!=nil{fmt.Println("A circle inheritance occurred.") }Checks if any of the specified roles have a permission:
roles:= []string{"role-a", "role-b", "role-c"} ifgorbac.AnyGranted(rbac, roles, pA, nil){fmt.Println("At least one role has permission-a.") }Checks if all of the specified roles have a permission:
roles:= []string{"role-a", "role-b", "role-c"} ifgorbac.AllGranted(rbac, roles, pA, nil){fmt.Println("All roles have permission-a.") }Iterates through all roles in the RBAC instance:
handler:=func(r gorbac.Role[string], parents []string) error{fmt.Printf("Role: %s, Parents: %v\n", r.ID, parents) returnnil } gorbac.Walk(rbac, handler)goRBAC supports custom types for role and permission IDs through Go generics:
// Using integer IDsrbacInt:=gorbac.New[int]() role1:=gorbac.NewRole(1) permission1:=gorbac.NewPermission(100) // Using custom struct IDstypeRoleIDstruct{NamestringTypestring } rbacStruct:=gorbac.New[RoleID]() roleCustom:=gorbac.NewRole(RoleID{Name: "admin", Type: "system"}) permissionCustom:=gorbac.NewPermission(RoleID{Name: "read", Type: "data"})The most asked question is how to persist the goRBAC instance. Please check the post HOW TO PERSIST GORBAC INSTANCE for the details.
- Xing Xing [email protected]Blog@Twitter
See LICENSE.

