Description
RBAC is role based access control library. At core it uses sync.Map so, it can be used from multiple goroutines concurrently. "Keep it simple" is also in core. It supports role inheritance, persisting and loading. It can be used in middlewares with granular permissions.
RBAC alternatives and similar packages
Based on the "Authentication & OAuth" category.
Alternatively, view RBAC alternatives based on common mentions on social networks and blogs.
-
aws-doc-sdk-examples
Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. -
casbin
An authorization library that supports access control models like ACL, RBAC, ABAC in Golang -
jwt-go
ARCHIVE - Golang implementation of JSON Web Tokens (JWT). This project is now maintained at: -
goth
Package goth provides a simple, clean, and idiomatic way to write authentication packages for Go web applications. -
go-oauth2-server
A standalone, specification-compliant, OAuth2 server written in Golang. -
loginsrv
JWT login microservice with plugable backends such as OAuth2, Google, Github, htpasswd, osiam, .. -
gorbac
goRBAC provides a lightweight role-based access control (RBAC) implementation in Golang. -
permissions2
:closed_lock_with_key: Middleware for keeping track of users, login states and permissions -
jwt-auth
This package provides json web token (jwt) middleware for goLang http servers -
yubigo
Yubigo is a Yubikey client API library that provides an easy way to integrate the Yubico Yubikey into your existing Go-based user authentication infrastructure. -
sessions
A dead simple, highly performant, highly customizable sessions middleware for go http servers. -
Facecontrol
Simple authentication, single sign-on and (optinal) authorization solution.
Access the most powerful time series database as a service
Do you think we are missing an alternative of RBAC or a related project?
Popular Comparisons
README
RBAC - Simple, concurrent Role Based Access Control(GO)
RBAC is role based access control library for GOlang. At core uses sync.Map
so, it can be used from multiple goroutines concurrently. "Keep it simple" is also in core.
It supports role inheritance.
It can be used in middleware(example for echo framework is given )
Go 1.9+ is required.
It is built on;
Type | Description | Example |
---|---|---|
Action | Defines what can possible for a permission | Create ,Read ,Update ... |
Permission | Defines permission related to a resource to be accessed | users |
Role | Defines group of permissions with defined actions | admin |
Usage
Library usage has 2 phases:
- Development
- Runtime
Development Phase
First get an instance for RBAC
import "github.com/euroteltr/rbac"
R := rbac.New(nil)
// you can pass a logger to constructor also:
// R := rbac.New(rbac.ConsoleLogger)
During development you will register your permissions for your each resource with valid actions for that permission:
// You can also use rbac.CRUD for those crud actions
usersPerm, err := R.RegisterPermission("users", "User resource", rbac.Create, rbac.Read, rbac.Update, rbac.Delete)
if err != nil {
panic(err)
}
userPerm
is defined with CRUD actions, which means that any action not in that list will be invalid. You can define your own actions( like ApproveAction := rbac.Action("approve")
) and add them also.
Runtime Phase
At run time we define our roles and permit permissions to them.
adminRole, err := R.RegisterRole("admin", "Admin role")
if err != nil {
fmt.Printf("can not add admin role, err: %v\n", err)
}
if err = R.Permit(adminRole.ID, usersPerm, rbac.CRUD, ApproveAction); err != nil {
fmt.Errorf("can not permit crud and ApproveAction actions to role %s\n", adminRole.ID)
}
Now we can check if a role is granted some permission:
if !R.IsGranted(adminRole.ID, usersPerm, rbac.Write) {
fmt.Printf("admin role does not have write grant on users\n")
}else{
fmt.Printf("admin role does have write grant on users\n")
}
// You can also check by perm.ID also
if !R.IsGrantedStr("admin", "users", rbac.CRUD) {
fmt.Printf("admin role does not have CRUD grants on users\n")
}else{
fmt.Printf("admin role does have CRUD grants on users\n")
}
Persisting and Loading
rbac.RBAC
is json
compatible. You can dump all data in RBAC
instance to JSON:
b, err := json.Marshal(R)
if err != nil {
fmt.Printf("rback marshall failed with %v\n", err)
}else{
fmt.Printf("RBAC: %s", b)
}
Also you can use builtin SaveJSON
function to save to a io.Writer
:
filename := "/tmp/rbac.json"
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Printf("can not create json file %s, err: %v\n", filename, err)
return err
}
defer f.Close()
if err = R.SaveJSON(f); err != nil {
fmt.Printf("unable to save to json file, err:%v\n", err)
}
And load it from file:
filename := "/tmp/rbac.json"
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
if err = R.LoadJSON(f); err != nil {
fmt.Errorf("unable to load from json file, err:%v\n", err)
}
In dumped JSON root permissions
part is just for reference. Root roles
is the part you can modify in file and reload it to define Role
s with Permission
s.
{
"permissions": [
{
"id": "users",
"description": "User resource",
"actions": [
"create",
"read",
"update",
"delete"
]
}
],
"roles": [
{
"id": "admin",
"description": "Admin role",
"grants": {
"users": [
"create",
"read",
"update",
"delete"
]
},
"parents": []
}
]
}
Role inheritance
A Role
can have parent Role
s. You can add a parent Role
like this:
// Add a new role
sysAdmRole, err := R.RegisterRole("sysadm", "System admin role")
if err != nil {
fmt.Printf("can not add agent role, err: %v\n", err)
}
// Now add adminRole as parent
if err = sysAdmRole.AddParent(adminRole); err != nil {
fmt.Printf("adding parent role failed with: %v\n", err)
}
// Now all permissions in adminRole will be also valid for sysAdmRole
if R.IsGranted(sysAdmRole.ID, usersPerm, rbac.CRUD) {
fmt.Printf("sysadmin role has all crud actions granted\n")
}
If circular parent reference is found, you'll get error while running AddParent
.
Usage as middleware
You can check example middleware function for [echo](github.com/labstack/echo) framework here
Middleware usage with granular permissions
If you want user
role may modify his own user resource, but not others, you can build a wrapper for RBAC.IsGranted
function like(example for echo
framework:
// idParam is the parameter name where user_id for data will be gotten
func isGrantedResource(perm *rbac.Permission, action rbac.Action, idParam string) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
rolesI := c.Get("roles")
if rolesI == nil {
log.Errorf("No rbac roles key %s", "roles")
} else if config.RBAC.AnyGranted(rolesI.([]string), perm, actions...) {
// Get id parameter from route,form... example from: "user/:id"
userID, err := strconv.ParseInt(c.Param(idParam), 10, 64)
if err != nil {
return http.StatusBadRequest
}
// Get current user_id and check if data belongs to current user
userIDI := c.Get("user_id")
if userIDI==nil || userIDI.(int64) != userID {
return http.StatusForbidden
}
return next(c)
}
return echo.ErrUnauthorized
}
}
}
*Note that all licence references and agreements mentioned in the RBAC README section above
are relevant to that project's source code only.