Documentation
¶
Overview ¶
Package authorization compiles explicit declarations and evaluates roles before constructing policies. Prepared captures security metadata, not a permission: operations must evaluate it and recheck it before invoking a handler. Tenant membership remains an independent boundary, including on public operations.
Index ¶
- Variables
- func RegisterPolicy[P Policy](r *Registry, name string, factory Factory[P], options PolicyOptions, ...) error
- type ConfigurationError
- type Context
- type Decision
- type DeniedError
- type Evaluator
- type Factory
- type Kind
- type Options
- type Policy
- type PolicyFunc
- type PolicyOptions
- type Prepared
- type Registry
- type Target
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrDenied identifies ordinary authorization denial. ErrDenied = errors.New("authorization denied") // ErrInvalidConfiguration identifies malformed declaration or registry input. ErrInvalidConfiguration = errors.New("invalid authorization configuration") // ErrDuplicate identifies duplicate policies or artifact identities. ErrDuplicate = errors.New("duplicate authorization registration") // ErrFrozen identifies changes after successful Build. ErrFrozen = errors.New("authorization registry frozen") // ErrUnknownPolicy identifies an unregistered policy name. ErrUnknownPolicy = errors.New("unknown authorization policy") // ErrUnsupportedScheme identifies unsupported native authentication schemes. ErrUnsupportedScheme = errors.New("authentication schemes unsupported") // ErrUnknownTarget identifies a target absent from the compiled catalog. ErrUnknownTarget = errors.New("unknown authorization target") // ErrIdentityChanged identifies replacement of principal/tenant or their presence. ErrIdentityChanged = errors.New("authorization identity changed") // ErrNotPrepared identifies a zero Prepared value. ErrNotPrepared = errors.New("authorization not prepared") )
var ErrCatalogMismatch = errors.New("authorization catalog mismatch")
ErrCatalogMismatch identifies missing targets or changed frozen declarations.
var ErrScopeRequired = errors.New("authorization policy requires an operation scope")
ErrScopeRequired identifies direct evaluation of an applicable scoped policy.
Functions ¶
func RegisterPolicy ¶
func RegisterPolicy[P Policy](r *Registry, name string, factory Factory[P], options PolicyOptions, keys ...di.Key) error
RegisterPolicy registers a lazy scoped policy without activating its factory. Nil factories, invalid keys and duplicate names fail. Optional exact dependency keys are copied and checked by pipeline Build without constructing the policy. Omit keys for manually wired factories. Resources own disposal of the policy.
Types ¶
type ConfigurationError ¶
type ConfigurationError struct {
// Target is the malformed artifact, or zero for registry configuration.
Target Target
// Policy is the declaration's policy identity, if relevant.
Policy string
// Kind is the inspectable failure category.
Kind error
}
ConfigurationError describes configuration identities, never request values.
func (*ConfigurationError) Error ¶
func (e *ConfigurationError) Error() string
Error describes the configuration identity and failure category.
func (*ConfigurationError) Unwrap ¶
func (e *ConfigurationError) Unwrap() []error
Unwrap preserves the category and general configuration failure identity.
type Context ¶
type Context struct {
// Principal is the authenticated actor snapshot, or empty for a guest.
Principal identity.Principal
// Tenant is the selected tenant, not evidence of membership.
Tenant tenancy.ID
// Target identifies the command or query.
Target Target
// Resource is borrowed for this evaluation only.
Resource any
// ReceivedAt is the operation dispatch receipt, if installed.
ReceivedAt time.Time
}
Context is immutable operation metadata plus borrowed, operation-specific data. Policies must not mutate or retain Resource.
type Decision ¶
type Decision struct {
// contains filtered or unexported fields
}
Decision is an immutable verdict. Zero denies; it is not a reusable access token.
type DeniedError ¶
type DeniedError struct {
// Reason is diagnostic application text, not safe HTTP response content.
Reason string
}
DeniedError retains local diagnostic reason without including it in error text.
type Evaluator ¶
type Evaluator struct {
// contains filtered or unexported fields
}
Evaluator is immutable and concurrent-safe with concurrently callable policies. It caches declarations, never decisions. Construct using Registry.Build.
func (*Evaluator) CheckCatalog ¶
CheckCatalog verifies coverage and exact declaration content, including absent declarations and overridden model levels. Supersets are allowed. It does not run policies, and never treats matching names alone as compatible authority.
func (*Evaluator) CheckDependencies ¶
CheckDependencies checks effective policy manifests for the supplied catalog subset, after checking its frozen declarations. Overridden policies and other targets do not require dependencies for this pipeline. No policies or factories run. Missing/typed-nil catalogs fail only when applicable declared keys exist; manually captured dependencies remain the application's responsibility.
type Factory ¶
Factory constructs a borrowed policy only during scoped evaluation. Its scope view is non-closing and expires on return from EvaluateScoped.
type Options ¶
type Options struct {
// Fallback applies only to undeclared operations and is copied by Build.
Fallback *metadata.Authorization
}
Options configures frozen application fallback declarations.
type Policy ¶
Policy evaluates synchronously and must honor cancellation. Shared policies must support concurrent use. Unexpected panics propagate to pipeline boundaries.
type PolicyFunc ¶
PolicyFunc adapts a policy callback.
type PolicyOptions ¶
type PolicyOptions struct {
// EvaluatesAnonymous explicitly opts this policy into guest evaluation.
EvaluatesAnonymous bool
}
PolicyOptions controls whether policy-only declarations may evaluate guests.
type Prepared ¶
type Prepared struct {
// contains filtered or unexported fields
}
Prepared captures a declaration and security metadata before dependencies run. Zero is invalid. It is not an authorization token; Evaluate is required for every operation, and Check must run again immediately before handler invocation.
func (Prepared) Check ¶
Check verifies cancellation and unchanged principal/tenant, including presence. Receipt/correlation changes do not alter security ownership.
func (Prepared) Evaluate ¶
Evaluate checks security metadata, roles, then direct policies in declaration order. A policy error returns a denied Decision plus its original error. Policy panics propagate to pipeline boundaries. Resource is borrowed, never retained. This API is container-neutral; it neither creates nor validates service scopes.
func (Prepared) EvaluateScoped ¶
func (p Prepared) EvaluateScoped(ctx context.Context, scope *execution.Scope, resource any) (decision Decision, err error)
EvaluateScoped admits evaluation for the scope's lifetime. All authentication and role requirements run before any policy factory. Factories and policies receive only a non-closing view; panics become execution.PanicError. A scope grants no permission and decisions are never cached.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is a single-owner builder; zero is ready for use. Successful Build freezes it. Build validates configuration without constructing any policy.
Example ¶
var registry authorization.Registry
err := registry.Register("owner", authorization.PolicyFunc(func(_ context.Context, value authorization.Context) (authorization.Decision, error) {
if value.Principal.ID() == value.Resource {
return authorization.Allow(), nil
}
return authorization.Deny("not owner"), nil
}), authorization.PolicyOptions{})
if err != nil {
panic(err)
}
e, err := registry.Build(catalog(&metadata.Authorization{Requirements: []metadata.AuthorizationRequirement{{Policy: "owner"}}}), authorization.Options{})
if err != nil {
panic(err)
}
ctx := identity.WithPrincipal(context.Background(), identity.NewPrincipal(identity.PrincipalData{ID: "alice", AuthenticationType: "verified"}))
prepared, err := e.Prepare(ctx, create)
if err != nil {
panic(err)
}
decision, err := prepared.Evaluate(ctx, "alice")
if err != nil {
panic(err)
}
fmt.Println(decision.IsAllowed())
Output: true
func (*Registry) Build ¶
Build validates every declaration, including overridden levels, and copies the effective graph. Commands use command then fallback; queries use method then read model then fallback. Queries of the same read model must supply identical read-model declarations by content. No declaration and no fallback is public.