authz

package
v0.0.0-...-b64ac56 Latest Latest
Warning

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

Go to latest
Published: May 14, 2026 License: AGPL-3.0 Imports: 26 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SystemRoleAdmin  = "admin"
	SystemRoleMember = "member"
)
View Source
const (
	DispositionReadOnly    = "read_only"
	DispositionDestructive = "destructive"
	DispositionIdempotent  = "idempotent"
	DispositionOpenWorld   = "open_world"
)

Disposition values matching MCP tool annotation hint names (snake_case, no _hint suffix).

View Source
const WildcardResource = "*"

Variables

View Source
var ErrDenied = errors.New("authz denied")
View Source
var ErrInvalidCheck = errors.New("invalid authz check")
View Source
var ErrMissingGrants = errors.New("authz grants missing from context")
View Source
var ErrNoChecks = errors.New("at least one authz check is required")

SystemRoleGrants defines the canonical grant sets for the built-in system roles. These are seeded when RBAC is enabled and replace any existing grants for these roles (idempotent, won't clobber custom roles).

Functions

func CalculateSubScopes

func CalculateSubScopes(scope Scope) []string

func Denied

func Denied(scope Scope, selector Selector) error

func GrantsToContext

func GrantsToContext(ctx context.Context, grants []Grant) context.Context

GrantsToContext stores resolved grants on the request context.

func InvalidCheck

func InvalidCheck(scope Scope, resourceID string) error

func ResourceKindForScope

func ResourceKindForScope(scope Scope) string

ResourceKindForScope derives the resource kind from a scope's family prefix.

func SeedSystemRoleGrants

func SeedSystemRoleGrants(ctx context.Context, logger *slog.Logger, db *pgxpool.Pool, organizationID string) error

SeedSystemRoleGrants upserts the fixed grant sets for all system roles.

func SyncGrants

func SyncGrants(ctx context.Context, logger *slog.Logger, db *pgxpool.Pool, orgID string, roleSlug string, grants []*RoleGrant) error

func ValidateSelector

func ValidateSelector(scope Scope, sel Selector) error

ValidateSelector checks that a selector is well-formed for the given scope. Rules:

  • resource_kind and resource_id must both be present
  • resource_kind must match the scope family (or be "*" for root)
  • extra keys must be in the allowed set for the scope family
  • unknown keys are rejected

Types

type ChallengeLoggingEnabled

type ChallengeLoggingEnabled func(ctx context.Context, organizationID string) (bool, error)

ChallengeLoggingEnabled checks whether authz challenge logging to ClickHouse is enabled for a given organization. Same signature as IsRBACEnabled.

type Check

type Check struct {
	Scope        Scope
	ResourceKind string
	ResourceID   string
	Dimensions   map[string]string
}

Check describes a single authorization requirement. ResourceID identifies the resource. ResourceKind overrides the kind derived from the scope — leave empty to derive automatically. Dimensions carry optional narrowing attributes (tool, disposition, collection) for multi-dimensional checks.

func MCPCheck

func MCPCheck(scope Scope, resourceID, projectID string) Check

MCPCheck builds a Check for an MCP scope (read/write/connect) with project_id injected as a dimension so project-scoped grants can match.

func MCPToolCallCheck

func MCPToolCallCheck(toolsetID string, dims MCPToolCallDimensions) Check

MCPToolCallCheck builds a Check for an MCP tool call with the given dimensions.

type DeniedError

type DeniedError struct {
	Scope    Scope
	Selector Selector
	// contains filtered or unexported fields
}

func (*DeniedError) Error

func (e *DeniedError) Error() string

func (*DeniedError) Unwrap

func (e *DeniedError) Unwrap() error

type Engine

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

func NewEngine

func NewEngine(logger *slog.Logger, db *pgxpool.Pool, chDB clickhouse.Conn, isEnabled IsRBACEnabled, challengeLogging ChallengeLoggingEnabled, membership MembershipFetcher, roleCache cache.Cache, opts ...EngineOpts) *Engine

func (*Engine) Filter

func (e *Engine) Filter(ctx context.Context, checks []Check) ([]string, error)

Filter evaluates each check and returns the resource IDs of those the caller is authorized for. When RBAC is not enforced all resource IDs are returned.

func (*Engine) GetScopeOverrides

func (e *Engine) GetScopeOverrides(ctx context.Context) ([]RoleGrant, bool)

GetScopeOverrides returns the parsed scope overrides from the request context if they are present AND the caller is authorised to use them. In local dev any authenticated user may use the override header; in production only superadmins can. Returns nil, false when overrides are absent or disallowed.

func (*Engine) InvalidateAllRoleCaches

func (e *Engine) InvalidateAllRoleCaches(ctx context.Context, orgID string)

InvalidateAllRoleCaches removes all cached role slugs for an org. Call this after bulk role reassignments where individual user IDs aren't tracked.

func (*Engine) InvalidateRoleCache

func (e *Engine) InvalidateRoleCache(ctx context.Context, userID, orgID string)

InvalidateRoleCache removes the cached role slug for a single user. Call this after updating a specific member's role via UpdateMemberRole.

func (*Engine) PrepareContext

func (e *Engine) PrepareContext(ctx context.Context) (context.Context, error)

func (*Engine) Require

func (e *Engine) Require(ctx context.Context, checks ...Check) error

func (*Engine) RequireAny

func (e *Engine) RequireAny(ctx context.Context, checks ...Check) error

func (*Engine) ShouldEnforce

func (e *Engine) ShouldEnforce(ctx context.Context) (bool, error)

type EngineOpts

type EngineOpts struct {
	DevMode bool
}

type Grant

type Grant struct {
	PrincipalUrn string
	Scope        Scope
	Selector     Selector
}

func GrantsFromContext

func GrantsFromContext(ctx context.Context) ([]Grant, bool)

GrantsFromContext loads resolved grants from the request context.

func GrantsFromOverrides

func GrantsFromOverrides(overrides []RoleGrant) []Grant

GrantsFromOverrides builds a Grants slice from parsed scope overrides. Scopes with no selectors get wildcard access; scopes with selectors get one grant per selector. For backward compatibility with the header format, bare resource IDs are converted to selectors via NewSelector.

func LoadGrants

func LoadGrants(ctx context.Context, db accessrepo.DBTX, organizationID string, principals []urn.Principal) ([]Grant, error)

LoadGrants loads and normalizes grants for the given organization and principals.

func NewGrant

func NewGrant(scope Scope, resourceID string) Grant

NewGrant creates a Grant with selector derived from scope and resource ID.

func NewGrantWithSelector

func NewGrantWithSelector(scope Scope, selector Selector) Grant

NewGrantWithSelector creates a Grant with an explicit selector.

type InvalidCheckError

type InvalidCheckError struct {
	Scope      Scope
	ResourceID string
	// contains filtered or unexported fields
}

func (*InvalidCheckError) Error

func (e *InvalidCheckError) Error() string

func (*InvalidCheckError) Unwrap

func (e *InvalidCheckError) Unwrap() error

type IsRBACEnabled

type IsRBACEnabled func(ctx context.Context, organizationID string) (bool, error)

type MCPToolCallDimensions

type MCPToolCallDimensions struct {
	Tool        string
	Disposition string
	ProjectID   string
}

MCPToolCallDimensions carries the typed attributes of an MCP tool call. Zero-value fields are omitted from the check dimensions.

type MembershipFetcher

type MembershipFetcher interface {
	GetOrgMembership(ctx context.Context, workOSUserID, workOSOrgID string) (*workos.Member, error)
}

MembershipFetcher retrieves a WorkOS membership for a user+org pair.

type RoleGrant

type RoleGrant struct {
	Scope     string
	Selectors []Selector
}

type Scope

type Scope string

Scope identifies an authorization capability granted on a resource.

const (
	ScopeRoot             Scope = "root"
	ScopeOrgRead          Scope = "org:read"
	ScopeOrgAdmin         Scope = "org:admin"
	ScopeProjectRead      Scope = "project:read"
	ScopeProjectWrite     Scope = "project:write"
	ScopeMCPRead          Scope = "mcp:read"
	ScopeMCPWrite         Scope = "mcp:write"
	ScopeMCPConnect       Scope = "mcp:connect"
	ScopeEnvironmentRead  Scope = "environment:read"
	ScopeEnvironmentWrite Scope = "environment:write"
)

type ScopedGrant

type ScopedGrant struct {
	Scope     string
	SubScopes []string
	Selectors []Selector
}

func GrantsForRole

func GrantsForRole(ctx context.Context, logger *slog.Logger, db *pgxpool.Pool, orgID string, roleSlug string) ([]*ScopedGrant, error)

func GrantsToScopedGrants

func GrantsToScopedGrants(rows []Grant) []*ScopedGrant

GrantsToScopedGrants groups raw grants by scope, collapsing wildcards.

type Selector

type Selector map[string]string

Selector is a set of key-value constraints attached to a grant or check. Grants use explicit resource_kind and resource_id keys, e.g. {"resource_kind":"project","resource_id":"proj_123"}. Wildcard uses {"resource_kind":"*","resource_id":"*"}. For a grant selector to match a check selector, every key in the grant must either equal the corresponding check value or be the wildcard "*".

func NewSelector

func NewSelector(scope Scope, resourceID string) Selector

NewSelector creates a selector with resource_kind derived from scope.

func SelectorFromRow

func SelectorFromRow(selectors []byte) (Selector, error)

SelectorFromRow parses the selectors JSONB column into a Selector.

func (Selector) MarshalJSON

func (s Selector) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler. A nil selector marshals as the explicit wildcard {"resource_kind":"*","resource_id":"*"}.

func (Selector) Matches

func (s Selector) Matches(check Selector) bool

Matches reports whether this (grant) selector satisfies the given check selector. A nil/empty grant selector matches any check (defensive fallback). For each key present in BOTH the grant and check selectors, the values must be equal or the grant value must be "*". Keys present in the grant but absent from the check are skipped — the check is not constraining that dimension. This allows disposition-scoped grants (e.g. {"disposition":"read_only"}) to match connection-level checks that don't yet specify a disposition.

func (Selector) ResourceID

func (s Selector) ResourceID() string

ResourceID extracts the resource_id value from the selector. Returns "*" if no resource_id key is present.

Directories

Path Synopsis
Package repo writes authz challenge rows to ClickHouse.
Package repo writes authz challenge rows to ClickHouse.

Jump to

Keyboard shortcuts

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