Improve auth around osquery endpoints (#44209)

Added an optional HTTP-level pre-auth middleware (enabled using the
FLEET_OSQUERY_ALLOW_BODY_AUTH_FALLBACK server config) that validates
incoming osquery requests based on `Authorization: NodeKey <node_key>`
header.
This commit is contained in:
Juan Fernandez
2026-05-08 12:08:10 -04:00
committed by GitHub
parent d25a76ac7a
commit 0ef22939f4
14 changed files with 1335 additions and 70 deletions
+19 -1
View File
@@ -909,6 +909,10 @@ type CommonEndpointer[H any] struct {
// CustomMiddlewareAfterAuth are middlewares that run after authentication.
CustomMiddlewareAfterAuth []endpoint.Middleware
// HTTPPreAuthMiddleware wraps the final http.Handler, running BEFORE the
// kithttp decode-body step.
HTTPPreAuthMiddleware func(http.Handler) http.Handler
// HandlerRegistry, if set, records handlers by method+path for deprecated
// path alias lookup. The pointer is shared across shallow copies (created
// by builder methods like WithAltPaths) so all registrations land in the
@@ -991,7 +995,13 @@ func (e *CommonEndpointer[H]) makeEndpoint(f H, v interface{}) http.Handler {
// If no value is configured set default, or if the set endpoint value is less than global default use default.
e.requestBodySizeLimit = platform_http.MaxRequestBodySize
}
return newServer(endp, e.MakeDecoderFn(v, e.requestBodySizeLimit), e.EncodeFn, e.Opts)
h := newServer(endp, e.MakeDecoderFn(v, e.requestBodySizeLimit), e.EncodeFn, e.Opts)
// The HTTP pre-auth middleware runs outside the kithttp.Server so it can
// short-circuit requests before the decode-body step reads any bytes.
if e.HTTPPreAuthMiddleware != nil {
h = e.HTTPPreAuthMiddleware(h)
}
return h
}
func newServer(e endpoint.Endpoint, decodeFn kithttp.DecodeRequestFunc, encodeFn kithttp.EncodeResponseFunc,
@@ -1062,6 +1072,14 @@ func (e *CommonEndpointer[H]) SkipRequestBodySizeLimit() *CommonEndpointer[H] {
return &ae
}
// WithHTTPPreAuth installs a raw http.Handler middleware that runs outside the
// kithttp server, before the decoder reads the body.
func (e *CommonEndpointer[H]) WithHTTPPreAuth(mw func(http.Handler) http.Handler) *CommonEndpointer[H] {
ae := *e
ae.HTTPPreAuthMiddleware = mw
return &ae
}
// PathHandler registers a handler for the verb and path. The pathHandler is
// a function that receives the actual path to which it will be mounted, and
// returns the actual http.Handler that will handle this endpoint. This is for