accessx

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: 5 Imported by: 0

Documentation

Overview

Package accessx provides Kernel's request-time access guard.

accessx is the runtime orchestration layer for authn + authz + audit. In the normal Kernel server path, middleware/authn authenticates first and injects an authn.Principal into context. accessx then consumes that principal, applies authorization policy, resolves SkipPolicy, and records audit. A legacy authenticator hook remains on Guard only for direct callers that still pass raw credentials in Check.

accessx.Guard vs authz.Authorizer

Use accessx.Guard when handling a request and you need the whole access chain: principal resolution, optional authn fallback, authz decision, SkipPolicy and audit.

Use authz.Authorizer when you only need to ask the authorization backend for a provider-neutral decision. authz must not grow a second request-time guard.

SkipPolicy

SkipPolicy controls whether the Guard performs authentication and/or authorization checks. It replaces the deprecated AllowAll + AuthzMode combination with a single, clearer policy:

  • SkipDefault — performs the full authentication + authorization check.
  • SkipAuthz — skips the SpiceDB authorization check but still requires authentication and records audit. Use for operations like GetMe or CreateOrganization where the target resource does not yet exist in the authorization graph.
  • SkipAll — skips both authentication AND authorization. Use for public endpoints like health checks, login, token exchange, etc. Guard.Require still records audit with an anonymous actor.

AccessConfig

AccessConfig controls per-operation access policies via YAML configuration. It supports three operation lists evaluated in priority order:

  1. PublicOperations — operations that skip both authn and authz but still audit (SkipAll).
  2. SkipOperations — operations that skip authz but keep authn (SkipAuthz).
  3. AllowAllOperations (deprecated) — legacy, use SkipOperations instead.

Example YAML:

security:
  access:
    skip_operations:
      - GetMe
      - CreateOrganization
    public_operations:
      - Login
      - Exchange

SkipPolicyResolver

NewSkipPolicyResolver creates a SkipPolicyResolver from an AccessConfig. It supports matching against short method names, full gRPC method names, HTTP URL paths, and wildcard/prefix patterns (e.g. "/v1/authn/*"). The resolver is used by middleware/access to short-circuit requests before calling the main Resolver or Guard.Require.

Backward Compatibility

The deprecated AuthzMode (AuthzModeDefault / AuthzModeNone) and AllowAll fields on Check are still supported. When SkipPolicy is set, it takes priority over the deprecated fields. New code should use SkipPolicy.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsSkipPolicy added in v0.2.4

func IsSkipPolicy(p SkipPolicy) bool

IsSkipPolicy returns true when the given policy indicates some form of skipping (either SkipAuthz or SkipAll).

Types

type AccessConfig added in v0.2.4

type AccessConfig struct {
	// SkipOperations lists operations that should skip the SpiceDB
	// authorization check but still require authentication and record audit.
	// Each entry can be a short method name (e.g. "GetMe"), a full gRPC
	// method name (e.g. "iam.v1.IAMAuthService/GetMe"), or an HTTP path
	// (e.g. "/v1/iam/control-plane/orgs").
	//
	// This is the recommended replacement for the deprecated AllowAllOperations.
	SkipOperations []string `json:"skip_operations" yaml:"skip_operations"`

	// PublicOperations lists operations that skip both authentication AND
	// authorization. Use for endpoints that must be accessible without any
	// credentials (health checks, login, token exchange, etc.). Guard.Require
	// still records audit with an anonymous actor.
	//
	// Each entry follows the same matching rules as SkipOperations.
	PublicOperations []string `json:"public_operations" yaml:"public_operations"`

	// AllowAllOperations lists operations where any authenticated user is
	// allowed. This is the legacy field — new deployments should use
	// SkipOperations instead.
	//
	// Deprecated: Use SkipOperations instead.
	AllowAllOperations []string `json:"allow_all_operations" yaml:"allow_all_operations"`
}

AccessConfig controls per-operation access policies. Each entry maps an operation pattern to its access mode. This allows operators to override the default authorization behavior without code changes.

Example YAML:

security:
  access:
    skip_operations:
      - GetMe
      - CreateOrganization
    public_operations:
      - Login
      - Exchange
    allow_all_operations:   # deprecated, use skip_operations instead
      - GetMe

type AccessRule added in v0.2.4

type AccessRule struct {
	ID           string               `json:"id" yaml:"id"`
	Authn        AuthnMode            `json:"authn" yaml:"authn"`
	Permission   string               `json:"permission" yaml:"permission"`
	Resource     ResourceResolverSpec `json:"resource" yaml:"resource"`
	Subject      SubjectResolverSpec  `json:"subject" yaml:"subject"`
	ShortCircuit ShortCircuitSpec     `json:"short_circuit" yaml:"short_circuit"`
	Audit        AuditSpec            `json:"audit" yaml:"audit"`
}

