auth

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package auth provides authentication and authorization building blocks: a transport-neutral Principal carried in context, credential extraction from HTTP requests, a pluggable Verifier (token -> Principal), a built-in JWT verifier, and net/http middleware for authentication and role-based access control.

The Verifier seam keeps the middleware independent of the token format: the bundled JWTVerifier covers HMAC and RSA/ECDSA (and JWKS via a custom Keyfunc), but any Verifier — an opaque-token introspection client, a test stub — plugs in the same way. Rejections are written as *errs.Error JSON with the right status (401/403), each carrying an i18n MessageID.

Usage

Build a Verifier, then compose the middleware onto your router. Authenticate both verifies and requires a token; RequireRole gates by role:

v, err := auth.NewJWTVerifier(auth.JWTConfig{
    HMACSecret: []byte(secret),
    Issuer:     "myapp",
    Audience:   "myapp-api",
})
if err != nil {
    return err
}

mux.Handle("/me", auth.Authenticate(v, log)(meHandler))
mux.Handle("/admin",
    auth.Authenticate(v, log)(auth.RequireRole("admin")(adminHandler)))

// Inside a handler, read the verified identity:
func meHandler(w http.ResponseWriter, r *http.Request) {
    p, ok := auth.PrincipalFromContext(r.Context())
    if !ok {
        return
    }
    _ = p.Subject
    if p.HasRole("admin") { /* ... */ }
}

Principal

Principal is the authenticated identity (Subject, Roles, and the full verified Claims). HasRole / HasAnyRole answer authorization questions; HasAnyRole with no arguments returns true (authentication alone suffices). WithPrincipal and PrincipalFromContext move it through the request context.

Credential extraction

BearerToken pulls a token from "Authorization: Bearer <token>" (case-insensitive scheme); APIKey reads a named header such as "X-API-Key".

Middleware

  • Authenticate — extract, verify, and require a token (401 on failure).
  • Optional — verify when present, never reject; an invalid token is ignored.
  • RequireAuthenticated — reject requests with no Principal (place after Optional).
  • RequireRole — 401 when unauthenticated, 403 when authenticated without a required role.

JWTConfig

Exactly one key source must be set: HMACSecret, RSAPublicKeyPEM, ECPublicKeyPEM, or a custom Keyfunc (use the latter for JWKS). Other fields:

  • ValidMethods — accepted "alg" values; defaults derive from the key source (HS*/RS*/ES*) and are required when using Keyfunc.
  • Issuer / Audience — validated against the token claims when set.
  • Leeway — clock-skew tolerance for time-based claims.
  • SubjectClaim — principal-id claim (default "sub").
  • RolesClaim — roles claim (default "roles"); accepts a JSON array of strings or a single space-separated string.

NewJWTVerifier always requires expiration and restricts accepted algorithms, so "alg":"none" and algorithm-confusion attacks are rejected.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func APIKey

func APIKey(r *http.Request, header string) (string, bool)

APIKey extracts a token from the named header (e.g. "X-API-Key").

func BearerToken

func BearerToken(r *http.Request) (string, bool)

BearerToken extracts a token from an "Authorization: Bearer <token>" header. The scheme match is case-insensitive.

func WithPrincipal

func WithPrincipal(ctx context.Context, p *Principal) context.Context

WithPrincipal returns a context carrying p.

Types

type JWTConfig

type JWTConfig struct {
	HMACSecret      []byte
	RSAPublicKeyPEM []byte
	ECPublicKeyPEM  []byte
	// Keyfunc overrides the key sources above (e.g. JWKS). When set, ValidMethods
	// should list the algorithms you accept.
	Keyfunc jwt.Keyfunc

	// ValidMethods restricts accepted "alg" values. Defaults are derived from the
	// configured key source (HS*/RS*/ES*); set explicitly when using Keyfunc.
	ValidMethods []string

	// Issuer / Audience, when set, are validated against the token claims.
	Issuer   string
	Audience string
	// Leeway tolerates small clock skew on time-based claims.
	Leeway time.Duration

	// SubjectClaim names the principal-id claim (default "sub").
	SubjectClaim string
	// RolesClaim names the roles claim (default "roles"). Accepts a JSON array of
	// strings or a single space-separated string.
	RolesClaim string
}

JWTConfig configures the built-in JWT verifier. Exactly one key source must be set: HMACSecret, RSAPublicKeyPEM, ECPublicKeyPEM, or a custom Keyfunc (use the latter for JWKS — e.g. a keyfunc backed by a remote key set).

type JWTVerifier

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

JWTVerifier verifies JWTs and maps their claims to a Principal.

func NewJWTVerifier

func NewJWTVerifier(cfg JWTConfig) (*JWTVerifier, error)

NewJWTVerifier builds a JWTVerifier from cfg.

func (*JWTVerifier) Verify

func (v *JWTVerifier) Verify(_ context.Context, token string) (*Principal, error)

Verify parses and validates token, returning its Principal.

type Middleware

type Middleware func(http.Handler) http.Handler

Middleware is standard net/http middleware (composes with router.Use).

func Authenticate

func Authenticate(v Verifier, log *logger.Logger) Middleware

Authenticate extracts a bearer token, verifies it, and stores the resulting Principal in the request context. Requests without a valid token are rejected with 401. log may be nil.

func Optional

func Optional(v Verifier) Middleware

Optional verifies a bearer token when present and stores the Principal, but never rejects the request. Downstream handlers use PrincipalFromContext (or RequireAuthenticated) to enforce access. An invalid token is ignored.

func RequireAuthenticated

func RequireAuthenticated() Middleware

RequireAuthenticated rejects requests that carry no Principal with 401. Place it after Optional, or use Authenticate which both verifies and requires.

func RequireRole

func RequireRole(roles ...string) Middleware

RequireRole rejects requests whose Principal lacks at least one of roles: 401 when unauthenticated, 403 when authenticated without a required role.

type Principal

type Principal struct {
	// Subject is the unique principal id (JWT "sub").
	Subject string
	// Roles are the principal's authorization roles.
	Roles []string
	// Claims carries the full, verified claim set for application use.
	Claims map[string]any
}

Principal is the authenticated identity attached to a request context.

func PrincipalFromContext

func PrincipalFromContext(ctx context.Context) (*Principal, bool)

PrincipalFromContext returns the principal stored by the middleware, if any.

func (*Principal) HasAnyRole

func (p *Principal) HasAnyRole(roles ...string) bool

HasAnyRole reports whether the principal has at least one of roles. With no roles given it returns true (authentication alone suffices).

func (*Principal) HasRole

func (p *Principal) HasRole(role string) bool

HasRole reports whether the principal has the given role.

type Verifier

type Verifier interface {
	Verify(ctx context.Context, token string) (*Principal, error)
}

Verifier turns a raw credential (e.g. a bearer token) into a Principal. Implementations must return a non-nil error for any invalid credential.

Jump to

Keyboard shortcuts

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