rbac

package
v0.1.11 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package rbac defines authorization with row-level security. An Authorizer is consulted before every DML tool execution (invariant I5: RBAC runs before the cost gate). GrantAuthorizer resolves the principal's grants (direct user grants, top-level role grants and entity-level role configuration), keeps only grants that cover every field the request uses, projects fields (invariant I6), and injects the effective row filter (invariant I7: user_predicate AND (OR of covering grant rows) AND tenant_policy).

Authorization denials are Decision{Allowed:false}, not errors; errors are reserved for authorization-system failures.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NormalizeRole

func NormalizeRole(role string) string

NormalizeRole returns the canonical role identity used by authorization, transport session binding, and configuration.

Types

type Authorizer

type Authorizer interface {
	Authorize(ctx context.Context, req Request) (Decision, error)
}

Authorizer authorizes a request. Implementations must be safe for concurrent use (invariant I9).

type Decision

type Decision struct {
	Allowed   bool
	Reason    string
	Fields    []string
	RowFilter relalg.Predicate
	Grants    []string
	// FieldScopes is set on an ambiguous-field-scope denial: each entry is a
	// field set one grant covers, so the caller can retry with explicit fields.
	FieldScopes [][]string
}

Decision is the authorization outcome. When Allowed, Fields is the projected set the caller may read (empty for create/update/delete, which return no rows), and RowFilter is the effective row-level predicate (covering grants ORed, tenant policy ANDed) to AND with the request predicate. Grants lists the covering grant IDs for decision traces.

func (Decision) Reachable added in v0.1.11

func (d Decision) Reachable() bool

Reachable reports that the caller can use the entity for the action with some field selection: the default projection is allowed, or it was denied only because the readable fields are split across grants, in which case an explicit selection within one of FieldScopes is allowed. Entity discovery (describe_entities, the authorized-schema resource) shares this rule.

func (Decision) Scopes added in v0.1.11

func (d Decision) Scopes() [][]string

Scopes returns the non-empty FieldScopes: the field sets an explicit selection may use after an ambiguous-field-scope denial.

type Grant added in v0.1.11

type Grant struct {
	ID      string
	Actions []entity.Action
	Fields  *entity.FieldPermissions
	Rows    relalg.Predicate
}

Grant is one compiled entity permission. Nil Fields grants every visible field; nil Rows grants every row.

type GrantAuthorizer added in v0.1.11

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

GrantAuthorizer authorizes against an immutable entity.Registry and Policy.

func NewGrantAuthorizer added in v0.1.11

func NewGrantAuthorizer(reg *entity.Registry, policy Policy) *GrantAuthorizer

NewGrantAuthorizer returns an Authorizer for the registry and policy.

func NewRoleAuthorizer

func NewRoleAuthorizer(reg *entity.Registry) *GrantAuthorizer

NewRoleAuthorizer returns an Authorizer that only uses entity-level role configuration.

func (*GrantAuthorizer) Authorize added in v0.1.11

func (a *GrantAuthorizer) Authorize(_ context.Context, req Request) (Decision, error)

Authorize applies the covering rule: only grants that allow the action and cover every field the request uses contribute, their row filters are ORed, and the entity tenant policy is always ANDed. Every returned row and column is therefore covered by at least one single grant. An unknown entity or an unpermitted principal yields Allowed=false (not an error).

type Policy added in v0.1.11

type Policy struct {
	Roles      map[string]map[string][]Grant
	Principals map[string]Principal
}

Policy is the compiled top-level authorization model. Roles maps a role to its grants by entity; Principals maps a principal key (for example "user:alice") to a configured user. A principal key without an entry is a role name, which keeps entity-level roles/fieldACL/rowPolicies working.

type Principal added in v0.1.11

type Principal struct {
	Roles  []string
	Grants map[string][]Grant
}

Principal is a configured user: its roles and direct grants by entity.

type Request

type Request struct {
	Role        string
	Entity      string
	Action      entity.Action
	Fields      []string         // requested fields; nil/empty means all visible
	ReadFields  []string         // fields used by projections, filters, grouping, or aggregates
	WriteFields []string         // fields assigned by create/update
	Subject     map[string]any   // caller attributes for ${subject.x} row-policy resolution
	Predicate   relalg.Predicate // the request's own filter (for context, not mutated here)
}

Request describes an authorization query.

Jump to

Keyboard shortcuts

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