authz

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package authz defines Kernel's authorization-provider boundary.

The package owns only the question "can this subject do this action on this resource?". It supports RBAC as relationships, ReBAC as Zanzibar tuples and ABAC through request attributes/caveats, while keeping business code unaware of SpiceDB, OpenFGA, OPA or Casbin.

Boundary rules:

  • Business hot paths that only need a permission decision should depend on Authorizer.
  • Provisioning/control-plane paths may also use RelationshipWriter, RelationshipReader and SchemaManager.
  • Request-time orchestration of authentication, authorization, SkipPolicy and audit belongs to accessx.Guard, not this package.
  • AuditedAuthorizer is a low-level decorator for non-request-time checks; normal HTTP/gRPC server paths should audit through accessx.Guard.

Do not introduce a second runtime guard in authz. Generated policy contracts should resolve to accessx.Check/accessx.Guard or to the provider-neutral Authorizer interface.

Package authz defines Kernel's provider-neutral authorization contracts.

Index

Constants

View Source
const (
	CodePermissionDenied      = errorx.Code("AUTHZ_PERMISSION_DENIED")
	CodeInvalidRequest        = errorx.Code("AUTHZ_INVALID_REQUEST")
	CodeRelationshipConflict  = errorx.Code("AUTHZ_RELATIONSHIP_CONFLICT")
	CodeRelationshipNotFound  = errorx.Code("AUTHZ_RELATIONSHIP_NOT_FOUND")
	CodeBackendFailed         = errorx.Code("AUTHZ_BACKEND_FAILED")
	CodeUnsupportedCapability = errorx.Code("AUTHZ_UNSUPPORTED_CAPABILITY")
)
View Source
const (
	SubjectTypeUser    = "user"
	SubjectTypeService = "service"
	SubjectTypeGroup   = "group"
	SubjectTypeTeam    = "team"
)

Variables

This section is empty.

Functions

func DefaultAuditRecord

func DefaultAuditRecord(req CheckRequest, decision Decision, checkErr error) auditx.Record

func ErrBackendFailed

func ErrBackendFailed(message string, cause error) error

func ErrInvalidRequest

func ErrInvalidRequest(message string) error

func ErrPermissionDenied

func ErrPermissionDenied(message string) error

func ErrUnsupportedCapability

func ErrUnsupportedCapability(message string) error

func ValidateCheckRequest

func ValidateCheckRequest(req CheckRequest) error

func ValidateRelationship

func ValidateRelationship(r Relationship) error

Types

type AdminProvider added in v0.1.16

type AdminProvider interface {
	Service
}

AdminProvider is the full authorization control-plane surface. Kernel's production ReBAC implementation is authz/spicedb.Client.

type AttributeSet

type AttributeSet map[string]any

AttributeSet carries ABAC/caveat context. Values must be JSON-serializable when passed to remote engines such as SpiceDB caveats or OPA.

type AuditRecordBuilder

type AuditRecordBuilder func(req CheckRequest, decision Decision, checkErr error) auditx.Record

type AuditedAuthorizer

type AuditedAuthorizer struct {
	Next       Authorizer
	Recorder   auditx.Recorder
	Builder    AuditRecordBuilder
	FailClosed bool
}

AuditedAuthorizer decorates any Authorizer and records the decision. Audit failures do not block authorization unless FailClosed is true.

func NewAuditedAuthorizer

func NewAuditedAuthorizer(next Authorizer, recorder auditx.Recorder, opts ...AuditedAuthorizerOption) AuditedAuthorizer

func (AuditedAuthorizer) Check

type AuditedAuthorizerOption

type AuditedAuthorizerOption func(*AuditedAuthorizer)

func WithAuditFailClosed

func WithAuditFailClosed(enabled bool) AuditedAuthorizerOption

func WithAuditRecordBuilder

func WithAuditRecordBuilder(builder AuditRecordBuilder) AuditedAuthorizerOption

type Authorizer

type Authorizer interface {
	Check(ctx context.Context, req CheckRequest) (Decision, error)
}

func AllowAllForDevOnly

func AllowAllForDevOnly() Authorizer

func DenyAll

func DenyAll() Authorizer

