auth

package module
v0.0.0-...-4ff1bda Latest Latest
Warning

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

Go to latest
Published: Aug 14, 2026 License: MIT Imports: 31 Imported by: 0

README

Azugo Auth

status-badge

[!WARNING] This library is currently EXPERIMENTAL and breaking changes are expected!

Azugo framework authentication toolkit — OAuth 2.0 / OpenID Connect building blocks with PASETO v4.local tokens.

Features

  • PASETO v4.local access tokens, session cookies and API keys with zero-downtime secret rotation.
  • Pluggable user provider, session store, client registry and JTI allowlist.
  • Cache-backed session and JTI stores out of the box.

Usage

	a, err := auth.New(app, cfg, users, sessions, clients)
	if err != nil {
		panic(err)
	}

Where app is a *core.App, cfg is an *auth.Configuration, users implements auth.UserProvider, sessions a session.Store and clients a client.Registry.

auth.Auth is a transport-free service that takes a request struct and return a result

  • directive struct, with no HTTP dependency. Two optional layers sit on top:
  • azugo.io/auth/routes - azugo HTTP adapters. routes.Bind(router, prefix, a) mounts every group a's configuration supports; pass one or more routes.Group values (or routes.OIDC()) to restrict it. For a Handler built with routes.New(a, ...) and mounted manually at custom paths, pass routes.MountPrefix and/or routes.TokenEndpoint/UserinfoEndpoint/JWKSEndpoint so the discovery document still reports correct URLs.
  • azugo.io/auth/middleware - middleware.Auth(a, ...) resolves ctx.User() from the Authorization header (and, with middleware.Cookie(), the session cookie); middleware.RequireAuth(...) halts the chain for an anonymous request, optionally redirecting (middleware.RedirectTo, middleware.ReturnTo) instead of returning a JSON 401.

See _examples/portal for a complete server-side-rendered app wiring all of the above together.

Environment variables

  • AUTH_SECRET - PASETO local secret used to seal tokens (min. 32 bytes).
  • AUTH_SECURE - Mark session cookies as Secure. Default true.
  • AUTH_SAME_SITE - Session cookie SameSite policy: strict, lax or none. Default strict.
  • AUTH_COOKIE_NAME - Session cookie name. Default __session.
  • AUTH_COOKIE_PATH - Session cookie path. Default: the auth mount prefix.
  • AUTH_LOGOUT_INVALIDATES_COOKIE - Make logout authoritative server-side. Default true.
  • AUTH_ACCESS_TOKEN_TTL - Access token lifetime. Default 20m.
  • AUTH_SESSION_TTL - Session lifetime. Default 8h.
  • AUTH_CODE_TTL - Authorization-code lifetime. Default 60s.
  • AUTH_BASE_URL - Public base URL used to resolve the issuer and default cookie path. Optional; derived from the request otherwise (needed behind a proxy or on a split origin).
  • AUTH_ISSUER - OIDC issuer identifier. Optional; derived from the request base URL when unset.
  • AUTH_THROTTLE_ENABLED - Enable the brute-force lockout guard. Default true.
  • AUTH_THROTTLE_MAX_ATTEMPTS - Attempts before lockout. Default 5.
  • AUTH_THROTTLE_WINDOW - Attempt-counting window. Default 15m.
  • AUTH_THROTTLE_LOCKOUT_TTL - Lockout duration. Default 15m.
  • AUTH_THROTTLE_MFA_RESEND_COOLDOWN - MFA code resend cooldown. Default 60s.
  • AUTH_THROTTLE_MFA_MAX_RESENDS - Maximum MFA code resends. Default 3.
  • AUTH_KEYS_PRIMARY (or AUTH_KEYS_PRIMARY_FILE) - PEM-encoded primary signing key (RSA or ECDSA private key). Enables JWT/JWKS signing; unset means introspect-only mode.
  • AUTH_KEYS_PRIMARY_ALGORITHM - Primary key algorithm: RS256, RS384, RS512, ES256, ES384 or ES512. Optional; defaults to the curve-mandated algorithm for an EC key, or RS256 for RSA.
  • AUTH_KEYS_SECONDARY (or AUTH_KEYS_SECONDARY_FILE) - One or more concatenated PEM-encoded public keys accepted for verification alongside the primary key (e.g. during key rotation).

