Documentation
¶
Overview ¶
Package auth integrates transport-layer httpauth.Provider chains into stdhttp.
Package auth integrates transport-layer httpauth.Provider chains into stdhttp (R4, design §13).
Index ¶
- func DefaultFrontendIDFromRequest(r *http.Request) string
- func Middleware(log *slog.Logger, providers []httpauth.Provider, next http.Handler) http.Handler
- func NewCredentialPresenceDispositionProbe(providers []httpauth.Provider) httpcontract.CredentialProbe
- func NewCredentialPresenceProbe(providers []httpauth.Provider) func(r *http.Request) bool
- func SelfDefenseMiddleware(log *slog.Logger, providers []httpauth.Provider, hooks SelfDefenseHooks, ...) http.Handler
- type DefaultAuthErrorRenderer
- type PolicyProvider
- type PolicySnapshot
- type SelfDefenseHooks
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Middleware ¶
Middleware returns an HTTP handler that runs providers in order before delegating to next. Provider errors are fail-closed (HTTP 500). Empty provider list is a no-op passthrough here only; product wiring must supply providers so anonymous pass-through never replaces configured authentication (auth-architecture 1.7 / 5.6). A non-empty nil-only list fails closed (HTTP 500). When log is non-nil, provider failures emit one structured log line (trace via request context). It is the zero-hook compatibility wrapper around SelfDefenseMiddleware and observes nothing.
func NewCredentialPresenceDispositionProbe ¶
func NewCredentialPresenceDispositionProbe(providers []httpauth.Provider) httpcontract.CredentialProbe
NewCredentialPresenceDispositionProbe is the disposition-returning sibling of NewCredentialPresenceProbe and the single fail-open decision point of the conservative credential-presence question. Both constructors run the same aggregate over the same fixed active provider set, so a composition root that projects the cycle-neutral disposition can never disagree with the boolean form: it must not re-derive, wrap or cache the answer itself.
The answer is httpcontract.DefinitelyNoCredential only when EVERY active provider proves the request cannot authenticate as presented; a provider that is credential-free, can authenticate the request, or cannot answer at all makes the whole chain httpcontract.MayAuthenticate, and an unusable active set returns a nil probe, which is structurally the safe default.
func NewCredentialPresenceProbe ¶
NewCredentialPresenceProbe aggregates one fixed active provider set into the conservative pre-auth credential-presence probe used to decide whether a quarantined source may still be refused before authentication. The answer is "cannot authenticate as presented" only when EVERY active provider proves it; a provider that is credential-free, can authenticate the request, or cannot answer at all makes the whole chain fail open, and an unusable active set fails open structurally with a nil result. This deliberately biases toward legitimate access rather than maximum auth-backend shielding, so a legitimate user behind shared NAT, VPN or corporate egress is never locked out by another actor on the same public address.
The decision itself lives in NewCredentialPresenceDispositionProbe, the disposition-returning sibling the composition root projects through the cycle-neutral self-defense contract; it must not be reimplemented there. This boolean form is only its inverse view, so the two can never answer differently for the same request and the composition root needs no second aggregate.
func SelfDefenseMiddleware ¶
func SelfDefenseMiddleware(log *slog.Logger, providers []httpauth.Provider, hooks SelfDefenseHooks, next http.Handler) http.Handler
SelfDefenseMiddleware is the observed variant the standard stack builds when ingress self-defense is enabled. It runs the same provider chain, renders the same responses and delegates to the same route mux as Middleware; the hooks only add authoritative adaptive state observation, and the zero SelfDefenseHooks value is exactly Middleware.
Types ¶
type DefaultAuthErrorRenderer ¶
type DefaultAuthErrorRenderer struct{}
DefaultAuthErrorRenderer maps authentication denials and challenges to generic, safe JSON (or empty body) and stable status codes. It does not include secrets or per-key material.
func (DefaultAuthErrorRenderer) RenderAuthError ¶
func (DefaultAuthErrorRenderer) RenderAuthError( ctx context.Context, in httpauth.AuthErrorRenderInput, ) httpauth.AuthErrorRenderResult
RenderAuthError implements httpauth.AuthErrorRenderer.
type PolicyProvider ¶
type PolicyProvider struct {
Auth coreauth.Authenticator
Events *coreauth.EventDispatcher
Policy PolicySnapshot
Renderer httpauth.AuthErrorRenderer
RendererByFrontend map[string]httpauth.AuthErrorRenderer
FrontendID func(*http.Request) string
HTTPHeaders lipsdk.HTTPHeaders
}
func NewPolicyProvider ¶
func NewPolicyProvider(authenticator coreauth.Authenticator, events *coreauth.EventDispatcher, pol PolicySnapshot, renderer httpauth.AuthErrorRenderer) *PolicyProvider
func (*PolicyProvider) Authenticate ¶
func (p *PolicyProvider) Authenticate(ctx context.Context, w http.ResponseWriter, r *http.Request) (httpauth.AuthenticationResult, error)
type PolicySnapshot ¶
type PolicySnapshot struct {
AccessMode auth.AccessMode
HandlerKind auth.HandlerKind
RequiredLevel auth.RequiredLevel
}
type SelfDefenseHooks ¶
type SelfDefenseHooks struct {
// RecordAuthFailure records exactly one counted unauthenticated-failure
// offense for the resolved source address of a terminal pre-principal 401.
RecordAuthFailure func(addr netip.Addr)
// ClearSource clears the adaptive hostile state of that exact source address
// after a full successful authentication chain.
ClearSource func(addr netip.Addr)
}
SelfDefenseHooks is the optional ingress self-defense observation seam the standard stack supplies when self-defense is enabled. The zero value observes nothing, which is the structural disabled posture: Middleware is then exactly the pre-existing request path. The hooks never decide an authentication outcome; the provider chain stays authoritative for status, headers and body, and both hooks are no-ops unless the outer gate published a source-address snapshot for this request.