type AuthorizerGuard added in v0.1.10

type AuthorizerGuard struct{ Authorizer Authorizer }

AuthorizerGuard adapts a simple Authorizer into the generated Guard contract. It supports CHECK_ONLY flows. SCOPED_TOKEN requires an IAM implementation that can issue scoped tokens and should use a custom Guard.

func NewAuthorizerGuard added in v0.1.10

func NewAuthorizerGuard(authorizer Authorizer) AuthorizerGuard

func (AuthorizerGuard) Require added in v0.1.10

func (g AuthorizerGuard) Require(ctx context.Context, req CheckRequest) (Decision, error)

func (AuthorizerGuard) RequireScopedToken added in v0.1.10

func (g AuthorizerGuard) RequireScopedToken(ctx context.Context, req ScopedTokenRequest) (string, Decision, error)

type BatchAuthorizer

type BatchAuthorizer interface {
	BatchCheck(ctx context.Context, req BatchCheckRequest) (BatchCheckResult, error)
}

type BatchCheckRequest

type BatchCheckRequest struct {
	Checks      []CheckRequest
	Consistency Consistency
}

type BatchCheckResult

type BatchCheckResult struct {
	Decisions []Decision
}

type CheckRequest

type CheckRequest struct {
	Subject    SubjectRef
	Resource   ObjectRef
	Permission string

	TenantID  string
	OrgID     string
	ProjectID string

	SubjectAttrs     AttributeSet
	ResourceAttrs    AttributeSet
	EnvironmentAttrs AttributeSet
	Consistency      Consistency
}

type Consistency

type Consistency struct {
	Mode  ConsistencyMode
	Token string
}

Consistency carries a SpiceDB-style causal token without making callers know about the concrete backend. Token maps to SpiceDB ZedToken for ReBAC engines.

type ConsistencyMode

type ConsistencyMode string
const (
	ConsistencyMinimizeLatency ConsistencyMode = "minimize_latency"
	ConsistencyAtLeastAsFresh  ConsistencyMode = "at_least_as_fresh"
	ConsistencyFullyConsistent ConsistencyMode = "fully_consistent"
)

type Decision

type Decision struct {
	// Effect preserves the important difference between explicit deny and no
	// matching relationship/policy. Allowed is kept for ergonomic callers and
	// backwards-compatible checks.
	Effect           DecisionEffect
	Allowed          bool
	Reason           string
	ConsistencyToken string
	Partial          bool
	MissingContext   []string
}

func Allow

func Allow(reason string) Decision

func Deny

func Deny(reason string) Decision

func NoMatch

func NoMatch(reason string) Decision

func (Decision) IsAllowed

func (d Decision) IsAllowed() bool

func (Decision) IsDenied

func (d Decision) IsDenied() bool

func (Decision) IsNoMatch

func (d Decision) IsNoMatch() bool

type DecisionEffect

type DecisionEffect string
const (
	DecisionAllow   DecisionEffect = "allow"
	DecisionDeny    DecisionEffect = "deny"
	DecisionNoMatch DecisionEffect = "no_match"
)

type Guard added in v0.1.10

type Guard interface {
	Require(ctx context.Context, req CheckRequest) (Decision, error)
	RequireScopedToken(ctx context.Context, req ScopedTokenRequest) (string, Decision, error)
}

Guard is the high-level API used by generated secure clients. Implement it with your IAM adapter. Kernel provides the contract; concrete deployments can back it with SpiceDB/OpenFGA/OPA/decision cache/scoped JWT issuance.

type LookupResourcesRequest

type LookupResourcesRequest struct {
	Subject      SubjectRef
	ResourceType string
	Permission   string

	TenantID  string
	OrgID     string
	ProjectID string

	SubjectAttrs     AttributeSet
	EnvironmentAttrs AttributeSet
	Consistency      Consistency
	Limit            int
	Cursor           string
}

type LookupResourcesResult

type LookupResourcesResult struct {
	Resources        []ObjectRef
	NextCursor       string
	ConsistencyToken string
}

type LookupSubjectsRequest