Documentation

Overview

Package auth is the transport-free coordinator for the azugo authentication library.

Index

Constants

View Source
const AssertionTypeJWTBearer = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"

AssertionTypeJWTBearer is the RFC 7523 client_assertion_type for private_key_jwt.

Variables

View Source
var (
	// ErrInvalidCredentials is returned for a bad username and/or password.
	ErrInvalidCredentials = contract.ErrInvalidCredentials
	// ErrUserAlreadyExists is returned when the account is taken.
	ErrUserAlreadyExists = contract.ErrUserAlreadyExists
	// ErrUserNotFound is returned when the user is unknown.
	ErrUserNotFound = contract.ErrUserNotFound
	// ErrUnsupportedGrantType is returned for grant_type this library does not
	// support.
	ErrUnsupportedGrantType = errors.New("unsupported grant type")
	// ErrLoginRequired is returned by Refresh when the presented session cookie is missing,
	// expired, or otherwise cannot be silently re-authenticated.
	ErrLoginRequired = errors.New("login required")
)

Functions

func NewOAuthAuthenticateError

func NewOAuthAuthenticateError(code ErrorCode, description, realm, scope string, opts ...OAuthErrorOption) error

NewOAuthAuthenticateError creates a 401 Unauthorized OAuthError that emits an RFC 6750 WWW-Authenticate: Bearer challenge.

func NewOAuthError

func NewOAuthError(status int, code ErrorCode, description string, opts ...OAuthErrorOption) error

NewOAuthError creates an OAuthError with the given HTTP status, error code and description. Optional attributes (e.g. OAuthErrorURI option).

func NewOAuthErrorFrom

func NewOAuthErrorFrom(err error) error

NewOAuthErrorFrom maps a authentication specifc errors to OAuth 2.0 error and status code.

func NewThrottledError

func NewThrottledError(retryAfter time.Duration) error

NewThrottledError creates a 429 Too Many Requests OAuthError carrying a Retry-After hint.

Types

type Auth

type Auth struct {

	// Cookie provides session cookie attribute helpers.
	Cookie CookieCtx
	// Issuer provides OIDC issuer resolution helpers.
	Issuer IssuerCtx
	// Transaction provides multi-write transaction helpers.
	Transaction TransactionCtx
	// contains filtered or unexported fields
}

Auth is the transport-free authentication service.

func New

func New(app *core.App, config *Configuration, users UserProvider, sessions session.Store, clients client.Registry, opts ...Option) (*Auth, error)

New creates an Auth instance.

func (*Auth) AuthenticateClient

func (a *Auth) AuthenticateClient(ctx context.Context, creds ClientCredentials, baseURL, mountPath, tokenEndpoint string) (*client.Client, error)

AuthenticateClient resolves client credentials and enforces the client's registered TokenEndpointAuthMethod.

func (*Auth) AuthorizationCodeGrant

func (a *Auth) AuthorizationCodeGrant(ctx context.Context, in AuthorizationCodeGrantRequest) (TokenResult, error)

AuthorizationCodeGrant redeems a single-use authorization code for tokens. A replayed code revokes the bound session.

func (*Auth) Authorize

func (a *Auth) Authorize(ctx context.Context, in AuthorizeRequest) (AuthorizeResult, error)

Authorize handles the authorization-code flow: it validates the request, establishes the user from the session cookie, mints a single-use code and returns the redirect.

func (*Auth) ClientCredentialsGrant

func (a *Auth) ClientCredentialsGrant(ctx context.Context, in ClientCredentialsGrantRequest) (TokenResult, error)

ClientCredentialsGrant issues a JWT access token to a confidential client without a user or session.

func (*Auth) Clients

func (a *Auth) Clients() client.Registry

Clients returns the configured client registry.

func (*Auth) Codes

func (a *Auth) Codes() code.Store

Codes returns the configured authorization-code store.

func (*Auth) Config

func (a *Auth) Config() *Configuration

