This document provides a comprehensive guide to the goRBAC (Role-Based Access Control) package for LLM coders who need to understand and work with this Go library without going through the entire codebase.
goRBAC is a lightweight role-based access control implementation in Golang. It provides a simple and efficient way to manage roles, permissions, and their relationships in applications that require access control.
- Identity: An entity that has one or more roles.
- Role: A named entity that can be assigned permissions and can inherit from parent roles.
- Permission: An entity that represents an action or resource access right.
- Inheritance: Roles can inherit permissions from parent roles, forming a hierarchical structure.
- Generic support for different ID types (string, int, etc.)
- Role inheritance with circular dependency detection
- Thread-safe operations
- JSON serialization support
- Extensible interfaces for custom implementations
- Built-in utility functions for common operations
gorbac/
├── rbac.go # Main RBAC implementation
├── role.go # Role interface and standard implementation
├── permission.go # Permission interface and standard implementation
├── helper.go # Utility functions
├── helper_test.go # Tests for helper functions
├── rbac_test.go # Tests for RBAC implementation
├── role_test.go # Tests for role implementation
├── permission_test.go # Tests for permission implementation
├── example_test.go # Usage examples
├── examples/ # Complete example applications
│ ├── persistence/ # Example showing data persistence
│ └── user-defined/ # Example with custom role implementation
├── README.md # Project documentation
└── go.mod # Go module definition
The main RBAC structure manages roles and their inheritance relationships.
New[T comparable]() *RBAC[T]- Creates a new RBAC instanceAdd(r *Role[T]) error- Adds a role to the RBAC instanceRemove(id T) error- Removes a role by IDGet(id T) (*Role[T], []T, error)- Gets a role and its parentsSetParent(id T, parent T) error- Sets a parent for a roleSetParents(id T, parents []T) error- Sets multiple parents for a roleGetParents(id T) ([]T, error)- Gets all parents of a roleRemoveParent(id T, parent T) error- Removes a parent from a roleIsGranted(id T, p Permission[T], assert AssertionFunc[T]) bool- Checks if a role has a permission
All operations on the RBAC structure are thread-safe using read-write mutexes.
The Role[T] struct is the default implementation:
type Role[T comparable] struct {
sync.RWMutex
ID T `json:"id"`
permissions Permissions[T]
}NewRole[T comparable](id T) *Role[T]- Creates a new roleAssign(p Permission[T]) error- Assigns a permission to the rolePermit(p Permission[T]) bool- Checks if the role has a specific permissionRevoke(p Permission[T]) error- Revokes a permission from the rolePermissions() []Permission[T]- Returns all permissions assigned to the role
The Permission[T] interface defines the contract for permissions:
type Permission[T comparable] interface {
ID() T
Match(Permission[T]) bool
}The package provides StdPermission[T] as the default implementation:
SID- Serializable ID of the permission
NewPermission[T comparable](id T) Permission[T]- Creates a new permissionID() T- Returns the permission IDMatch(Permission[T]) bool- Checks if this permission matches another
Utility functions for common operations:
Walk[T comparable](rbac *RBAC[T], h WalkHandler[T]) error- Iterates through all roles
InherCircle[T comparable](rbac *RBAC[T]) error- Detects circular inheritance
AnyGranted[T comparable](rbac *RBAC[T], roles []T, permission Permission[T], assert AssertionFunc[T]) bool- Checks if any role has a permissionAllGranted[T comparable](rbac *RBAC[T], roles []T, permission Permission[T], assert AssertionFunc[T]) bool- Checks if all roles have a permission
// Create a new RBAC instance
rbac := gorbac.New[string]()
// Create roles
rA := gorbac.NewRole("role-a")
rB := gorbac.NewRole("role-b")
// Create permissions
pA := gorbac.NewPermission("permission-a")
pB := gorbac.NewPermission("permission-b")
// Assign permissions to roles
rA.Assign(pA)
rB.Assign(pB)
// Add roles to RBAC
rbac.Add(rA)
rbac.Add(rB)
// Set inheritance
rbac.SetParent("role-a", "role-b")
// Check permissions
if rbac.IsGranted("role-a", pA, nil) {
// role-a has permission-a
}The package supports generic ID types:
// String IDs
rbacStr := gorbac.New[string]()
// Integer IDs
rbacInt := gorbac.New[int]()
// Custom struct IDs
type RoleID struct {
Name string
Type string
}
rbacStruct := gorbac.New[RoleID]()You can provide custom assertion functions for fine-grained control:
assertFunc := func(r *gorbac.RBAC[string], id string, p gorbac.Permission[string]) bool {
// Custom logic to determine if permission should be granted
return true // or false
}
if rbac.IsGranted("role-a", pA, assertFunc) {
// Permission granted based on custom logic
}The package doesn't include built-in persistence but provides mechanisms for implementing it:
See examples/persistence/persistence.go for a complete example of:
- Loading roles and permissions from JSON files
- Building the RBAC structure from persisted data
- Saving the RBAC structure back to JSON files
- Serialize roles and their permissions
- Serialize inheritance relationships
- Reconstruct the RBAC instance from persisted data
You can create custom roles by embedding the standard role:
type myRole struct {
*gorbac.Role[string] // Embed the standard role
Label string
Description string
}You can implement the Permission[T] interface to create custom permissions with additional logic in the Match method.
The package defines standard errors:
ErrRoleNotExist- When a role doesn't existErrRoleExist- When trying to add a role that already existsErrFoundCircle- When circular inheritance is detected
Always check and handle these errors appropriately in your applications.
- RBAC operations use read-write mutexes for thread safety
- Permission checking with inheritance uses recursive traversal
- Circular inheritance detection uses depth-first search
- Consider caching results for frequently checked permissions in performance-critical applications
The package includes comprehensive tests covering:
- Basic RBAC operations
- Role and permission management
- Inheritance relationships
- Circular dependency detection
- Helper functions
- Various ID types
See the *_test.go files for detailed usage examples.
| Component | File | Key Functions |
|---|---|---|
| RBAC Core | rbac.go |
New, Add, Remove, IsGranted, SetParent |
| Roles | role.go |
NewRole, Assign, Permit, Revoke |
| Permissions | permission.go |
NewPermission, Match |
| Utilities | helper.go |
Walk, InherCircle, AnyGranted, AllGranted |
| Examples | example_test.go |
Complete usage examples |
rbac := gorbac.New[string]()
// Create roles and permissions
// Assign permissions to roles
// Add roles to RBAC
// Set up inheritanceif rbac.IsGranted("user-role", requiredPermission, nil) {
// Allow access
} else {
// Deny access
}roles := []string{"role1", "role2", "role3"}
if gorbac.AnyGranted(rbac, roles, permission, nil) {
// At least one role has the permission
}
if gorbac.AllGranted(rbac, roles, permission, nil) {
// All roles have the permission
}- Embed standard
Role[T]struct for domain-specific role behavior - Implement custom
Permission[T]interfaces for complex permission matching logic - Use the
Walkfunction to export RBAC state for persistence - Add middleware functions for logging or metrics around RBAC operations
This guide provides a comprehensive overview of the goRBAC package. For implementation details, refer to the source files in the package structure.