AccessRule is the declarative form of a runtime accessx.Check. Gateway route registry and protobuf codegen can store this shape without importing Casdoor or SpiceDB implementation packages.

type AuditSpec added in v0.2.4

type AuditSpec struct {
	Action string `json:"action" yaml:"action"`
	Level  string `json:"level" yaml:"level"`
}

type AuthnMode added in v0.2.4

type AuthnMode string

AuthnMode is the provider-neutral authentication requirement declared by a generated protobuf operation, gateway route, or service manifest. It is not a Casdoor concept; concrete middleware maps it to TokenVerifier/Authenticator behavior.

const (
	AuthnModePublic   AuthnMode = "public"
	AuthnModeRequired AuthnMode = "required"
	AuthnModeOptional AuthnMode = "optional"
	AuthnModeInternal AuthnMode = "internal"
)

type AuthzMode deprecated added in v0.2.4

type AuthzMode string

AuthzMode controls whether the Guard performs a SpiceDB/ReBAC authorization check or skips it. Operations that bootstrap a new resource (which cannot exist in SpiceDB yet) should use AuthzModeNone.

Deprecated: Use SkipPolicy instead. AuthzMode is kept for backward compatibility and will be removed in a future version.

const (
	// AuthzModeDefault performs the standard SpiceDB authorization check.
	AuthzModeDefault AuthzMode = ""
	// AuthzModeNone skips the SpiceDB authorization check entirely. The request
	// still goes through authentication, platform policy, and audit.
	//
	// Deprecated: Use SkipPolicy=SkipAuthz instead.
	AuthzModeNone AuthzMode = "None"
)

type Check

type Check struct {
	Credential authn.Credential
	Principal  authn.Principal

	Permission string
	Resource   authz.ObjectRef

	// SkipPolicy controls whether authorization (and optionally authentication)
	// is skipped. The default (SkipDefault) performs the full authn+authz check.
	// When set to SkipAuthz, the Guard skips the SpiceDB check but still
	// authenticates and records audit. When set to SkipAll, both authentication
	// and authorization are skipped.
	//
	// If SkipPolicy is SkipDefault, the deprecated AuthzMode and AllowAll fields
	// are checked for backward compatibility.
	SkipPolicy SkipPolicy

	// AuthzMode controls whether SpiceDB authorization is required.
	// Use AuthzModeNone for operations like CreateOrganization where the
	// target resource does not yet exist in the authorization graph.
	//
	// Deprecated: Use SkipPolicy=SkipAuthz instead.
	AuthzMode AuthzMode

	// AllowAll grants access to every authenticated principal when true.
	// This is useful for self-service operations (e.g. CreateOrganization,
	// CreateProject) where any authenticated user should be allowed.
	// When AllowAll is true, AuthzMode is implicitly AuthzModeNone.
	// This can be made configurable per deployment via platform policy.
	//
	// Deprecated: Use SkipPolicy=SkipAuthz instead.
	AllowAll bool

	TenantID  string
	OrgID     string
	ProjectID string

	SubjectAttrs     authz.AttributeSet
	ResourceAttrs    authz.AttributeSet
	EnvironmentAttrs authz.AttributeSet
	Consistency      authz.Consistency

	AuditAction string
	RequestID   string
	TraceID     string
	ClientIP    string
	UserAgent   string
	Metadata    auditx.AttributeSet
}

type Guard

type Guard struct {
	// Authn is retained only as a legacy fallback for callers that still pass
	// credentials directly to accessx.Check. The primary framework path is:
	// middleware/authn authenticates first, injects authn.Principal into context,
	// then accessx consumes Check.Principal. New services should not rely on this
	// field for the normal request path.
	Authn authn.Authenticator
	Authz authz.Authorizer
	Audit auditx.Recorder
}

func AllowAllForDevOnly

func AllowAllForDevOnly() Guard

func DenyAllGuard

func DenyAllGuard() Guard

func New

func New(authenticator authn.Authenticator, authorizer authz.Authorizer, recorder auditx.Recorder) Guard

New constructs a Guard. The authenticator parameter is a legacy fallback; new code should authenticate through middleware/authn and pass nil here.

func NewGuard added in v0.2.4

func NewGuard(authorizer authz.Authorizer, recorder auditx.Recorder) Guard

NewGuard constructs the preferred access-only guard. Authentication must have run before accessx.Require, and the principal must be available in Check or context.

func (Guard) Authenticate

func (g Guard) Authenticate(ctx context.Context, check Check) (authn.Principal, error)

