auth

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Overview

Package auth handles authentication: it validates JWT Bearer tokens and records the caller's role, claims, and any token-validation error in the request context. It makes no authorization decisions and writes no HTTP responses — authorization lives in internal/policy (role checks) and the gates in internal/api (which translate decisions into HTTP responses).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AuthErrorFromContext

func AuthErrorFromContext(ctx context.Context) error

AuthErrorFromContext returns the token-validation error recorded when a present token failed to validate (bad signature, malformed, expired). It is nil for a valid token or for no token at all. Gates use it to fail loud — surfacing the token problem instead of a bare "forbidden" — when a request that fell back to the default role is denied for lacking permission.

func ClaimsFromContext

func ClaimsFromContext(ctx context.Context) (jwt.MapClaims, bool)

ClaimsFromContext extracts JWT claims from the request context. ok is false when no valid token established claims.

func IsOperator

func IsOperator(ctx context.Context) bool

IsOperator reports whether the request was authenticated with the operator key. See WithOperator.

func Middleware

func Middleware(cfg Config, store *policy.Store, logger *slog.Logger) (func(http.Handler) http.Handler, error)

Middleware authenticates Bearer tokens and records the caller's role, claims, and any validation error in the request context. Authentication is decoupled from authorization: this middleware NEVER rejects a request and writes no response. A missing token, a token with no role claim, or an invalid/expired/malformed token all yield an EMPTY role, which downstream gates resolve to the policy default_role. When a present token fails to validate, the (sanitized) error is stashed in the context so a gate that later denies the request can fail loud rather than silently treating the caller as the public default.

Verification is JWKS-or-HMAC, not both: when JWKSURL is configured (and initializes) JWKS is the sole verifier and the HMAC secret is ignored; otherwise the HMAC secret (JWTSecret) is used. Accepted signing algorithms are restricted to the active verifier's family (asymmetric for JWKS, HMAC otherwise) so a token can't force an alg-confusion or alg:none bypass. With neither JWKSURL nor JWTSecret configured, no token can validate and every request falls back to the default role — i.e. a pure public deployment.

If JWKSURL is set but its JWK Set can't be fetched at startup, Middleware returns an error so the caller can fail fast instead of booting into a degraded state where no token can validate.

When cfg.OperatorKey is set, a non-JWT operator path is checked before the Bearer token (see operatorKey below): a constant-time match on the presented credential authorizes a full-access platform operator independent of the JWT verifier. store and logger back that path — the live admin role is read from store per request, and operator authentications are logged at info (audit). A presented credential that does not match is logged at warn and counted by wavehouse_auth_operator_key_failures_total (a probing signal), then falls through like any unauthenticated request. Both store and logger may be nil when no operator key is configured.

func RoleFromContext

func RoleFromContext(ctx context.Context) string

RoleFromContext extracts the role string from the request context. An empty string means no role was established — no token, a token without a role claim, or an invalid/expired token — which callers resolve to the policy default_role via policy.ResolveRole.

func WithAuthError

func WithAuthError(ctx context.Context, err error) context.Context

WithAuthError returns a copy of ctx carrying a token-validation error, used by gates to fail loud when a request that fell back to the default role is denied. See AuthErrorFromContext.

func WithClaims

func WithClaims(ctx context.Context, claims jwt.MapClaims) context.Context

WithClaims returns a copy of ctx carrying the given JWT claims. Set by the middleware; exported so tests (and any code constructing an authenticated context) can establish identity.

func WithOperator

func WithOperator(ctx context.Context) context.Context

WithOperator returns a copy of ctx marked as a platform-operator request, set by the middleware when a valid operator key is presented (Authorization: Operator <key>, or the X-Operator-Key alias). The operator bit authorizes the admin surface independently of the policy — RequireAdmin honors it even when the policy is nil/deleted — so it is the break-glass path for restoring a wiped policy over HTTP.

func WithRole

func WithRole(ctx context.Context, role string) context.Context

WithRole returns a copy of ctx carrying the given role string.

Types

type Config

type Config struct {
	JWTSecret   string
	JWKSURL     string
	RoleClaim   string // dot-separated claim path, e.g. "role" or "app_metadata.role"
	OperatorKey string // optional non-JWT operator credential; a match on the presented credential (Authorization: Operator <key>, or the X-Operator-Key alias) authorizes a full-access platform operator (see Middleware)
}

Config holds configuration for the JWT authentication middleware.

Jump to

Keyboard shortcuts

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