type LookupSubjectsRequest struct {
	Resource    ObjectRef
	Permission  string
	SubjectType string

	TenantID  string
	OrgID     string
	ProjectID string

	ResourceAttrs    AttributeSet
	EnvironmentAttrs AttributeSet
	Consistency      Consistency
	Limit            int
	Cursor           string
}

type LookupSubjectsResult

type LookupSubjectsResult struct {
	Subjects         []SubjectRef
	NextCursor       string
	ConsistencyToken string
}

type MemoryAuthorizer

type MemoryAuthorizer struct{ Store RelationshipReader }

MemoryAuthorizer allows when resource#permission@subject exists exactly.

func NewMemoryAuthorizer

func NewMemoryAuthorizer(store RelationshipReader) MemoryAuthorizer

func (MemoryAuthorizer) Check

type MemoryRelationshipStore

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

MemoryRelationshipStore is for unit tests and local demos only. It does not evaluate recursive permissions; production ReBAC should use SpiceDB/OpenFGA.

func NewMemoryRelationshipStore

func NewMemoryRelationshipStore() *MemoryRelationshipStore

func (*MemoryRelationshipStore) DeleteRelationships

func (s *MemoryRelationshipStore) DeleteRelationships(ctx context.Context, filter RelationshipFilter) (WriteResult, error)

func (*MemoryRelationshipStore) ReadRelationships

func (s *MemoryRelationshipStore) ReadRelationships(ctx context.Context, filter RelationshipFilter) ([]Relationship, error)

func (*MemoryRelationshipStore) WriteRelationships

func (s *MemoryRelationshipStore) WriteRelationships(ctx context.Context, relationships ...Relationship) (WriteResult, error)

type ObjectRef

type ObjectRef struct {
	Type string
	ID   string
}

func (ObjectRef) IsZero

func (r ObjectRef) IsZero() bool

func (ObjectRef) String

func (r ObjectRef) String() string

type Provider added in v0.1.16

type Provider interface {
	Authorizer
}

Provider is Kernel's runtime authorization surface.

Business hot paths usually require only Check. Admin/provisioning code can use Service to manage schema and relationships. Concrete engines such as SpiceDB, Casbin or Casdoor-backed policy adapters must implement these Kernel contracts instead of being imported by business packages.

type ProviderSet added in v0.1.16

type ProviderSet struct {
	Runtime Provider
	Admin   AdminProvider
}

ProviderSet groups runtime and admin authorization providers for boot wiring.

func (ProviderSet) Authorizer added in v0.1.16

func (p ProviderSet) Authorizer() Authorizer

func (ProviderSet) Service added in v0.1.16

func (p ProviderSet) Service() Service

type Relationship

type Relationship struct {
	Resource      ObjectRef
	Relation      string
	Subject       SubjectRef
	CaveatName    string
	CaveatContext AttributeSet

	// ExpiresAt supports time-limited sharing and temporary grants. For SpiceDB
	// adapters this can be implemented with relationship expiration when
	// available, or encoded as a caveat otherwise. Zero means no expiry.
	ExpiresAt time.Time
}

Relationship is a Zanzibar/ReBAC tuple, optionally caveated for ABAC. Example: document:doc_1#viewer@user:u_1.

type RelationshipFilter

type RelationshipFilter struct {
	ResourceType string
	ResourceID   string
	Relation     string
	SubjectType  string
	SubjectID    string
	SubjectRel   string
}

type RelationshipProjector

type RelationshipProjector interface {
	ProjectRelationships(ctx context.Context, event any) ([]Relationship, error)
}

RelationshipProjector converts domain events from Kernel IAM/Hub/etc. into ReBAC tuples. Pair it with a transactional outbox to avoid dual-write drift.

type RelationshipReader

type RelationshipReader interface {
	ReadRelationships(ctx context.Context, filter RelationshipFilter) ([]Relationship, error)
}

type RelationshipStore

type RelationshipStore interface {
	RelationshipWriter
	RelationshipReader
}

type RelationshipWriter

type RelationshipWriter interface {
	WriteRelationships(ctx context.Context, relationships ...Relationship) (WriteResult, error)
	DeleteRelationships(ctx context.Context, filter RelationshipFilter) (WriteResult, error)
}

type ResourceLookup

type ResourceLookup interface {
	LookupResources(ctx context.Context, req LookupResourcesRequest) (LookupResourcesResult, error)
}

