policy

package
v0.7.3 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package policy provides route-level middleware for auth, RBAC, tenant checks, rate limiting, and cache control.

Policies are registered in deterministic order and validated at startup to prevent unsafe route wiring.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Chain

func Chain(h http.Handler, policies ...Policy) http.Handler

Chain composes policies in registration order.

Usage:

r.Handle(http.MethodGet, "/profile", handler,
    policy.AuthRequired(engine, mode),
    policy.RequirePerm("profile.read"),
)

func MustValidateRoute

func MustValidateRoute(method, pattern string, policies ...Policy)

MustValidateRoute validates route policy wiring and panics on invalid config.

Use this during route registration to fail fast on unsafe policy combinations.

func ValidateRoute

func ValidateRoute(method, pattern string, policies ...Policy) error

ValidateRoute validates route policy wiring and returns descriptive validation errors.

func ValidateRouteMetadata

func ValidateRouteMetadata(method, pattern string, metas []Metadata) error

ValidateRouteMetadata validates precomputed policy metadata.

This entrypoint is used by both runtime route registration and static analyzers.

Types

type CacheControlConfig added in v0.6.0

type CacheControlConfig struct {
	// Public allows shared caches (CDN/proxy) to store this response.
	Public bool
	// Private restricts caching to end-user caches.
	Private bool
	// NoStore disables response storage in any cache.
	NoStore bool
	// NoCache requires revalidation before reuse.
	NoCache bool
	// MustRevalidate requires stale responses to be revalidated.
	MustRevalidate bool
	// Immutable marks content as immutable for its freshness lifetime.
	Immutable bool
	// MaxAge sets max-age directive for clients.
	MaxAge time.Duration
	// SharedMaxAge sets s-maxage directive for shared caches.
	SharedMaxAge time.Duration
	// StaleWhileRevalidate allows serving stale while revalidating in background.
	StaleWhileRevalidate time.Duration
	// StaleIfError allows serving stale responses when origin errors.
	StaleIfError time.Duration
	// Vary appends response Vary dimensions.
	Vary []string
}

CacheControlConfig defines explicit client/proxy caching directives for a route.

type CacheInvalidateMetadata

type CacheInvalidateMetadata struct {
	// TagSpecCount is the number of invalidation tag specs configured.
	TagSpecCount int
}

CacheInvalidateMetadata stores cache invalidation policy details.

type CacheReadMetadata

type CacheReadMetadata struct {
	// AllowAuthenticated indicates route opted into authenticated caching.
	AllowAuthenticated bool
	// VaryByUserID indicates cache key varies by user ID.
	VaryByUserID bool
	// VaryByTenantID indicates cache key varies by tenant ID.
	VaryByTenantID bool
}

CacheReadMetadata stores safety flags needed for route validation.

type Metadata

type Metadata struct {
	// Type is the policy classifier.
	Type PolicyType
	// Name is human-readable policy name for diagnostics.
	Name string
	// TenantPathParam is the tenant route parameter for tenant-match policy.
	TenantPathParam string
	// CacheRead holds cache-read safety metadata.
	CacheRead CacheReadMetadata
	// CacheInvalidate holds cache invalidation metadata.
	CacheInvalidate CacheInvalidateMetadata
}

Metadata captures validator-relevant attributes of one policy.

func DescribePolicies

func DescribePolicies(policies ...Policy) ([]Metadata, error)

DescribePolicies returns metadata list for all policies or an error if any policy is invalid.

func DescribePolicy

func DescribePolicy(p Policy) (Metadata, bool)

DescribePolicy returns policy metadata when the policy is annotated.

type Policy

type Policy func(http.Handler) http.Handler

Policy wraps an HTTP handler with route-level behavior.

Policies are applied during route registration and composed with Chain.

func AnnotateCustom

func AnnotateCustom(name string, p Policy) Policy

AnnotateCustom annotates custom policy metadata for validator compatibility.

func AuthRequired

func AuthRequired(engine *goauth.Engine, mode auth.Mode) Policy

AuthRequired enforces authentication on a route.

It validates bearer token claims using the configured goAuth engine and injects auth.AuthContext into request context for downstream policies.

Behavior: - Returns 401 if token is missing or invalid - Uses selected mode (jwt_only, hybrid, strict)

