Fleet server verifies HTTP signature (#30825)

Fixes #30473 

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] Added/updated automated tests
- [ ] Manual QA for all new/changed functionality

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for TPM-backed host identity certificates enabling
hardware-backed HTTP signature authentication for hosts.
* Introduced HTTP signature verification middleware for API requests,
applied conditionally for premium licenses.
* Hosts presenting identity certificates must authenticate with matching
HTTP message signatures during enrollment and authentication.
* Added SCEP-based certificate issuance for secure host identity
management.
* Updated enrollment endpoints to use standardized request/response
contract types.

* **Bug Fixes**
* Enhanced authentication logic to verify consistency between host
identity certificates and host records, preventing duplicate or
mismatched identities.

* **Chores**
* Updated dependencies and test infrastructure to support HTTP signature
verification and host identity certificate workflows.
* Added comprehensive integration and datastore tests for host identity
certificate issuance, storage, and authentication.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Victor Lyuboslavsky
2025-07-16 20:08:27 +02:00
committed by GitHub
parent a31db7fc83
commit 836cc044d2
31 changed files with 1883 additions and 428 deletions
+10
View File
@@ -26,6 +26,7 @@ import (
eeservice "github.com/fleetdm/fleet/v4/ee/server/service"
"github.com/fleetdm/fleet/v4/ee/server/service/digicert"
"github.com/fleetdm/fleet/v4/ee/server/service/hostidentity"
"github.com/fleetdm/fleet/v4/ee/server/service/hostidentity/httpsig"
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/fleetdm/fleet/v4/pkg/scripts"
"github.com/fleetdm/fleet/v4/server"
@@ -1073,6 +1074,14 @@ the way that the Fleet server works.
KeyPrefix: "ratelimit::",
}
var httpSigVerifier func(http.Handler) http.Handler
if license.IsPremium() {
httpSigVerifier, err = httpsig.Middleware(ds, kitlog.With(logger, "component", "http-sig-verifier"))
if err != nil {
initFatal(err, "initializing HTTP signature verifier")
}
}
var apiHandler, frontendHandler, endUserEnrollOTAHandler http.Handler
{
frontendHandler = service.PrometheusMetricsHandler(
@@ -1086,6 +1095,7 @@ the way that the Fleet server works.
if config.MDM.SSORateLimitPerMinute > 0 {
extra = append(extra, service.WithMdmSsoRateLimit(throttled.PerMin(config.MDM.SSORateLimitPerMinute)))
}
extra = append(extra, service.WithHTTPSigVerifier(httpSigVerifier))
apiHandler = service.MakeHandler(svc, config, httpLogger, limiterStore,
[]endpoint_utils.HandlerRoutesFunc{android_service.GetRoutes(svc, androidSvc)}, extra...)
+2 -1
View File
@@ -39,6 +39,7 @@ import (
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/mdm"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/service"
"github.com/fleetdm/fleet/v4/server/service/contract"
"github.com/google/uuid"
)
@@ -1272,7 +1273,7 @@ func (a *agent) waitingDo(fn func() *http.Request) *http.Response {
// now, we assume that the agent is not already enrolled, if you kill the agent
// process then those Orbit node keys are gone.
func (a *agent) orbitEnroll() error {
params := service.EnrollOrbitRequest{
params := contract.EnrollOrbitRequest{
EnrollSecret: a.EnrollSecret,
HardwareUUID: a.UUID,
HardwareSerial: a.SerialNumber,