authly

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnsupportedMode indicates an unsupported authentication mode was selected.
	ErrUnsupportedMode = errors.New("unsupported auth mode")
	// ErrInvalidToken indicates the token format doesn't match the configured mode.
	ErrInvalidToken = errors.New("invalid token")
	// ErrClaimMissing is returned when a required claim is not present.
	ErrClaimMissing = errors.New("required claim missing")
	// ErrClaimForbidden is returned when a denied claim is present.
	ErrClaimForbidden = errors.New("claim is forbidden")
	// ErrClaimValueNotAllowed is returned when a claim value is not in the allow-list.
	ErrClaimValueNotAllowed = errors.New("claim value not allowed")
	// ErrUnknownClaimNotAllowed is returned when a claim is not in the allow-list.
	ErrUnknownClaimNotAllowed = errors.New("unknown claim not allowed")
	// ErrActorMissing is returned when the actor claim is required but missing.
	ErrActorMissing = errors.New("actor claim missing")
	// ErrActorNotAllowed is returned when the extracted actor subject is not allowed.
	ErrActorNotAllowed = errors.New("actor subject not allowed")
	// ErrLuaPolicy is returned when a Lua policy script rejects the token.
	ErrLuaPolicy = errors.New("lua policy violation")
	// ErrBasicAuthFailed is returned when Basic Auth credentials are invalid.
	ErrBasicAuthFailed = errors.New("basic auth failed")
	// ErrAudienceBlocked is returned when a token audience matches the blocklist.
	ErrAudienceBlocked = errors.New("audience blocked")
	// ErrAudienceMissing is returned when the token has no audience claim.
	ErrAudienceMissing = errors.New("audience missing")
	// ErrAudienceNotAllowed is returned when the token audience does not satisfy allow rules.
	ErrAudienceNotAllowed = errors.New("audience not allowed")
	// ErrMissingRequiredMetadata is returned when a required metadata header is missing or empty.
	ErrMissingRequiredMetadata = errors.New("missing required metadata")
)

Package-level errors returned by the library.

Functions

This section is empty.

Types

type ActorInfo

type ActorInfo struct {
	Subject string
	Claims  map[string]any
}

ActorInfo carries extracted actor subject and claims.

type ActorPolicy

type ActorPolicy struct {
	Enabled bool

	ActorClaimKey        string
	ActorSubjectKey      string
	AllowedActorSubjects []string
	ActorClaimsPolicy    *ClaimPolicy
}

ActorPolicy configures extraction and validation of an "actor" claim (aka RFC 8693 actor). When Enabled, the engine extracts the actor subject and validates it against AllowedActorSubjects.

func (ActorPolicy) ExtractAndValidate

func (ap ActorPolicy) ExtractAndValidate(claims map[string]any) (*ActorInfo, error)

ExtractAndValidate retrieves the actor from claims (if enabled) and validates it.

type AudienceRule

type AudienceRule struct {
	// AnyAudience means do not enforce aud at all ("*").
	AnyAudience bool

	// AnyOf: token aud must contain at least one of these values (OR).
	AnyOf []string

	// AllOf: token aud must contain all of these values (AND).
	AllOf []string

	// Blocklist: if token aud contains ANY of these values => reject.
	Blocklist []string
}

AudienceRule configures rich audience validation for JWT tokens.

Matching logic order:

  1. If Blocklist has any match => reject (always wins)
  2. If AnyAudience=true => accept (skip allow checks, but still apply blocklist)
  3. If AllOf non-empty => require all present
  4. If AnyOf non-empty => require at least one present
  5. If both AllOf and AnyOf are empty => do not enforce audience

func EffectiveAudienceRule

func EffectiveAudienceRule(cfg OAuth2Config) AudienceRule

EffectiveAudienceRule returns the resolved AudienceRule for the given OAuth2Config. If AudienceRule is explicitly configured, it is returned as-is. Otherwise the legacy Audience string is converted:

  • "*" => AnyAudience=true
  • non-empty => AnyOf=[Audience]
  • empty => zero AudienceRule (no enforcement)

func (AudienceRule) Validate

func (r AudienceRule) Validate(tokenAud []string) error

Validate checks the given token audiences against the AudienceRule.

Matching logic order:

  1. If Blocklist has any match => reject (always wins)
  2. If AnyAudience=true => accept
  3. If AllOf non-empty => require all present
  4. If AnyOf non-empty => require at least one present
  5. If both AllOf and AnyOf are empty => accept (no enforcement)

type AuthMode

type AuthMode string

AuthMode selects the top-level authentication mode.

Security: OAuth2 and Basic modes are supported. Mixed mode uses AuthModeOAuth2 with BasicAuth.Enabled=true on the Config.

const (
	// AuthModeOAuth2 enables OAuth 2.0 style verification (JWT and/or opaque introspection).
	AuthModeOAuth2 AuthMode = "oauth2"
	// AuthModeBasic enables Basic Authentication (username/password with bcrypt).
	AuthModeBasic AuthMode = "basic"
)