Usage:

r.Handle(http.MethodGet, "/api/v1/system/whoami", httpx.Adapter(handler),
    policy.AuthRequired(engine, mode),
)

Notes: - Place before RBAC and tenant policies - Requires a non-nil engine when route is expected to be protected

func CacheControl added in v0.6.0

func CacheControl(cfg CacheControlConfig) Policy

CacheControl applies explicit Cache-Control/Vary headers on matched routes.

func CacheInvalidate

func CacheInvalidate(manager *cache.Manager, cfg cache.CacheInvalidateConfig) Policy

CacheInvalidate bumps cache tag versions after successful write operations.

Usage:

r.Handle(http.MethodPost, "/api/v1/projects", handler,
    policy.CacheInvalidate(cacheMgr, cache.CacheInvalidateConfig{
        TagSpecs: []cache.CacheTagSpec{{Name: "project", PathParams: []string{"id"}}},
    }),
)

func CacheRead

func CacheRead(manager *cache.Manager, cfg cache.CacheReadConfig) Policy

CacheRead enables route-level response caching backed by cache.Manager.

Behavior: - Builds deterministic cache keys using route and selected vary dimensions - Serves cached responses on hit - Writes successful cacheable responses on miss

Usage:

r.Handle(http.MethodGet, "/api/v1/projects/{id}", handler,
    policy.CacheRead(cacheMgr, cache.CacheReadConfig{
        TTL: 30 * time.Second,
        TagSpecs: []cache.CacheTagSpec{{Name: "project", PathParams: []string{"id"}}},
        VaryBy: cache.CacheVaryBy{TenantID: true, UserID: true},
    }),
)

Notes: - TTL must be > 0 - Authenticated cache usage requires VaryBy.UserID or VaryBy.TenantID

func Noop

func Noop() Policy

Noop returns a policy that forwards requests unchanged.

func PublicRead

func PublicRead(opts ...PresetOption) []Policy

PublicRead returns a validated policy chain for unauthenticated read routes.

func RateLimit

func RateLimit(limiter ratelimit.Limiter, rule ratelimit.Rule) Policy

RateLimit applies route-level throttling using default rule key resolution.

Use RateLimitWithKeyer when you need custom identity key extraction.

func RateLimitWithKeyer

func RateLimitWithKeyer(limiter ratelimit.Limiter, name string, rule ratelimit.Rule, keyer ratelimit.Keyer) Policy

RateLimitWithKeyer applies route-level throttling with optional custom keyer.

Behavior: - Returns 429 when budget is exceeded - Returns 503 when limiter fails in fail-closed mode - Emits Retry-After header when retry delay is known

func RequireAnyPerm

func RequireAnyPerm(perms ...string) Policy

RequireAnyPerm enforces any-of permission checks for authenticated users.

Behavior: - Returns 401 if auth context is missing - Returns 403 if none of the permissions match

func RequireJSON

func RequireJSON() Policy

RequireJSON enforces application/json content type for body-carrying requests.

Behavior: - Validates Content-Type for POST/PUT/PATCH and payload-bearing requests - Returns 415 when content type is not JSON

func RequirePerm

func RequirePerm(perms ...string) Policy

RequirePerm enforces all-of permission checks for authenticated users.

Behavior: - Returns 401 if auth context is missing - Returns 403 if any required permission is missing

func TenantMatchFromPath

func TenantMatchFromPath(paramName string) Policy

TenantMatchFromPath enforces tenant isolation using a route path parameter.

Behavior: - Returns 400 when route tenant parameter is missing - Returns 401 when auth context is missing - Returns 404 when principal tenant and route tenant mismatch

Usage:

r.Handle(http.MethodGet, "/api/v1/tenants/{tenant_id}/projects", handler,
    policy.AuthRequired(engine, mode),
    policy.TenantRequired(),
    policy.TenantMatchFromPath("tenant_id"),
)

func TenantRead

func TenantRead(opts ...PresetOption) []Policy

TenantRead returns a validated policy chain for tenant-scoped read routes.

Usage:

policies := policy.TenantRead(
    policy.WithAuthEngine(engine, auth.ModeStrict),
    policy.WithLimiter(limiter),
    policy.WithCacheManager(cacheMgr),
)

func TenantRequired

func TenantRequired() Policy

