auth

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: AGPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package auth is the single contract for authenticating inbound HTTP requests in clank. One Authenticator interface, one Principal type, one Middleware. Self-hosters and embedders plug in custom verifiers (Supabase, Auth0, Keycloak, custom DB lookup, etc.) by implementing Authenticator and passing it via daemoncli.ServerOptions.Auth.

Bundled implementations:

  • JWTHS256: HS256 JWT verifier (dev / shared-secret deployments).
  • OIDC: RS256/ES256 JWT + JWKS verifier (production / SSO).
  • StaticBearer: fixed shared secret (opt-in CLANK_AUTH_TOKEN path).
  • AllowAll: no-op verifier for the unix-socket listener and tests.

Index

Constants

View Source
const BearerPrefix = "Bearer "

BearerPrefix is the case-sensitive prefix of the Authorization header value used throughout. Exported so verifiers don't have to agree on a magic string.

Variables

View Source
var ErrUnauthenticated = errors.New("auth: unauthenticated")

ErrUnauthenticated is the sentinel for "no/invalid credentials". Authenticator implementations should return this (or wrap it) and Middleware maps it to HTTP 401.

Functions

func ExtractBearer

func ExtractBearer(r *http.Request) (string, error)

ExtractBearer returns the token portion of the Authorization header, or empty + ErrUnauthenticated when absent/malformed. Helper for Authenticator implementations.

func Middleware

func Middleware(next http.Handler, a Authenticator) http.Handler

Middleware runs a.Verify on every request and, on success, injects the resulting Principal into the request context before delegating to next. On failure it returns 401 with a WWW-Authenticate header.

func WithPrincipal

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

WithPrincipal returns a copy of ctx with p stored. Middleware sets it after a successful Verify; downstream code reads via PrincipalFrom or MustPrincipal.

Types

type AllowAll

type AllowAll struct {
	UserID string
}

AllowAll accepts every request and resolves it to a fixed UserID. Used by the unix-socket listener (file permissions are the gate) and tests. Never use on a network-exposed listener.

func (*AllowAll) Verify

func (a *AllowAll) Verify(*http.Request) (Principal, error)

Verify always returns Principal{UserID: a.UserID}.

type Authenticator

type Authenticator interface {
	Verify(r *http.Request) (Principal, error)
}

Authenticator verifies an inbound request and returns the caller's Principal. Implementations should return ErrUnauthenticated (or a wrapped version) so Middleware can map the failure to 401.

type JWTHS256

type JWTHS256 struct {
	// Secret is the HMAC key. Required.
	Secret []byte

	// ClaimMapper extracts a Principal from verified claims. When nil,
	// the default mapper uses claims["sub"] as the UserID and stores
	// the full claim map on Principal.Claims.
	ClaimMapper func(jwt.MapClaims) (Principal, error)
}

JWTHS256 verifies HS256 JWTs signed with a shared Secret. Used by dev profiles (clank-auth-stub) and self-hosted single-secret deployments. For production OIDC/SSO, use OIDC instead.

func (*JWTHS256) Verify

func (a *JWTHS256) Verify(r *http.Request) (Principal, error)

Verify parses and verifies a Bearer token, then maps claims to a Principal. Uses jwt/v5's WithValidMethods to reject any algorithm other than HS256 (algorithm-confusion guard) and its built-in exp/nbf/iat validation.

type OIDC

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

OIDC verifies RS256/ES256 JWTs against a JWKS-published key set, enforces iss + aud claims, and maps a configurable claim to the Principal's UserID. Works with any standard OIDC provider (Auth0, Okta, Keycloak, Microsoft Entra, Google Workspace, Supabase, ...).

func NewOIDC

func NewOIDC(ctx context.Context, cfg OIDCConfig) (*OIDC, error)

NewOIDC constructs an OIDC Authenticator. Performs the initial JWKS fetch (and, when JWKSURL is unset, OIDC discovery). Returns an error when the IdP is unreachable, which surfaces misconfiguration at startup rather than at first request.

func (*OIDC) Verify

func (a *OIDC) Verify(r *http.Request) (Principal, error)

Verify validates a bearer JWT against the provider's JWKS and the configured issuer/audience/algorithms, then maps UserClaim to the Principal.

type OIDCConfig

type OIDCConfig struct {
	// Issuer is the OIDC provider's issuer URL. Required. Enforced
	// against the JWT "iss" claim and (when JWKSURL is unset) used
	// for discovery of jwks_uri.
	Issuer string

	// Audience is the expected JWT "aud" claim. Required. clankd
	// deployments typically set this to a clankd-specific audience
	// configured at the IdP (e.g. "clank-api").
	Audience string

	// JWKSURL is the JWK Set endpoint. Optional. When unset,
	// resolved via OIDC discovery from
	// {Issuer}/.well-known/openid-configuration.
	JWKSURL string

	// UserClaim is the claim name used to populate Principal.UserID.
	// Optional; defaults to "sub".
	UserClaim string

	// Algorithms restricts the accepted signing algorithms. Optional;
	// defaults to ["RS256", "ES256"]. "none" is never accepted.
	Algorithms []string

	// HTTPTimeout caps the OIDC discovery HTTP request. Optional;
	// defaults to 10s. JWKS fetches and refreshes use the keyfunc
	// library's defaults — configure those separately if needed.
	HTTPTimeout time.Duration
}

OIDCConfig configures an OIDC Authenticator. Issuer + Audience are required; JWKSURL is optional (discovered via the issuer's .well-known/openid-configuration when unset).

type Principal

type Principal struct {
	UserID string
	Claims map[string]any
}

Principal is the verified caller identity. Middleware injects it into the request context; downstream handlers read it via MustPrincipal. Claims carries the raw claim map produced by the underlying verifier (JWT payload, OAuth introspection response, etc.); it may be nil for verifiers that don't have one (e.g. StaticBearer, AllowAll).

func MustPrincipal

func MustPrincipal(ctx context.Context) Principal

MustPrincipal returns the Principal stored in ctx. Panics if absent — use at handler boundaries that are guaranteed to run after Middleware. Surfaces middleware-misconfiguration bugs loudly instead of silently producing requests with an empty UserID.

func PrincipalFrom

func PrincipalFrom(ctx context.Context) (Principal, bool)

PrincipalFrom returns the Principal stored in ctx, if any.

type StaticBearer

type StaticBearer struct {
	// Token is the expected bearer. Required.
	Token string

	// UserID is the Principal.UserID populated on a successful match.
	// Required (no implicit default — callers must decide what user
	// the shared bearer represents, e.g. the OS username).
	UserID string
}

StaticBearer verifies a fixed shared-secret Bearer token via constant-time compare. On match, every request resolves to the configured UserID. Useful only for single-user / self-hosted fallback (CLANK_AUTH_TOKEN); production deployments should use JWTHS256 or OIDC.

func (*StaticBearer) Verify

func (a *StaticBearer) Verify(r *http.Request) (Principal, error)

Verify compares the bearer to the configured token in constant time and returns Principal{UserID: a.UserID} on match.

Jump to

Keyboard shortcuts

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