Supported AuthMode values.

type BasicAuthConfig

type BasicAuthConfig struct {
	// Enabled activates Basic Auth mode.
	Enabled bool

	// Users maps usernames to bcrypt-hashed passwords.
	// Use golang.org/x/crypto/bcrypt.GenerateFromPassword to produce hashes.
	Users map[string]string

	// Validator is an optional custom credential validation function.
	// When set, it takes priority over Users.
	// Must return (true, nil) for valid credentials, (false, nil) for invalid, or (false, err) on error.
	Validator func(ctx context.Context, username, password string) (bool, error)

	// Realm is returned in the WWW-Authenticate header. Defaults to "Restricted" if empty.
	Realm string
}

BasicAuthConfig configures Basic Authentication for the Engine.

If Validator is set, it takes priority over the Users map. If only Users is provided, passwords are compared using bcrypt (constant-time). Passwords in the Users map must be bcrypt hashes — storing plaintext is a security violation.

Security: bcrypt comparison is used to mitigate timing attacks. A dummy comparison is performed for unknown usernames to prevent user enumeration.

Concurrency: BasicAuthConfig is immutable after passing to Config; do not mutate concurrently.

type Cache

type Cache interface {
	Get(key string) (any, bool)
	Set(key string, value any, cost int64, ttl time.Duration) bool
	Del(key string)
}

Cache abstracts a tiny TTL cache used by Engine.

Concurrency: Implementations must be safe for concurrent use.

type ClaimPolicy

type ClaimPolicy struct {
	Allowlist      []string
	Denylist       []string
	EnforcedValues map[string][]any
	Required       []string
	// ApplyTo limits the policy to specific token types. If empty, applies to all.
	ApplyTo []TokenType
}

ClaimPolicy validates token claims using allow/deny/required and value constraints.

Security: Use allowlist to reject unknown/unexpected claims when feasible.

func (ClaimPolicy) Validate

func (p ClaimPolicy) Validate(claims map[string]any) error

Validate enforces the policy on the provided claims map.

type ClientAuth

type ClientAuth struct {
	Kind         ClientAuthKind
	ClientID     string
	ClientSecret string
	HeaderName   string
	HeaderValue  string
}

ClientAuth configures client authentication for introspection or JWKS requests.

type ClientAuthKind

type ClientAuthKind string

ClientAuthKind selects how client credentials are sent.

const (
	ClientAuthNone   ClientAuthKind = "none"
	ClientAuthBasic  ClientAuthKind = "basic"
	ClientAuthBody   ClientAuthKind = "body"
	ClientAuthHeader ClientAuthKind = "header"
	ClientAuthBearer ClientAuthKind = "bearer"
)

type Config

type Config struct {
	Mode      AuthMode
	OAuth2    OAuth2Config
	BasicAuth BasicAuthConfig
	Policies  Policies
}

Config controls Engine behavior.

Concurrency: Config is immutable after passing to New; do not mutate concurrently. Security: Set Issuer/Audience and algorithms to enforce constraints.

func (Config) Validate

func (c Config) Validate() error

Validate checks Config correctness and required fields per mode.

type Engine

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

Engine verifies tokens according to the provided Config.

Concurrency: Engine is safe for concurrent use if the provided Cache and HTTP client are safe for concurrent use (the defaults are). No method mutates shared state.

func New

func New(cfg Config, opts ...Option) (*Engine, error)

New creates a new Engine using cfg and optional Options. Security: Ensure Issuer/Audience and algorithms are set to your expectations.

func (*Engine) Verify

func (e *Engine) Verify(ctx context.Context, token string) (*Result, error)

func (*Engine) VerifyBasic

func (e *Engine) VerifyBasic(ctx context.Context, username, password string) (*Result, error)

VerifyBasic verifies username and password using the configured Basic Auth settings.

Returns a Result with Type "basic", Subject set to the username, and Claims containing "auth_method": "basic".

If Basic Auth is not configured (Mode != AuthModeBasic or BasicAuth.Enabled is false), returns ErrUnsupportedMode.

Concurrency: safe for concurrent use.

type IntrospectionConfig

type IntrospectionConfig struct {
	Endpoint       string
	ClientID       string
	ClientSecret   string
	Timeout        time.Duration
	Auth           ClientAuth
	TokenTransport TokenTransport
	ExtraBody      map[string]string
	ExtraHeaders   map[string]string
}

IntrospectionConfig holds RFC 7662 endpoint settings.

type JWKSAuth

type JWKSAuth struct {
	Kind        ClientAuthKind
	Username    string
	Password    string
	HeaderName  string
	HeaderValue string
	BearerToken string
}

JWKSAuth configures authentication for JWKS endpoint requests.

type JWKSConfig

type JWKSConfig struct {
	URL          string
	CacheTTL     time.Duration
	Auth         JWKSAuth
	ExtraHeaders map[string]string
}

JWKSConfig holds JWKS endpoint settings with optional authentication.

type LuaClaimsPolicy

type LuaClaimsPolicy struct {
	Enabled bool
	Script  string
}

LuaClaimsPolicy configures an optional Lua script for advanced claim validation.

type OAuth2Config

type OAuth2Config struct {
	Mode OAuth2Mode

	Issuer      string
	Audience    string
	AllowedAlgs []string

	// AudienceRule provides rich audience validation (wildcard, AND/OR, blocklist).
	// If set (non-zero), it overrides the legacy Audience string field.
	AudienceRule AudienceRule

	JWKSURL        string
	JWKSCacheTTL   time.Duration
	AllowStaleJWKS bool

	JWKS JWKSConfig

	Introspection         IntrospectionConfig
	IntrospectionCacheTTL time.Duration

	// Opaque controls opaque-token specific semantics.
	Opaque OpaquePolicy
}

OAuth2Config configures OAuth2 verification.

JWKS caching is controlled by JWKSCacheTTL/AllowStaleJWKS. Introspection responses can be cached via IntrospectionCacheTTL.

type OAuth2Mode

type OAuth2Mode string

OAuth2Mode specifies which OAuth2 token types are accepted.

const (
	// OAuth2JWTOnly accepts only JWT tokens.
	OAuth2JWTOnly OAuth2Mode = "jwt_only"
	// OAuth2OpaqueOnly accepts only opaque tokens via introspection.
	OAuth2OpaqueOnly OAuth2Mode = "opaque_only"
	// OAuth2JWTAndOpaque accepts both JWT and opaque tokens.
	OAuth2JWTAndOpaque OAuth2Mode = "jwt_and_opaque"
)

Supported OAuth2Mode values.

type OpaquePolicy

type OpaquePolicy struct {
	RequireActive     bool
	ExposeActiveClaim bool
}

OpaquePolicy configures RFC 7662 opaque-token semantics.

Defaults:

  • RequireActive: true
  • ExposeActiveClaim: false

If RequireActive is true, responses with active != true are rejected. If ExposeActiveClaim is false, the "active" claim is removed before returning Result.

type Option

type Option func(*Engine)

Option configures Engine construction.

func WithCache

func WithCache(c Cache) Option

WithCache overrides the cache used by the Engine.

func WithHTTPClient

func WithHTTPClient(c *http.Client) Option

WithHTTPClient overrides the HTTP client used for JWKS and introspection.

func WithKeepRawToken

func WithKeepRawToken() Option

WithKeepRawToken instructs the Engine to include RawToken in Result.

type Policies

type Policies struct {
	// Backward compatibility: TokenClaims applies to both types unless JWTClaims/OpaqueClaims override.
	TokenClaims ClaimPolicy
	// Type-specific claim policies. If empty and TokenClaims is non-empty, TokenClaims is used.
	JWTClaims    ClaimPolicy
	OpaqueClaims ClaimPolicy
	Actor        ActorPolicy
	Lua          LuaClaimsPolicy
}

Policies configures claim and actor validation.

type Result

type Result struct {
	Type      TokenType
	Source    string // "jwt" or "introspection"
	Subject   string
	Actor     *ActorInfo
	Scopes    []string
	ExpiresAt time.Time
	Claims    map[string]any
	RawToken  string
}

Result contains verification output for a token.

Concurrency: Result is immutable once returned.

func (*Result) IsBasic

func (r *Result) IsBasic() bool

IsBasic reports whether the result originated from a Basic Auth verification.

func (*Result) IsJWT

func (r *Result) IsJWT() bool

IsJWT reports whether the result originated from a JWT verification.

func (*Result) IsOpaque

func (r *Result) IsOpaque() bool

IsOpaque reports whether the result originated from an opaque token introspection.

type TokenTransport

type TokenTransport struct {
	Kind   TokenTransportKind
	Field  string // body field name, default "token"
	Header string // header name when Kind == header, default "Authorization"
	Prefix string // header value prefix when Kind == header, e.g. "Bearer "
}

TokenTransport controls how the token is delivered to the introspection endpoint.

type TokenTransportKind

type TokenTransportKind string

TokenTransportKind selects how the token is sent to the introspection endpoint.

const (
	// TokenTransportBody sends the token in the POST body (default, RFC 7662).
	TokenTransportBody TokenTransportKind = "body"
	// TokenTransportHeader sends the token in a request header.
	TokenTransportHeader TokenTransportKind = "header"
)

type TokenType

type TokenType string

TokenType describes the verified token kind.

const (
	// TokenTypeJWT indicates a JWT token was verified.
	TokenTypeJWT TokenType = "jwt"
	// TokenTypeOpaque indicates an opaque token was introspected and verified.
	TokenTypeOpaque TokenType = "opaque"
)

Supported token types returned in Result.

const TokenTypeBasic TokenType = "basic"

TokenTypeBasic indicates a Basic Auth verification result.

Jump to

Keyboard shortcuts

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