authz

package
v0.9.8 Latest Latest
Warning

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

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

Documentation

Overview

Package authz answers "can this actor perform this action on this resource?" — a deliberate seam so the v1 always-allow implementation can later be swapped for Casbin / OpenFGA / Keto without touching call sites.

Handlers call:

if err := d.Authz.Authorize(ctx, "policy.write", authz.Resource{...}); err != nil {
    return nil, err
}

before mutating state. Today the call is a near-no-op for any authenticated caller; tomorrow it gates the action against per-org permissions, ABAC predicates, or whatever the SaaS tier needs.

Index

Constants

This section is empty.

Variables

View Source
var ErrForbidden = errors.New("authz: forbidden")

ErrForbidden is returned when an authenticated actor lacks permission. Mapped to HTTP 403.

View Source
var ErrUnauthenticated = errors.New("authz: unauthenticated")

ErrUnauthenticated is returned when the call has no actor in context. Mapped to HTTP 401 by the control-plane middleware.

Functions

This section is empty.

Types

type AlwaysAllowAuthenticated

type AlwaysAllowAuthenticated struct{}

AlwaysAllowAuthenticated is the v1 implementation: any authenticated caller (user session or admin-token bypass) is granted any action. Unauthenticated callers are rejected.

This exists so handler call sites are permanent. Swap the concrete type when multi-tenant work lands; handlers stay the same.

func (AlwaysAllowAuthenticated) Authorize

Authorize implements Authorizer.

type Authorizer

type Authorizer interface {
	Authorize(ctx context.Context, action string, resource Resource) error
}

Authorizer is the policy-decision interface. Authorize returns nil to allow, ErrForbidden/ErrUnauthenticated to deny, or any other error to signal a backend failure (which the middleware should treat as 500, not 403 — failure to authorize is not the same as denial).

type OwnerScoped added in v0.8.0

type OwnerScoped struct{}

OwnerScoped grants each authenticated user access to catalog reads and to rows they own, and reserves everything else for admins (the "admin" role or the RELAY_ADMIN_TOKEN break-glass).

The policy, per row owner:

  • system / provider / host (catalog rows): readable by everyone, mutable by admins only (still behind settings.Governs).
  • user rows with owner.ID == caller: fully owned.
  • user rows with empty owner.ID (operator/grandfathered rows, incl. everything the admin token creates): admins only.

Mutations fail closed: an Authorize call that carries no Resource.Owner is treated as "not provably owned" and denied for non-admins. Handlers that operate on a specific row must fetch it and pass its owner.

func (OwnerScoped) Authorize added in v0.8.0

func (OwnerScoped) Authorize(ctx context.Context, action string, res Resource) error

Authorize implements Authorizer.

func (OwnerScoped) Visible added in v0.8.0

func (OwnerScoped) Visible(ctx context.Context, _ string, owner meta.Owner) bool

Visible implements Scoper.

type Resource

type Resource struct {
	Kind string // "provider", "policy", "model", ...
	ID   string // resource id, if known (UUID)
	Name string // resource slug, if id is not known
	// Owner is the target row's provenance, populated by handlers that
	// have already fetched the row (mutations authorize twice as cheaply
	// as fetching twice). Nil means "owner unknown" — owner-aware
	// implementations must fail closed on mutations, not open.
	Owner *meta.Owner
}

Resource describes the target of an authorization check. Fields are optional; populate what the action needs.

type Scoper added in v0.8.0

type Scoper interface {
	// Visible reports whether the current actor may see a row of kind
	// with the given owner in lists and reads.
	Visible(ctx context.Context, kind string, owner meta.Owner) bool
}

Scoper is an optional interface an Authorizer may implement to gate per-row visibility in list/read paths, where per-row Authorize calls would be the wrong shape. Handlers filter rows through Visible when the configured Authorizer implements it; an Authorizer that doesn't (the default AlwaysAllowAuthenticated) leaves reads unfiltered.

Jump to

Keyboard shortcuts

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