func (Guard) Authorize

func (g Guard) Authorize(ctx context.Context, principal authn.Principal, check Check) (authz.Decision, error)

func (Guard) Can

func (g Guard) Can(ctx context.Context, check Check) (bool, error)

func (Guard) Record

func (g Guard) Record(ctx context.Context, record auditx.Record) error

func (Guard) Require

func (g Guard) Require(ctx context.Context, check Check) (authn.Principal, error)

type Providers added in v0.1.16

type Providers struct {
	Authn authn.ProviderSet
	Authz authz.ProviderSet
	Audit auditx.Recorder
}

Providers is the framework-level authn/authz/audit bundle consumed by serverx/autowire. It keeps concrete implementations such as Casdoor and SpiceDB outside business packages.

func (Providers) Guard added in v0.1.16

func (p Providers) Guard() Guard

Guard builds the request-time access guard from provider-neutral Kernel interfaces. Missing authz defaults to deny-all at the Guard layer.

type ResourceResolverSpec added in v0.2.4

type ResourceResolverSpec struct {
	Type     string `json:"type" yaml:"type"`
	StaticID string `json:"static_id" yaml:"static_id"`
	IDFrom   string `json:"id_from" yaml:"id_from"`
}

type ShortCircuitMode added in v0.2.4

type ShortCircuitMode string

ShortCircuitMode names the reason an operation intentionally bypasses the normal authorization check. SkipAuthz still requires authentication; SkipAll is reserved for truly public endpoints.

const (
	ShortCircuitNone      ShortCircuitMode = "none"
	ShortCircuitPublic    ShortCircuitMode = "public"
	ShortCircuitSelf      ShortCircuitMode = "self"
	ShortCircuitBootstrap ShortCircuitMode = "bootstrap"
	ShortCircuitInternal  ShortCircuitMode = "internal"
	ShortCircuitSystem    ShortCircuitMode = "system"
)

type ShortCircuitSpec added in v0.2.4

type ShortCircuitSpec struct {
	Mode   ShortCircuitMode `json:"mode" yaml:"mode"`
	Reason string           `json:"reason" yaml:"reason"`
}

func (ShortCircuitSpec) SkipPolicy added in v0.2.4

func (s ShortCircuitSpec) SkipPolicy() SkipPolicy

type SkipPolicy added in v0.2.4

type SkipPolicy string

SkipPolicy controls whether the Guard performs authentication and/or authorization checks. It replaces the previous AllowAll + AuthzMode combination with a single, clearer policy.

const (
	// SkipDefault performs the standard authentication + authorization check.
	SkipDefault SkipPolicy = ""
	// SkipAuthz skips the SpiceDB authorization check but still requires
	// authentication and records audit. Use for operations like GetMe
	// where the resource is the caller's own identity, or CreateOrganization
	// where the target resource does not yet exist in the authorization graph.
	SkipAuthz SkipPolicy = "skip_authz"
	// SkipAll skips both authentication AND authorization. The request passes
	// through without any authenticated principal, but Guard.Require still records
	// audit with an anonymous actor. Use for public endpoints like health checks,
	// login, token exchange, etc.
	// WARNING: No authenticated principal will be available in the handler.
	SkipAll SkipPolicy = "skip_all"
)

type SkipPolicyResolver added in v0.2.4

type SkipPolicyResolver func(operation string) SkipPolicy

SkipPolicyResolver returns a SkipPolicy for a given operation name. This is the standard way to integrate config-driven skip policies into the middleware/access layer.

func NewSkipPolicyResolver added in v0.2.4

func NewSkipPolicyResolver(cfg AccessConfig) SkipPolicyResolver

NewSkipPolicyResolver creates a SkipPolicyResolver from an AccessConfig. It supports matching against:

  • Short method names (e.g. "GetMe")
  • Full gRPC method names (e.g. "iam.v1.IAMAuthService/GetMe")
  • Prefixed gRPC method names (e.g. "/iam.v1.IAMAuthService/GetMe")
  • HTTP URL paths (e.g. "/v1/iam/control-plane/orgs")

The resolver checks operations in this priority order: 1. PublicOperations — returns SkipAll (skip authn + authz, still audit) 2. SkipOperations — returns SkipAuthz (skip authz only) 3. AllowAllOperations (deprecated) — returns SkipAuthz (skip authz only) 4. Otherwise — returns SkipDefault (perform full check)

type SubjectResolverSpec added in v0.2.4

type SubjectResolverSpec struct {
	Type     string `json:"type" yaml:"type"`
	IDFrom   string `json:"id_from" yaml:"id_from"`
	Relation string `json:"relation" yaml:"relation"`
}

Jump to

Keyboard shortcuts

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