auth

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package auth provides OIDC-based authentication primitives: a Validator interface plus a generic OIDCValidator implementation, principal extraction from a verified JWT, chi middleware that runs the validation, and helpers for scope-based authorisation. IdP-specific validators live in sub-packages and register themselves with the mode registry behind build tags. See `oidc_validator.go` for the generic JWT validation pipeline and `mode.go` for runtime mode selection.

Index

Constants

View Source
const MockAudience = "mock-client"

MockAudience is the audience claim expected by mock-mode tokens. The mockoidc fixture's Issue() helper sets `aud = clientID`, so callers minting tokens for mock-mode validation should use this string as the clientID.

Variables

View Source
var ErrModeUnavailable = errors.New("auth mode unavailable in this build")

ErrModeUnavailable indicates the requested KAFKITO_AUTH_MODE is not compiled in. Most notably, "off" is gated behind the `devauth` build tag.

Functions

func AudienceContains

func AudienceContains(tok jwt.Token, want string) bool

AudienceContains reports whether tok's "aud" claim contains want.

func HostBelongsToDomain

func HostBelongsToDomain(rawURL, domain string) bool

HostBelongsToDomain reports whether rawURL's host equals domain or sits one or more labels below it (e.g. "auth.example.com" belongs to "example.com"). The comparison is case-insensitive. Used by IdP-specific validators that constrain JKU URLs to an allow-list domain.

func Middleware

func Middleware(v Validator) func(http.Handler) http.Handler

Middleware returns an http middleware that validates the bearer token via v and stores the resulting Principal in the request context. On any failure it responds with 401 and writes a structured error.

func MiddlewareFor

func MiddlewareFor(v Validator) func(http.Handler) http.Handler

MiddlewareFor returns the correct http.Handler middleware for the given Validator. If v implements syntheticValidator (i.e. the devauth off-mode alwaysAllowValidator) the middleware injects the synthetic Principal on every request without requiring a Bearer header. Otherwise it delegates to Middleware which enforces bearer token validation.

func MiddlewareWithSyntheticPrincipal

func MiddlewareWithSyntheticPrincipal(p *Principal) func(http.Handler) http.Handler

MiddlewareWithSyntheticPrincipal injects p on every request without checking any header. Used by `off` mode so local dev does not need a token at all.

func Register

func Register(name string, factory ModeFactory)

Register binds a ModeFactory to the given mode name. Intended for use from init() in mode-specific files. Re-registering a name overwrites the previous factory; this is how mode_devauth.go upgrades "off" from the default (unavailable) to the synthetic-principal variant.

func RequireScope

func RequireScope(scope string) func(http.Handler) http.Handler

RequireScope returns middleware that 403s requests whose principal lacks scope. 401s if no principal is in context (i.e. Middleware did not run upstream).

func TokString

func TokString(tok jwt.Token, key string) (string, bool)

TokString reads a string-typed claim by key. Returns ok=false if the key is missing or has a non-string value.

func TokStringSlice

func TokStringSlice(tok jwt.Token, key string) []string

TokStringSlice reads a claim that may be either a JSON string array or a space-separated string (the latter being how some OIDC IdPs encode "scope"). Returns nil when the claim is missing or empty.

func WithPrincipal

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

WithPrincipal returns a context carrying p.

Types

type MockOIDC

type MockOIDC struct {
	Server *httptest.Server
	// contains filtered or unexported fields
}

MockOIDC is an in-process JWKS+token issuer used in tests. It signs RS256 tokens with a freshly generated key, exposes the public key at /jwks, and lets callers mint tokens with arbitrary claims via Issue().

By default the mock emits a generic OIDC token: scopes are written to the "scope" claim verbatim, and no tenant/zone claim is added. Callers that need tenant-flavored tokens (e.g. SAP-style scope namespacing or a zone claim) can opt in via MockOIDCOption values passed to NewMockOIDC.

func NewMockOIDC

func NewMockOIDC(opts ...MockOIDCOption) (*MockOIDC, error)

NewMockOIDC starts the mock and returns it. By default tokens carry no zone claim and scopes are not namespaced; use WithScopePrefix / WithZoneID to opt into tenant-flavored behavior.

func (*MockOIDC) Close

func (m *MockOIDC) Close()

Close stops the test server.

func (*MockOIDC) Host

func (m *MockOIDC) Host() string

Host returns the bare hostname (no port) of the mock server, suitable for use as a UAADomain in tests.

func (*MockOIDC) Issue

func (m *MockOIDC) Issue(sub, clientID, issuer string, scopes []string, extra map[string]any) (string, error)

