fleet/server/service/testing_utils.go

1508 lines
44 KiB
Go
Raw Normal View History

package service
import (
"context"
"crypto/sha256"
"crypto/tls"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"net/http/httptest"
"os"
"sort"
"sync"
"testing"
"time"
"github.com/WatchBeam/clock"
ma "github.com/fleetdm/fleet/v4/ee/maintained-apps"
"github.com/fleetdm/fleet/v4/ee/server/scim"
eeservice "github.com/fleetdm/fleet/v4/ee/server/service"
Okta SCEP endpoint (#34721) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34542 - Added SCEP endpoint for issuing certs for conditional access for Okta. Functionally similar to host identity and Apple MDM SCEP endpoints. - Changes file will be added later (this is a sub-task of the feature). - A standard SCEP payload can be used to get a cert to an Apple device: ``` <!-- SCEP Configuration --> <dict> <key>PayloadContent</key> <dict> <key>URL</key> <string>https://myfleet.example.com/api/fleet/conditional_access/scep</string> <key>Challenge</key> <string>ENROLLMENT_SECRET</string> <key>Keysize</key> <integer>2048</integer> <key>Key Type</key> <string>RSA</string> <key>Key Usage</key> <integer>5</integer> <key>ExtendedKeyUsage</key> <array> <string>1.3.6.1.5.5.7.3.2</string> </array> <key>Subject</key> <array> <array> <array> <string>CN</string> <string>Fleet conditional access for Okta</string> </array> </array> </array> <key>SubjectAltName</key> <dict> <key>uniformResourceIdentifier</key> <array> <string>urn:device:apple:uuid:%HardwareUUID%</string> </array> </dict> <key>Retries</key> <integer>3</integer> <key>RetryDelay</key> <integer>10</integer> <!-- ACL for browser access --> <key>AllowAllAppsAccess</key> <true/> <!-- Set true for Safari access. Set false if Safari support not needed. --> <key>KeyIsExtractable</key> <false/> </dict> <key>PayloadDescription</key> <string>Configures SCEP for Fleet conditional access for Okta certificate</string> <key>PayloadDisplayName</key> <string>Fleet conditional access SCEP</string> <key>PayloadIdentifier</key> <string>com.fleetdm.conditional-access-scep</string> <key>PayloadType</key> <string>com.apple.security.scep</string> <key>PayloadUUID</key> <string>B2C3D4E5-F6A7-4B6C-9D8E-0F1A2B3C4D5E</string> <key>PayloadVersion</key> <integer>1</integer> </dict> ``` # Checklist for submitter ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features * Adds Conditional Access SCEP certificate enrollment support, enabling hosts to obtain device identity certificates through secure certificate enrollment protocol endpoints. * Implements rate limiting for certificate enrollment requests to prevent abuse. ## Tests * Adds comprehensive integration tests for Conditional Access SCEP functionality, including certificate operations, rate limiting validation, and edge cases. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-06 23:07:17 +00:00
"github.com/fleetdm/fleet/v4/ee/server/service/condaccess"
"github.com/fleetdm/fleet/v4/ee/server/service/digicert"
"github.com/fleetdm/fleet/v4/ee/server/service/est"
Add SCEP endpoint for host identity. (#30589) Fixes #30458 Contributor docs PR: https://github.com/fleetdm/fleet/pull/30651 # Checklist for submitter - We will add changes file later. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [x] If database migrations are included, checked table schema to confirm autoupdate - For database migrations: - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [x] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [x] Added/updated automated tests - Did not do manual QA since the SCEP client I have doesn't support ECC. Will rely on next subtasks for manual QA. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced Host Identity SCEP (Simple Certificate Enrollment Protocol) support, enabling secure host identity certificate enrollment and management. * Added new API endpoints for Host Identity SCEP, including certificate issuance and retrieval. * Implemented MySQL-backed storage and management for host identity SCEP certificates and serials. * Added new database tables for storing host identity SCEP certificates and serial numbers. * Provided utilities for encoding certificates and keys, and handling ECDSA public keys. * **Bug Fixes** * None. * **Tests** * Added comprehensive integration and unit tests for Host Identity SCEP functionality, including certificate issuance, validation, and error scenarios. * **Chores** * Updated test utilities to support unique test names and new SCEP storage options. * Extended mock datastore and interfaces for new host identity certificate methods. * **Documentation** * Added comments and documentation for new SCEP-related interfaces, methods, and database schema changes. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-11 14:44:07 +00:00
"github.com/fleetdm/fleet/v4/ee/server/service/hostidentity"
"github.com/fleetdm/fleet/v4/ee/server/service/hostidentity/httpsig"
speed up macOS profile delivery for initial enrollments (#41960) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34433 It speeds up the cron, meaning fleetd, bootstrap and now profiles should be sent within 10 seconds of being known to fleet, compared to the previous 1 minute. It's heavily based on my last PR, so the structure and changes are close to identical, with some small differences. **I did not do the redis key part in this PR, as I think that should come in it's own PR, to avoid overlooking logic bugs with that code, and since this one is already quite sized since we're moving core pieces of code around.** # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Faster macOS onboarding: device profiles are delivered and installed as part of DEP enrollment, shortening initial setup. * Improved profile handling: per-host profile preprocessing, secret detection, and clearer failure marking. * **Improvements** * Consolidated SCEP/NDES error messaging for clearer diagnostics. * Cron/work scheduling tuned to prioritize Apple MDM profile delivery. * **Tests** * Expanded MDM unit and integration tests, including DeclarativeManagement handling. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-19 19:58:10 +00:00
"github.com/fleetdm/fleet/v4/ee/server/service/scep"
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
"github.com/fleetdm/fleet/v4/server/acl/activityacl"
activity_api "github.com/fleetdm/fleet/v4/server/activity/api"
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
activity_bootstrap "github.com/fleetdm/fleet/v4/server/activity/bootstrap"
"github.com/fleetdm/fleet/v4/server/authz"
2021-06-26 04:46:51 +00:00
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/contexts/license"
"github.com/fleetdm/fleet/v4/server/datastore/cached_mysql"
"github.com/fleetdm/fleet/v4/server/datastore/filesystem"
New rate limit algorithm for Fleet Desktop endpoints (#33344) Resolves #31890 This new approach allows up to 1000 consecutive failing requests per minute. If the threshold of 1000 consecutive failures is reached for an IP, then we ban request (return 429) from such IP for a duration of 1 minute. (Any successful request for an IP clears the count.) This supports the scenario where all hosts are behind a NAT (same IP) AND still provides protection against brute force attacks (attackers can only probe 1k requests per minute). This approach was discussed in Slack with @rfairburn: https://fleetdm.slack.com/archives/C051QJU3D0V/p1755625131298319?thread_ts=1755101701.844249&cid=C051QJU3D0V. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [X] Added/updated automated tests - [X] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [X] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - New Features - Introduced IP-based rate limiting for Fleet Desktop endpoints to better support many hosts behind a single public IP (NAT). Requests from abusive IPs may be temporarily blocked, returning 429 Too Many Requests with a retry-after hint. - Documentation - Added README for a new desktop rate-limit tester, describing usage and expected behavior. - Tests - Added integration tests covering desktop endpoint rate limiting and Redis-backed banning logic. - Chores - Added a command-line tool to stress-test desktop endpoints and verify rate limiting behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-09-26 18:03:50 +00:00
"github.com/fleetdm/fleet/v4/server/datastore/redis"
"github.com/fleetdm/fleet/v4/server/datastore/redis/redistest"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/errorstore"
2021-06-26 04:46:51 +00:00
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/logging"
Fix SMTP e-mail send when SMTP server has credentials (#10758) #9609 This PR also fixes #10777. The issue is: We were using `svc.AppConfig` instead of `svc.ds.AppConfig` to retrieve the SMTP credentials. `svc.AppConfig` obfuscates credentials, whereas `svc.ds.AppConfig` does not. To help prevent this from happening again I've renamed `svc.AppConfig` to `svc.AppConfigObfuscated`. I've also added a new test SMTP server (https://github.com/axllent/mailpit) that supports Basic Authentication and tests that make use of it to catch these kind of bugs (the tests are executed when running `go test` with `MAIL_TEST=1`). - [X] Changes file added for user-visible changes in `changes/` or `orbit/changes/`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - ~[ ] Documented any API changes (docs/Using-Fleet/REST-API.md or docs/Contributing/API-for-contributors.md)~ - ~[ ] Documented any permissions changes~ - ~[ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements)~ - ~[ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features.~ - [X] Added/updated tests - [X] Manual QA for all new/changed functionality - ~For Orbit and Fleet Desktop changes:~ - ~[ ] Manual QA must be performed in the three main OSs, macOS, Windows and Linux.~ - ~[ ] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)).~
2023-03-28 18:23:15 +00:00
"github.com/fleetdm/fleet/v4/server/mail"
"github.com/fleetdm/fleet/v4/server/mdm/android"
android_mock "github.com/fleetdm/fleet/v4/server/mdm/android/mock"
android_service "github.com/fleetdm/fleet/v4/server/mdm/android/service"
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
maintained_apps "github.com/fleetdm/fleet/v4/server/mdm/maintainedapps"
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
nanodep_storage "github.com/fleetdm/fleet/v4/server/mdm/nanodep/storage"
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/mdm"
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/push"
nanomdm_push "github.com/fleetdm/fleet/v4/server/mdm/nanomdm/push"
scep_depot "github.com/fleetdm/fleet/v4/server/mdm/scep/depot"
fleet_mock "github.com/fleetdm/fleet/v4/server/mock"
nanodep_mock "github.com/fleetdm/fleet/v4/server/mock/nanodep"
"github.com/fleetdm/fleet/v4/server/platform/endpointer"
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
common_mysql "github.com/fleetdm/fleet/v4/server/platform/mysql"
2021-06-26 04:46:51 +00:00
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/service/async"
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
"github.com/fleetdm/fleet/v4/server/service/middleware/auth"
"github.com/fleetdm/fleet/v4/server/service/mock"
"github.com/fleetdm/fleet/v4/server/service/redis_key_value"
"github.com/fleetdm/fleet/v4/server/service/redis_lock"
"github.com/fleetdm/fleet/v4/server/sso"
"github.com/fleetdm/fleet/v4/server/test"
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
"github.com/go-kit/kit/endpoint"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/throttled/throttled/v2"
"github.com/throttled/throttled/v2/store/memstore"
"google.golang.org/api/androidmanagement/v1"
)
func newTestService(t *testing.T, ds fleet.Datastore, rs fleet.QueryResultStore, lq fleet.LiveQueryStore, opts ...*TestServerOpts) (fleet.Service, context.Context) {
return newTestServiceWithConfig(t, ds, config.TestConfig(), rs, lq, opts...)
}
func newTestServiceWithConfig(t *testing.T, ds fleet.Datastore, fleetConfig config.FleetConfig, rs fleet.QueryResultStore, lq fleet.LiveQueryStore, opts ...*TestServerOpts) (fleet.Service, context.Context) {
lic := &fleet.LicenseInfo{Tier: fleet.TierFree}
logger := slog.New(slog.DiscardHandler)
writer, err := logging.NewFilesystemLogWriter(t.Context(), fleetConfig.Filesystem.StatusLogFile, logger, fleetConfig.Filesystem.EnableLogRotation,
Changes needed before gokit/log to slog transition. (#39527) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #38889 PLEASE READ BELOW before looking at file changes Before converting individual files/packages to slog, we generally need to make these 2 changes to make the conversion easier: - Replace uses of `kitlog.With` since they are not fully compatible with our kitlog adapter - Directly use the kitlog adapter logger type instead of the kitlog interface, which will let us have direct access to the underlying slog logger: `*logging.Logger` Note: that I did not replace absolutely all uses of `kitlog.Logger`, but I did remove all uses of `kitlog.With` except for these due to complexity: - server/logging/filesystem.go and the other log writers (webhook, firehose, kinesis, lambda, pubsub, nats) - server/datastore/mysql/nanomdm_storage.go (adapter pattern) - server/vulnerabilities/nvd/* (cascades to CLI tools) - server/service/osquery_utils/queries.go (callback type signatures cascade broadly) - cmd/maintained-apps/ (standalone, so can be transitioned later all at once) Most of the changes in this PR follow these patterns: - `kitlog.Logger` type → `*logging.Logger` - `kitlog.With(logger, ...)` → `logger.With(...)` - `kitlog.NewNopLogger() → logging.NewNopLogger()`, including similar variations such as `logging.NewLogfmtLogger(w)` and `logging.NewJSONLogger(w)` - removed many now-unused kitlog imports Unique changes that the PR review should focus on: - server/platform/logging/kitlog_adapter.go: Core adapter changes - server/platform/logging/logging.go: New convenience functions - server/service/integration_logger_test.go: Test changes for slog # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - Was added in previous PR ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Migrated the codebase to a unified internal structured logging system for more consistent, reliable logs and observability. * No user-facing functionality changed; runtime behavior and APIs remain compatible. * **Tests** * Updated tests to use the new logging helpers to ensure consistent test logging and validation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-11 16:08:33 +00:00
fleetConfig.Filesystem.EnableLogCompression, 500, 28, 3)
require.NoError(t, err)
osqlogger := &OsqueryLogger{Status: writer, Result: writer}
var (
Microsoft Compliance Partner backend changes (#29540) For #27042. Ready for review, just missing integration tests that I will be writing today. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features. - [X] If database migrations are included, checked table schema to confirm autoupdate - For new Fleet configuration settings - [X] Verified that the setting can be managed via GitOps, or confirmed that the setting is explicitly being excluded from GitOps. If managing via Gitops: - [X] Verified that the setting is exported via `fleetctl generate-gitops` - [X] Added the setting to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [X] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled - For database migrations: - [X] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [X] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [X] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [x] Added/updated automated tests - [X] Manual QA for all new/changed functionality --------- Co-authored-by: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-06-11 17:22:46 +00:00
failingPolicySet fleet.FailingPolicySet = NewMemFailingPolicySet()
enrollHostLimiter fleet.EnrollHostLimiter = nopEnrollHostLimiter{}
depStorage nanodep_storage.AllDEPStorage = &nanodep_mock.Storage{}
mailer fleet.MailService = &mockMailService{SendEmailFn: func(e fleet.Email) error { return nil }}
c clock.Clock = clock.C
speed up macOS profile delivery for initial enrollments (#41960) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34433 It speeds up the cron, meaning fleetd, bootstrap and now profiles should be sent within 10 seconds of being known to fleet, compared to the previous 1 minute. It's heavily based on my last PR, so the structure and changes are close to identical, with some small differences. **I did not do the redis key part in this PR, as I think that should come in it's own PR, to avoid overlooking logic bugs with that code, and since this one is already quite sized since we're moving core pieces of code around.** # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Faster macOS onboarding: device profiles are delivered and installed as part of DEP enrollment, shortening initial setup. * Improved profile handling: per-host profile preprocessing, secret detection, and clearer failure marking. * **Improvements** * Consolidated SCEP/NDES error messaging for clearer diagnostics. * Cron/work scheduling tuned to prioritize Apple MDM profile delivery. * **Tests** * Expanded MDM unit and integration tests, including DeclarativeManagement handling. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-19 19:58:10 +00:00
scepConfigService = scep.NewSCEPConfigService(logger, nil)
digiCertService = digicert.NewService(digicert.WithLogger(logger))
estCAService = est.NewService(est.WithLogger(logger))
Microsoft Compliance Partner backend changes (#29540) For #27042. Ready for review, just missing integration tests that I will be writing today. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features. - [X] If database migrations are included, checked table schema to confirm autoupdate - For new Fleet configuration settings - [X] Verified that the setting can be managed via GitOps, or confirmed that the setting is explicitly being excluded from GitOps. If managing via Gitops: - [X] Verified that the setting is exported via `fleetctl generate-gitops` - [X] Added the setting to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [X] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled - For database migrations: - [X] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [X] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [X] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [x] Added/updated automated tests - [X] Manual QA for all new/changed functionality --------- Co-authored-by: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-06-11 17:22:46 +00:00
conditionalAccessMicrosoftProxy ConditionalAccessMicrosoftProxy
mdmStorage fleet.MDMAppleStore
mdmPusher nanomdm_push.Pusher
ssoStore sso.SessionStore
profMatcher fleet.ProfileMatcher
softwareInstallStore fleet.SoftwareInstallerStore
bootstrapPackageStore fleet.MDMBootstrapPackageStore
softwareTitleIconStore fleet.SoftwareTitleIconStore
distributedLock fleet.Lock
keyValueStore fleet.KeyValueStore
androidService android.Service
)
if len(opts) > 0 {
if opts[0].Clock != nil {
c = opts[0].Clock
}
}
if len(opts) > 0 && opts[0].KeyValueStore != nil {
keyValueStore = opts[0].KeyValueStore
}
OpenTelemetry minor improvements (#32324) Fixes #32313 OpenTelemetry Tracing - Added tracing to async task collectors: FlushHostsLastSeen, collectHostsLastSeen, collectLabelQueryExecutions, collectPolicyQueryExecutions, collectScheduledQueryStats - Updated HTTP middleware to use OTEL semantic convention for span names ({method} {route}) - Added OTELEnabled() helper to FleetConfig Optimizations - Reduced OTEL batch size from 512 to 256 spans to prevent gRPC message size errors - Enabled gzip compression for trace exports NOTE: I tried to improve OTEL instrumentation for cron jobs, but it got too complicated due to goroutines in `schedule.go` so that effort should be separate. We do have SQL instrumentation for cron jobs, but we are missing root spans for cron jobs as a whole. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Expanded OpenTelemetry tracing for async tasks (host last seen, label membership, policy membership, scheduled query stats) to provide richer observability. * More descriptive HTTP span names using “METHOD /route” for clearer trace analysis. * **Bug Fixes** * Improved OTLP gRPC exporter reliability by enabling gzip compression and reducing export batch size, mitigating intermittent gRPC errors. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-08-29 00:32:46 +00:00
task := async.NewTask(ds, nil, c, nil)
if len(opts) > 0 {
if opts[0].Task != nil {
task = opts[0].Task
} else {
opts[0].Task = task
}
}
if len(opts) > 0 {
if opts[0].Logger != nil {
logger = opts[0].Logger
}
if opts[0].License != nil {
lic = opts[0].License
}
if opts[0].Pool != nil {
ssoStore = sso.NewSessionStore(opts[0].Pool)
profMatcher = apple_mdm.NewProfileMatcher(opts[0].Pool)
distributedLock = redis_lock.NewLock(opts[0].Pool)
keyValueStore = redis_key_value.New(opts[0].Pool)
}
if opts[0].ProfileMatcher != nil {
profMatcher = opts[0].ProfileMatcher
}
if opts[0].FailingPolicySet != nil {
failingPolicySet = opts[0].FailingPolicySet
}
if opts[0].EnrollHostLimiter != nil {
enrollHostLimiter = opts[0].EnrollHostLimiter
}
Fix SMTP e-mail send when SMTP server has credentials (#10758) #9609 This PR also fixes #10777. The issue is: We were using `svc.AppConfig` instead of `svc.ds.AppConfig` to retrieve the SMTP credentials. `svc.AppConfig` obfuscates credentials, whereas `svc.ds.AppConfig` does not. To help prevent this from happening again I've renamed `svc.AppConfig` to `svc.AppConfigObfuscated`. I've also added a new test SMTP server (https://github.com/axllent/mailpit) that supports Basic Authentication and tests that make use of it to catch these kind of bugs (the tests are executed when running `go test` with `MAIL_TEST=1`). - [X] Changes file added for user-visible changes in `changes/` or `orbit/changes/`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - ~[ ] Documented any API changes (docs/Using-Fleet/REST-API.md or docs/Contributing/API-for-contributors.md)~ - ~[ ] Documented any permissions changes~ - ~[ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements)~ - ~[ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features.~ - [X] Added/updated tests - [X] Manual QA for all new/changed functionality - ~For Orbit and Fleet Desktop changes:~ - ~[ ] Manual QA must be performed in the three main OSs, macOS, Windows and Linux.~ - ~[ ] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)).~
2023-03-28 18:23:15 +00:00
if opts[0].UseMailService {
mailer, err = mail.NewService(config.TestConfig())
require.NoError(t, err)
Fix SMTP e-mail send when SMTP server has credentials (#10758) #9609 This PR also fixes #10777. The issue is: We were using `svc.AppConfig` instead of `svc.ds.AppConfig` to retrieve the SMTP credentials. `svc.AppConfig` obfuscates credentials, whereas `svc.ds.AppConfig` does not. To help prevent this from happening again I've renamed `svc.AppConfig` to `svc.AppConfigObfuscated`. I've also added a new test SMTP server (https://github.com/axllent/mailpit) that supports Basic Authentication and tests that make use of it to catch these kind of bugs (the tests are executed when running `go test` with `MAIL_TEST=1`). - [X] Changes file added for user-visible changes in `changes/` or `orbit/changes/`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - ~[ ] Documented any API changes (docs/Using-Fleet/REST-API.md or docs/Contributing/API-for-contributors.md)~ - ~[ ] Documented any permissions changes~ - ~[ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements)~ - ~[ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features.~ - [X] Added/updated tests - [X] Manual QA for all new/changed functionality - ~For Orbit and Fleet Desktop changes:~ - ~[ ] Manual QA must be performed in the three main OSs, macOS, Windows and Linux.~ - ~[ ] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)).~
2023-03-28 18:23:15 +00:00
}
if opts[0].SoftwareInstallStore != nil {
softwareInstallStore = opts[0].SoftwareInstallStore
}
if opts[0].BootstrapPackageStore != nil {
bootstrapPackageStore = opts[0].BootstrapPackageStore
}
if opts[0].SoftwareTitleIconStore != nil {
softwareTitleIconStore = opts[0].SoftwareTitleIconStore
}
Add Apple MDM functionality (#7940) * WIP * Adding DEP functionality to Fleet * Better organize additional MDM code * Add cmdr.py and amend API paths * Fix lint * Add demo file * Fix demo.md * go mod tidy * Add munki setup to Fleet * Add diagram to demo.md * Add fixes * Update TODOs and demo.md * Fix cmdr.py and add TODO * Add endpoints to demo.md * Add more Munki PoC/demo stuff * WIP * Remove proposals from PoC * Replace prepare commands with fleetctl commands * Update demo.md with current state * Remove config field * Amend demo * Remove Munki setup from MVP-Dogfood * Update demo.md * Add apple mdm commands (#7769) * fleetctl enqueue mdm command * fix deps * Fix build Co-authored-by: Lucas Rodriguez <lucas@fleetdm.com> * Add command to upload installers * go mod tidy * fix subcommands help There is a bug in urfave/cli where help text is not generated properly when subcommands are nested too deep. * Add support for installing apps * Add a way to list enrolled devices * Add dep listing * Rearrange endpoints * Move DEP routine to schedule * Define paths globally * Add a way to list enrollments and installers * Parse device-ids as comma-separated string * Remove unused types * Add simple commands and nest under enqueue-command * Fix simple commands * Add help to enqueue-command * merge apple_mdm database * Fix commands * update nanomdm * Split nanomdm and nanodep schemas * Set 512 MB in memory for upload * Remove empty file * Amend profile * Add sample commands * Add delete installers and fix bug in DEP profile assigning * Add dogfood.md deployment guide * Update schema.sql * Dump schema with MySQL 5 * Set default value for authenticate_at * add tokens to enrollment profiles When a device downloads an MDM enrollment profile, verify the token passed as a query parameter. This ensures untrusted devices don't enroll with our MDM server. - Rename enrollments to enrollment profiles. Enrollments is used by nano to refer to devices that are enrolled with MDM - Rename endpoint /api/<version>/fleet/mdm/apple/enrollments to ../enrollmentprofiles - Generate a token for authentication when creating an enrollment profile - Return unauthorized if token is invalid when downloading an enrollment profile from /api/mdm/apple/enroll?token= * remove mdm apple server url * update docs * make dump-test-schema * Update nanomdm with missing prefix table * Add docs and simplify changes * Add changes file * Add method docs * Fix compile and revert prepare.go changes * Revert migration status check change * Amend comments * Add more docs * Clarify storage of installers * Remove TODO * Remove unused * update dogfood.md * remove cmdr.py * Add authorization tests * Add TODO comment * use kitlog for nano logging * Add yaml tags * Remove unused flag * Remove changes file * Only run DEP routine if MDM is enabled * Add docs to all new exported types * Add docs * more nano logging changes * Fix unintentional removal * more nano logging changes * Fix compile test * Use string for configs and fix config test * Add docs and amend changes * revert changes to basicAuthHandler * remove exported BasicAuthHandler * rename rego authz type * Add more information to dep list * add db tag * update deps * Fix schema * Remove unimplemented Co-authored-by: Michal Nicpon <39177923+michalnicp@users.noreply.github.com> Co-authored-by: Michal Nicpon <michal@fleetdm.com>
2022-10-05 22:53:54 +00:00
// allow to explicitly set MDM storage to nil
mdmStorage = opts[0].MDMStorage
if opts[0].DEPStorage != nil {
depStorage = opts[0].DEPStorage
}
Add Apple MDM functionality (#7940) * WIP * Adding DEP functionality to Fleet * Better organize additional MDM code * Add cmdr.py and amend API paths * Fix lint * Add demo file * Fix demo.md * go mod tidy * Add munki setup to Fleet * Add diagram to demo.md * Add fixes * Update TODOs and demo.md * Fix cmdr.py and add TODO * Add endpoints to demo.md * Add more Munki PoC/demo stuff * WIP * Remove proposals from PoC * Replace prepare commands with fleetctl commands * Update demo.md with current state * Remove config field * Amend demo * Remove Munki setup from MVP-Dogfood * Update demo.md * Add apple mdm commands (#7769) * fleetctl enqueue mdm command * fix deps * Fix build Co-authored-by: Lucas Rodriguez <lucas@fleetdm.com> * Add command to upload installers * go mod tidy * fix subcommands help There is a bug in urfave/cli where help text is not generated properly when subcommands are nested too deep. * Add support for installing apps * Add a way to list enrolled devices * Add dep listing * Rearrange endpoints * Move DEP routine to schedule * Define paths globally * Add a way to list enrollments and installers * Parse device-ids as comma-separated string * Remove unused types * Add simple commands and nest under enqueue-command * Fix simple commands * Add help to enqueue-command * merge apple_mdm database * Fix commands * update nanomdm * Split nanomdm and nanodep schemas * Set 512 MB in memory for upload * Remove empty file * Amend profile * Add sample commands * Add delete installers and fix bug in DEP profile assigning * Add dogfood.md deployment guide * Update schema.sql * Dump schema with MySQL 5 * Set default value for authenticate_at * add tokens to enrollment profiles When a device downloads an MDM enrollment profile, verify the token passed as a query parameter. This ensures untrusted devices don't enroll with our MDM server. - Rename enrollments to enrollment profiles. Enrollments is used by nano to refer to devices that are enrolled with MDM - Rename endpoint /api/<version>/fleet/mdm/apple/enrollments to ../enrollmentprofiles - Generate a token for authentication when creating an enrollment profile - Return unauthorized if token is invalid when downloading an enrollment profile from /api/mdm/apple/enroll?token= * remove mdm apple server url * update docs * make dump-test-schema * Update nanomdm with missing prefix table * Add docs and simplify changes * Add changes file * Add method docs * Fix compile and revert prepare.go changes * Revert migration status check change * Amend comments * Add more docs * Clarify storage of installers * Remove TODO * Remove unused * update dogfood.md * remove cmdr.py * Add authorization tests * Add TODO comment * use kitlog for nano logging * Add yaml tags * Remove unused flag * Remove changes file * Only run DEP routine if MDM is enabled * Add docs to all new exported types * Add docs * more nano logging changes * Fix unintentional removal * more nano logging changes * Fix compile test * Use string for configs and fix config test * Add docs and amend changes * revert changes to basicAuthHandler * remove exported BasicAuthHandler * rename rego authz type * Add more information to dep list * add db tag * update deps * Fix schema * Remove unimplemented Co-authored-by: Michal Nicpon <39177923+michalnicp@users.noreply.github.com> Co-authored-by: Michal Nicpon <michal@fleetdm.com>
2022-10-05 22:53:54 +00:00
// allow to explicitly set mdm pusher to nil
mdmPusher = opts[0].MDMPusher
}
ctx := license.NewContext(context.Background(), lic)
2022-11-28 19:28:06 +00:00
cronSchedulesService := fleet.NewCronSchedules()
var eh *errorstore.Handler
if len(opts) > 0 {
if opts[0].Pool != nil {
eh = errorstore.NewHandler(ctx, opts[0].Pool, logger, time.Minute*10)
ctx = ctxerr.NewContext(ctx, eh)
}
if opts[0].StartCronSchedules != nil {
for _, fn := range opts[0].StartCronSchedules {
err = cronSchedulesService.StartCronSchedule(fn(ctx, ds))
require.NoError(t, err)
}
2022-11-28 19:28:06 +00:00
}
}
if len(opts) > 0 && opts[0].SCEPConfigService != nil {
scepConfigService = opts[0].SCEPConfigService
}
if len(opts) > 0 && opts[0].DigiCertService != nil {
digiCertService = opts[0].DigiCertService
}
Microsoft Compliance Partner backend changes (#29540) For #27042. Ready for review, just missing integration tests that I will be writing today. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features. - [X] If database migrations are included, checked table schema to confirm autoupdate - For new Fleet configuration settings - [X] Verified that the setting can be managed via GitOps, or confirmed that the setting is explicitly being excluded from GitOps. If managing via Gitops: - [X] Verified that the setting is exported via `fleetctl generate-gitops` - [X] Added the setting to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [X] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled - For database migrations: - [X] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [X] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [X] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [x] Added/updated automated tests - [X] Manual QA for all new/changed functionality --------- Co-authored-by: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-06-11 17:22:46 +00:00
if len(opts) > 0 && opts[0].ConditionalAccessMicrosoftProxy != nil {
conditionalAccessMicrosoftProxy = opts[0].ConditionalAccessMicrosoftProxy
fleetConfig.MicrosoftCompliancePartner.ProxyAPIKey = "insecure" // setting this so the feature is "enabled".
}
2022-11-28 19:28:06 +00:00
if len(opts) > 0 && opts[0].androidModule != nil {
androidService = opts[0].androidModule
}
var wstepManager microsoft_mdm.CertManager
if fleetConfig.MDM.WindowsWSTEPIdentityCert != "" && fleetConfig.MDM.WindowsWSTEPIdentityKey != "" {
rawCert, err := os.ReadFile(fleetConfig.MDM.WindowsWSTEPIdentityCert)
require.NoError(t, err)
rawKey, err := os.ReadFile(fleetConfig.MDM.WindowsWSTEPIdentityKey)
require.NoError(t, err)
wstepManager, err = microsoft_mdm.NewCertManager(ds, rawCert, rawKey)
require.NoError(t, err)
}
Add Apple MDM functionality (#7940) * WIP * Adding DEP functionality to Fleet * Better organize additional MDM code * Add cmdr.py and amend API paths * Fix lint * Add demo file * Fix demo.md * go mod tidy * Add munki setup to Fleet * Add diagram to demo.md * Add fixes * Update TODOs and demo.md * Fix cmdr.py and add TODO * Add endpoints to demo.md * Add more Munki PoC/demo stuff * WIP * Remove proposals from PoC * Replace prepare commands with fleetctl commands * Update demo.md with current state * Remove config field * Amend demo * Remove Munki setup from MVP-Dogfood * Update demo.md * Add apple mdm commands (#7769) * fleetctl enqueue mdm command * fix deps * Fix build Co-authored-by: Lucas Rodriguez <lucas@fleetdm.com> * Add command to upload installers * go mod tidy * fix subcommands help There is a bug in urfave/cli where help text is not generated properly when subcommands are nested too deep. * Add support for installing apps * Add a way to list enrolled devices * Add dep listing * Rearrange endpoints * Move DEP routine to schedule * Define paths globally * Add a way to list enrollments and installers * Parse device-ids as comma-separated string * Remove unused types * Add simple commands and nest under enqueue-command * Fix simple commands * Add help to enqueue-command * merge apple_mdm database * Fix commands * update nanomdm * Split nanomdm and nanodep schemas * Set 512 MB in memory for upload * Remove empty file * Amend profile * Add sample commands * Add delete installers and fix bug in DEP profile assigning * Add dogfood.md deployment guide * Update schema.sql * Dump schema with MySQL 5 * Set default value for authenticate_at * add tokens to enrollment profiles When a device downloads an MDM enrollment profile, verify the token passed as a query parameter. This ensures untrusted devices don't enroll with our MDM server. - Rename enrollments to enrollment profiles. Enrollments is used by nano to refer to devices that are enrolled with MDM - Rename endpoint /api/<version>/fleet/mdm/apple/enrollments to ../enrollmentprofiles - Generate a token for authentication when creating an enrollment profile - Return unauthorized if token is invalid when downloading an enrollment profile from /api/mdm/apple/enroll?token= * remove mdm apple server url * update docs * make dump-test-schema * Update nanomdm with missing prefix table * Add docs and simplify changes * Add changes file * Add method docs * Fix compile and revert prepare.go changes * Revert migration status check change * Amend comments * Add more docs * Clarify storage of installers * Remove TODO * Remove unused * update dogfood.md * remove cmdr.py * Add authorization tests * Add TODO comment * use kitlog for nano logging * Add yaml tags * Remove unused flag * Remove changes file * Only run DEP routine if MDM is enabled * Add docs to all new exported types * Add docs * more nano logging changes * Fix unintentional removal * more nano logging changes * Fix compile test * Use string for configs and fix config test * Add docs and amend changes * revert changes to basicAuthHandler * remove exported BasicAuthHandler * rename rego authz type * Add more information to dep list * add db tag * update deps * Fix schema * Remove unimplemented Co-authored-by: Michal Nicpon <39177923+michalnicp@users.noreply.github.com> Co-authored-by: Michal Nicpon <michal@fleetdm.com>
2022-10-05 22:53:54 +00:00
svc, err := NewService(
ctx,
Add Apple MDM functionality (#7940) * WIP * Adding DEP functionality to Fleet * Better organize additional MDM code * Add cmdr.py and amend API paths * Fix lint * Add demo file * Fix demo.md * go mod tidy * Add munki setup to Fleet * Add diagram to demo.md * Add fixes * Update TODOs and demo.md * Fix cmdr.py and add TODO * Add endpoints to demo.md * Add more Munki PoC/demo stuff * WIP * Remove proposals from PoC * Replace prepare commands with fleetctl commands * Update demo.md with current state * Remove config field * Amend demo * Remove Munki setup from MVP-Dogfood * Update demo.md * Add apple mdm commands (#7769) * fleetctl enqueue mdm command * fix deps * Fix build Co-authored-by: Lucas Rodriguez <lucas@fleetdm.com> * Add command to upload installers * go mod tidy * fix subcommands help There is a bug in urfave/cli where help text is not generated properly when subcommands are nested too deep. * Add support for installing apps * Add a way to list enrolled devices * Add dep listing * Rearrange endpoints * Move DEP routine to schedule * Define paths globally * Add a way to list enrollments and installers * Parse device-ids as comma-separated string * Remove unused types * Add simple commands and nest under enqueue-command * Fix simple commands * Add help to enqueue-command * merge apple_mdm database * Fix commands * update nanomdm * Split nanomdm and nanodep schemas * Set 512 MB in memory for upload * Remove empty file * Amend profile * Add sample commands * Add delete installers and fix bug in DEP profile assigning * Add dogfood.md deployment guide * Update schema.sql * Dump schema with MySQL 5 * Set default value for authenticate_at * add tokens to enrollment profiles When a device downloads an MDM enrollment profile, verify the token passed as a query parameter. This ensures untrusted devices don't enroll with our MDM server. - Rename enrollments to enrollment profiles. Enrollments is used by nano to refer to devices that are enrolled with MDM - Rename endpoint /api/<version>/fleet/mdm/apple/enrollments to ../enrollmentprofiles - Generate a token for authentication when creating an enrollment profile - Return unauthorized if token is invalid when downloading an enrollment profile from /api/mdm/apple/enroll?token= * remove mdm apple server url * update docs * make dump-test-schema * Update nanomdm with missing prefix table * Add docs and simplify changes * Add changes file * Add method docs * Fix compile and revert prepare.go changes * Revert migration status check change * Amend comments * Add more docs * Clarify storage of installers * Remove TODO * Remove unused * update dogfood.md * remove cmdr.py * Add authorization tests * Add TODO comment * use kitlog for nano logging * Add yaml tags * Remove unused flag * Remove changes file * Only run DEP routine if MDM is enabled * Add docs to all new exported types * Add docs * more nano logging changes * Fix unintentional removal * more nano logging changes * Fix compile test * Use string for configs and fix config test * Add docs and amend changes * revert changes to basicAuthHandler * remove exported BasicAuthHandler * rename rego authz type * Add more information to dep list * add db tag * update deps * Fix schema * Remove unimplemented Co-authored-by: Michal Nicpon <39177923+michalnicp@users.noreply.github.com> Co-authored-by: Michal Nicpon <michal@fleetdm.com>
2022-10-05 22:53:54 +00:00
ds,
task,
rs,
logger,
Add Apple MDM functionality (#7940) * WIP * Adding DEP functionality to Fleet * Better organize additional MDM code * Add cmdr.py and amend API paths * Fix lint * Add demo file * Fix demo.md * go mod tidy * Add munki setup to Fleet * Add diagram to demo.md * Add fixes * Update TODOs and demo.md * Fix cmdr.py and add TODO * Add endpoints to demo.md * Add more Munki PoC/demo stuff * WIP * Remove proposals from PoC * Replace prepare commands with fleetctl commands * Update demo.md with current state * Remove config field * Amend demo * Remove Munki setup from MVP-Dogfood * Update demo.md * Add apple mdm commands (#7769) * fleetctl enqueue mdm command * fix deps * Fix build Co-authored-by: Lucas Rodriguez <lucas@fleetdm.com> * Add command to upload installers * go mod tidy * fix subcommands help There is a bug in urfave/cli where help text is not generated properly when subcommands are nested too deep. * Add support for installing apps * Add a way to list enrolled devices * Add dep listing * Rearrange endpoints * Move DEP routine to schedule * Define paths globally * Add a way to list enrollments and installers * Parse device-ids as comma-separated string * Remove unused types * Add simple commands and nest under enqueue-command * Fix simple commands * Add help to enqueue-command * merge apple_mdm database * Fix commands * update nanomdm * Split nanomdm and nanodep schemas * Set 512 MB in memory for upload * Remove empty file * Amend profile * Add sample commands * Add delete installers and fix bug in DEP profile assigning * Add dogfood.md deployment guide * Update schema.sql * Dump schema with MySQL 5 * Set default value for authenticate_at * add tokens to enrollment profiles When a device downloads an MDM enrollment profile, verify the token passed as a query parameter. This ensures untrusted devices don't enroll with our MDM server. - Rename enrollments to enrollment profiles. Enrollments is used by nano to refer to devices that are enrolled with MDM - Rename endpoint /api/<version>/fleet/mdm/apple/enrollments to ../enrollmentprofiles - Generate a token for authentication when creating an enrollment profile - Return unauthorized if token is invalid when downloading an enrollment profile from /api/mdm/apple/enroll?token= * remove mdm apple server url * update docs * make dump-test-schema * Update nanomdm with missing prefix table * Add docs and simplify changes * Add changes file * Add method docs * Fix compile and revert prepare.go changes * Revert migration status check change * Amend comments * Add more docs * Clarify storage of installers * Remove TODO * Remove unused * update dogfood.md * remove cmdr.py * Add authorization tests * Add TODO comment * use kitlog for nano logging * Add yaml tags * Remove unused flag * Remove changes file * Only run DEP routine if MDM is enabled * Add docs to all new exported types * Add docs * more nano logging changes * Fix unintentional removal * more nano logging changes * Fix compile test * Use string for configs and fix config test * Add docs and amend changes * revert changes to basicAuthHandler * remove exported BasicAuthHandler * rename rego authz type * Add more information to dep list * add db tag * update deps * Fix schema * Remove unimplemented Co-authored-by: Michal Nicpon <39177923+michalnicp@users.noreply.github.com> Co-authored-by: Michal Nicpon <michal@fleetdm.com>
2022-10-05 22:53:54 +00:00
osqlogger,
fleetConfig,
mailer,
c,
ssoStore,
lq,
ds,
failingPolicySet,
&fleet.NoOpGeoIP{},
enrollHostLimiter,
depStorage,
mdmStorage,
mdmPusher,
2022-11-28 19:28:06 +00:00
cronSchedulesService,
wstepManager,
scepConfigService,
digiCertService,
Microsoft Compliance Partner backend changes (#29540) For #27042. Ready for review, just missing integration tests that I will be writing today. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features. - [X] If database migrations are included, checked table schema to confirm autoupdate - For new Fleet configuration settings - [X] Verified that the setting can be managed via GitOps, or confirmed that the setting is explicitly being excluded from GitOps. If managing via Gitops: - [X] Verified that the setting is exported via `fleetctl generate-gitops` - [X] Added the setting to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [X] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled - For database migrations: - [X] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [X] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [X] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [x] Added/updated automated tests - [X] Manual QA for all new/changed functionality --------- Co-authored-by: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-06-11 17:22:46 +00:00
conditionalAccessMicrosoftProxy,
keyValueStore,
androidService,
Add Apple MDM functionality (#7940) * WIP * Adding DEP functionality to Fleet * Better organize additional MDM code * Add cmdr.py and amend API paths * Fix lint * Add demo file * Fix demo.md * go mod tidy * Add munki setup to Fleet * Add diagram to demo.md * Add fixes * Update TODOs and demo.md * Fix cmdr.py and add TODO * Add endpoints to demo.md * Add more Munki PoC/demo stuff * WIP * Remove proposals from PoC * Replace prepare commands with fleetctl commands * Update demo.md with current state * Remove config field * Amend demo * Remove Munki setup from MVP-Dogfood * Update demo.md * Add apple mdm commands (#7769) * fleetctl enqueue mdm command * fix deps * Fix build Co-authored-by: Lucas Rodriguez <lucas@fleetdm.com> * Add command to upload installers * go mod tidy * fix subcommands help There is a bug in urfave/cli where help text is not generated properly when subcommands are nested too deep. * Add support for installing apps * Add a way to list enrolled devices * Add dep listing * Rearrange endpoints * Move DEP routine to schedule * Define paths globally * Add a way to list enrollments and installers * Parse device-ids as comma-separated string * Remove unused types * Add simple commands and nest under enqueue-command * Fix simple commands * Add help to enqueue-command * merge apple_mdm database * Fix commands * update nanomdm * Split nanomdm and nanodep schemas * Set 512 MB in memory for upload * Remove empty file * Amend profile * Add sample commands * Add delete installers and fix bug in DEP profile assigning * Add dogfood.md deployment guide * Update schema.sql * Dump schema with MySQL 5 * Set default value for authenticate_at * add tokens to enrollment profiles When a device downloads an MDM enrollment profile, verify the token passed as a query parameter. This ensures untrusted devices don't enroll with our MDM server. - Rename enrollments to enrollment profiles. Enrollments is used by nano to refer to devices that are enrolled with MDM - Rename endpoint /api/<version>/fleet/mdm/apple/enrollments to ../enrollmentprofiles - Generate a token for authentication when creating an enrollment profile - Return unauthorized if token is invalid when downloading an enrollment profile from /api/mdm/apple/enroll?token= * remove mdm apple server url * update docs * make dump-test-schema * Update nanomdm with missing prefix table * Add docs and simplify changes * Add changes file * Add method docs * Fix compile and revert prepare.go changes * Revert migration status check change * Amend comments * Add more docs * Clarify storage of installers * Remove TODO * Remove unused * update dogfood.md * remove cmdr.py * Add authorization tests * Add TODO comment * use kitlog for nano logging * Add yaml tags * Remove unused flag * Remove changes file * Only run DEP routine if MDM is enabled * Add docs to all new exported types * Add docs * more nano logging changes * Fix unintentional removal * more nano logging changes * Fix compile test * Use string for configs and fix config test * Add docs and amend changes * revert changes to basicAuthHandler * remove exported BasicAuthHandler * rename rego authz type * Add more information to dep list * add db tag * update deps * Fix schema * Remove unimplemented Co-authored-by: Michal Nicpon <39177923+michalnicp@users.noreply.github.com> Co-authored-by: Michal Nicpon <michal@fleetdm.com>
2022-10-05 22:53:54 +00:00
)
if err != nil {
panic(err)
}
if lic.IsPremium() {
if softwareInstallStore == nil {
// default to file-based
dir := t.TempDir()
store, err := filesystem.NewSoftwareInstallerStore(dir)
if err != nil {
panic(err)
}
softwareInstallStore = store
}
var androidModule android.Service
if len(opts) > 0 {
androidModule = opts[0].androidModule
}
svc, err = eeservice.NewService(
svc,
ds,
logger,
fleetConfig,
mailer,
c,
depStorage,
apple_mdm.NewMDMAppleCommander(mdmStorage, mdmPusher),
ssoStore,
profMatcher,
softwareInstallStore,
bootstrapPackageStore,
softwareTitleIconStore,
distributedLock,
keyValueStore,
Hydrant CA Feature Branch (#31807) There are still some TODOs particularly within Gitops test code which will be worked on in a followup PR # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [ ] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [x] Confirmed that the fix is not expected to adversely impact load test results - [x] Alerted the release DRI if additional load testing is needed ## Database migrations - [x] Checked table schema to confirm autoupdate - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [x] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). ## New Fleet configuration settings - [ ] Setting(s) is/are explicitly excluded from GitOps If you didn't check the box above, follow this checklist for GitOps-enabled settings: - [ ] Verified that the setting is exported via `fleetctl generate-gitops` - [x] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [x] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled --------- Co-authored-by: Gabriel Hernandez <ghernandez345@gmail.com> Co-authored-by: Magnus Jensen <magnus@fleetdm.com> Co-authored-by: Sarah Gillespie <73313222+gillespi314@users.noreply.github.com>
2025-09-04 16:39:41 +00:00
scepConfigService,
digiCertService,
androidModule,
estCAService,
)
if err != nil {
panic(err)
}
}
// Set up mock activity service for unit tests. When DBConns is provided,
// RunServerForTestsWithServiceWithDS will overwrite this with the real bounded context.
activityMock := &fleet_mock.MockActivityService{
NewActivityFunc: func(_ context.Context, _ *activity_api.User, _ activity_api.ActivityDetails) error {
return nil
},
}
svc.SetActivityService(activityMock)
if len(opts) > 0 {
opts[0].ActivityMock = activityMock
}
return svc, ctx
}
func newTestServiceWithClock(t *testing.T, ds fleet.Datastore, rs fleet.QueryResultStore, lq fleet.LiveQueryStore, c clock.Clock) (fleet.Service, context.Context) {
testConfig := config.TestConfig()
return newTestServiceWithConfig(t, ds, testConfig, rs, lq, &TestServerOpts{
Clock: c,
})
}
func createTestUsers(t *testing.T, ds fleet.Datastore) map[string]fleet.User {
users := make(map[string]fleet.User)
// Map iteration is random so we sort and iterate using the testUsers keys.
var keys []string
for key := range testUsers {
keys = append(keys, key)
}
sort.Strings(keys)
userID := uint(1)
for _, key := range keys {
u := testUsers[key]
user := &fleet.User{
ID: userID, // We need to set this in case ds is a mocked Datastore.
Name: "Test Name " + u.Email,
Email: u.Email,
GlobalRole: u.GlobalRole,
}
err := user.SetPassword(u.PlaintextPassword, 10, 10)
require.Nil(t, err)
user, err = ds.NewUser(context.Background(), user)
require.Nil(t, err)
users[user.Email] = *user
userID++
}
return users
}
const (
TestAdminUserEmail = "admin1@example.com"
TestMaintainerUserEmail = "user1@example.com"
TestObserverUserEmail = "user2@example.com"
)
var testUsers = map[string]struct {
Email string
PlaintextPassword string
GlobalRole *string
}{
"admin1": {
PlaintextPassword: test.GoodPassword,
Email: TestAdminUserEmail,
GlobalRole: ptr.String(fleet.RoleAdmin),
},
"user1": {
PlaintextPassword: test.GoodPassword,
Email: TestMaintainerUserEmail,
GlobalRole: ptr.String(fleet.RoleMaintainer),
},
"user2": {
PlaintextPassword: test.GoodPassword,
Email: TestObserverUserEmail,
GlobalRole: ptr.String(fleet.RoleObserver),
},
}
func createEnrollSecrets(t *testing.T, count int) []*fleet.EnrollSecret {
secrets := make([]*fleet.EnrollSecret, count)
for i := 0; i < count; i++ {
secrets[i] = &fleet.EnrollSecret{Secret: fmt.Sprintf("testSecret%d", i)}
}
return secrets
}
type mockMailService struct {
SendEmailFn func(e fleet.Email) error
Invoked bool
}
func (svc *mockMailService) SendEmail(ctx context.Context, e fleet.Email) error {
svc.Invoked = true
return svc.SendEmailFn(e)
}
func (svc *mockMailService) CanSendEmail(smtpSettings fleet.SMTPSettings) bool {
return smtpSettings.SMTPConfigured
}
2022-11-28 19:28:06 +00:00
type TestNewScheduleFunc func(ctx context.Context, ds fleet.Datastore) fleet.NewCronScheduleFunc
// HostIdentity combines host identity-related test options
type HostIdentity struct {
SCEPStorage scep_depot.Depot
RequireHTTPMessageSignature bool
}
Okta SCEP endpoint (#34721) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34542 - Added SCEP endpoint for issuing certs for conditional access for Okta. Functionally similar to host identity and Apple MDM SCEP endpoints. - Changes file will be added later (this is a sub-task of the feature). - A standard SCEP payload can be used to get a cert to an Apple device: ``` <!-- SCEP Configuration --> <dict> <key>PayloadContent</key> <dict> <key>URL</key> <string>https://myfleet.example.com/api/fleet/conditional_access/scep</string> <key>Challenge</key> <string>ENROLLMENT_SECRET</string> <key>Keysize</key> <integer>2048</integer> <key>Key Type</key> <string>RSA</string> <key>Key Usage</key> <integer>5</integer> <key>ExtendedKeyUsage</key> <array> <string>1.3.6.1.5.5.7.3.2</string> </array> <key>Subject</key> <array> <array> <array> <string>CN</string> <string>Fleet conditional access for Okta</string> </array> </array> </array> <key>SubjectAltName</key> <dict> <key>uniformResourceIdentifier</key> <array> <string>urn:device:apple:uuid:%HardwareUUID%</string> </array> </dict> <key>Retries</key> <integer>3</integer> <key>RetryDelay</key> <integer>10</integer> <!-- ACL for browser access --> <key>AllowAllAppsAccess</key> <true/> <!-- Set true for Safari access. Set false if Safari support not needed. --> <key>KeyIsExtractable</key> <false/> </dict> <key>PayloadDescription</key> <string>Configures SCEP for Fleet conditional access for Okta certificate</string> <key>PayloadDisplayName</key> <string>Fleet conditional access SCEP</string> <key>PayloadIdentifier</key> <string>com.fleetdm.conditional-access-scep</string> <key>PayloadType</key> <string>com.apple.security.scep</string> <key>PayloadUUID</key> <string>B2C3D4E5-F6A7-4B6C-9D8E-0F1A2B3C4D5E</string> <key>PayloadVersion</key> <integer>1</integer> </dict> ``` # Checklist for submitter ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features * Adds Conditional Access SCEP certificate enrollment support, enabling hosts to obtain device identity certificates through secure certificate enrollment protocol endpoints. * Implements rate limiting for certificate enrollment requests to prevent abuse. ## Tests * Adds comprehensive integration tests for Conditional Access SCEP functionality, including certificate operations, rate limiting validation, and edge cases. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-06 23:07:17 +00:00
// ConditionalAccess combines conditional access-related test options
type ConditionalAccess struct {
SCEPStorage scep_depot.Depot
}
type TestServerOpts struct {
Logger *slog.Logger
Microsoft Compliance Partner backend changes (#29540) For #27042. Ready for review, just missing integration tests that I will be writing today. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features. - [X] If database migrations are included, checked table schema to confirm autoupdate - For new Fleet configuration settings - [X] Verified that the setting can be managed via GitOps, or confirmed that the setting is explicitly being excluded from GitOps. If managing via Gitops: - [X] Verified that the setting is exported via `fleetctl generate-gitops` - [X] Added the setting to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [X] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled - For database migrations: - [X] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [X] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [X] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [x] Added/updated automated tests - [X] Manual QA for all new/changed functionality --------- Co-authored-by: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-06-11 17:22:46 +00:00
License *fleet.LicenseInfo
SkipCreateTestUsers bool
Rs fleet.QueryResultStore
Lq fleet.LiveQueryStore
Pool fleet.RedisPool
FailingPolicySet fleet.FailingPolicySet
Clock clock.Clock
Task *async.Task
EnrollHostLimiter fleet.EnrollHostLimiter
Is fleet.InstallerStore
FleetConfig *config.FleetConfig
MDMStorage fleet.MDMAppleStore
DEPStorage nanodep_storage.AllDEPStorage
SCEPStorage scep_depot.Depot
MDMPusher nanomdm_push.Pusher
HTTPServerConfig *http.Server
StartCronSchedules []TestNewScheduleFunc
UseMailService bool
APNSTopic string
ProfileMatcher fleet.ProfileMatcher
EnableCachedDS bool
NoCacheDatastore bool
SoftwareInstallStore fleet.SoftwareInstallerStore
BootstrapPackageStore fleet.MDMBootstrapPackageStore
SoftwareTitleIconStore fleet.SoftwareTitleIconStore
Microsoft Compliance Partner backend changes (#29540) For #27042. Ready for review, just missing integration tests that I will be writing today. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features. - [X] If database migrations are included, checked table schema to confirm autoupdate - For new Fleet configuration settings - [X] Verified that the setting can be managed via GitOps, or confirmed that the setting is explicitly being excluded from GitOps. If managing via Gitops: - [X] Verified that the setting is exported via `fleetctl generate-gitops` - [X] Added the setting to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [X] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled - For database migrations: - [X] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [X] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [X] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [x] Added/updated automated tests - [X] Manual QA for all new/changed functionality --------- Co-authored-by: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-06-11 17:22:46 +00:00
KeyValueStore fleet.KeyValueStore
EnableSCEPProxy bool
WithDEPWebview bool
FeatureRoutes []endpointer.HandlerRoutesFunc
Microsoft Compliance Partner backend changes (#29540) For #27042. Ready for review, just missing integration tests that I will be writing today. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features. - [X] If database migrations are included, checked table schema to confirm autoupdate - For new Fleet configuration settings - [X] Verified that the setting can be managed via GitOps, or confirmed that the setting is explicitly being excluded from GitOps. If managing via Gitops: - [X] Verified that the setting is exported via `fleetctl generate-gitops` - [X] Added the setting to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [X] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled - For database migrations: - [X] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [X] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [X] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [x] Added/updated automated tests - [X] Manual QA for all new/changed functionality --------- Co-authored-by: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-06-11 17:22:46 +00:00
SCEPConfigService fleet.SCEPConfigService
DigiCertService fleet.DigiCertService
EnableSCIM bool
ConditionalAccessMicrosoftProxy ConditionalAccessMicrosoftProxy
HostIdentity *HostIdentity
androidMockClient *android_mock.Client
androidModule android.Service
Okta SCEP endpoint (#34721) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34542 - Added SCEP endpoint for issuing certs for conditional access for Okta. Functionally similar to host identity and Apple MDM SCEP endpoints. - Changes file will be added later (this is a sub-task of the feature). - A standard SCEP payload can be used to get a cert to an Apple device: ``` <!-- SCEP Configuration --> <dict> <key>PayloadContent</key> <dict> <key>URL</key> <string>https://myfleet.example.com/api/fleet/conditional_access/scep</string> <key>Challenge</key> <string>ENROLLMENT_SECRET</string> <key>Keysize</key> <integer>2048</integer> <key>Key Type</key> <string>RSA</string> <key>Key Usage</key> <integer>5</integer> <key>ExtendedKeyUsage</key> <array> <string>1.3.6.1.5.5.7.3.2</string> </array> <key>Subject</key> <array> <array> <array> <string>CN</string> <string>Fleet conditional access for Okta</string> </array> </array> </array> <key>SubjectAltName</key> <dict> <key>uniformResourceIdentifier</key> <array> <string>urn:device:apple:uuid:%HardwareUUID%</string> </array> </dict> <key>Retries</key> <integer>3</integer> <key>RetryDelay</key> <integer>10</integer> <!-- ACL for browser access --> <key>AllowAllAppsAccess</key> <true/> <!-- Set true for Safari access. Set false if Safari support not needed. --> <key>KeyIsExtractable</key> <false/> </dict> <key>PayloadDescription</key> <string>Configures SCEP for Fleet conditional access for Okta certificate</string> <key>PayloadDisplayName</key> <string>Fleet conditional access SCEP</string> <key>PayloadIdentifier</key> <string>com.fleetdm.conditional-access-scep</string> <key>PayloadType</key> <string>com.apple.security.scep</string> <key>PayloadUUID</key> <string>B2C3D4E5-F6A7-4B6C-9D8E-0F1A2B3C4D5E</string> <key>PayloadVersion</key> <integer>1</integer> </dict> ``` # Checklist for submitter ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features * Adds Conditional Access SCEP certificate enrollment support, enabling hosts to obtain device identity certificates through secure certificate enrollment protocol endpoints. * Implements rate limiting for certificate enrollment requests to prevent abuse. ## Tests * Adds comprehensive integration tests for Conditional Access SCEP functionality, including certificate operations, rate limiting validation, and edge cases. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-06 23:07:17 +00:00
ConditionalAccess *ConditionalAccess
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
DBConns *common_mysql.DBConnections
// ActivityMock is populated automatically by newTestServiceWithConfig.
// After setup, tests can use it to intercept or assert on activity creation.
ActivityMock *fleet_mock.MockActivityService
}
func RunServerForTestsWithDS(t *testing.T, ds fleet.Datastore, opts ...*TestServerOpts) (map[string]fleet.User, *httptest.Server) {
if len(opts) > 0 && opts[0].EnableCachedDS {
ds = cached_mysql.New(ds)
}
cfg := config.TestConfig()
if len(opts) > 0 && opts[0].FleetConfig != nil {
cfg = *opts[0].FleetConfig
}
svc, ctx := NewTestService(t, ds, cfg, opts...)
return RunServerForTestsWithServiceWithDS(t, ctx, ds, svc, opts...)
}
func RunServerForTestsWithServiceWithDS(t *testing.T, ctx context.Context, ds fleet.Datastore, svc fleet.Service,
opts ...*TestServerOpts,
) (map[string]fleet.User, *httptest.Server) {
var cfg config.FleetConfig
if len(opts) > 0 && opts[0].FleetConfig != nil {
cfg = *opts[0].FleetConfig
} else {
cfg = config.TestConfig()
}
users := map[string]fleet.User{}
if len(opts) == 0 || (len(opts) > 0 && !opts[0].SkipCreateTestUsers) {
users = createTestUsers(t, ds)
}
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
if len(opts) > 0 && opts[0].Logger != nil {
logger = opts[0].Logger
}
if len(opts) > 0 {
opts[0].FeatureRoutes = append(opts[0].FeatureRoutes, android_service.GetRoutes(svc, opts[0].androidModule))
}
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
// Add activity routes if DBConns is provided
if len(opts) > 0 && opts[0].DBConns != nil {
legacyAuthorizer, err := authz.NewAuthorizer()
require.NoError(t, err)
activityAuthorizer := authz.NewAuthorizerAdapter(legacyAuthorizer)
activityACLAdapter := activityacl.NewFleetServiceAdapter(svc)
activitySvc, activityRoutesFn := activity_bootstrap.New(
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
opts[0].DBConns,
activityAuthorizer,
activityACLAdapter,
logger,
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
)
svc.SetActivityService(activitySvc)
Activity bounded context: `/api/latest/fleet/activities` (1 of 2) (#38115) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37806 This PR creates an activity bounded context and moves the following HTTP endpoint (including the full vertical slice) there: `/api/latest/fleet/activities` NONE of the other activity functionality is moved! This is an incremental approach starting with just 1 API/service endpoint. A significant part of this PR is tests. This feature is now receiving significantly more unit/integration test coverage than before. Also, this PR does not remove the `ListActivities` datastore method in the legacy code. That will be done in the follow up PR (part 2 of 2). This refactoring effort also uncovered an activity/user authorization issue: https://fleetdm.slack.com/archives/C02A8BRABB5/p1768582236611479 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Activity listing API now available with query filtering, date-range filtering, and type-based filtering * Pagination support for activity results with cursor-based and offset-based options * Configurable sorting by creation date or activity ID in ascending or descending order * Automatic enrichment of activity records with actor user details (name, email, avatar) * Role-based access controls applied to activity visibility based on user permissions <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-19 14:07:14 +00:00
activityAuthMiddleware := func(next endpoint.Endpoint) endpoint.Endpoint {
return auth.AuthenticatedUser(svc, next)
}
opts[0].FeatureRoutes = append(opts[0].FeatureRoutes, activityRoutesFn(activityAuthMiddleware))
}
var mdmPusher nanomdm_push.Pusher
if len(opts) > 0 && opts[0].MDMPusher != nil {
mdmPusher = opts[0].MDMPusher
}
rootMux := http.NewServeMux()
memLimitStore, _ := memstore.New(0)
var limitStore throttled.GCRAStore = memLimitStore
var redisPool fleet.RedisPool
if len(opts) > 0 && opts[0].Pool != nil {
redisPool = opts[0].Pool
limitStore = &redis.ThrottledStore{
Pool: opts[0].Pool,
KeyPrefix: "ratelimit::",
}
} else {
redisPool = redistest.SetupRedis(t, t.Name(), false, false, false) // We are good to initalize a redis pool here as it is only called by integration tests
}
if len(opts) > 0 {
mdmStorage := opts[0].MDMStorage
scepStorage := opts[0].SCEPStorage
commander := apple_mdm.NewMDMAppleCommander(mdmStorage, mdmPusher)
if mdmStorage != nil && scepStorage != nil {
vppInstaller := svc.(fleet.AppleMDMVPPInstaller)
checkInAndCommand := NewMDMAppleCheckinAndCommandService(ds, commander, vppInstaller, opts[0].License.IsPremium(), logger, redis_key_value.New(redisPool), svc.NewActivity)
checkInAndCommand.RegisterResultsHandler("InstalledApplicationList", NewInstalledApplicationListResultsHandler(ds, commander, logger, cfg.Server.VPPVerifyTimeout, cfg.Server.VPPVerifyRequestDelay, svc.NewActivity))
checkInAndCommand.RegisterResultsHandler(fleet.DeviceLocationCmdName, NewDeviceLocationResultsHandler(ds, commander, logger))
checkInAndCommand.RegisterResultsHandler(fleet.SetRecoveryLockCmdName, NewSetRecoveryLockResultsHandler(ds, logger, svc.NewActivity))
err := RegisterAppleMDMProtocolServices(
rootMux,
cfg.MDM,
mdmStorage,
scepStorage,
logger,
checkInAndCommand,
&MDMAppleDDMService{
ds: ds,
logger: logger,
},
commander,
"https://test-url.com",
cfg,
)
require.NoError(t, err)
}
if opts[0].EnableSCEPProxy {
var timeout *time.Duration
if opts[0].SCEPConfigService != nil {
speed up macOS profile delivery for initial enrollments (#41960) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34433 It speeds up the cron, meaning fleetd, bootstrap and now profiles should be sent within 10 seconds of being known to fleet, compared to the previous 1 minute. It's heavily based on my last PR, so the structure and changes are close to identical, with some small differences. **I did not do the redis key part in this PR, as I think that should come in it's own PR, to avoid overlooking logic bugs with that code, and since this one is already quite sized since we're moving core pieces of code around.** # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Faster macOS onboarding: device profiles are delivered and installed as part of DEP enrollment, shortening initial setup. * Improved profile handling: per-host profile preprocessing, secret detection, and clearer failure marking. * **Improvements** * Consolidated SCEP/NDES error messaging for clearer diagnostics. * Cron/work scheduling tuned to prioritize Apple MDM profile delivery. * **Tests** * Expanded MDM unit and integration tests, including DeclarativeManagement handling. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-19 19:58:10 +00:00
scepConfig, ok := opts[0].SCEPConfigService.(*scep.SCEPConfigService)
if ok {
// In tests, we share the same Timeout pointer between SCEPConfigService and SCEPProxy
timeout = scepConfig.Timeout
}
}
err := RegisterSCEPProxy(
rootMux,
ds,
logger,
timeout,
&cfg,
)
require.NoError(t, err)
}
}
if len(opts) > 0 && opts[0].WithDEPWebview {
frontendHandler := WithMDMEnrollmentMiddleware(svc, logger, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// do nothing and return 200
w.WriteHeader(http.StatusOK)
}))
rootMux.Handle("/", frontendHandler)
}
var featureRoutes []endpointer.HandlerRoutesFunc
if len(opts) > 0 && len(opts[0].FeatureRoutes) > 0 {
featureRoutes = opts[0].FeatureRoutes
}
var extra []ExtraHandlerOption
extra = append(extra, WithLoginRateLimit(throttled.PerMin(1000)))
if len(opts) > 0 && opts[0].HostIdentity != nil {
require.NoError(t, hostidentity.RegisterSCEP(rootMux, opts[0].HostIdentity.SCEPStorage, ds, logger, &cfg))
var httpSigVerifier func(http.Handler) http.Handler
Changes needed before gokit/log to slog transition. (#39527) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #38889 PLEASE READ BELOW before looking at file changes Before converting individual files/packages to slog, we generally need to make these 2 changes to make the conversion easier: - Replace uses of `kitlog.With` since they are not fully compatible with our kitlog adapter - Directly use the kitlog adapter logger type instead of the kitlog interface, which will let us have direct access to the underlying slog logger: `*logging.Logger` Note: that I did not replace absolutely all uses of `kitlog.Logger`, but I did remove all uses of `kitlog.With` except for these due to complexity: - server/logging/filesystem.go and the other log writers (webhook, firehose, kinesis, lambda, pubsub, nats) - server/datastore/mysql/nanomdm_storage.go (adapter pattern) - server/vulnerabilities/nvd/* (cascades to CLI tools) - server/service/osquery_utils/queries.go (callback type signatures cascade broadly) - cmd/maintained-apps/ (standalone, so can be transitioned later all at once) Most of the changes in this PR follow these patterns: - `kitlog.Logger` type → `*logging.Logger` - `kitlog.With(logger, ...)` → `logger.With(...)` - `kitlog.NewNopLogger() → logging.NewNopLogger()`, including similar variations such as `logging.NewLogfmtLogger(w)` and `logging.NewJSONLogger(w)` - removed many now-unused kitlog imports Unique changes that the PR review should focus on: - server/platform/logging/kitlog_adapter.go: Core adapter changes - server/platform/logging/logging.go: New convenience functions - server/service/integration_logger_test.go: Test changes for slog # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - Was added in previous PR ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Migrated the codebase to a unified internal structured logging system for more consistent, reliable logs and observability. * No user-facing functionality changed; runtime behavior and APIs remain compatible. * **Tests** * Updated tests to use the new logging helpers to ensure consistent test logging and validation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-11 16:08:33 +00:00
httpSigVerifier, err := httpsig.Middleware(ds, opts[0].HostIdentity.RequireHTTPMessageSignature,
logger.With("component", "http-sig-verifier"))
require.NoError(t, err)
extra = append(extra, WithHTTPSigVerifier(httpSigVerifier))
}
Okta SCEP endpoint (#34721) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34542 - Added SCEP endpoint for issuing certs for conditional access for Okta. Functionally similar to host identity and Apple MDM SCEP endpoints. - Changes file will be added later (this is a sub-task of the feature). - A standard SCEP payload can be used to get a cert to an Apple device: ``` <!-- SCEP Configuration --> <dict> <key>PayloadContent</key> <dict> <key>URL</key> <string>https://myfleet.example.com/api/fleet/conditional_access/scep</string> <key>Challenge</key> <string>ENROLLMENT_SECRET</string> <key>Keysize</key> <integer>2048</integer> <key>Key Type</key> <string>RSA</string> <key>Key Usage</key> <integer>5</integer> <key>ExtendedKeyUsage</key> <array> <string>1.3.6.1.5.5.7.3.2</string> </array> <key>Subject</key> <array> <array> <array> <string>CN</string> <string>Fleet conditional access for Okta</string> </array> </array> </array> <key>SubjectAltName</key> <dict> <key>uniformResourceIdentifier</key> <array> <string>urn:device:apple:uuid:%HardwareUUID%</string> </array> </dict> <key>Retries</key> <integer>3</integer> <key>RetryDelay</key> <integer>10</integer> <!-- ACL for browser access --> <key>AllowAllAppsAccess</key> <true/> <!-- Set true for Safari access. Set false if Safari support not needed. --> <key>KeyIsExtractable</key> <false/> </dict> <key>PayloadDescription</key> <string>Configures SCEP for Fleet conditional access for Okta certificate</string> <key>PayloadDisplayName</key> <string>Fleet conditional access SCEP</string> <key>PayloadIdentifier</key> <string>com.fleetdm.conditional-access-scep</string> <key>PayloadType</key> <string>com.apple.security.scep</string> <key>PayloadUUID</key> <string>B2C3D4E5-F6A7-4B6C-9D8E-0F1A2B3C4D5E</string> <key>PayloadVersion</key> <integer>1</integer> </dict> ``` # Checklist for submitter ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features * Adds Conditional Access SCEP certificate enrollment support, enabling hosts to obtain device identity certificates through secure certificate enrollment protocol endpoints. * Implements rate limiting for certificate enrollment requests to prevent abuse. ## Tests * Adds comprehensive integration tests for Conditional Access SCEP functionality, including certificate operations, rate limiting validation, and edge cases. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-06 23:07:17 +00:00
if len(opts) > 0 && opts[0].ConditionalAccess != nil {
require.NoError(t, condaccess.RegisterSCEP(ctx, rootMux, opts[0].ConditionalAccess.SCEPStorage, ds, logger, &cfg))
require.NoError(t, condaccess.RegisterIdP(rootMux, ds, logger, &cfg, limitStore))
Okta SCEP endpoint (#34721) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34542 - Added SCEP endpoint for issuing certs for conditional access for Okta. Functionally similar to host identity and Apple MDM SCEP endpoints. - Changes file will be added later (this is a sub-task of the feature). - A standard SCEP payload can be used to get a cert to an Apple device: ``` <!-- SCEP Configuration --> <dict> <key>PayloadContent</key> <dict> <key>URL</key> <string>https://myfleet.example.com/api/fleet/conditional_access/scep</string> <key>Challenge</key> <string>ENROLLMENT_SECRET</string> <key>Keysize</key> <integer>2048</integer> <key>Key Type</key> <string>RSA</string> <key>Key Usage</key> <integer>5</integer> <key>ExtendedKeyUsage</key> <array> <string>1.3.6.1.5.5.7.3.2</string> </array> <key>Subject</key> <array> <array> <array> <string>CN</string> <string>Fleet conditional access for Okta</string> </array> </array> </array> <key>SubjectAltName</key> <dict> <key>uniformResourceIdentifier</key> <array> <string>urn:device:apple:uuid:%HardwareUUID%</string> </array> </dict> <key>Retries</key> <integer>3</integer> <key>RetryDelay</key> <integer>10</integer> <!-- ACL for browser access --> <key>AllowAllAppsAccess</key> <true/> <!-- Set true for Safari access. Set false if Safari support not needed. --> <key>KeyIsExtractable</key> <false/> </dict> <key>PayloadDescription</key> <string>Configures SCEP for Fleet conditional access for Okta certificate</string> <key>PayloadDisplayName</key> <string>Fleet conditional access SCEP</string> <key>PayloadIdentifier</key> <string>com.fleetdm.conditional-access-scep</string> <key>PayloadType</key> <string>com.apple.security.scep</string> <key>PayloadUUID</key> <string>B2C3D4E5-F6A7-4B6C-9D8E-0F1A2B3C4D5E</string> <key>PayloadVersion</key> <integer>1</integer> </dict> ``` # Checklist for submitter ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features * Adds Conditional Access SCEP certificate enrollment support, enabling hosts to obtain device identity certificates through secure certificate enrollment protocol endpoints. * Implements rate limiting for certificate enrollment requests to prevent abuse. ## Tests * Adds comprehensive integration tests for Conditional Access SCEP functionality, including certificate operations, rate limiting validation, and edge cases. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-06 23:07:17 +00:00
}
var carveStore fleet.CarveStore = ds // In tests, we use MySQL as storage for carves.
apiHandler := MakeHandler(svc, cfg, logger, limitStore, redisPool, carveStore, featureRoutes, extra...)
rootMux.Handle("/api/", apiHandler)
var errHandler *errorstore.Handler
ctxErrHandler := ctxerr.FromContext(ctx)
if ctxErrHandler != nil {
errHandler = ctxErrHandler.(*errorstore.Handler)
}
debugHandler := MakeDebugHandler(svc, cfg, logger, errHandler, ds)
rootMux.Handle("/debug/", debugHandler)
rootMux.Handle("/enroll", ServeEndUserEnrollOTA(svc, "", ds, logger, false))
if len(opts) > 0 && opts[0].EnableSCIM {
require.NoError(t, scim.RegisterSCIM(rootMux, ds, svc, logger, &cfg))
rootMux.Handle("/api/v1/fleet/scim/details", apiHandler)
rootMux.Handle("/api/latest/fleet/scim/details", apiHandler)
}
server := httptest.NewUnstartedServer(rootMux)
server.Config = cfg.Server.DefaultHTTPServer(ctx, rootMux)
// WriteTimeout is set for security purposes.
// If we don't set it, (bugy or malignant) clients making long running
// requests could DDOS Fleet.
require.NotZero(t, server.Config.WriteTimeout)
if len(opts) > 0 && opts[0].HTTPServerConfig != nil {
server.Config = opts[0].HTTPServerConfig
// make sure we use the application handler we just created
server.Config.Handler = rootMux
}
server.Start()
t.Cleanup(func() {
server.Close()
})
return users, server
}
func NewTestService(t *testing.T, ds fleet.Datastore, cfg config.FleetConfig, opts ...*TestServerOpts) (fleet.Service, context.Context) {
var rs fleet.QueryResultStore
if len(opts) > 0 && opts[0].Rs != nil {
rs = opts[0].Rs
}
var lq fleet.LiveQueryStore
if len(opts) > 0 && opts[0].Lq != nil {
lq = opts[0].Lq
}
return newTestServiceWithConfig(t, ds, cfg, rs, lq, opts...)
}
func testSESPluginConfig() config.FleetConfig {
c := config.TestConfig()
c.Email = config.EmailConfig{EmailBackend: "ses"}
c.SES = config.SESConfig{
Region: "us-east-1",
AccessKeyID: "foo",
SecretAccessKey: "bar",
StsAssumeRoleArn: "baz",
SourceArn: "qux",
}
return c
}
func testKinesisPluginConfig() config.FleetConfig {
c := config.TestConfig()
c.Osquery.ResultLogPlugin = "kinesis"
c.Osquery.StatusLogPlugin = "kinesis"
c.Activity.AuditLogPlugin = "kinesis"
c.Kinesis = config.KinesisConfig{
Region: "us-east-1",
AccessKeyID: "foo",
SecretAccessKey: "bar",
StsAssumeRoleArn: "baz",
StatusStream: "test-status-stream",
ResultStream: "test-result-stream",
AuditStream: "test-audit-stream",
}
return c
}
func testFirehosePluginConfig() config.FleetConfig {
c := config.TestConfig()
c.Osquery.ResultLogPlugin = "firehose"
c.Osquery.StatusLogPlugin = "firehose"
c.Activity.AuditLogPlugin = "firehose"
c.Firehose = config.FirehoseConfig{
Region: "us-east-1",
AccessKeyID: "foo",
SecretAccessKey: "bar",
StsAssumeRoleArn: "baz",
StatusStream: "test-status-firehose",
ResultStream: "test-result-firehose",
AuditStream: "test-audit-firehose",
}
return c
}
func testLambdaPluginConfig() config.FleetConfig {
c := config.TestConfig()
c.Osquery.ResultLogPlugin = "lambda"
c.Osquery.StatusLogPlugin = "lambda"
c.Activity.AuditLogPlugin = "lambda"
c.Lambda = config.LambdaConfig{
Region: "us-east-1",
AccessKeyID: "foo",
SecretAccessKey: "bar",
StsAssumeRoleArn: "baz",
ResultFunction: "result-func",
StatusFunction: "status-func",
AuditFunction: "audit-func",
}
return c
}
func testPubSubPluginConfig() config.FleetConfig {
c := config.TestConfig()
c.Osquery.ResultLogPlugin = "pubsub"
c.Osquery.StatusLogPlugin = "pubsub"
c.Activity.AuditLogPlugin = "pubsub"
c.PubSub = config.PubSubConfig{
Project: "test",
StatusTopic: "status-topic",
ResultTopic: "result-topic",
AuditTopic: "audit-topic",
AddAttributes: false,
}
return c
}
func testStdoutPluginConfig() config.FleetConfig {
c := config.TestConfig()
c.Osquery.ResultLogPlugin = "stdout"
c.Osquery.StatusLogPlugin = "stdout"
c.Activity.AuditLogPlugin = "stdout"
return c
}
func testUnrecognizedPluginConfig() config.FleetConfig {
c := config.TestConfig()
c.Osquery = config.OsqueryConfig{
ResultLogPlugin: "bar",
StatusLogPlugin: "bar",
}
c.Activity.AuditLogPlugin = "bar"
return c
}
func assertBodyContains(t *testing.T, resp *http.Response, expected string) {
bodyBytes, err := io.ReadAll(resp.Body)
require.Nil(t, err)
bodyString := string(bodyBytes)
assert.Contains(t, bodyString, expected)
}
func getJSON(r *http.Response, target interface{}) error {
return json.NewDecoder(r.Body).Decode(target)
}
func assertErrorCodeAndMessage(t *testing.T, resp *http.Response, code int, message string) {
err := &fleet.Error{}
require.Nil(t, getJSON(resp, err))
assert.Equal(t, code, err.Code)
assert.Equal(t, message, err.Message)
}
type memFailingPolicySet struct {
mMu sync.RWMutex
m map[uint][]fleet.PolicySetHost
}
var _ fleet.FailingPolicySet = (*memFailingPolicySet)(nil)
func NewMemFailingPolicySet() *memFailingPolicySet {
return &memFailingPolicySet{
m: make(map[uint][]fleet.PolicySetHost),
}
}
// AddFailingPoliciesForHost adds the given host to the policy sets.
func (m *memFailingPolicySet) AddHost(policyID uint, host fleet.PolicySetHost) error {
m.mMu.Lock()
defer m.mMu.Unlock()
m.m[policyID] = append(m.m[policyID], host)
return nil
}
// ListHosts returns the list of hosts present in the policy set.
func (m *memFailingPolicySet) ListHosts(policyID uint) ([]fleet.PolicySetHost, error) {
m.mMu.RLock()
defer m.mMu.RUnlock()
hosts := make([]fleet.PolicySetHost, len(m.m[policyID]))
copy(hosts, m.m[policyID])
return hosts, nil
}
// RemoveHosts removes the hosts from the policy set.
func (m *memFailingPolicySet) RemoveHosts(policyID uint, hosts []fleet.PolicySetHost) error {
m.mMu.Lock()
defer m.mMu.Unlock()
if _, ok := m.m[policyID]; !ok {
return nil
}
hostsSet := make(map[uint]struct{})
for _, host := range hosts {
hostsSet[host.ID] = struct{}{}
}
n := 0
for _, host := range m.m[policyID] {
if _, ok := hostsSet[host.ID]; !ok {
m.m[policyID][n] = host
n++
}
}
m.m[policyID] = m.m[policyID][:n]
return nil
}
// RemoveSet removes a policy set.
func (m *memFailingPolicySet) RemoveSet(policyID uint) error {
m.mMu.Lock()
defer m.mMu.Unlock()
delete(m.m, policyID)
return nil
}
// ListSets lists all the policy sets.
func (m *memFailingPolicySet) ListSets() ([]uint, error) {
m.mMu.RLock()
defer m.mMu.RUnlock()
var policyIDs []uint
for policyID := range m.m {
policyIDs = append(policyIDs, policyID)
}
return policyIDs, nil
}
type nopEnrollHostLimiter struct{}
func (nopEnrollHostLimiter) CanEnrollNewHost(ctx context.Context) (bool, error) {
return true, nil
}
func (nopEnrollHostLimiter) SyncEnrolledHostIDs(ctx context.Context) error {
return nil
}
func newMockAPNSPushProviderFactory() (*mock.APNSPushProviderFactory, *mock.APNSPushProvider) {
provider := &mock.APNSPushProvider{}
provider.PushFunc = mockSuccessfulPush
factory := &mock.APNSPushProviderFactory{}
factory.NewPushProviderFunc = func(*tls.Certificate) (push.PushProvider, error) {
return provider, nil
}
return factory, provider
}
func mockSuccessfulPush(_ context.Context, pushes []*mdm.Push) (map[string]*push.Response, error) {
res := make(map[string]*push.Response, len(pushes))
for _, p := range pushes {
res[p.Token.String()] = &push.Response{
Id: uuid.New().String(),
Err: nil,
}
}
return res, nil
}
func mdmConfigurationRequiredEndpoints() []struct {
method, path string
deviceAuthenticated bool
premiumOnly bool
} {
return []struct {
method, path string
deviceAuthenticated bool
premiumOnly bool
}{
{"POST", "/api/latest/fleet/mdm/apple/enqueue", false, false},
{"GET", "/api/latest/fleet/mdm/apple/commandresults", false, false},
{"GET", "/api/latest/fleet/mdm/apple/installers/1", false, false},
{"DELETE", "/api/latest/fleet/mdm/apple/installers/1", false, false},
{"GET", "/api/latest/fleet/mdm/apple/installers", false, false},
{"GET", "/api/latest/fleet/mdm/apple/devices", false, false},
{"GET", "/api/latest/fleet/mdm/apple/profiles", false, false},
{"GET", "/api/latest/fleet/mdm/apple/profiles/1", false, false},
{"DELETE", "/api/latest/fleet/mdm/apple/profiles/1", false, false},
{"GET", "/api/latest/fleet/mdm/apple/profiles/summary", false, false},
{"PATCH", "/api/latest/fleet/mdm/hosts/1/unenroll", false, false},
{"DELETE", "/api/latest/fleet/hosts/1/mdm", false, false},
{"GET", "/api/latest/fleet/mdm/hosts/1/profiles", false, true},
{"GET", "/api/latest/fleet/hosts/1/configuration_profiles", false, true},
{"POST", "/api/latest/fleet/mdm/hosts/1/lock", false, false},
{"POST", "/api/latest/fleet/mdm/hosts/1/wipe", false, false},
{"PATCH", "/api/latest/fleet/mdm/apple/settings", false, false},
{"GET", "/api/latest/fleet/mdm/apple", false, false},
{"GET", "/api/latest/fleet/apns", false, false},
{"GET", apple_mdm.EnrollPath + "?token=test", false, false},
{"GET", apple_mdm.InstallerPath + "?token=test", false, false},
{"GET", "/api/latest/fleet/mdm/setup/eula/0982A979-B1C9-4BDF-B584-5A37D32A1172", false, true},
{"GET", "/api/latest/fleet/setup_experience/eula/0982A979-B1C9-4BDF-B584-5A37D32A1172", false, true},
{"DELETE", "/api/latest/fleet/mdm/setup/eula/token", false, true},
{"DELETE", "/api/latest/fleet/setup_experience/eula/token", false, true},
{"GET", "/api/latest/fleet/mdm/setup/eula/metadata", false, true},
{"GET", "/api/latest/fleet/setup_experience/eula/metadata", false, true},
{"GET", "/api/latest/fleet/mdm/apple/setup/eula/0982A979-B1C9-4BDF-B584-5A37D32A1172", false, false},
{"DELETE", "/api/latest/fleet/mdm/apple/setup/eula/token", false, false},
{"GET", "/api/latest/fleet/mdm/apple/setup/eula/metadata", false, false},
{"GET", "/api/latest/fleet/mdm/apple/enrollment_profile", false, false},
{"GET", "/api/latest/fleet/enrollment_profiles/automatic", false, false},
{"POST", "/api/latest/fleet/mdm/apple/enrollment_profile", false, false},
{"POST", "/api/latest/fleet/enrollment_profiles/automatic", false, false},
{"DELETE", "/api/latest/fleet/mdm/apple/enrollment_profile", false, false},
{"DELETE", "/api/latest/fleet/enrollment_profiles/automatic", false, false},
{"POST", "/api/latest/fleet/device/%s/migrate_mdm", true, true},
{"POST", "/api/latest/fleet/mdm/apple/profiles/preassign", false, true},
{"POST", "/api/latest/fleet/mdm/apple/profiles/match", false, true},
{"POST", "/api/latest/fleet/mdm/commands/run", false, false},
{"POST", "/api/latest/fleet/commands/run", false, false},
{"GET", "/api/latest/fleet/mdm/commandresults", false, false},
{"GET", "/api/latest/fleet/commands/results", false, false},
{"GET", "/api/latest/fleet/mdm/commands", false, false},
{"GET", "/api/latest/fleet/commands", false, false},
{"POST", "/api/fleet/orbit/disk_encryption_key", false, false},
2023-11-29 14:32:42 +00:00
{"GET", "/api/latest/fleet/mdm/profiles/1", false, false},
{"GET", "/api/latest/fleet/configuration_profiles/1", false, false},
// TODO: those endpoints accept multipart/form data that gets
// parsed before the MDM check, we need to refactor this
// function to return more information to the caller, or find a
// better way to test these endpoints.
// {"POST", "/api/latest/fleet/mdm/profiles", false, false},
// {"POST", "/api/latest/fleet/configuration_profiles", false, false},
// {"POST", "/api/latest/fleet/mdm/setup/eula"},
// {"POST", "/api/latest/fleet/setup_experience/eula"},
// {"POST", "/api/latest/fleet/mdm/bootstrap", false, true},
// {"POST", "/api/latest/fleet/bootstrap", false, true},
2023-11-29 14:32:42 +00:00
{"GET", "/api/latest/fleet/mdm/profiles", false, false},
{"GET", "/api/latest/fleet/configuration_profiles", false, false},
{"GET", "/api/latest/fleet/mdm/manual_enrollment_profile", false, true},
{"GET", "/api/latest/fleet/enrollment_profiles/manual", false, true},
{"GET", "/api/latest/fleet/mdm/bootstrap/1/metadata", false, true},
{"GET", "/api/latest/fleet/bootstrap/1/metadata", false, true},
{"DELETE", "/api/latest/fleet/mdm/bootstrap/1", false, true},
{"DELETE", "/api/latest/fleet/bootstrap/1", false, true},
{"GET", "/api/latest/fleet/mdm/bootstrap?token=1", false, true},
{"GET", "/api/latest/fleet/bootstrap?token=1", false, true},
{"GET", "/api/latest/fleet/mdm/bootstrap/summary", false, true},
{"GET", "/api/latest/fleet/mdm/apple/bootstrap/summary", false, true},
{"GET", "/api/latest/fleet/bootstrap/summary", false, true},
{"PATCH", "/api/latest/fleet/mdm/apple/setup", false, true},
{"PATCH", "/api/latest/fleet/setup_experience", false, true},
{"POST", "/api/fleet/orbit/setup_experience/status", false, true},
{"POST", "/api/latest/fleet/software/web_apps", false, true},
}
}
func windowsMDMConfigurationRequiredEndpoints() []string {
return []string{
"/api/fleet/orbit/disk_encryption_key",
}
}
func androidMDMConfigurationRequiredEndpoints() []string {
return []string{
"/api/latest/fleet/software/web_apps",
}
}
// getURLSchemas returns a list of all valid URI schemas
func getURISchemas() []string {
return []string{
"aaa",
"aaas",
"about",
"acap",
"acct",
"acd",
"acr",
"adiumxtra",
"adt",
"afp",
"afs",
"aim",
"amss",
"android",
"appdata",
"apt",
"ar",
"ark",
"at",
"attachment",
"aw",
"barion",
"bb",
"beshare",
"bitcoin",
"bitcoincash",
"blob",
"bolo",
"browserext",
"cabal",
"calculator",
"callto",
"cap",
"cast",
"casts",
"chrome",
"chrome-extension",
"cid",
"coap",
"coap+tcp",
"coap+ws",
"coaps",
"coaps+tcp",
"coaps+ws",
"com-eventbrite-attendee",
"content",
"content-type",
"crid",
"cstr",
"cvs",
"dab",
"dat",
"data",
"dav",
"dhttp",
"diaspora",
"dict",
"did",
"dis",
"dlna-playcontainer",
"dlna-playsingle",
"dns",
"dntp",
"doi",
"dpp",
"drm",
"drop",
"dtmi",
"dtn",
"dvb",
"dvx",
"dweb",
"ed2k",
"eid",
"elsi",
"embedded",
"ens",
"ethereum",
"example",
"facetime",
"fax",
"feed",
"feedready",
"fido",
"file",
"filesystem",
"finger",
"first-run-pen-experience",
"fish",
"fm",
"ftp",
"fuchsia-pkg",
"geo",
"gg",
"git",
"gitoid",
"gizmoproject",
"go",
"gopher",
"graph",
"grd",
"gtalk",
"h323",
"ham",
"hcap",
"hcp",
"http",
"https",
"hxxp",
"hxxps",
"hydrazone",
"hyper",
"iax",
"icap",
"icon",
"im",
"imap",
"info",
"iotdisco",
"ipfs",
"ipn",
"ipns",
"ipp",
"ipps",
"irc",
"irc6",
"ircs",
"iris",
"iris.beep",
"iris.lwz",
"iris.xpc",
"iris.xpcs",
"isostore",
"itms",
"jabber",
"jar",
"jms",
"keyparc",
"lastfm",
"lbry",
"ldap",
"ldaps",
"leaptofrogans",
"lorawan",
"lpa",
"lvlt",
"magnet",
"mailserver",
"mailto",
"maps",
"market",
"matrix",
"message",
"microsoft.windows.camera",
"microsoft.windows.camera.multipicker",
"microsoft.windows.camera.picker",
"mid",
"mms",
"modem",
"mongodb",
"moz",
"ms-access",
"ms-appinstaller",
"ms-browser-extension",
"ms-calculator",
"ms-drive-to",
"ms-enrollment",
"ms-excel",
"ms-eyecontrolspeech",
"ms-gamebarservices",
"ms-gamingoverlay",
"ms-getoffice",
"ms-help",
"ms-infopath",
"ms-inputapp",
"ms-launchremotedesktop",
"ms-lockscreencomponent-config",
"ms-media-stream-id",
"ms-meetnow",
"ms-mixedrealitycapture",
"ms-mobileplans",
"ms-newsandinterests",
"ms-officeapp",
"ms-people",
"ms-project",
"ms-powerpoint",
"ms-publisher",
"ms-remotedesktop",
"ms-remotedesktop-launch",
"ms-restoretabcompanion",
"ms-screenclip",
"ms-screensketch",
"ms-search",
"ms-search-repair",
"ms-secondary-screen-controller",
"ms-secondary-screen-setup",
"ms-settings",
"ms-settings-airplanemode",
"ms-settings-bluetooth",
"ms-settings-camera",
"ms-settings-cellular",
"ms-settings-cloudstorage",
"ms-settings-connectabledevices",
"ms-settings-displays-topology",
"ms-settings-emailandaccounts",
"ms-settings-language",
"ms-settings-location",
"ms-settings-lock",
"ms-settings-nfctransactions",
"ms-settings-notifications",
"ms-settings-power",
"ms-settings-privacy",
"ms-settings-proximity",
"ms-settings-screenrotation",
"ms-settings-wifi",
"ms-settings-workplace",
"ms-spd",
"ms-stickers",
"ms-sttoverlay",
"ms-transit-to",
"ms-useractivityset",
"ms-virtualtouchpad",
"ms-visio",
"ms-walk-to",
"ms-whiteboard",
"ms-whiteboard-cmd",
"ms-word",
"msnim",
"msrp",
"msrps",
"mss",
"mt",
"mtqp",
"mumble",
"mupdate",
"mvn",
"news",
"nfs",
"ni",
"nih",
"nntp",
"notes",
"num",
"ocf",
"oid",
"onenote",
"onenote-cmd",
"opaquelocktoken",
"openpgp4fpr",
"otpauth",
"p1",
"pack",
"palm",
"paparazzi",
"payment",
"payto",
"pkcs11",
"platform",
"pop",
"pres",
"prospero",
"proxy",
"pwid",
"psyc",
"pttp",
"qb",
"query",
"quic-transport",
"redis",
"rediss",
"reload",
"res",
"resource",
"rmi",
"rsync",
"rtmfp",
"rtmp",
"rtsp",
"rtsps",
"rtspu",
"sarif",
"secondlife",
"secret-token",
"service",
"session",
"sftp",
"sgn",
"shc",
"shttp",
"sieve",
"simpleledger",
"simplex",
"sip",
"sips",
"skype",
"smb",
"smp",
"sms",
"smtp",
"snews",
"snmp",
"soap.beep",
"soap.beeps",
"soldat",
"spiffe",
"spotify",
"ssb",
"ssh",
"starknet",
"steam",
"stun",
"stuns",
"submit",
"svn",
"swh",
"swid",
"swidpath",
"tag",
"taler",
"teamspeak",
"tel",
"teliaeid",
"telnet",
"tftp",
"things",
"thismessage",
"tip",
"tn3270",
"tool",
"turn",
"turns",
"tv",
"udp",
"unreal",
"upt",
"urn",
"ut2004",
"uuid-in-package",
"v-event",
"vemmi",
"ventrilo",
"ves",
"videotex",
"vnc",
"view-source",
"vscode",
"vscode-insiders",
"vsls",
"w3",
"wais",
"web3",
"wcr",
"webcal",
"web+ap",
"wifi",
"wpid",
"ws",
"wss",
"wtai",
"wyciwyg",
"xcon",
"xcon-userid",
"xfire",
"xmlrpc.beep",
"xmlrpc.beeps",
"xmpp",
"xri",
"ymsgr",
"z39.50",
"z39.50r",
"z39.50s",
}
}
func createAndroidDeviceID(name string) string {
return "enterprises/mock-enterprise-id/devices/" + name
}
func statusReportMessageWithEnterpriseSpecificID(t *testing.T, deviceInfo androidmanagement.Device, enterpriseSpecificID string) *android.PubSubMessage {
return messageWithAndroidIdentifiers(t, android.PubSubStatusReport, deviceInfo, enterpriseSpecificID, "")
}
func enrollmentMessageWithEnterpriseSpecificID(t *testing.T, deviceInfo androidmanagement.Device, enterpriseSpecificID string) *android.PubSubMessage {
return messageWithAndroidIdentifiers(t, android.PubSubEnrollment, deviceInfo, enterpriseSpecificID, "")
}
func statusReportMessageWithSerialNumber(t *testing.T, deviceInfo androidmanagement.Device, serialNumber string) *android.PubSubMessage {
return messageWithAndroidIdentifiers(t, android.PubSubStatusReport, deviceInfo, "", serialNumber)
}
func enrollmentMessageWithSerialNumber(t *testing.T, deviceInfo androidmanagement.Device, serialNumber string) *android.PubSubMessage {
return messageWithAndroidIdentifiers(t, android.PubSubEnrollment, deviceInfo, "", serialNumber)
}
func messageWithAndroidIdentifiers(t *testing.T, notificationType android.NotificationType, deviceInfo androidmanagement.Device, enterpriseSpecificID, serialNumber string) *android.PubSubMessage {
if serialNumber == "" && enterpriseSpecificID == "" || serialNumber != "" && enterpriseSpecificID != "" {
t.Fatalf("exactly one of serialNumber or enterpriseSpecificID must be provided")
}
deviceInfo.HardwareInfo = &androidmanagement.HardwareInfo{
Brand: "TestBrand",
Model: "TestModel",
Hardware: "test-hardware",
}
if enterpriseSpecificID != "" {
deviceInfo.Ownership = android_service.DeviceOwnershipPersonallyOwned
deviceInfo.HardwareInfo.EnterpriseSpecificId = enterpriseSpecificID
deviceInfo.HardwareInfo.SerialNumber = enterpriseSpecificID
}
if serialNumber != "" {
deviceInfo.Ownership = android_service.DeviceOwnershipCompanyOwned
deviceInfo.HardwareInfo.SerialNumber = serialNumber
}
deviceInfo.SoftwareInfo = &androidmanagement.SoftwareInfo{
AndroidBuildNumber: "test-build",
AndroidVersion: "1",
}
deviceInfo.MemoryInfo = &androidmanagement.MemoryInfo{
TotalRam: int64(8 * 1024 * 1024 * 1024), // 8GB RAM in bytes
TotalInternalStorage: int64(64 * 1024 * 1024 * 1024), // 64GB system partition
}
deviceInfo.MemoryEvents = []*androidmanagement.MemoryEvent{
{
EventType: "EXTERNAL_STORAGE_DETECTED",
ByteCount: int64(64 * 1024 * 1024 * 1024), // 64GB external/built-in storage total capacity
CreateTime: "2024-01-15T09:00:00Z",
},
{
EventType: "INTERNAL_STORAGE_MEASURED",
ByteCount: int64(10 * 1024 * 1024 * 1024), // 10GB free in system partition
CreateTime: "2024-01-15T10:00:00Z",
},
{
EventType: "EXTERNAL_STORAGE_MEASURED",
ByteCount: int64(25 * 1024 * 1024 * 1024), // 25GB free in external/built-in storage
CreateTime: "2024-01-15T10:00:00Z",
},
}
data, err := json.Marshal(deviceInfo)
require.NoError(t, err)
encodedData := base64.StdEncoding.EncodeToString(data)
return &android.PubSubMessage{
Attributes: map[string]string{
"notificationType": string(notificationType),
},
Data: encodedData,
}
}
type fmaTestState struct {
version string
installerBytes []byte
sha256 string
installerPath string
Override patch policy query (#42322) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #41815 ### Changes - Extracted patch policy creation to `pkg/patch_policy` - Added a `patch_query` column to the `software_installers` table - By default that column is empty, and patch policies will generate with the default query if so - On app manifest ingestion, the appropriate entry in `software_installers` will save the override "patch" query from the manifest in patch_query # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [ ] QA'd all new/changed functionality manually - Relied on integration test for FMA version pinning ## Database migrations - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [ ] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`).
2026-03-25 14:32:41 +00:00
patchQuery string
}
func (s *fmaTestState) ComputeSHA(b []byte) {
h := sha256.New()
h.Write(b)
s.sha256 = hex.EncodeToString(h.Sum(nil))
}
func startFMAServers(t *testing.T, ds fleet.Datastore, states map[string]*fmaTestState) {
if len(states) == 0 {
states = make(map[string]*fmaTestState, 1)
states["/zoom/windows.json"] = &fmaTestState{
version: "1.0",
installerBytes: []byte("xyz"),
installerPath: "/zoom.msi",
}
}
statesByInstallerPath := make(map[string]*fmaTestState, len(states))
for _, state := range states {
state.ComputeSHA(state.installerBytes)
statesByInstallerPath[state.installerPath] = state
}
var downloadMu sync.Mutex
// Mock installer server — routes by path to serve per-FMA bytes.
installerServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
downloadMu.Lock()
defer downloadMu.Unlock()
state, found := statesByInstallerPath[r.URL.Path]
if !found {
http.NotFound(w, r)
return
}
_, _ = w.Write(state.installerBytes)
}))
// call Refresh directly (instead of SyncApps) since we're using the server above and not the file server
// created in SyncApps
err := maintained_apps.Refresh(t.Context(), ds, slog.New(slog.DiscardHandler))
require.NoError(t, err)
manifestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var state *fmaTestState
state, found := states[r.URL.Path]
if !found {
http.NotFound(w, r)
return
}
versions := []*ma.FMAManifestApp{
{
Override patch policy query (#42322) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #41815 ### Changes - Extracted patch policy creation to `pkg/patch_policy` - Added a `patch_query` column to the `software_installers` table - By default that column is empty, and patch policies will generate with the default query if so - On app manifest ingestion, the appropriate entry in `software_installers` will save the override "patch" query from the manifest in patch_query # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [ ] QA'd all new/changed functionality manually - Relied on integration test for FMA version pinning ## Database migrations - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [ ] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`).
2026-03-25 14:32:41 +00:00
Version: state.version,
Queries: ma.FMAQueries{
Exists: "SELECT 1 FROM osquery_info;",
Patch: state.patchQuery,
},
InstallerURL: installerServer.URL + state.installerPath,
InstallScriptRef: "foobaz",
UninstallScriptRef: "foobaz",
SHA256: state.sha256,
DefaultCategories: []string{"Productivity"},
},
}
manifest := ma.FMAManifestFile{
Versions: versions,
Refs: map[string]string{"foobaz": "Hello World!"},
}
require.NoError(t, json.NewEncoder(w).Encode(manifest))
}))
t.Cleanup(func() {
manifestServer.Close()
installerServer.Close()
})
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL, t)
}