Config returns the auth Configuration.

func (*Auth) Introspect

Introspect implements RFC 7662 for confidential clients: opaque PASETO tokens are validated through the in-process issuer path, JWT access tokens by signature + deny-list.

func (*Auth) IntrospectToken

func (a *Auth) IntrospectToken(ctx context.Context, tok string) (UserInfo, *session.Session, error)

IntrospectToken validates a Bearer access token or session-cookie token and returns the resolved user and session.

func (*Auth) JTI

func (a *Auth) JTI() jti.Store

JTI returns the configured JTI allowlist store.

func (*Auth) Keys

func (a *Auth) Keys() token.KeyProvider

Keys returns the configured key provider, or nil in introspect-only mode.

func (*Auth) ListSessions

func (a *Auth) ListSessions(ctx context.Context, userID string, filter *session.Filter, page *paginator.Paginator) ([]*session.Session, *paginator.Paginator, error)

ListSessions returns userID's sessions, ordered by LastSeen descending.

func (*Auth) Login

func (a *Auth) Login(ctx context.Context, in LoginRequest) (LoginResult, error)

Login authenticates a password-grant request, creates an active session and returns the directives the caller should apply.

func (*Auth) Logout

func (a *Auth) Logout(ctx context.Context, in LogoutRequest) (LogoutResult, error)

Logout is the authoritative server-side logout.

func (*Auth) ReadSessionToken

func (a *Auth) ReadSessionToken(ctx *azugo.Context) string

ReadSessionToken extracts the presented credential.

func (*Auth) Refresh

func (a *Auth) Refresh(ctx context.Context, in RefreshRequest) (LoginResult, error)

Refresh performs the portal's silent re-authentication.

func (*Auth) RevokeSession

func (a *Auth) RevokeSession(ctx context.Context, userID, sessionID string) error

RevokeSession revokes sessionID after verifying it belongs to userID.

func (*Auth) RevokeToken

func (a *Auth) RevokeToken(ctx context.Context, in RevokeTokenRequest) error

RevokeToken implements RFC 7009: an opaque token revokes its session and JTI when it belongs to the calling client.

func (*Auth) Sessions

func (a *Auth) Sessions() session.Store

Sessions returns the configured session store.

func (*Auth) Users

func (a *Auth) Users() UserProvider

Users returns the configured user provider.

func (*Auth) ValidateJWTAccessToken

func (a *Auth) ValidateJWTAccessToken(ctx context.Context, tok string) (UserInfo, error)

ValidateJWTAccessToken verifies a signed JWT bearer token (signature, expiry, deny-list) and resolves its subject through the UserProvider.

func (*Auth) WriteCookie

func (a *Auth) WriteCookie(ctx *azugo.Context, d *CookieDirective)

WriteCookie applies a CookieDirective to the response.

type AuthorizationCodeGrantRequest

type AuthorizationCodeGrantRequest struct {
	Credentials   ClientCredentials
	Code          string
	RedirectURI   string
	CodeVerifier  string
	BaseURL       string
	MountPath     string
	TokenEndpoint string
	IP            string
}

AuthorizationCodeGrantRequest carries an authorization_code redemption.

type AuthorizeRequest

type AuthorizeRequest struct {
	ResponseType        string
	ClientID            string
	RedirectURI         string
	Scope               string
	State               string
	Nonce               string
	ACRValues           string
	CodeChallenge       string
	CodeChallengeMethod string
	// SessionToken is the presented session cookie establishing the user's identity.
	SessionToken string
}

AuthorizeRequest carries an OIDC authorization request (GET /authorize, response_type=code).

type AuthorizeResult

type AuthorizeResult struct {
	RedirectURI string
}

AuthorizeResult carries the redirect the caller should perform.

type ClaimMapper

type ClaimMapper = contract.ClaimMapper

ClaimMapper maps a UserInfo into token / id_token claims.

type ClaimMapperFunc

type ClaimMapperFunc = contract.ClaimMapperFunc

ClaimMapperFunc adapts a plain function to the ClaimMapper interface.

type ClientCredentials