Issue mints a signed RS256 JWT with sensible defaults plus caller-supplied claims. Pass scopes as local names; if the mock was constructed with WithScopePrefix, each scope is namespaced as prefix + "." + scope.

func (*MockOIDC) IssueWithoutJKU

func (m *MockOIDC) IssueWithoutJKU(sub, clientID, issuer string, scopes []string) (string, error)

IssueWithoutJKU mints a token like Issue but deliberately omits the jku header, for testing the validator's "missing jku" rejection branch.

func (*MockOIDC) JKU

func (m *MockOIDC) JKU() string

JKU returns the JWKS URL the mock serves.

type MockOIDCOption

type MockOIDCOption func(*MockOIDC)

MockOIDCOption configures a MockOIDC at construction time.

func WithScopePrefix

func WithScopePrefix(prefix string) MockOIDCOption

WithScopePrefix namespaces every scope passed to Issue/IssueWithoutJKU as prefix + "." + scope. An empty prefix disables namespacing (the default).

func WithZoneID

func WithZoneID(zoneID string) MockOIDCOption

WithZoneID makes the mock emit a "zid" claim on every issued token. An empty zoneID disables emission (the default).

type ModeConfig

type ModeConfig struct {
	// Mode selects which registered factory to use (e.g. "off", "mock"). The
	// set of valid values depends on the build tags the binary was compiled
	// with: a default build registers "off" and "mock"; tagged builds may
	// register additional IdP-specific modes.
	Mode string
	// VCAPServices is the raw VCAP_SERVICES JSON, used by IdP modes that
	// expect their credentials in a Cloud Foundry service binding.
	VCAPServices string
	// XSAppName is an IdP-specific application identifier consumed by modes
	// that need it. Ignored by the generic modes.
	XSAppName string
}

ModeConfig drives validator construction. Fields not relevant to a given mode are simply ignored by that mode's factory.

type ModeFactory

type ModeFactory func(cfg ModeConfig) (Validator, func(), error)

ModeFactory constructs a Validator for a registered auth mode. The returned cleanup function (may be nil) is run on shutdown by callers — used by the mock mode to stop its embedded JWKS server.

type OIDCConfig

type OIDCConfig struct {
	// IssuerURL is the expected "iss" claim. Tokens whose iss does not equal
	// this value (or, for compatibility with multi-tenant IdPs, sit immediately
	// under it via "<IssuerURL>/...") are rejected.
	IssuerURL string
	// Audience is the expected "aud" claim. Tokens whose aud claim does not
	// contain this value are rejected.
	Audience string
	// JWKSEndpoint is the URL serving the issuer's JSON Web Key Set used to
	// verify token signatures. Required: this generic validator does not
	// auto-discover via /.well-known/openid-configuration.
	JWKSEndpoint string
}

OIDCConfig configures a generic OIDC JWT validator.

type OIDCValidator

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

OIDCValidator validates RS-signed JWTs against a fixed issuer/audience and a JWKS endpoint. Use this as the default "mock" mode validator, and as a drop-in for any OIDC IdP that publishes a JWKS URL.

func NewOIDCValidator

func NewOIDCValidator(cfg OIDCConfig) (*OIDCValidator, error)

NewOIDCValidator constructs a validator. The JWKS cache is started lazily on first Validate call (per jwx semantics) and refreshes on unknown kid.

func (*OIDCValidator) Validate

func (o *OIDCValidator) Validate(ctx context.Context, raw string) (*Principal, error)

Validate parses and signature-verifies raw, then enforces iss/aud/exp/nbf.

type Principal

type Principal struct {
	Subject    string   // sub
	Email      string   // email (may be empty depending on IdP)
	UserName   string   // user_name (or preferred_username)
	GivenName  string   // given_name
	FamilyName string   // family_name
	Origin     string   // origin (IdP key)
	Tenant     string   // tenant identifier (claim shape varies per IdP)
	Scopes     []string // local scope names (IdP-specific prefixes stripped)
}

Principal is the authenticated caller as derived from a verified OIDC token (or a synthetic value injected by the dev/mock modes).

func PrincipalFromContext

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

PrincipalFromContext extracts the principal previously stored via WithPrincipal.

func (*Principal) HasScope

func (p *Principal) HasScope(name string) bool

HasScope reports whether the principal carries the given local scope name.

type Validator

type Validator interface {
	Validate(ctx context.Context, rawToken string) (*Principal, error)
}

Validator authenticates a raw bearer token and returns a Principal.

func BuildValidator

func BuildValidator(cfg ModeConfig) (Validator, func(), error)

BuildValidator returns the configured validator plus an optional cleanup function callers should defer (used by mock mode to stop the embedded server).

Jump to

Keyboard shortcuts

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