type Rule added in v0.1.10

type Rule struct {
	Service    string   `json:"service" yaml:"service"`
	Method     string   `json:"method" yaml:"method"`
	FullMethod string   `json:"full_method" yaml:"full_method"`
	Action     string   `json:"action" yaml:"action"`
	Resource   string   `json:"resource" yaml:"resource"`
	Audience   string   `json:"audience" yaml:"audience"`
	Mode       RuleMode `json:"mode" yaml:"mode"`

	AuditEvent string `json:"audit_event,omitempty" yaml:"audit_event,omitempty"`
	AuditRisk  string `json:"audit_risk,omitempty" yaml:"audit_risk,omitempty"`
	Capability string `json:"capability,omitempty" yaml:"capability,omitempty"`
}

Rule is the generated, protocol-neutral authorization contract for one RPC. It is intentionally small and can be reused by grpcx, REST/BFF handlers, docs, tests, and future Buf check plugins.

type RuleMode added in v0.1.10

type RuleMode string

RuleMode describes how a generated authz rule should be enforced.

const (
	RuleModeUnspecified RuleMode = "UNSPECIFIED"
	// RuleModeCheckOnly means callers should call IAM.Check and rely on the
	// resulting decision_id for downstream propagation.
	RuleModeCheckOnly RuleMode = "CHECK_ONLY"
	// RuleModeScopedToken means callers should ask IAM for a short-lived scoped
	// token and pass that token to the target service.
	RuleModeScopedToken RuleMode = "SCOPED_TOKEN"
	// RuleModeSelfCheck means the resource service should perform the final IAM
	// check at its own boundary. This is suited for high-risk operations.
	RuleModeSelfCheck RuleMode = "SELF_CHECK"
)

type RuleResolver added in v0.1.10

type RuleResolver struct{}

RuleResolver expands generated resource templates such as skill:{skill_id} from a protobuf request object. It uses reflection against exported Go fields and protobuf-style snake_case names.

func (RuleResolver) ResolveResource added in v0.1.10

func (RuleResolver) ResolveResource(rule Rule, req any) (ObjectRef, error)

ResolveResource expands rule.Resource into an ObjectRef. Resource templates are expected to use the form "type:{field_name}" or "type:literal".

type Rules added in v0.1.10

type Rules map[string]Rule

Rules is a generated rules table keyed by gRPC full method name, for example /skill.v1.SkillService/DownloadSkillPackage.

type Schema

type Schema struct {
	Text    string
	Version string
}

type SchemaManager

type SchemaManager interface {
	ReadSchema(ctx context.Context) (Schema, error)
	WriteSchema(ctx context.Context, schema Schema) error
	ValidateSchema(ctx context.Context, schema Schema) error
}

SchemaManager is implemented by engines like SpiceDB that own an explicit authorization schema.

type ScopedTokenRequest added in v0.1.10

type ScopedTokenRequest struct {
	Subject  SubjectRef
	Action   string
	Resource ObjectRef
	Audience string
	Rule     Rule

	TenantID  string
	OrgID     string
	ProjectID string

	DecisionID string
	Reason     string
	Attributes AttributeSet
}

ScopedTokenRequest asks an IAM implementation for a token that is bound to a concrete service audience, action, and resource.

type Service

Service is the complete authorization surface. Business hot paths usually need only Authorizer; admin/provisioning paths need relationship/schema APIs.

type SubjectLookup

type SubjectLookup interface {
	LookupSubjects(ctx context.Context, req LookupSubjectsRequest) (LookupSubjectsResult, error)
}

type SubjectRef

type SubjectRef struct {
	Type     string
	ID       string
	Relation string
}

func (SubjectRef) IsZero

func (s SubjectRef) IsZero() bool

func (SubjectRef) String

func (s SubjectRef) String() string

type WriteResult

type WriteResult struct {
	ConsistencyToken string
	Written          int
	Deleted          int
}

Directories

Path Synopsis
Package spicedb contains SpiceDB adapter contracts and configuration for authz.
Package spicedb contains SpiceDB adapter contracts and configuration for authz.

Jump to

Keyboard shortcuts

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