type ClientCredentials struct {
	ClientID      string
	Secret        string
	AssertionType string
	Assertion     string
}

ClientCredentials carries the authentication material presented at a client-authenticated endpoint (/token, /introspect, /revoke).

type ClientCredentialsGrantRequest

type ClientCredentialsGrantRequest struct {
	Credentials   ClientCredentials
	Scope         string
	BaseURL       string
	MountPath     string
	TokenEndpoint string
	IP            string
}

ClientCredentialsGrantRequest carries a client_credentials request.

type Configuration

type Configuration = contract.Configuration

Configuration is the authentication configuration section.

type CookieCtx

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

CookieCtx provides session cookie attribute helpers derived from the auth configuration and app environment.

func (*CookieCtx) Path

func (c *CookieCtx) Path(baseURL, mountPath string) string

Path returns the effective session cookie path based on configuration.

func (*CookieCtx) SameSite

func (c *CookieCtx) SameSite() string

SameSite returns the effective cookie SameSite mode based on configuration.

func (*CookieCtx) Secure

func (c *CookieCtx) Secure(requestTLS bool) bool

Secure returns the effective cookie Secure flag for a request based on configuration.

type CookieDirective

type CookieDirective struct {
	Name, Value, Path, Domain string
	MaxAge                    int
	Secure, HTTPOnly          bool
	SameSite                  string
}

CookieDirective describes how to set or clear the session cookie.

A negative MaxAge deletes the cookie.

type ErrorCode

type ErrorCode string

ErrorCode is an RFC 6749 / RFC 6750 / RFC 9470 OAuth 2.0 error code.

const (
	ErrCodeLoginRequired                   ErrorCode = "login_required"
	ErrCodeSessionRevoked                  ErrorCode = "session_revoked"
	ErrCodeInvalidRequest                  ErrorCode = "invalid_request"
	ErrCodeInvalidClient                   ErrorCode = "invalid_client"
	ErrCodeInvalidGrant                    ErrorCode = "invalid_grant"
	ErrCodeUnauthorizedClient              ErrorCode = "unauthorized_client"
	ErrCodeUnsupportedGrantType            ErrorCode = "unsupported_grant_type"
	ErrCodeAccessDenied                    ErrorCode = "access_denied"
	ErrCodeUnmetAuthenticationRequirements ErrorCode = "unmet_authentication_requirements"
	ErrCodeInvalidDPoPProof                ErrorCode = "invalid_dpop_proof"
	ErrCodeUseDPoPNonce                    ErrorCode = "use_dpop_nonce"
	ErrCodeInvalidToken                    ErrorCode = "invalid_token"
	ErrCodeInsufficientScope               ErrorCode = "insufficient_scope"
	ErrCodeServerError                     ErrorCode = "server_error"
	ErrCodeUnsupportedResponseType         ErrorCode = "unsupported_response_type"
	ErrCodeInvalidScope                    ErrorCode = "invalid_scope"
	ErrCodeSlowDown                        ErrorCode = "slow_down"
)

OAuth error codes.

type ExternalUserProvider

type ExternalUserProvider = contract.ExternalUserProvider

ExternalUserProvider resolves identities for external IdP logins and passwordless authenticators.

type IntrospectRequest

type IntrospectRequest struct {
	Credentials   ClientCredentials
	Token         string
	BaseURL       string
	MountPath     string
	TokenEndpoint string
}

IntrospectRequest carries an RFC 7662 introspection request. The token_type_hint parameter is ignored.

type IntrospectionResponse

type IntrospectionResponse struct {
	Active    bool   `json:"active"`
	Scope     string `json:"scope,omitempty"`
	ClientID  string `json:"client_id,omitempty"`
	Username  string `json:"username,omitempty"`
	TokenType string `json:"token_type,omitempty"`
	Subject   string `json:"sub,omitempty"`
	Audience  string `json:"aud,omitempty"`
	Issuer    string `json:"iss,omitempty"`
	ExpiresAt int64  `json:"exp,omitempty"`
	IssuedAt  int64  `json:"iat,omitempty"`
	SessionID string `json:"sid,omitempty"`
}

IntrospectionResponse is the RFC 7662 introspection response.