TenantRequired ensures authenticated requests carry tenant scope.

Behavior: - Returns 401 when authentication context is absent - Returns 403 when tenant scope is missing

Notes: - Required for tenant-isolated routes - Place after AuthRequired

func TenantWrite

func TenantWrite(opts ...PresetOption) []Policy

TenantWrite returns a validated policy chain for tenant-scoped write routes.

func WithHeader

func WithHeader(key, value string) Policy

WithHeader injects a static response header for matched routes.

type PolicyType

type PolicyType string

PolicyType classifies policy behavior for validation and diagnostics.

const (
	// PolicyTypeUnknown marks unclassified policy metadata.
	PolicyTypeUnknown PolicyType = "unknown"
	// PolicyTypeNoop marks no-op wrapper policies.
	PolicyTypeNoop PolicyType = "noop"
	// PolicyTypeRequireJSON marks content-type enforcement policy.
	PolicyTypeRequireJSON PolicyType = "require_json"
	// PolicyTypeWithHeader marks static header injection policy.
	PolicyTypeWithHeader PolicyType = "with_header"
	// PolicyTypeCacheControl marks explicit Cache-Control response policy.
	PolicyTypeCacheControl PolicyType = "cache_control"
	// PolicyTypeAuthRequired marks authentication enforcement policy.
	PolicyTypeAuthRequired PolicyType = "auth_required"
	// PolicyTypeRequirePerm marks all-of permission enforcement policy.
	PolicyTypeRequirePerm PolicyType = "require_perm"
	// PolicyTypeRequireAnyPerm marks any-of permission enforcement policy.
	PolicyTypeRequireAnyPerm PolicyType = "require_any_perm"
	// PolicyTypeTenantRequired marks tenant scope enforcement policy.
	PolicyTypeTenantRequired PolicyType = "tenant_required"
	// PolicyTypeTenantMatchFromPath marks path-tenant isolation policy.
	PolicyTypeTenantMatchFromPath PolicyType = "tenant_match_from_path"
	// PolicyTypeRateLimit marks route throttling policy.
	PolicyTypeRateLimit PolicyType = "rate_limit"
	// PolicyTypeCacheRead marks cache read/write policy.
	PolicyTypeCacheRead PolicyType = "cache_read"
	// PolicyTypeCacheInvalidate marks cache invalidation policy.
	PolicyTypeCacheInvalidate PolicyType = "cache_invalidate"
	// PolicyTypeCustom marks user-defined annotated policies.
	PolicyTypeCustom PolicyType = "custom"
)

type PresetOption

type PresetOption func(*presetConfig)

PresetOption mutates preset behavior used by TenantRead/TenantWrite/PublicRead.

func WithAuthEngine

func WithAuthEngine(engine *goauth.Engine, mode auth.Mode) PresetOption

WithAuthEngine sets auth engine and mode for preset-generated auth policies.

func WithCache

func WithCache(ttl time.Duration, tagSpecs ...cache.CacheTagSpec) PresetOption

WithCache configures cache TTL and tag specs used by preset-generated cache read policy.

func WithCacheManager

func WithCacheManager(manager *cache.Manager) PresetOption

WithCacheManager sets the cache manager used by preset-generated cache policies.

func WithCacheVaryBy

func WithCacheVaryBy(varyBy cache.CacheVaryBy) PresetOption

WithCacheVaryBy overrides vary dimensions for preset-generated cache reads.

func WithInvalidateTags

func WithInvalidateTags(tagSpecs ...cache.CacheTagSpec) PresetOption

WithInvalidateTags sets tag specs used by preset-generated cache invalidation policy.

func WithLimiter

func WithLimiter(limiter ratelimit.Limiter) PresetOption

WithLimiter sets the limiter used by preset-generated rate limit policies.

func WithRateLimit

func WithRateLimit(limit int, window time.Duration) PresetOption

WithRateLimit configures default limit/window for preset-generated rate limit policy.

func WithStrictAuth

func WithStrictAuth() PresetOption

WithStrictAuth forces auth mode strict regardless of previous mode options.

func WithTenantMatchParam

func WithTenantMatchParam(param string) PresetOption

WithTenantMatchParam overrides tenant path parameter name used by presets.

Jump to

Keyboard shortcuts

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