authz

package
v0.3.0 Latest Latest
Warning

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

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

Documentation

Overview

Package authz provides multi-principal, RBAC-style access control for the control plane. It generalizes the legacy single static bearer token into a set of named principals, each with its own token, an allowed-profile glob list, and permission flags.

The zero value and a nil *Store both mean "RBAC not configured", allowing the caller to fall back to legacy single-token behavior.

Index

Constants

View Source
const (
	EnvOIDCIssuer   = "RUNEWARD_OIDC_ISSUER"
	EnvOIDCAudience = "RUNEWARD_OIDC_AUDIENCE"
	EnvOIDCJWKSURL  = "RUNEWARD_OIDC_JWKS_URL"
)
View Source
const EnvFile = "RUNEWARD_AUTHZ_FILE"

EnvFile is the environment variable that points at the RBAC principals file.

Variables

View Source
var ErrEmpty = errors.New("authz: store not configured")

ErrEmpty is returned by helpers that require a configured store. It is exported for callers that wish to distinguish "not configured" from other failures.

Functions

This section is empty.

Types

type OIDCVerifier added in v0.3.0

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

OIDCVerifier validates RS256 OIDC JWTs and maps signed Runeward claims onto the same Principal model used by local authz files.

func NewOIDCFromEnv added in v0.3.0

func NewOIDCFromEnv() (*OIDCVerifier, bool, error)

NewOIDCFromEnv configures OIDC when RUNEWARD_OIDC_ISSUER is set.

func (*OIDCVerifier) Verify added in v0.3.0

func (v *OIDCVerifier) Verify(token string) (*Principal, error)

Verify authenticates a JWT and derives a least-privilege Principal from its signed Runeward claims. Tokens without runeward_profiles can launch nothing.

type Principal

type Principal struct {
	// Name is the human-readable identity used as the audit actor.
	Name string `json:"name"`
	// Tenant is the ownership boundary shared by principals that may collaborate
	// on the same Citadels, Cohorts, snapshots, and runs. Empty preserves the
	// legacy one-principal-per-tenant behavior by falling back to Name.
	Tenant string `json:"tenant,omitempty"`
	// Token is the bearer token that authenticates this principal.
	Token string `json:"token"`
	// AllowedProfiles is a list of glob patterns (path.Match syntax) matched
	// against a profile name. An empty list for a non-admin principal means it
	// may launch nothing; a list containing "*" allows every profile.
	AllowedProfiles []string `json:"allowed_profiles"`
	// CanApprove permits the principal to approve or deny pending actions.
	CanApprove bool `json:"can_approve"`
	// ApprovalProfiles optionally limits approval visibility and decisions to
	// actions from matching profiles. Empty preserves global reviewer behavior.
	ApprovalProfiles []string `json:"approval_profiles,omitempty"`
	// Admin bypasses all profile restrictions and implies approval rights.
	Admin bool `json:"admin"`
}

Principal is a named identity that authenticates with a bearer token and carries its own authorization scope.

func (*Principal) CanApproveProfile added in v0.3.0

func (p *Principal) CanApproveProfile(profileName string) bool

CanApproveProfile reports whether the principal may review an action from profileName. Admins may review everything. An approver with no explicit approval_profiles remains a global reviewer for backward compatibility.

func (*Principal) CanLaunch

func (p *Principal) CanLaunch(profile string) bool

CanLaunch reports whether the principal may launch the named profile. Admins bypass all restrictions. For non-admins, the profile must match at least one of the AllowedProfiles glob patterns.

func (*Principal) MayApprove

func (p *Principal) MayApprove() bool

MayApprove reports whether the principal may approve or deny actions.

func (*Principal) MayLaunch added in v0.3.0

func (p *Principal) MayLaunch() bool

MayLaunch reports whether the principal may launch any profile at all. Admins always may. Non-admins may when they have at least one non-empty allowed-profile pattern (including "*"); an empty list means they can launch nothing.

func (*Principal) TenantID added in v0.3.0

func (p *Principal) TenantID() string

TenantID returns the stable resource-ownership boundary for the principal. Existing authz files remain isolated per principal until they explicitly assign multiple principals to the same tenant.

type Store

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

Store holds principals indexed by token. It is safe for concurrent reads. A nil *Store means RBAC is not configured.

func FromEnv

func FromEnv() (*Store, error)

FromEnv builds a Store from the file named by RUNEWARD_AUTHZ_FILE. When the variable is unset (or empty) it returns (nil, nil), signaling that RBAC is not configured and the caller should fall back to legacy single-token auth.

func Load

func Load(filePath string) (*Store, error)

Load reads a JSON principals file of the form:

{"principals": [ {"name": "...", "token": "...", ...}, ... ]}

It rejects entries with empty names, empty tokens, or duplicate tokens.

func (*Store) Identify

func (s *Store) Identify(token string) (*Principal, bool)

Identify returns the principal that owns the given bearer token. It returns (nil, false) when the token is unknown, empty, or the store is nil. Token comparison is done with a constant-time compare to reduce timing leakage.

func (*Store) Len

func (s *Store) Len() int

Len reports the number of configured principals. A nil Store has length 0.

func (*Store) ValidateForNetwork added in v0.3.0

func (s *Store) ValidateForNetwork() error

ValidateForNetwork rejects credentials that are too short for an exposed control plane. Local development may keep compact fixtures, while any non-loopback listener requires at least 32 bytes of token entropy material.

Jump to

Keyboard shortcuts

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