type IssuerCtx

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

IssuerCtx provides OIDC issuer resolution helpers derived from the auth configuration.

func (*IssuerCtx) URL

func (c *IssuerCtx) URL(baseURL, mountPath string) string

URL returns the effective OIDC issuer.

type LoginRequest

type LoginRequest struct {
	ClientID   string
	Username   string
	Password   string
	ReturnTo   string
	RequestTLS bool
	BaseURL    string
	MountPath  string
	// IP is the caller's remote address.
	IP string
}

LoginRequest carries the password-grant credentials and the request-derived values.

type LoginResult

type LoginResult struct {
	Status      session.Status
	Cookie      *CookieDirective
	AccessToken string
	// IDToken is set only for a client.ResponseModeJSON client whose granted scope contains
	// "openid".
	IDToken   string
	ExpiresIn int
	Redirect  string
}

LoginResult is returned by Login and Refresh based on client mode and configuration.

type LogoutRequest

type LogoutRequest struct {
	Token      string
	RequestTLS bool
	BasePath   string
	MountPath  string
}

LogoutRequest carries the presented token and the request-derived values.

type LogoutResult

type LogoutResult struct {
	ClearCookie *CookieDirective
}

LogoutResult is returned by Logout.

type OAuthError

type OAuthError struct {
	// Code is the RFC 6749 error code (e.g. "invalid_token", "insufficient_scope").
	Code ErrorCode
	// Description is the human-readable error_description.
	Description string
	// RetryAfter, when non-zero, is surfaced as a Retry-After header (throttled requests).
	RetryAfter time.Duration
	// contains filtered or unexported fields
}

OAuthError represents an OAuth 2.0 error response.

func (*OAuthError) Error

func (e *OAuthError) Error() string

Error string.

func (*OAuthError) ErrorHeaders

func (e *OAuthError) ErrorHeaders() iter.Seq2[string, string]

ErrorHeaders sets the WWW-Authenticate: Bearer header and, when throttled, Retry-After.

func (*OAuthError) MarshalError

func (e *OAuthError) MarshalError(contentType string) ([]byte, string, bool)

MarshalError renders the RFC 6749 JSON response.

func (*OAuthError) SafeError

func (e *OAuthError) SafeError() string

SafeError returns error description.

func (*OAuthError) StatusCode

func (e *OAuthError) StatusCode() int

StatusCode to set for error response.

func (*OAuthError) Unwrap

func (e *OAuthError) Unwrap() error

Unwrap exposes the wrapped cause (set by NewOAuthErrorFrom) so the server can log/inspect the original error with errors.Is/As.

type OAuthErrorOption

type OAuthErrorOption func(*OAuthError)

OAuthErrorOption customizes an OAuthError at construction.

func OAuthErrorURI

func OAuthErrorURI(uri string) OAuthErrorOption

OAuthErrorURI sets the optional error_uri pointing to error documentation.

type Option

type Option func(*Auth)

Option configures an Auth instance at construction.

func CodeStore

func CodeStore(store code.Store) Option

CodeStore replaces the default cache-backed authorization-code store with a custom.

func CookieScopeToBasePath

func CookieScopeToBasePath() Option

CookieScopeToBasePath makes the default session cookie Path resolve to the app's base path.

func Events

func Events(sink event.Sink) Option

Events replaces the default audit event sink. The default writes each event as a structured log record via the request logger.

func JTIStore

func JTIStore(store jti.Store) Option

JTIStore replaces the default cache-backed CacheStore with a custom jti.Store.

func KeyProvider

func KeyProvider(p token.KeyProvider) Option

KeyProvider replaces the default ConfigKeyProvider with a custom.

func Throttle

func Throttle(t throttle.Throttle) Option

Throttle replaces the default ThrottleConfig-driven brute-force guard with a custom.

func Transactor

func Transactor(t TxRunner) Option

Transactor to allow to run multi-write handler sequences so they can be made atomic.

type PasswordChanger

type PasswordChanger = contract.PasswordChanger

PasswordChanger is an optional UserProvider extension for changing a password.

type PasswordResetter

