rbac

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package rbac provides typed roles, permissions, assignments, and bounded role inheritance.

Example
package main

import (
	"context"
	"fmt"

	authorization "github.com/faustbrian/go-authorization"
	"github.com/faustbrian/go-authorization/rbac"
)

func main() {
	evaluator, err := rbac.New(
		[]rbac.Role{{ID: "reader", Tenant: "acme"}},
		[]rbac.Permission{
			{
				ID:           "read-documents",
				RoleID:       "reader",
				Tenant:       "acme",
				Action:       "document.read",
				ResourceType: "document",
				Effect:       authorization.Allow,
			},
		},
		[]rbac.Assignment{
			{
				ID: "alice-reader",
				Subject: authorization.Subject{
					Kind: authorization.SubjectUser,
					ID:   "alice",
				},
				RoleID: "reader",
				Tenant: "acme",
			},
		},
	)
	if err != nil {
		panic(err)
	}

	decision, err := evaluator.Evaluate(context.Background(), authorization.Request{
		Subject: authorization.Subject{
			Kind: authorization.SubjectUser,
			ID:   "alice",
		},
		Action: "document.read",
		Resource: authorization.Resource{
			Type: "document",
			ID:   "document-1",
		},
		Tenant: "acme",
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(decision.Outcome == authorization.Allow)
}
Output:
true

Index

Examples

Constants

View Source
const (
	EffectAllow = "allow"
	EffectDeny  = "deny"
)
View Source
const (
	ReasonAllow         authorization.ReasonCode = "rbac-allow"
	ReasonExplicitDeny  authorization.ReasonCode = "rbac-explicit-deny"
	ReasonLimitExceeded authorization.ReasonCode = "rbac-limit-exceeded"
)
View Source
const DocumentVersion uint64 = 1

Variables

View Source
var (
	ErrInvalidDocument            = errors.New("invalid RBAC document")
	ErrUnsupportedDocumentVersion = errors.New("unsupported RBAC document version")
	ErrDocumentLimitExceeded      = errors.New("RBAC document size limit exceeded")
)
View Source
var (
	ErrRoleCycle                = errors.New("RBAC role inheritance cycle")
	ErrInheritanceDepthExceeded = errors.New("RBAC inheritance depth exceeded")
	ErrUnknownParentRole        = errors.New("RBAC parent role does not exist")
	ErrCrossTenantInheritance   = errors.New("RBAC inheritance crosses tenants")
	ErrInvalidRole              = errors.New("invalid RBAC role")
	ErrDuplicateRole            = errors.New("duplicate RBAC role")
	ErrInvalidPermission        = errors.New("invalid RBAC permission")
	ErrDuplicatePermission      = errors.New("duplicate RBAC permission")
	ErrInvalidAssignment        = errors.New("invalid RBAC assignment")
	ErrDuplicateAssignment      = errors.New("duplicate RBAC assignment")
	ErrUnknownRole              = errors.New("RBAC role does not exist")
	ErrRoleTenantMismatch       = errors.New("RBAC role tenant mismatch")
	ErrRoleLimitExceeded        = errors.New("RBAC role limit exceeded")
	ErrPermissionLimitExceeded  = errors.New("RBAC permission limit exceeded")
	ErrAssignmentLimitExceeded  = errors.New("RBAC assignment limit exceeded")
	ErrGroupLimitExceeded       = errors.New("RBAC group limit exceeded")
	ErrMatchLimitExceeded       = errors.New("RBAC match limit exceeded")
	ErrBatchLimitExceeded       = errors.New("RBAC batch limit exceeded")
)

Functions

func EncodeDocument

func EncodeDocument(document Document) ([]byte, error)

Types

type Assignment

type Assignment struct {
	ID      authorization.PolicyID
	Subject authorization.Subject
	RoleID  RoleID
	Tenant  authorization.TenantID
}

type AssignmentDocument

type AssignmentDocument struct {
	ID          authorization.PolicyID    `json:"id"`
	SubjectKind authorization.SubjectKind `json:"subject_kind"`
	SubjectID   authorization.SubjectID   `json:"subject_id"`
	RoleID      RoleID                    `json:"role_id"`
	Tenant      authorization.TenantID    `json:"tenant,omitempty"`
}

type Decoder

type Decoder struct{}

func (Decoder) Decode

func (Decoder) Decode(document json.RawMessage) (authorization.Evaluator, error)

type Document

type Document struct {
	Version           uint64               `json:"version"`
	GlobalInheritance bool                 `json:"global_inheritance,omitempty"`
	Limits            Limits               `json:"limits,omitempty"`
	Roles             []RoleDocument       `json:"roles"`
	Permissions       []PermissionDocument `json:"permissions"`
	Assignments       []AssignmentDocument `json:"assignments"`
}

func (Document) Build

func (document Document) Build() (*Evaluator, error)

type Evaluator

type Evaluator struct {
	// contains filtered or unexported fields
}

func DecodeDocument

func DecodeDocument(encoded []byte) (*Evaluator, error)

func New

func New(
	roles []Role,
	permissions []Permission,
	assignments []Assignment,
	options ...Option,
) (*Evaluator, error)

func (*Evaluator) EffectivePermissions

func (evaluator *Evaluator) EffectivePermissions(
	ctx context.Context,
	subject authorization.Subject,
	tenant authorization.TenantID,
) ([]Permission, error)

func (*Evaluator) Evaluate

func (evaluator *Evaluator) Evaluate(
	ctx context.Context,
	request authorization.Request,
) (authorization.Decision, error)

func (*Evaluator) EvaluateBatch

func (evaluator *Evaluator) EvaluateBatch(
	ctx context.Context,
	requests []authorization.Request,
) ([]authorization.Decision, error)

type Limits

type Limits struct {
	MaxInheritanceDepth int `json:"max_inheritance_depth,omitempty"`
	MaxRoles            int `json:"max_roles,omitempty"`
	MaxPermissions      int `json:"max_permissions,omitempty"`
	MaxAssignments      int `json:"max_assignments,omitempty"`
	MaxGroups           int `json:"max_groups,omitempty"`
	MaxMatches          int `json:"max_matches,omitempty"`
	MaxBatchSize        int `json:"max_batch_size,omitempty"`
}

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager provides synchronized in-memory assignment administration. Each Evaluator call returns a new immutable evaluator view.

func NewManager

func NewManager(
	roles []Role,
	permissions []Permission,
	assignments []Assignment,
	options ...Option,
) (*Manager, error)

NewManager validates and copies an initial RBAC administrative view.

func (*Manager) Assign

func (manager *Manager) Assign(assignment Assignment) error

Assign validates and atomically adds a subject-role assignment.

func (*Manager) Assignments

func (manager *Manager) Assignments(
	subject authorization.Subject,
	tenant authorization.TenantID,
) []Assignment

Assignments returns defensive copies of exact-scope subject assignments.

func (*Manager) Evaluator

func (manager *Manager) Evaluator() (*Evaluator, error)

Evaluator returns an immutable evaluator for the manager's current view.

func (*Manager) Revision

func (manager *Manager) Revision() authorization.Revision

Revision returns the manager's monotonic in-memory revision.

func (*Manager) RevokeAssignment

func (manager *Manager) RevokeAssignment(id authorization.PolicyID) bool

RevokeAssignment removes an assignment by stable ID.

type Option

type Option func(*Evaluator)

func WithGlobalInheritance

func WithGlobalInheritance() Option

func WithLimits

func WithLimits(limits Limits) Option

type Permission

type Permission struct {
	ID           authorization.PolicyID
	RoleID       RoleID
	Tenant       authorization.TenantID
	Action       authorization.Action
	ResourceType authorization.ResourceType
	ResourceID   authorization.ResourceID
	Effect       authorization.Outcome
	Priority     int
}

type PermissionDocument

type PermissionDocument struct {
	ID           authorization.PolicyID     `json:"id"`
	RoleID       RoleID                     `json:"role_id"`
	Tenant       authorization.TenantID     `json:"tenant,omitempty"`
	Action       authorization.Action       `json:"action"`
	ResourceType authorization.ResourceType `json:"resource_type"`
	ResourceID   authorization.ResourceID   `json:"resource_id,omitempty"`
	Effect       string                     `json:"effect"`
	Priority     int                        `json:"priority,omitempty"`
}

type Role

type Role struct {
	ID      RoleID
	Tenant  authorization.TenantID
	Parents []RoleID
}

type RoleDocument

type RoleDocument struct {
	ID      RoleID                 `json:"id"`
	Tenant  authorization.TenantID `json:"tenant,omitempty"`
	Parents []RoleID               `json:"parents,omitempty"`
}

type RoleID

type RoleID string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL