bearer

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: MIT, MIT Imports: 18 Imported by: 0

README

gomodularauth-bearer

gomodularauth-bearer provides transport-independent Bearer token authentication for server-side APIs built with GoModularAuth.

Installation

go get github.com/BladiCreator/go-modular-auth/plugins/bearer

Quick Start


Detailed guide: doc/plugins/bearer.md.

Documentation

Overview

Package bearer implements opaque bearer token issuance, transport extraction, and stateful token revocation for GoModularAuth.

Package bearer provides transport-independent Bearer token authentication for GoModularAuth.

Index

Constants

View Source
const (
	// DefaultCacheTTL is the duration cached token records remain valid in the cache adapter.
	DefaultCacheTTL = 5 * time.Minute

	// DefaultTokenPrefix is prepended to generated opaque tokens to facilitate identification.
	DefaultTokenPrefix = "gmb_"
)
View Source
const (
	// TokenEntropyBytes defines the amount of cryptographically secure random bytes
	// used for generating opaque bearer tokens (32 bytes = 256 bits of entropy).
	TokenEntropyBytes = 32

	// IDEntropyBytes defines the amount of random bytes used for generating entity IDs (16 bytes = 128 bits).
	IDEntropyBytes = 16
)
View Source
const (
	// EventBearerTokenIssued is emitted when a new bearer token has been successfully generated and persisted.
	EventBearerTokenIssued auth.EventName = "bearer.token.issued"

	// EventBearerTokenRevoked is emitted when an existing bearer token is revoked.
	EventBearerTokenRevoked auth.EventName = "bearer.token.revoked"

	// EventBearerAuthenticated is emitted when a bearer token is successfully authenticated.
	EventBearerAuthenticated auth.EventName = "bearer.authenticated"

	// EventBearerTokenExpired is emitted when an authentication attempt encounters an expired token.
	EventBearerTokenExpired auth.EventName = "bearer.token.expired"
)
View Source
const DefaultTokenTTL = 30 * 24 * time.Hour

DefaultTokenTTL defines the default duration before a newly issued bearer token expires.

View Source
const (
	ModelBearerTokens = "bearer_tokens"
)

Variables

View Source
var (
	// ErrInvalidToken is returned when a bearer token is empty, malformed, or does not match any record.
	// To prevent credential enumeration and token leakage, detailed failure reasons are omitted.
	ErrInvalidToken = errors.New("bearer: invalid token")

	// ErrTokenExpired is returned when the bearer token has passed its expiration time.
	ErrTokenExpired = errors.New("bearer: token expired")

	// ErrTokenRevoked is returned when the bearer token has been explicitly revoked.
	ErrTokenRevoked = errors.New("bearer: token revoked")

	// ErrInsufficientScope is returned when the bearer token does not grant all required scopes.
	ErrInsufficientScope = errors.New("bearer: insufficient scope")

	// ErrTokenNotFound is returned when querying metadata for a non-existent token ID.
	ErrTokenNotFound = errors.New("bearer: token not found")

	// ErrInvalidInput is returned when required parameters (e.g., subject or ID) are missing or invalid.
	ErrInvalidInput = errors.New("bearer: invalid input")

	// ErrMissingBearerToken is returned by transport adapters when no Authorization Bearer header or credential is provided.
	ErrMissingBearerToken = errors.New("bearer: missing bearer token")

	// ErrMalformedBearerHeader is returned by transport adapters when the Authorization header is malformed.
	ErrMalformedBearerHeader = errors.New("bearer: malformed bearer authorization header")
)

Functions

func ConstantTimeCompare added in v1.3.0

func ConstantTimeCompare(a, b string) bool

ConstantTimeCompare compares two hash strings in constant time to prevent side-channel timing attacks.

func ExtractBearerToken added in v1.3.0

func ExtractBearerToken(authHeader string) (string, error)

ExtractBearerToken parses an authorization header value and extracts the raw bearer token. It supports case-insensitive "Bearer " prefixing and trims excess whitespace.

Examples:

  • "Bearer abc123xyz" -> "abc123xyz", nil
  • "bearer abc123xyz" -> "abc123xyz", nil
  • "" -> "", ErrMissingBearerToken
  • "Bearer " -> "", ErrMissingBearerToken
  • "Basic dXNlcjpwYXNz" -> "", ErrMalformedBearerHeader

func GenerateID added in v1.3.0

func GenerateID() (string, error)

GenerateID produces a random hex-encoded unique identifier for entity records.

func GenerateToken added in v1.3.0

func GenerateToken(prefix string) (string, error)

GenerateToken generates an opaque, URL-safe random secret bearer token. If prefix is non-empty, it prepends the prefix to the token (e.g. "gmb_").

func HashToken added in v1.3.0

func HashToken(token string) string

HashToken computes the SHA-256 digest of a bearer token and returns it as a lowercase hex string.

Bearer tokens carry 256 bits of entropy, so a fast cryptographic hash is optimal: brute-force attacks against 256 bits are mathematically infeasible, while lookups in persistence and cache remain strictly O(1).

func RegisterSchema added in v1.3.0

func RegisterSchema(s *schema.Schema) error

RegisterSchema registers the bearer_tokens model into the compiled schema.

func ValidateTokenFormat added in v1.3.0

func ValidateTokenFormat(token string) error

ValidateTokenFormat checks if a token string satisfies minimum sanity requirements (non-empty, sane length).

func WithTokenInfo added in v1.3.0

func WithTokenInfo(ctx context.Context, info *TokenInfo) context.Context

WithTokenInfo injects the authenticated TokenInfo into the context. Transport adapters should invoke this after successful authentication so downstream application handlers can inspect token metadata (e.g. scopes).

Types

type AuthResult added in v1.3.0

type AuthResult struct {
	// Principal is the core GoModularAuth authenticated identity.
	Principal auth.Principal `json:"principal"`

	// Token provides the metadata of the authenticated token (excluding secrets).
	Token *TokenInfo `json:"token"`
}

AuthResult is the result of a successful bearer token authentication.

type AuthenticateInput added in v1.3.0

type AuthenticateInput struct {
	// Token is the raw bearer token supplied by the caller/client.
	Token string `json:"token"`

	// RequiredScopes is a list of scopes that MUST be granted by the token.
	// If any required scope is missing, authentication fails with ErrInsufficientScope.
	RequiredScopes []string `json:"required_scopes,omitempty"`
}

AuthenticateInput encapsulates the transport-neutral credentials for authentication.

type AuthenticatedPayload added in v1.3.0

type AuthenticatedPayload struct {
	TokenID       string             `json:"token_id"`
	Subject       string             `json:"subject"`
	PrincipalType auth.PrincipalType `json:"principal_type"`
	Time          time.Time          `json:"time"`
}

AuthenticatedPayload carries diagnostic metadata about a successful authentication.

type Bearer added in v1.3.0

type Bearer interface {
	// Authenticate validates bearer credentials against persistence (and optional cache),
	// checks expiration, revocation, and scope permissions, and resolves the credentials into a Principal.
	Authenticate(ctx context.Context, in AuthenticateInput) (*AuthResult, error)

	// Issue generates and stores a new cryptographically secure opaque bearer token for the specified subject.
	// The plaintext token is returned strictly once in IssueResult and is never stored in plaintext.
	Issue(ctx context.Context, in IssueInput) (*IssueResult, error)

	// Revoke revokes an individual token by its record ID, immediately invalidating subsequent authentication attempts.
	Revoke(ctx context.Context, tokenID string) error

	// RevokeBySubject revokes all active bearer tokens belonging to the specified subject (e.g., on logout or account compromise).
	RevokeBySubject(ctx context.Context, subject string) error

	// Get retrieves public metadata for a token by its ID.
	// Returns ErrTokenNotFound if not found. Plaintext tokens and hashes are never exposed.
	Get(ctx context.Context, tokenID string) (*TokenInfo, error)

	// ListBySubject retrieves metadata for all tokens belonging to the specified subject.
	ListBySubject(ctx context.Context, subject string) ([]*TokenInfo, error)

	// Delete permanently removes a token record by its ID from persistence and invalidates cache.
	Delete(ctx context.Context, tokenID string) error

	// PurgeExpired removes all expired or revoked tokens from persistence.
	PurgeExpired(ctx context.Context) (int, error)
}

Bearer is the strongly typed capability provided by the bearer plugin. Applications and transport adapters retrieve this capability via:

bearerAuth, err := auth.Get[plugins.Bearer](app)
// or
bearerAuth := auth.MustGet[plugins.Bearer](app)

type Config

type Config struct {
	// DefaultTTL specifies the default expiration duration for newly issued tokens.
	DefaultTTL time.Duration

	// CacheTTL specifies the maximum time-to-live for cached token records.
	CacheTTL time.Duration

	// TokenPrefix is prepended to generated tokens (e.g. "gmb_").
	TokenPrefix string

	// Hooks provides lifecycle interceptors for bearer operations.
	Hooks *Hooks
}

Config configures the bearer token authentication plugin.

type Hooks added in v1.3.0

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

Hooks provides lifecycle extension points for bearer token operations. Registered hooks execute synchronously and may mutate inputs or abort operations by returning an error.

func NewHooks added in v1.3.0

func NewHooks() *Hooks

NewHooks initializes an empty Hooks registry.

func (*Hooks) AfterAuthenticate added in v1.3.0

func (h *Hooks) AfterAuthenticate(fn func(ctx context.Context, res *AuthResult) error)

AfterAuthenticate registers an interceptor invoked after successfully authenticating a bearer token.

func (*Hooks) AfterIssue added in v1.3.0

func (h *Hooks) AfterIssue(fn func(ctx context.Context, res *IssueResult) error)

AfterIssue registers an interceptor invoked after a bearer token has been persisted.

func (*Hooks) AfterRevoke added in v1.3.0

func (h *Hooks) AfterRevoke(fn func(ctx context.Context, tokenID string) error)

AfterRevoke registers an interceptor invoked after a token is marked revoked.

func (*Hooks) BeforeAuthenticate added in v1.3.0

func (h *Hooks) BeforeAuthenticate(fn func(ctx context.Context, in *AuthenticateInput) error)

BeforeAuthenticate registers an interceptor invoked before authenticating a bearer token.

func (*Hooks) BeforeIssue added in v1.3.0

func (h *Hooks) BeforeIssue(fn func(ctx context.Context, in *IssueInput) error)

BeforeIssue registers an interceptor invoked before generating and saving a new bearer token.

func (*Hooks) BeforeRevoke added in v1.3.0

func (h *Hooks) BeforeRevoke(fn func(ctx context.Context, tokenID string) error)

BeforeRevoke registers an interceptor invoked before revoking a token.

type IssueInput added in v1.3.0

type IssueInput struct {
	// Subject identifies the owner/principal of the token (required).
	Subject string `json:"subject"`

	// PrincipalType classifies the identity (optional; defaults to auth.PrincipalUser).
	PrincipalType auth.PrincipalType `json:"principal_type,omitempty"`

	// Scopes defines the authorization permissions granted to this token (optional).
	Scopes []string `json:"scopes,omitempty"`

	// TTL specifies the token lifespan. If zero or negative, Config.DefaultTTL is used.
	TTL time.Duration `json:"ttl,omitempty"`

	// Metadata attaches custom key-value attributes (optional).
	Metadata map[string]string `json:"metadata,omitempty"`
}

IssueInput specifies the parameters for generating and persisting a new bearer token.

type IssueResult added in v1.3.0

type IssueResult struct {
	// Token is the raw, opaque secret bearer token to provide to the client.
	Token string `json:"token"`

	// Info contains the persisted non-sensitive token metadata.
	Info *TokenInfo `json:"info"`
}

IssueResult contains the generated plaintext token and its associated metadata. The plaintext token is returned ONLY ONCE upon creation and cannot be retrieved later.

type Module added in v1.3.0

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

Module implements auth.PluginModule and auth.SchemaProvider for GoModularAuth Bearer token authentication using plugin-sdk.

func New

func New(opts ...Option) *Module

New constructs a new Bearer authentication plugin module.

func (*Module) ID added in v1.3.0

func (m *Module) ID() string

ID returns the module's unique identifier within GoModularAuth.

func (*Module) Init added in v1.3.0

func (m *Module) Init(h *auth.Host) error

Init initializes the plugin module on the host and registers its capability.

func (*Module) RegisterSchema added in v1.3.0

func (m *Module) RegisterSchema(s *schema.Schema) error

RegisterSchema contributes the bearer_tokens model to the compiled schema.

type Option

type Option func(*Config)

Option configures a Config struct.

func WithCacheTTL added in v1.3.0

func WithCacheTTL(d time.Duration) Option

WithCacheTTL sets the cache entry time-to-live.

func WithDefaultTTL added in v1.3.0

func WithDefaultTTL(d time.Duration) Option

WithDefaultTTL sets the default token expiration duration.

func WithHooks added in v1.3.0

func WithHooks(h *Hooks) Option

WithHooks sets the lifecycle hooks for the plugin.

func WithTokenPrefix added in v1.3.0

func WithTokenPrefix(prefix string) Option

WithTokenPrefix sets the prefix for newly generated tokens.

type TokenExpiredPayload added in v1.3.0

type TokenExpiredPayload struct {
	TokenID   string    `json:"token_id"`
	Subject   string    `json:"subject"`
	ExpiresAt time.Time `json:"expires_at"`
	Time      time.Time `json:"time"`
}

TokenExpiredPayload carries diagnostic metadata when an expired token is presented.

type TokenInfo added in v1.3.0

type TokenInfo struct {
	// ID is the unique random identifier for this token record.
	ID string `json:"id"`

	// Subject represents the authenticated identity (e.g. User ID, Service Account ID).
	Subject string `json:"subject"`

	// PrincipalType classifies the identity type (e.g. auth.PrincipalUser, auth.PrincipalServiceAccount).
	PrincipalType auth.PrincipalType `json:"principal_type"`

	// Scopes lists the authorization scopes granted to this token.
	Scopes []string `json:"scopes"`

	// Metadata holds arbitrary key-value application properties attached to the token.
	Metadata map[string]string `json:"metadata,omitempty"`

	// ExpiresAt is the timestamp at which this token becomes invalid.
	ExpiresAt time.Time `json:"expires_at"`

	// RevokedAt is the timestamp when this token was revoked, or nil if active.
	RevokedAt *time.Time `json:"revoked_at,omitempty"`

	// CreatedAt is the timestamp when the token was issued.
	CreatedAt time.Time `json:"created_at"`
}

TokenInfo represents the public, safe metadata of a bearer token. The plaintext token secret and its cryptographic hash are never exposed.

func TokenInfoFrom added in v1.3.0

func TokenInfoFrom(ctx context.Context) (*TokenInfo, bool)

TokenInfoFrom extracts the TokenInfo stored in the context, if present.

func (*TokenInfo) Active added in v1.3.0

func (t *TokenInfo) Active(now time.Time) bool

Active reports whether the token is neither expired nor revoked.

func (*TokenInfo) Expired added in v1.3.0

func (t *TokenInfo) Expired(now time.Time) bool

Expired reports whether the token has expired relative to the given time.

func (*TokenInfo) HasScope added in v1.3.0

func (t *TokenInfo) HasScope(scope string) bool

HasScope reports whether the token grants the specified scope.

func (*TokenInfo) HasScopes added in v1.3.0

func (t *TokenInfo) HasScopes(required ...string) bool

HasScopes reports whether the token grants all required scopes.

func (*TokenInfo) Principal added in v1.3.0

func (t *TokenInfo) Principal() auth.Principal

Principal converts the token's subject and principal type into a core auth.Principal.

func (*TokenInfo) Revoked added in v1.3.0

func (t *TokenInfo) Revoked() bool

Revoked reports whether the token has been revoked.

type TokenIssuedPayload added in v1.3.0

type TokenIssuedPayload struct {
	TokenID       string             `json:"token_id"`
	Subject       string             `json:"subject"`
	PrincipalType auth.PrincipalType `json:"principal_type"`
	Scopes        []string           `json:"scopes"`
	ExpiresAt     time.Time          `json:"expires_at"`
	CreatedAt     time.Time          `json:"created_at"`
}

TokenIssuedPayload carries metadata about an issued token. The plaintext token secret and its hash are NEVER included in events.

type TokenRecord added in v1.3.0

type TokenRecord struct {
	ID            string            `json:"id"`
	TokenHash     string            `json:"token_hash"`
	Subject       string            `json:"subject"`
	PrincipalType string            `json:"principal_type"`
	Scopes        []string          `json:"scopes"`
	Metadata      map[string]string `json:"metadata,omitempty"`
	ExpiresAt     time.Time         `json:"expires_at"`
	RevokedAt     *time.Time        `json:"revoked_at,omitempty"`
	CreatedAt     time.Time         `json:"created_at"`
	UpdatedAt     time.Time         `json:"updated_at"`
}

TokenRecord represents the persistent data model of a bearer token. The plaintext token secret is never stored; only TokenHash is persisted.

func (*TokenRecord) Active added in v1.3.0

func (r *TokenRecord) Active(now time.Time) bool

Active reports whether the token is neither expired nor revoked.

func (*TokenRecord) Expired added in v1.3.0

func (r *TokenRecord) Expired(now time.Time) bool

Expired reports whether the token has expired relative to the given time.

func (*TokenRecord) HasScope added in v1.3.0

func (r *TokenRecord) HasScope(scope string) bool

HasScope reports whether the record contains the specified scope.

func (*TokenRecord) HasScopes added in v1.3.0

func (r *TokenRecord) HasScopes(required ...string) bool

HasScopes reports whether the record satisfies all required scopes.

func (*TokenRecord) Revoked added in v1.3.0

func (r *TokenRecord) Revoked() bool

Revoked reports whether the token has been marked as revoked.

type TokenRevokedPayload added in v1.3.0

type TokenRevokedPayload struct {
	TokenID   string    `json:"token_id,omitempty"`
	Subject   string    `json:"subject"`
	RevokedAt time.Time `json:"revoked_at"`
}

TokenRevokedPayload carries metadata about a token revocation event.

type TransportAuthenticator added in v1.3.0

type TransportAuthenticator interface {
	// Authenticate validates the transport-neutral input and resolves the Principal.
	Authenticate(ctx context.Context, in AuthenticateInput) (*AuthResult, error)
}

TransportAuthenticator is the explicit integration contract for Transport Adapters (HTTP, gRPC, CLI, WebSocket, etc.). Any transport layer extracts raw bearer credentials from its protocol carrier and delegates authentication to this contract.

Directories

Path Synopsis
Package cache provides performance acceleration for bearer token validation using GoModularAuth's core cache adapter.
Package cache provides performance acceleration for bearer token validation using GoModularAuth's core cache adapter.
Package plugins exposes capability aliases for GoModularAuth plugins.
Package plugins exposes capability aliases for GoModularAuth plugins.

Jump to

Keyboard shortcuts

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