type PasswordResetter = contract.PasswordResetter

PasswordResetter is an optional UserProvider extension for resetting a forgotten password.

type ProfileManager

type ProfileManager = contract.ProfileManager

ProfileManager is an optional UserProvider extension for user profile data.

type RefreshRequest

type RefreshRequest struct {
	Token      string
	ReturnTo   string
	RequestTLS bool
	BaseURL    string
	MountPath  string
}

RefreshRequest carries the presented refresh token and the request-derived values.

type Registerer

type Registerer = contract.Registerer

Registerer is an optional UserProvider extension for registering new accounts.

type RegistrationRequest

type RegistrationRequest = contract.RegistrationRequest

RegistrationRequest carries the data for a new user registration.

type RevokeTokenRequest

type RevokeTokenRequest struct {
	Credentials   ClientCredentials
	Token         string
	BaseURL       string
	MountPath     string
	TokenEndpoint string
	IP            string
}

RevokeTokenRequest carries an RFC 7009 revocation request. The token_type_hint parameter is ignored.

type TokenResult

type TokenResult struct {
	AccessToken string `json:"access_token"`
	TokenType   string `json:"token_type"`
	ExpiresIn   int    `json:"expires_in"`
	IDToken     string `json:"id_token,omitempty"`
	Scope       string `json:"scope,omitempty"`
}

TokenResult is the RFC 6749 §5.1 access token response for the authorization_code and client_credentials grants.

type TransactionCtx

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

TransactionCtx provides multi-write transaction helpers.

func (*TransactionCtx) Run

func (c *TransactionCtx) Run(ctx context.Context, fn func(ctx context.Context) error) error

Run executes function inside the transaction.

type TransactorFunc

type TransactorFunc func(ctx context.Context, fn func(ctx context.Context) error) error

TransactorFunc adapts a plain function to the TxRunner interface.

func (TransactorFunc) RunInTx

func (f TransactorFunc) RunInTx(ctx context.Context, fn func(ctx context.Context) error) error

RunInTx implements TxRunner.

type TxRunner

type TxRunner interface {
	RunInTx(ctx context.Context, fn func(ctx context.Context) error) error
}

TxRunner allows to run the multi-write handler sequences so they can be made atomic.

type UserInfo

type UserInfo = contract.UserInfo

UserInfo is the user record returned by a UserProvider.

type UserProvider

type UserProvider = contract.UserProvider

UserProvider validates credentials and loads user data.

Directories

Path Synopsis
Package client defines the OAuth client model and the Registry that resolves client metadata.
Package client defines the OAuth client model and the Registry that resolves client metadata.
Package code implements the single-use authorization codes minted by GET /authorize and redeemed by the authorization_code grant at POST /token.
Package code implements the single-use authorization codes minted by GET /authorize and redeemed by the authorization_code grant at POST /token.
Package contract holds the cross-cutting types and interfaces shared between the base auth package and the plugin packages.
Package contract holds the cross-cutting types and interfaces shared between the base auth package and the plugin packages.
Package event defines the audit event sink for security-relevant auth events.
Package event defines the audit event sink for security-relevant auth events.
Package jti implements the JTI (JWT/token ID) allowlist that backs token revocation and session-bound replay detection.
Package jti implements the JTI (JWT/token ID) allowlist that backs token revocation and session-bound replay detection.
Package middleware provides azugo HTTP middleware over the transport-free auth service.
Package middleware provides azugo HTTP middleware over the transport-free auth service.
Package routes is the optional HTTP adapter tier over the transport-free auth service.
Package routes is the optional HTTP adapter tier over the transport-free auth service.
Package session defines the server-side session model and the Store interface that persists it.
Package session defines the server-side session model and the Store interface that persists it.
Package throttle guards credential-checking endpoints against brute force.
Package throttle guards credential-checking endpoints against brute force.
Package token implements the PASETO v4.local tokens used by the auth library: short-lived access tokens, long-lived session cookies, and API-key tokens.
Package token implements the PASETO v4.local tokens used by the auth library: short-lived access tokens, long-lived session cookies, and API-key tokens.

Jump to

Keyboard shortcuts

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