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
- Variables
- func ExtractBearer(r *http.Request) (string, error)
- func Middleware(next http.Handler, a Authenticator) http.Handler
- func WithPrincipal(ctx context.Context, p Principal) context.Context
- type AllowAll
- type Authenticator
- type JWTHS256
- type OIDC
- type OIDCConfig
- type Principal
- type StaticBearer
Constants ¶
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 ¶
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 ¶
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.
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.
type Authenticator ¶
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.
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.
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 ¶
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 ¶
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.
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.