From 518a4a1f98db33ad62fccf35231b5191e11e8d0a Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Tue, 17 Sep 2024 15:21:25 -0500 Subject: [PATCH 01/81] Use previous package filename for activity if installer edit doesn't change the package (#22177) Also adds a line in the makefile help for generate-doc, as it took me way too long to find that command this time. # Checklist for submitter - [x] Manual QA for all new/changed functionality --- Makefile | 1 + docs/Contributing/Audit-logs.md | 2 +- ee/server/service/software_installers.go | 9 +++++---- server/fleet/activities.go | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 46115cf47903..9e63214ebd9a 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,7 @@ define HELP_TEXT make generate-go - Generate and bundle required go code make generate-js - Generate and bundle required js code make generate-dev - Generate and bundle required code in a watch loop + make generate-doc - Generate updated API documentation for activities, osquery flags make clean - Clean all build artifacts make clean-assets - Clean assets only diff --git a/docs/Contributing/Audit-logs.md b/docs/Contributing/Audit-logs.md index 7ed5be322f73..25062d463f06 100644 --- a/docs/Contributing/Audit-logs.md +++ b/docs/Contributing/Audit-logs.md @@ -1222,7 +1222,7 @@ Generated when a software installer is updated in Fleet. This activity contains the following fields: - "software_title": Name of the software. -- "software_package": Filename of the installer. `null` if the installer package was not modified. +- "software_package": Filename of the installer as of this update (including if unchanged). - "team_name": Name of the team on which this software was updated. `null` if it was updated on no team. - "team_id": The ID of the team on which this software was updated. `null` if it was updated on no team. - "self_service": Whether the software is available for installation by the end user. diff --git a/ee/server/service/software_installers.go b/ee/server/service/software_installers.go index 4745e85416b9..de943471ea95 100644 --- a/ee/server/service/software_installers.go +++ b/ee/server/service/software_installers.go @@ -175,10 +175,11 @@ func (svc *Service) UpdateSoftwareInstaller(ctx context.Context, payload *fleet. } activity := fleet.ActivityTypeEditedSoftware{ - SoftwareTitle: existingInstaller.SoftwareTitle, - TeamName: teamName, - TeamID: payload.TeamID, - SelfService: existingInstaller.SelfService, + SoftwareTitle: existingInstaller.SoftwareTitle, + TeamName: teamName, + TeamID: payload.TeamID, + SelfService: existingInstaller.SelfService, + SoftwarePackage: &existingInstaller.Name, } var payloadForNewInstallerFile *fleet.UploadSoftwareInstallerPayload diff --git a/server/fleet/activities.go b/server/fleet/activities.go index a0702955b9ba..373aa5b720a8 100644 --- a/server/fleet/activities.go +++ b/server/fleet/activities.go @@ -1597,7 +1597,7 @@ func (a ActivityTypeEditedSoftware) ActivityName() string { func (a ActivityTypeEditedSoftware) Documentation() (string, string, string) { return `Generated when a software installer is updated in Fleet.`, `This activity contains the following fields: - "software_title": Name of the software. -- "software_package": Filename of the installer.` + " `null` " + `if the installer package was not modified. +- "software_package": Filename of the installer as of this update (including if unchanged). - "team_name": Name of the team on which this software was updated.` + " `null` " + `if it was updated on no team. - "team_id": The ID of the team on which this software was updated.` + " `null` " + `if it was updated on no team. - "self_service": Whether the software is available for installation by the end user.`, `{ From f135d5b732a4bc7985a51e6db09dbd6c7fa8764b Mon Sep 17 00:00:00 2001 From: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:04:12 -0400 Subject: [PATCH 02/81] =?UTF-8?q?UI=20=E2=80=93=202=20small=20unreleased?= =?UTF-8?q?=20bug=20fixes=20for=20software=20install=20policy=20automation?= =?UTF-8?q?s=20UI=20(#22181)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 2 small fixes for issues found in QA - Capitalize word in tooltip - Correctly render error message, with correctly colored icon - [x] Manual QA for all new/changed functionality --------- Co-authored-by: Jacob Shandling --- .../SoftwarePackageCard/SoftwarePackageCard.tsx | 4 ++-- .../SoftwarePage/components/AddPackage/AddPackage.tsx | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwarePackageCard/SoftwarePackageCard.tsx b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwarePackageCard/SoftwarePackageCard.tsx index 55e4e7cfdd14..30a0578191fd 100644 --- a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwarePackageCard/SoftwarePackageCard.tsx +++ b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwarePackageCard/SoftwarePackageCard.tsx @@ -9,7 +9,7 @@ import { InjectedRouter } from "react-router"; import PATHS from "router/paths"; import { AppContext } from "context/app"; import { NotificationContext } from "context/notification"; -import { SoftwareInstallStatus, ISoftwarePackage } from "interfaces/software"; +import { ISoftwarePackage } from "interfaces/software"; import softwareAPI from "services/entities/software"; import { buildQueryStringFromParams } from "utilities/url"; @@ -104,7 +104,7 @@ const STATUS_DISPLAY_OPTIONS: Record<
with exit code 0). Currently, if the software is uninstalled, the
- "installed" status won't be updated. + "Installed" status won't be updated. ), }, diff --git a/frontend/pages/SoftwarePage/components/AddPackage/AddPackage.tsx b/frontend/pages/SoftwarePage/components/AddPackage/AddPackage.tsx index d96b81e69bbb..df20f7845af3 100644 --- a/frontend/pages/SoftwarePage/components/AddPackage/AddPackage.tsx +++ b/frontend/pages/SoftwarePage/components/AddPackage/AddPackage.tsx @@ -111,16 +111,19 @@ const AddPackage = ({ ) { renderFlash( "error", - `${reason}. ${( + <> + {reason}{" "} - )} ` + ); + } else { + renderFlash("error", getErrorMessage(e)); } - renderFlash("error", getErrorMessage(e)); } onExit(); From 2bfbf2fe3f56b2a80511ba6cf8d69908c7df616c Mon Sep 17 00:00:00 2001 From: Roberto Dip Date: Tue, 17 Sep 2024 18:07:34 -0300 Subject: [PATCH 03/81] Allow CA certificates with extendedKeyUsage attributes. (#22160) --- changes/22158-scep | 1 + server/mdm/crypto/scep.go | 26 ++++-- server/mdm/crypto/scep_test.go | 139 +++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 changes/22158-scep diff --git a/changes/22158-scep b/changes/22158-scep new file mode 100644 index 000000000000..ab7557468018 --- /dev/null +++ b/changes/22158-scep @@ -0,0 +1 @@ +* Allow custom SCEP CA certificates with any kind of extendedKeyUsage attributes. diff --git a/server/mdm/crypto/scep.go b/server/mdm/crypto/scep.go index 1367030bf4bf..2ba39d37d608 100644 --- a/server/mdm/crypto/scep.go +++ b/server/mdm/crypto/scep.go @@ -7,6 +7,7 @@ import ( "fmt" "github.com/fleetdm/fleet/v4/server/fleet" + "github.com/fleetdm/fleet/v4/server/mdm/assets" "github.com/fleetdm/fleet/v4/server/mdm/nanomdm/http/mdm" ) @@ -33,15 +34,21 @@ func (s *SCEPVerifier) Verify(cert *x509.Certificate) error { } // TODO(roberto): nano interfaces don't allow to pass a context to this function - assets, err := s.ds.GetAllMDMConfigAssetsByName(context.Background(), []fleet.MDMAssetName{ - fleet.MDMAssetCACert, - }) + rootCert, err := assets.X509Cert(context.Background(), s.ds, fleet.MDMAssetCACert) if err != nil { return fmt.Errorf("loading existing assets from the database: %w", err) } + opts.Roots.AddCert(rootCert) - if ok := opts.Roots.AppendCertsFromPEM(assets[fleet.MDMAssetCACert].Value); !ok { - return errors.New("unable to append cerver SCEP cert to pool verifier") + // the default SCEP cert issued by fleet doesn't have any extra key + // usages, however, customers might configure the server with any + // certificate they want (generally for touchless MDM migrations) + // + // given that go verifies ext key usages on the whole chain, we relax + // the constraints when the provided certificate has any ext key usage + // that would cause a failure. + if hasOtherKeyUsages(rootCert, x509.ExtKeyUsageClientAuth) { + opts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageAny} } if _, err := cert.Verify(opts); err != nil { @@ -50,3 +57,12 @@ func (s *SCEPVerifier) Verify(cert *x509.Certificate) error { return nil } + +func hasOtherKeyUsages(cert *x509.Certificate, usage x509.ExtKeyUsage) bool { + for _, u := range cert.ExtKeyUsage { + if u != usage { + return true + } + } + return false +} diff --git a/server/mdm/crypto/scep_test.go b/server/mdm/crypto/scep_test.go index a8865b58f9ad..179864b9d3ff 100644 --- a/server/mdm/crypto/scep_test.go +++ b/server/mdm/crypto/scep_test.go @@ -1,8 +1,20 @@ package mdmcrypto import ( + "context" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "errors" + "math/big" "testing" + "time" + "github.com/fleetdm/fleet/v4/server/fleet" + "github.com/fleetdm/fleet/v4/server/mock" "github.com/stretchr/testify/require" ) @@ -11,3 +23,130 @@ func TestSCEPVerifierVerifyEmptyCerts(t *testing.T) { err := v.Verify(nil) require.ErrorContains(t, err, "no certificate provided") } + +func TestVerify(t *testing.T) { + ds := new(mock.Store) + verifier := NewSCEPVerifier(ds) + + // generate a valid root certificate with ExtKeyUsageClientAuth + validRootCertBytes, validRootCert, rootKey := generateRootCertificate(t, []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}) + _, validClientCert := generateClientCertificate(t, validRootCert, rootKey) + + // generate a root certificate with an unrelated ExtKeyUsage + rootWithOtherUsagesBytes, rootWithOtherUsageCert, rootWithOtherUsageKey := generateRootCertificate(t, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}) + _, validClientCertFromMultipleUsageRoot := generateClientCertificate(t, rootWithOtherUsageCert, rootWithOtherUsageKey) + + cases := []struct { + name string + rootCert []byte + certToVerify *x509.Certificate + wantErr string + }{ + { + name: "no certificate provided", + rootCert: nil, + certToVerify: nil, + wantErr: "no certificate provided", + }, + { + name: "error loading root cert from database", + rootCert: nil, + certToVerify: validClientCert, + wantErr: "loading existing assets from the database", + }, + { + name: "valid certificate verification succeeds", + rootCert: validRootCertBytes, + certToVerify: validClientCert, + wantErr: "", + }, + { + name: "valid certificate with unrelated key usage in root cert", + rootCert: rootWithOtherUsagesBytes, + certToVerify: validClientCertFromMultipleUsageRoot, + wantErr: "", + }, + { + name: "mismatched certificate presented", + rootCert: rootWithOtherUsagesBytes, + certToVerify: validClientCert, + wantErr: "certificate signed by unknown authority", + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + ds.GetAllMDMConfigAssetsByNameFunc = func(ctx context.Context, assetNames []fleet.MDMAssetName) (map[fleet.MDMAssetName]fleet.MDMConfigAsset, error) { + if tt.rootCert == nil { + return nil, errors.New("test error") + } + + return map[fleet.MDMAssetName]fleet.MDMConfigAsset{ + fleet.MDMAssetCACert: {Value: tt.rootCert}, + }, nil + } + + err := verifier.Verify(tt.certToVerify) + if tt.wantErr == "" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, tt.wantErr) + } + }) + } +} + +func generateRootCertificate(t *testing.T, extKeyUsages []x509.ExtKeyUsage) ([]byte, *x509.Certificate, *ecdsa.PrivateKey) { + priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(t, err) + + rootCertTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + Organization: []string{"Test Root CA"}, + }, + NotBefore: time.Now(), + NotAfter: time.Now().Add(10 * 365 * 24 * time.Hour), + IsCA: true, + KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature, + ExtKeyUsage: extKeyUsages, + BasicConstraintsValid: true, + } + + rootCertDER, err := x509.CreateCertificate(rand.Reader, rootCertTemplate, rootCertTemplate, &priv.PublicKey, priv) + require.NoError(t, err) + + rootCertPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rootCertDER}) + + rootCert, err := x509.ParseCertificate(rootCertDER) + require.NoError(t, err) + + return rootCertPEM, rootCert, priv +} + +func generateClientCertificate(t *testing.T, rootCert *x509.Certificate, rootKey *ecdsa.PrivateKey) ([]byte, *x509.Certificate) { + clientPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(t, err) + + clientCertTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(2), + Subject: pkix.Name{ + Organization: []string{"Test Client"}, + }, + NotBefore: time.Now(), + NotAfter: time.Now().Add(1 * 365 * 24 * time.Hour), + KeyUsage: x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, + BasicConstraintsValid: true, + } + + clientCertDER, err := x509.CreateCertificate(rand.Reader, clientCertTemplate, rootCert, &clientPriv.PublicKey, rootKey) + require.NoError(t, err) + + clientCertPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: clientCertDER}) + + clientCert, err := x509.ParseCertificate(clientCertDER) + require.NoError(t, err) + + return clientCertPEM, clientCert +} From b11edd9398c2ab4db887476f16d9eb85d52125e3 Mon Sep 17 00:00:00 2001 From: Sharon Katz <121527325+sharon-fdm@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:49:23 -0400 Subject: [PATCH 04/81] Add CIS policy for tests (#22112) --- ...re-show-status-bar-is-enabled.mobileconfig | 37 +++++++++++++++++++ it-and-security/teams/workstations-canary.yml | 1 + 2 files changed, 38 insertions(+) create mode 100644 it-and-security/lib/configuration-profiles/macos-ensure-show-status-bar-is-enabled.mobileconfig diff --git a/it-and-security/lib/configuration-profiles/macos-ensure-show-status-bar-is-enabled.mobileconfig b/it-and-security/lib/configuration-profiles/macos-ensure-show-status-bar-is-enabled.mobileconfig new file mode 100644 index 000000000000..393f4ffbb544 --- /dev/null +++ b/it-and-security/lib/configuration-profiles/macos-ensure-show-status-bar-is-enabled.mobileconfig @@ -0,0 +1,37 @@ + + + + + PayloadContent + + + PayloadDisplayName + Ensure Show Status Bar Is Enabled + PayloadType + com.apple.Safari + PayloadIdentifier + com.fleetdm.cis-ensure-show-status-bar-is-enabled + PayloadUUID + 708B39DB-E2B7-405C-A523-88F3DDC8DFFC + ShowOverlayStatusBar + + + + PayloadDescription + Ensure Show Status Bar Is Enabled + PayloadDisplayName + Ensure Show Status Bar Is Enabled + PayloadIdentifier + com.fleetdm.cis-ensure-show-status-bar-is-enabled + PayloadRemovalDisallowed + + PayloadScope + System + PayloadType + Configuration + PayloadUUID + 00FB5D02-8044-4E6F-884C-D73E7A32A2E7 + PayloadVersion + 1 + + diff --git a/it-and-security/teams/workstations-canary.yml b/it-and-security/teams/workstations-canary.yml index 80ce1ee02ba1..353f9c8500f3 100644 --- a/it-and-security/teams/workstations-canary.yml +++ b/it-and-security/teams/workstations-canary.yml @@ -87,6 +87,7 @@ controls: - path: ../lib/configuration-profiles/macos-secure-terminal-keyboard.mobileconfig - path: ../lib/configuration-profiles/macos-disable-update-notifications.mobileconfig - path: ../lib/configuration-profiles/passcode-settings-ddm.json + - path: ../lib/configuration-profiles/macos-ensure-show-status-bar-is-enabled.mobileconfig macos_setup: bootstrap_package: "" enable_end_user_authentication: true From ddbdce4ab91fde578850959ec90f73e380d99ef8 Mon Sep 17 00:00:00 2001 From: Victor Lyuboslavsky Date: Tue, 17 Sep 2024 17:32:14 -0500 Subject: [PATCH 05/81] Updated PS1 install/uninstall scripts to fail on error. (#22164) --- pkg/file/scripts/install_exe.ps1 | 7 +++++ pkg/file/scripts/install_msi.ps1 | 9 +++++- pkg/file/scripts/uninstall_exe.ps1 | 31 +++++++++++++++++++ .../testdata/scripts/install_exe.ps1.golden | 7 +++++ .../testdata/scripts/install_msi.ps1.golden | 9 +++++- .../testdata/scripts/uninstall_exe.ps1.golden | 31 +++++++++++++++++++ 6 files changed, 92 insertions(+), 2 deletions(-) diff --git a/pkg/file/scripts/install_exe.ps1 b/pkg/file/scripts/install_exe.ps1 index bdf858461df2..f4e83b4de3fd 100644 --- a/pkg/file/scripts/install_exe.ps1 +++ b/pkg/file/scripts/install_exe.ps1 @@ -3,6 +3,8 @@ $exeFilePath = "${env:INSTALLER_PATH}" +try { + # Add argument to install silently # Argument to make install silent depends on installer, # each installer might use different argument (usually it's "/S" or "/s") @@ -20,3 +22,8 @@ $exitCode = $process.ExitCode # Prints the exit code Write-Host "Install exit code: $exitCode" Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/pkg/file/scripts/install_msi.ps1 b/pkg/file/scripts/install_msi.ps1 index 838c431c1df1..fbd89aa10bc5 100644 --- a/pkg/file/scripts/install_msi.ps1 +++ b/pkg/file/scripts/install_msi.ps1 @@ -1,9 +1,16 @@ $logFile = "${env:TEMP}/fleet-install-software.log" +try { + $installProcess = Start-Process msiexec.exe ` -ArgumentList "/quiet /norestart /lv ${logFile} /i `"${env:INSTALLER_PATH}`"" ` -PassThru -Verb RunAs -Wait Get-Content $logFile -Tail 500 -exit $installProcess.ExitCode +Exit $installProcess.ExitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/pkg/file/scripts/uninstall_exe.ps1 b/pkg/file/scripts/uninstall_exe.ps1 index 31b53ea58097..bc6ea1421422 100644 --- a/pkg/file/scripts/uninstall_exe.ps1 +++ b/pkg/file/scripts/uninstall_exe.ps1 @@ -14,6 +14,11 @@ $machineKey = ` 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' $machineKey32on64 = ` 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' + +$exitCode = 0 + +try { + [array]$uninstallKeys = Get-ChildItem ` -Path @($machineKey, $machineKey32on64) ` -ErrorAction SilentlyContinue | @@ -33,6 +38,24 @@ foreach ($key in $uninstallKeys) { $key.UninstallString } + # The uninstall command may contain command and args, like: + # "C:\Program Files\Software\uninstall.exe" --uninstall --silent + # Split the command and args + $splitArgs = $uninstallCommand.Split('"') + if ($splitArgs.Length -gt 1) { + if ($splitArgs.Length -eq 3) { + $uninstallArgs = "$( $splitArgs[2] ) $uninstallArgs".Trim() + } elseif ($splitArgs.Length -gt 3) { + Throw ` + "Uninstall command contains multiple quoted strings. " + + "Please update the uninstall script.`n" + + "Uninstall command: $uninstallCommand" + } + $uninstallCommand = $splitArgs[1] + } + Write-Host "Uninstall command: $uninstallCommand" + Write-Host "Uninstall args: $uninstallArgs" + $processOptions = @{ FilePath = $uninstallCommand PassThru = $true @@ -55,6 +78,14 @@ foreach ($key in $uninstallKeys) { if (-not $foundUninstaller) { Write-Host "Uninstaller for '$softwareName' not found." + # Change exit code to 0 if you don't want to fail if uninstaller is not + # found. This could happen if program was already uninstalled. $exitCode = 1 } + +} catch { + Write-Host "Error: $_" + $exitCode = 1 +} + Exit $exitCode diff --git a/pkg/file/testdata/scripts/install_exe.ps1.golden b/pkg/file/testdata/scripts/install_exe.ps1.golden index bdf858461df2..f4e83b4de3fd 100644 --- a/pkg/file/testdata/scripts/install_exe.ps1.golden +++ b/pkg/file/testdata/scripts/install_exe.ps1.golden @@ -3,6 +3,8 @@ $exeFilePath = "${env:INSTALLER_PATH}" +try { + # Add argument to install silently # Argument to make install silent depends on installer, # each installer might use different argument (usually it's "/S" or "/s") @@ -20,3 +22,8 @@ $exitCode = $process.ExitCode # Prints the exit code Write-Host "Install exit code: $exitCode" Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/pkg/file/testdata/scripts/install_msi.ps1.golden b/pkg/file/testdata/scripts/install_msi.ps1.golden index 838c431c1df1..fbd89aa10bc5 100644 --- a/pkg/file/testdata/scripts/install_msi.ps1.golden +++ b/pkg/file/testdata/scripts/install_msi.ps1.golden @@ -1,9 +1,16 @@ $logFile = "${env:TEMP}/fleet-install-software.log" +try { + $installProcess = Start-Process msiexec.exe ` -ArgumentList "/quiet /norestart /lv ${logFile} /i `"${env:INSTALLER_PATH}`"" ` -PassThru -Verb RunAs -Wait Get-Content $logFile -Tail 500 -exit $installProcess.ExitCode +Exit $installProcess.ExitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/pkg/file/testdata/scripts/uninstall_exe.ps1.golden b/pkg/file/testdata/scripts/uninstall_exe.ps1.golden index 31b53ea58097..bc6ea1421422 100644 --- a/pkg/file/testdata/scripts/uninstall_exe.ps1.golden +++ b/pkg/file/testdata/scripts/uninstall_exe.ps1.golden @@ -14,6 +14,11 @@ $machineKey = ` 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' $machineKey32on64 = ` 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' + +$exitCode = 0 + +try { + [array]$uninstallKeys = Get-ChildItem ` -Path @($machineKey, $machineKey32on64) ` -ErrorAction SilentlyContinue | @@ -33,6 +38,24 @@ foreach ($key in $uninstallKeys) { $key.UninstallString } + # The uninstall command may contain command and args, like: + # "C:\Program Files\Software\uninstall.exe" --uninstall --silent + # Split the command and args + $splitArgs = $uninstallCommand.Split('"') + if ($splitArgs.Length -gt 1) { + if ($splitArgs.Length -eq 3) { + $uninstallArgs = "$( $splitArgs[2] ) $uninstallArgs".Trim() + } elseif ($splitArgs.Length -gt 3) { + Throw ` + "Uninstall command contains multiple quoted strings. " + + "Please update the uninstall script.`n" + + "Uninstall command: $uninstallCommand" + } + $uninstallCommand = $splitArgs[1] + } + Write-Host "Uninstall command: $uninstallCommand" + Write-Host "Uninstall args: $uninstallArgs" + $processOptions = @{ FilePath = $uninstallCommand PassThru = $true @@ -55,6 +78,14 @@ foreach ($key in $uninstallKeys) { if (-not $foundUninstaller) { Write-Host "Uninstaller for '$softwareName' not found." + # Change exit code to 0 if you don't want to fail if uninstaller is not + # found. This could happen if program was already uninstalled. $exitCode = 1 } + +} catch { + Write-Host "Error: $_" + $exitCode = 1 +} + Exit $exitCode From 1f1bc9c949d74a0d729061b2a6b60f714f11fb6b Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 17 Sep 2024 18:00:58 -0500 Subject: [PATCH 06/81] Website: add default organization to Premium trial license keys. (#22192) Closes: #22190 Changes: - updated `save-questionnaire-progress` to set a default value for the `organization` value of generated license keys (if a user does not have an organization set) --- website/api/controllers/save-questionnaire-progress.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/api/controllers/save-questionnaire-progress.js b/website/api/controllers/save-questionnaire-progress.js index 4e3beddf0e7f..62faf3792994 100644 --- a/website/api/controllers/save-questionnaire-progress.js +++ b/website/api/controllers/save-questionnaire-progress.js @@ -147,7 +147,7 @@ module.exports = { let thirtyDaysFromNowAt = Date.now() + (1000 * 60 * 60 * 24 * 30); let trialLicenseKeyForThisUser = await sails.helpers.createLicenseKey.with({ numberOfHosts: 10, - organization: this.req.me.organization, + organization: this.req.me.organization ? this.req.me.organization : 'Fleet Premium trial', expiresAt: thirtyDaysFromNowAt, }); // Save the trial license key to the DB record for this user. From ea2a9787338f780f7deb744c029c50d29dd6829d Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Wed, 18 Sep 2024 09:46:09 -0500 Subject: [PATCH 07/81] Ensure edited scripts provided from the client with newline switches and no other changes get converted to "\n" (#22196) (#22199) # Checklist for submitter - [x] Manual QA for all new/changed functionality --- ee/server/service/software_installers.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ee/server/service/software_installers.go b/ee/server/service/software_installers.go index de943471ea95..5a1d67910665 100644 --- a/ee/server/service/software_installers.go +++ b/ee/server/service/software_installers.go @@ -242,16 +242,16 @@ func (svc *Service) UpdateSoftwareInstaller(ctx context.Context, payload *fleet. if installScript != existingInstaller.InstallScript { dirty["InstallScript"] = true - payload.InstallScript = &installScript } + payload.InstallScript = &installScript } if payload.PostInstallScript != nil { postInstallScript := file.Dos2UnixNewlines(*payload.PostInstallScript) if postInstallScript != existingInstaller.PostInstallScript { dirty["PostInstallScript"] = true - payload.PostInstallScript = &postInstallScript } + payload.PostInstallScript = &postInstallScript } if payload.UninstallScript != nil { @@ -271,10 +271,10 @@ func (svc *Service) UpdateSoftwareInstaller(ctx context.Context, payload *fleet. preProcessUninstallScript(payloadForUninstallScript) if payloadForUninstallScript.UninstallScript != existingInstaller.UninstallScript { - uninstallScript = payloadForUninstallScript.UninstallScript dirty["UninstallScript"] = true - payload.UninstallScript = &uninstallScript } + uninstallScript = payloadForUninstallScript.UninstallScript + payload.UninstallScript = &uninstallScript } // persist changes starting here, now that we've done all the validation/diffing we can From f7fab000f84226c0276d580b0f5c5cf5367a04c2 Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Wed, 18 Sep 2024 11:22:22 -0500 Subject: [PATCH 08/81] Pass through uninstall error messages from backend (#22208) # Checklist for submitter - [x] Manual QA for all new/changed functionality [See Slack](https://fleetdm.slack.com/archives/C01EZVBHFHU/p1726605318985819?thread_ts=1726588126.583269&cid=C01EZVBHFHU) from @noahtalerman for context --- .../details/cards/Software/HostSoftware.tsx | 6 ++-- .../hosts/details/cards/Software/helpers.tsx | 32 +++++++++++++++++-- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx index 1c56843986f8..818fbcd7d989 100644 --- a/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx +++ b/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx @@ -24,7 +24,7 @@ import Spinner from "components/Spinner"; import { generateSoftwareTableHeaders as generateHostSoftwareTableConfig } from "./HostSoftwareTableConfig"; import { generateSoftwareTableHeaders as generateDeviceSoftwareTableConfig } from "./DeviceSoftwareTableConfig"; import HostSoftwareTable from "./HostSoftwareTable"; -import { getErrorMessage } from "./helpers"; +import { getInstallErrorMessage, getUninstallErrorMessage } from "./helpers"; const baseClass = "software-card"; @@ -190,7 +190,7 @@ const HostSoftware = ({ "Software is installing or will install when the host comes online." ); } catch (e) { - renderFlash("error", getErrorMessage(e)); + renderFlash("error", getInstallErrorMessage(e)); } setSoftwareIdActionPending(null); refetchSoftware(); @@ -211,7 +211,7 @@ const HostSoftware = ({ ); } catch (e) { - renderFlash("error", "Couldn't uninstall. Please try again."); + renderFlash("error", getUninstallErrorMessage(e)); } setSoftwareIdActionPending(null); refetchSoftware(); diff --git a/frontend/pages/hosts/details/cards/Software/helpers.tsx b/frontend/pages/hosts/details/cards/Software/helpers.tsx index 2020a1487090..2c12ca9e101d 100644 --- a/frontend/pages/hosts/details/cards/Software/helpers.tsx +++ b/frontend/pages/hosts/details/cards/Software/helpers.tsx @@ -3,7 +3,10 @@ import { getErrorReason } from "interfaces/errors"; import { trimEnd, upperFirst } from "lodash"; const INSTALL_SOFTWARE_ERROR_PREFIX = "Couldn't install."; -const DEFAULT_ERROR_MESSAGE = `${INSTALL_SOFTWARE_ERROR_PREFIX} Please try again.`; +const DEFAULT_INSTALL_ERROR_MESSAGE = `${INSTALL_SOFTWARE_ERROR_PREFIX} Please try again.`; + +const UNINSTALL_SOFTWARE_ERROR_PREFIX = "Couldn't uninstall."; +const DEFAULT_UNINSTALL_ERROR_MESSAGE = `${UNINSTALL_SOFTWARE_ERROR_PREFIX} Please try again.`; const createOnlyInstallableOnMacOSMessage = (reason: string) => `Couldn't install. ${reason.replace("darwin", "macOS")}.`; @@ -28,7 +31,7 @@ const showAPIMessage = (message: string) => { }; // eslint-disable-next-line import/prefer-default-export -export const getErrorMessage = (e: unknown) => { +export const getInstallErrorMessage = (e: unknown) => { const reason = upperFirst(trimEnd(getErrorReason(e), ".")); if (reason.includes("fleetd installed")) { @@ -41,5 +44,28 @@ export const getErrorMessage = (e: unknown) => { return reason; } - return DEFAULT_ERROR_MESSAGE; + return DEFAULT_INSTALL_ERROR_MESSAGE; +}; + +// eslint-disable-next-line import/prefer-default-export +export const getUninstallErrorMessage = (e: unknown) => { + const reason = upperFirst(trimEnd(getErrorReason(e), ".")); + + if ( + reason.includes("run script") || + reason.includes("running script") || + reason.includes("have fleetd") || + reason.includes("only on") + ) { + return `${UNINSTALL_SOFTWARE_ERROR_PREFIX} ${reason}.`; + } else if (reason.startsWith("Couldn't uninstall software.")) { + return reason.replace( + "Couldn't uninstall software.", + "Couldn't uninstall." + ); + } else if (reason.startsWith("No uninstall script exists")) { + return `${UNINSTALL_SOFTWARE_ERROR_PREFIX}. An uninstall script does not exist for this package.`; + } + + return DEFAULT_UNINSTALL_ERROR_MESSAGE; }; From 4ee79ae4a6f0d1b5940736a368126149ec1a0576 Mon Sep 17 00:00:00 2001 From: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:47:11 -0400 Subject: [PATCH 09/81] UI: handle possibly 'null' 'storedPolicy.team_id' on update policy call (#22215) ## #22145 ![ezgif-2-c62195a3ba](https://github.com/user-attachments/assets/4db3fcf8-f706-40e5-a1e5-c422ff7ac6c6) - [x] Changes file added for user-visible changes in `changes/` - [x] Manual QA for all new/changed functionality Co-authored-by: Jacob Shandling --- frontend/pages/policies/PolicyPage/screens/QueryEditor.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/pages/policies/PolicyPage/screens/QueryEditor.tsx b/frontend/pages/policies/PolicyPage/screens/QueryEditor.tsx index 9da71beb8b11..553209818efd 100644 --- a/frontend/pages/policies/PolicyPage/screens/QueryEditor.tsx +++ b/frontend/pages/policies/PolicyPage/screens/QueryEditor.tsx @@ -198,7 +198,7 @@ const QueryEditor = ({ const updateAPIRequest = () => { // storedPolicy.team_id is used for existing policies because selectedTeamId is subject to change - const team_id = storedPolicy?.team_id; + const team_id = storedPolicy?.team_id ?? undefined; return team_id !== undefined ? teamPoliciesAPI.update(policyIdForEdit, { From 90959dbc9fb9894f4fde63fc3b0c368cb7bdf87d Mon Sep 17 00:00:00 2001 From: Lucas Manuel Rodriguez Date: Wed, 18 Sep 2024 14:16:59 -0300 Subject: [PATCH 10/81] Fixes for no-team.yml GitOps (#22210) #22185 - [X] Manual QA for all new/changed functionality --- cmd/fleetctl/gitops.go | 16 +++++++++++----- cmd/fleetctl/gitops_test.go | 5 ++--- pkg/spec/gitops.go | 11 ++++++++--- server/service/client.go | 10 +++++++--- server/service/client_policies.go | 1 + 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/cmd/fleetctl/gitops.go b/cmd/fleetctl/gitops.go index fc9e3c7a8374..a7db6be73ddb 100644 --- a/cmd/fleetctl/gitops.go +++ b/cmd/fleetctl/gitops.go @@ -82,15 +82,19 @@ func gitopsCommand() *cli.Command { } // We need to extract the controls from no-team.yml to be able to apply them when applying the global app config. - var noTeamControls spec.Controls + var ( + noTeamControls spec.Controls + noTeamPresent bool + ) for _, flFilename := range flFilenames.Value() { if filepath.Base(flFilename) == "no-team.yml" { baseDir := filepath.Dir(flFilename) - config, err := spec.GitOpsFromFile(flFilename, baseDir, appConfig, logf) + config, err := spec.GitOpsFromFile(flFilename, baseDir, appConfig, func(format string, a ...interface{}) {}) if err != nil { return err } noTeamControls = config.Controls + noTeamPresent = true break } } @@ -145,7 +149,7 @@ func gitopsCommand() *cli.Command { // name.) Because teams can be created/deleted during the same gitops run, we // grab some information to help us determine allowed/restricted actions and // when to perform the associations. - if isGlobalConfig && totalFilenames > 1 { + if isGlobalConfig && totalFilenames > 1 && !(totalFilenames == 2 && noTeamPresent) { abmTeams, hasMissingABMTeam, usesLegacyABMConfig, err = checkABMTeamAssignments(config, fleetClient) if err != nil { return err @@ -192,6 +196,7 @@ func gitopsCommand() *cli.Command { } } } + if flDryRun { incomingSecrets := fleetClient.GetGitOpsSecrets(config) for _, secret := range incomingSecrets { @@ -201,6 +206,7 @@ func gitopsCommand() *cli.Command { secrets[secret] = struct{}{} } } + assumptions, err := fleetClient.DoGitOps(c.Context, config, flFilename, logf, flDryRun, teamDryRunAssumptions, appConfig) if err != nil { return err @@ -349,7 +355,7 @@ func applyABMTokenAssignmentIfNeeded( if usesLegacyConfig { appleBMDefaultTeam := abmTeamNames[0] if !slices.Contains(teamNames, appleBMDefaultTeam) { - return fmt.Errorf("apple_bm_default_team %s not found in team configs", appleBMDefaultTeam) + return fmt.Errorf("apple_bm_default_team team %q not found in team configs", appleBMDefaultTeam) } appConfigUpdate = map[string]map[string]any{ "mdm": { @@ -359,7 +365,7 @@ func applyABMTokenAssignmentIfNeeded( } else { for _, abmTeam := range abmTeamNames { if !slices.Contains(teamNames, abmTeam) { - return fmt.Errorf("apple_business_manager team %s not found in team configs", abmTeam) + return fmt.Errorf("apple_business_manager team %q not found in team configs", abmTeam) } } diff --git a/cmd/fleetctl/gitops_test.go b/cmd/fleetctl/gitops_test.go index 0f6c33b061c4..64cb9fda19cc 100644 --- a/cmd/fleetctl/gitops_test.go +++ b/cmd/fleetctl/gitops_test.go @@ -2399,7 +2399,6 @@ software: ipadTeam, }, dryRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) { - t.Log(out) require.ErrorContains(t, err, "mdm.apple_bm_default_team has been deprecated") assert.NotContains(t, out, "[!] gitops dry run succeeded") }, @@ -2420,10 +2419,10 @@ software: workstations, }, dryRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) { - assert.ErrorContains(t, err, "apple_business_manager team 📱🏢 Company-owned iPhones not found in team configs") + assert.ErrorContains(t, err, "apple_business_manager team \"📱🏢 Company-owned iPhones\" not found in team configs") }, realRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) { - assert.ErrorContains(t, err, "apple_business_manager team 📱🏢 Company-owned iPhones not found in team configs") + assert.ErrorContains(t, err, "apple_business_manager team \"📱🏢 Company-owned iPhones\" not found in team configs") }, }, { diff --git a/pkg/spec/gitops.go b/pkg/spec/gitops.go index a5938e2b9eef..9e4adc22687e 100644 --- a/pkg/spec/gitops.go +++ b/pkg/spec/gitops.go @@ -358,7 +358,7 @@ func parseAgentOptions(top map[string]json.RawMessage, result *GitOps, baseDir s agentOptionsRaw, ok := top["agent_options"] if result.IsNoTeam() { if ok { - logFn("[!] 'agent_options' is not supported for \"No team\". This key will be ignored.") + logFn("[!] 'agent_options' is not supported for \"No team\". This key will be ignored.\n") } return multiError } else if !ok { @@ -570,7 +570,7 @@ func parseQueries(top map[string]json.RawMessage, result *GitOps, baseDir string queriesRaw, ok := top["queries"] if result.IsNoTeam() { if ok { - logFn("[!] 'queries' is not supported for \"No team\". This key will be ignored.") + logFn("[!] 'queries' is not supported for \"No team\". This key will be ignored.\n") } return multiError } else if !ok { @@ -660,7 +660,12 @@ func parseSoftware(top map[string]json.RawMessage, result *GitOps, baseDir strin if err := json.Unmarshal(softwareRaw, &software); err != nil { var typeErr *json.UnmarshalTypeError if errors.As(err, &typeErr) { - return multierror.Append(multiError, fmt.Errorf("Couldn't edit software. %q must be a %s, found %s", typeErr.Field, typeErr.Type.String(), typeErr.Value)) + typeErrField := typeErr.Field + if typeErrField == "" { + // UnmarshalTypeError.Field is empty when trying to set an invalid type on the root node. + typeErrField = "software" + } + return multierror.Append(multiError, fmt.Errorf("Couldn't edit software. %q must be a %s, found %s", typeErrField, typeErr.Type.String(), typeErr.Value)) } return multierror.Append(multiError, fmt.Errorf("failed to unmarshall softwarespec: %v", err)) } diff --git a/server/service/client.go b/server/service/client.go index 6be25f00834a..8924707784f1 100644 --- a/server/service/client.go +++ b/server/service/client.go @@ -1502,9 +1502,13 @@ func (c *Client) DoGitOps( return nil, err } - err = c.doGitOpsQueries(config, logFn, dryRun) - if err != nil { - return nil, err + // We currently don't support queries for "No team" thus + // we just do GitOps for queries for global and team files. + if !config.IsNoTeam() { + err = c.doGitOpsQueries(config, logFn, dryRun) + if err != nil { + return nil, err + } } return teamAssumptions, nil diff --git a/server/service/client_policies.go b/server/service/client_policies.go index a8425bebf573..089e6a2d477d 100644 --- a/server/service/client_policies.go +++ b/server/service/client_policies.go @@ -2,6 +2,7 @@ package service import ( "fmt" + "github.com/fleetdm/fleet/v4/server/fleet" ) From 36ea5ccd76ea824c4e319836b06258cce058fd7f Mon Sep 17 00:00:00 2001 From: Gabriel Hernandez Date: Wed, 18 Sep 2024 21:53:30 +0100 Subject: [PATCH 11/81] Update tooltip for mac minimum target OS version label (#22157) Co-authored-by: gillespi314 <73313222+gillespi314@users.noreply.github.com> Co-authored-by: Roberto Dip --- .../21976-update-macos-target-version-tooltip | 1 + .../AppleOSTargetForm/AppleOSTargetForm.tsx | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 changes/21976-update-macos-target-version-tooltip diff --git a/changes/21976-update-macos-target-version-tooltip b/changes/21976-update-macos-target-version-tooltip new file mode 100644 index 000000000000..5ae1a5ffdf3b --- /dev/null +++ b/changes/21976-update-macos-target-version-tooltip @@ -0,0 +1 @@ +- update the macos target minimum version tooltip diff --git a/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx b/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx index 8c12c4905388..d3c35e3f604b 100644 --- a/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx +++ b/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx @@ -178,16 +178,18 @@ const AppleOSTargetForm = ({ } }; - const getMinimumVersionTooltip = (platform: ApplePlatform) => { - switch (platform) { - case "darwin": - return "The end user sees the window until their macOS is at or above this version."; - case "ios": - case "ipados": - return "If the end user's host is below the minimum version, they see a notification in their Notification Center after the deadline. They can’t continue until the OS update is installed."; - default: - return ""; - } + const getMinimumVersionTooltip = () => { + return ( + <> + If an already enrolled host is below the minimum version, +
the host is updated to exactly the minimum version if it's +
available from Apple. +
+
If a new or wiped host is below the minimum version and +
automatically enrolls (ADE), the host is updated to Apple's +
lastest version during Setup Assistant. + + ); }; const getDeadlineTooltip = (platform: ApplePlatform) => { @@ -206,7 +208,7 @@ const AppleOSTargetForm = ({
Date: Wed, 18 Sep 2024 17:37:22 -0500 Subject: [PATCH 12/81] Website: Add search and breadcrumbs to article template page (#22171) Closes: #15857 Closes: #21850 Changes: - Updated the article page template to include a search input and breadcrumb links. --- .../articles/view-basic-article.js | 1 + .../js/pages/articles/basic-article.page.js | 14 ++ .../styles/pages/articles/basic-article.less | 147 +++++++++++++++++- .../views/pages/articles/basic-article.ejs | 78 +++++++--- 4 files changed, 211 insertions(+), 29 deletions(-) diff --git a/website/api/controllers/articles/view-basic-article.js b/website/api/controllers/articles/view-basic-article.js index 17b997f5f7c0..6648cebc580e 100644 --- a/website/api/controllers/articles/view-basic-article.js +++ b/website/api/controllers/articles/view-basic-article.js @@ -86,6 +86,7 @@ module.exports = { pageImageForMeta: thisPage.meta.articleImageUrl || undefined, articleCategorySlug, currentSection, + algoliaPublicKey: sails.config.custom.algoliaPublicKey, }; } diff --git a/website/assets/js/pages/articles/basic-article.page.js b/website/assets/js/pages/articles/basic-article.page.js index 29112e45acba..8a1564366605 100644 --- a/website/assets/js/pages/articles/basic-article.page.js +++ b/website/assets/js/pages/articles/basic-article.page.js @@ -25,6 +25,20 @@ parasails.registerPage('basic-article', { let startValue = parseInt(ol.getAttribute('start'), 10) - 1; ol.style.counterReset = 'custom-counter ' + startValue; }); + if(this.algoliaPublicKey) {// Note: Docsearch will only be enabled if sails.config.custom.algoliaPublicKey is set. If the value is undefined, the handbook search will be disabled. + docsearch({ + appId: 'NZXAYZXDGH', + apiKey: this.algoliaPublicKey, + indexName: 'fleetdm', + container: '#docsearch-query', + placeholder: 'Search', + debug: false, + clickAnalytics: true, + searchParameters: { + facetFilters: ['section:docs'] + }, + }); + } }, // ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗ diff --git a/website/assets/styles/pages/articles/basic-article.less b/website/assets/styles/pages/articles/basic-article.less index 12c5f77ea0b8..ad7025156098 100644 --- a/website/assets/styles/pages/articles/basic-article.less +++ b/website/assets/styles/pages/articles/basic-article.less @@ -10,8 +10,126 @@ width: 100%; } + [purpose='breadcrumbs-and-search'] { + padding-top: 64px; + max-width: 1072px; + margin: auto; + font-size: 14px; + [purpose='breadcrumbs'] { + margin-right: 24px; + } + [purpose='search'] { + // Note: We're using classes here to override the default Docsearch styles; + button { + width: 100%; + cursor: text; + margin: 0; + } + .DocSearch-Button { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + border: 1px solid @core-fleet-black-25; + background-color: #FFF; + padding: 6px; + height: 36px; + margin: 0; + width: 256px; + } + .DocSearch-Button:hover { + box-shadow: none; + border: 1px solid @core-fleet-black-25; + color: @core-fleet-black-50; + } + .DocSearch-Search-Icon { + margin-left: 10px; + height: 16px; + width: 16px; + color: @core-fleet-black-50; + stroke-width: 3px; + } + .DocSearch-Button-Keys { + display: none; + } + .input-group:focus-within { + border: 1px solid @core-vibrant-blue; + } + .DocSearch-Button-Placeholder { + font-size: 16px; + font-weight: 400; + padding-left: 12px; + } + [purpose='disabled-search'] { + input { + padding-top: 6px; + padding-bottom: 6px; + border: none; + } &::placeholder { + font-size: 16px; + line-height: 24px; + color: #8B8FA2; + } + .input-group { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + border: 1px solid @core-fleet-black-25; + background: #FFF; + } + .input-group:focus-within { + border: 1px solid @core-vibrant-blue; + } + .form-control { + border-radius: 6px; + padding: 6px; + height: 36px; + margin: 0; + width: 212px; + } + .docsearch-input:focus-visible { + outline: none; + } + .ds-input:focus { + outline: rgba(0, 0, 0, 0); + } + .input-group-text { + color: @core-fleet-black-50; + } + .form-control { + height: 36px; + padding: 0px; + font-size: 16px; + } &:focus { + border: none; + } + } + } + + [purpose='breadcrumbs-category'] { + color: #8B8FA2; + text-transform: capitalize; + margin-right: 8px; + &:hover { + color: #192147; + text-decoration: none; + } + } + [purpose='breadcrumbs-title'] { + margin-left: 8px; + } + + } + [purpose='article-container'] { + max-width: 800px; + margin: auto; + display: flex; + flex-direction: column; + + } [purpose='article-title'] { - padding-top: 80px; + padding-top: 64px; margin-bottom: 28px; h1 { margin-bottom: 4px; @@ -107,8 +225,8 @@ } } [purpose='article-content'] { - padding-top: 24px; - padding-bottom: 24px; + padding-top: 40px; + padding-bottom: 40px; word-wrap: break-word; h1:first-of-type { display: none; @@ -126,8 +244,13 @@ padding: 24px 0px 16px 0px; } a { - color: @core-vibrant-blue; + color: @core-fleet-black-75; word-break: break-word; + text-decoration: underline; + text-underline-offset: 2px; + &:hover { + color: @core-fleet-black-75; + } } h2 { font-size: 24px; @@ -429,6 +552,18 @@ [purpose='article-content'] { padding-bottom: 0px; } + [purpose='breadcrumbs-and-search'] { + [purpose='breadcrumbs'] { + margin-bottom: 24px; + margin-right: auto; + } + [purpose='search'] { + width: 100%; + .DocSearch-Button { + width: 100%; + } + } + } } @media (max-width: 769px) { @@ -449,6 +584,10 @@ margin-bottom: 16px; } } + [purpose='breadcrumbs-and-search'] { + padding-top: 32px; + + } } @media (max-width: 576px) { diff --git a/website/views/pages/articles/basic-article.ejs b/website/views/pages/articles/basic-article.ejs index bbcd597ebfad..e72f85219d13 100644 --- a/website/views/pages/articles/basic-article.ejs +++ b/website/views/pages/articles/basic-article.ejs @@ -1,32 +1,60 @@
-
-
-

<%=thisPage.meta.articleTitle %>

-

{{articleSubtitle}}

-
-
-
- - | - The author's GitHub profile picture -

<%=thisPage.meta.authorFullName %>

+
+
+
+ +
+ {{thisPage.meta.articleTitle}} +
-
- Subscribe - A pencil iconEdit page +
+
+
+
+ + search + +
+
+ +
+
+
-
- <%- partial(path.relative(path.dirname(__filename), path.resolve( sails.config.appPath, path.join(sails.config.builtStaticContent.compiledPagePartialsAppPath, thisPage.htmlId)))) %> -
-
-
-

Get started

-
- - Start now - - Talk to us +
+
+

<%=thisPage.meta.articleTitle %>

+

{{articleSubtitle}}

+
+
+
+ + | + The author's GitHub profile picture +

<%=thisPage.meta.authorFullName %>

+
+ +
+
+ <%- partial(path.relative(path.dirname(__filename), path.resolve( sails.config.appPath, path.join(sails.config.builtStaticContent.compiledPagePartialsAppPath, thisPage.htmlId)))) %> +
+
+
+

Get started

+
+ + Start now + + Talk to us +
From 9a1b3769c868cbb458e0190df848d78603d5050b Mon Sep 17 00:00:00 2001 From: Gabriel Hernandez Date: Thu, 19 Sep 2024 11:50:18 +0100 Subject: [PATCH 13/81] show correct chrome software icon for chrome packages (#22233) relates to #20865 Show the correct software icon for uploaded chrome packages ![image](https://github.com/user-attachments/assets/85215a31-0b63-438b-a4dc-661cea026c3b) - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [x] Manual QA for all new/changed functionality --- changes/20865-fix-chrome-icon | 1 + frontend/pages/SoftwarePage/components/icons/index.ts | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 changes/20865-fix-chrome-icon diff --git a/changes/20865-fix-chrome-icon b/changes/20865-fix-chrome-icon new file mode 100644 index 000000000000..9ac53c39ccd8 --- /dev/null +++ b/changes/20865-fix-chrome-icon @@ -0,0 +1 @@ +- show proper software icon for chrome packages diff --git a/frontend/pages/SoftwarePage/components/icons/index.ts b/frontend/pages/SoftwarePage/components/icons/index.ts index 59e618700949..2c8d355f7e98 100644 --- a/frontend/pages/SoftwarePage/components/icons/index.ts +++ b/frontend/pages/SoftwarePage/components/icons/index.ts @@ -45,6 +45,7 @@ const SOFTWARE_NAME_TO_ICON_MAP = { "microsoft teams": Teams, "visual studio code": VisualStudioCode, "microsoft word": Word, + "google chrome": ChromeApp, darwin: MacOS, windows: WindowsOS, chrome: ChromeOS, @@ -113,8 +114,6 @@ const matchStrictNameSourceToIcon = ({ return Zoom; case name === "zoom": return Zoom; - case name === "google chrome": - return ChromeApp; default: return null; } From ebb62af6d99c41c92fbeb2f6b3375466a766ba56 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 19 Sep 2024 09:09:21 -0500 Subject: [PATCH 14/81] Website: Deliver contact form messages to Slack (#22231) Related to: https://github.com/fleetdm/confidential/issues/8098 Changes: - Updated `deliver-contact-form-message` to send contact form submissions to a Slack webhook. --- .../deliver-contact-form-message.js | 23 +++---------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/website/api/controllers/deliver-contact-form-message.js b/website/api/controllers/deliver-contact-form-message.js index ea5d6251ec61..37e5693f5c0e 100644 --- a/website/api/controllers/deliver-contact-form-message.js +++ b/website/api/controllers/deliver-contact-form-message.js @@ -66,26 +66,9 @@ module.exports = { throw 'invalidEmailDomain'; } - // await sails.helpers.http.post(sails.config.custom.slackWebhookUrlForContactForm, { - // text: `New contact form message: (Remember: we have to email back; can't just reply to this thread.) cc @sales `+ - // `Name: ${firstName + ' ' + lastName}, Email: ${emailAddress}, Message: ${message ? message : 'No message.'}` - // }); - - await sails.helpers.sendTemplateEmail.with({ - to: sails.config.custom.fromEmailAddress, - replyTo: { - name: firstName + ' '+ lastName, - emailAddress: emailAddress, - }, - subject: 'New contact form message', - layout: false, - template: 'email-contact-form', - templateData: { - emailAddress, - firstName, - lastName, - message, - }, + await sails.helpers.http.post(sails.config.custom.slackWebhookUrlForContactForm, { + text: `New contact form message: (Remember: we have to email back; can't just reply to this thread.)`+ + `Name: ${firstName + ' ' + lastName}, Email: ${emailAddress}, Message: ${message ? message : 'No message.'}` }); sails.helpers.salesforce.updateOrCreateContactAndAccount.with({ From 246fa60007227b1b89274aaf129b17ac38f1f827 Mon Sep 17 00:00:00 2001 From: Mike McNeil Date: Thu, 19 Sep 2024 10:04:51 -0500 Subject: [PATCH 15/81] Iron out the nav -- Update layout.ejs (#22151) --- website/views/layouts/layout.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/views/layouts/layout.ejs b/website/views/layouts/layout.ejs index 702ba0d5f58c..c8a438213faf 100644 --- a/website/views/layouts/layout.ejs +++ b/website/views/layouts/layout.ejs @@ -169,7 +169,7 @@ Docs REST API Guides - <%= ['eo-it', 'mdm'].includes(primaryBuyingSituation) ? 'Device health checks' : 'Built-in queries' %> + Built-in queries Data tables SUPPORT
From 6ab05ded4c951e624fdddb5c1798de5b2072aff5 Mon Sep 17 00:00:00 2001 From: Mike McNeil Date: Thu, 19 Sep 2024 10:06:45 -0500 Subject: [PATCH 16/81] Update link + CTA on pricing.ejs (#22229) Co-authored-by: Eric --- website/assets/js/pages/contact.page.js | 4 ++-- website/views/pages/pricing.ejs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/website/assets/js/pages/contact.page.js b/website/assets/js/pages/contact.page.js index 36571b672ac9..c7595825ca62 100644 --- a/website/assets/js/pages/contact.page.js +++ b/website/assets/js/pages/contact.page.js @@ -50,8 +50,8 @@ parasails.registerPage('contact', { if(this.formToShow === 'contact'){ this.formToDisplay = this.formToShow; } else if(!this.primaryBuyingSituation){ - // Default to contact form for users who have no primaryBuyingSituation set. - this.formToDisplay = 'contact'; + // Otherwise, default to the formToShow value from the page's controller. + this.formToDisplay = this.formToShow; } if(this.primaryBuyingSituation){ // If the user has a priamry buying situation set in their sesssion, pre-fill the form. // Note: this will be overriden if the user is logged in and has a primaryBuyingSituation set in the database. diff --git a/website/views/pages/pricing.ejs b/website/views/pages/pricing.ejs index fe1865886a5e..0a739c7529a7 100644 --- a/website/views/pages/pricing.ejs +++ b/website/views/pages/pricing.ejs @@ -380,7 +380,7 @@
-

Couldn’t find an answer? Message us.

+

Couldn’t find an answer? Talk to us.

From ad4c05e9ec47480730de7adba73de075bb1840c3 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 19 Sep 2024 10:24:06 -0500 Subject: [PATCH 17/81] Website: Update start CTA orb image (psyStage 4) (#22232) Changes: - Updated the /start CTA image for psystage 4 users --- ...ail-psystage-4-has-use-case-128x128@2x.png | Bin 32368 -> 24713 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/website/assets/images/cta-thumbnail-psystage-4-has-use-case-128x128@2x.png b/website/assets/images/cta-thumbnail-psystage-4-has-use-case-128x128@2x.png index 29347073c01ca0a7a43f43f09124f9b7c46cb51d..c00066c4087dc112b74cfc352c5584f007e72fd1 100644 GIT binary patch literal 24713 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 literal 32368 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 From 90c04eef37690b8ebb98849f37fb0f403b775527 Mon Sep 17 00:00:00 2001 From: Jahziel Villasana-Espinoza Date: Thu, 19 Sep 2024 11:31:46 -0400 Subject: [PATCH 18/81] fix: stop profiles that never reached the host from showing up as failed (#22186) > Related issue: #21891 # 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/Committing-Changes.md#changes-files) for more information. - [x] Added/updated tests - [x] Manual QA for all new/changed functionality --- changes/21891-mdm-profile-fails | 2 + server/datastore/mysql/apple_mdm.go | 10 +- server/fleet/apple_mdm.go | 6 +- server/service/apple_mdm.go | 4 +- .../service/integration_mdm_profiles_test.go | 10 +- server/service/integration_mdm_test.go | 95 +++++++++++-------- 6 files changed, 74 insertions(+), 53 deletions(-) create mode 100644 changes/21891-mdm-profile-fails diff --git a/changes/21891-mdm-profile-fails b/changes/21891-mdm-profile-fails new file mode 100644 index 000000000000..a01bac1649cf --- /dev/null +++ b/changes/21891-mdm-profile-fails @@ -0,0 +1,2 @@ +- Fixes a bug where a profile wouldn't be removed from a host if it was deleted or if the host was + moved to another team before the profile was installed on the host. \ No newline at end of file diff --git a/server/datastore/mysql/apple_mdm.go b/server/datastore/mysql/apple_mdm.go index c545c898cc74..b4ae8c5ac0d1 100644 --- a/server/datastore/mysql/apple_mdm.go +++ b/server/datastore/mysql/apple_mdm.go @@ -2087,11 +2087,11 @@ func (ds *Datastore) bulkSetPendingMDMAppleHostProfilesDB( if _, ok := profileIntersection.GetMatchingProfileInDesiredState(p); ok { continue } - // If the installation failed, then we do not want to change the operation to "Remove". + // If the profile wasn't installed, then we do not want to change the operation to "Remove". // Doing so will result in Fleet attempting to remove a profile that doesn't exist on the // host (since the installation failed). Skipping it here will lead to it being removed from // the host in Fleet during profile reconciliation, which is what we want. - if p.FailedToInstallOnHost() { + if p.DidNotInstallOnHost() { continue } profilesToInsert[fmt.Sprintf("%s\n%s", p.HostUUID, p.ProfileUUID)] = &fleet.MDMAppleProfilePayload{ @@ -4410,7 +4410,8 @@ func (ds *Datastore) insertOrUpsertMDMAppleDeclaration(ctx context.Context, insO } func batchSetDeclarationLabelAssociationsDB(ctx context.Context, tx sqlx.ExtContext, - declarationLabels []fleet.ConfigurationProfileLabel) (updatedDB bool, err error) { + declarationLabels []fleet.ConfigurationProfileLabel, +) (updatedDB bool, err error) { if len(declarationLabels) == 0 { return false, nil } @@ -4618,7 +4619,8 @@ func (ds *Datastore) MDMAppleBatchSetHostDeclarationState(ctx context.Context) ( } func mdmAppleBatchSetHostDeclarationStateDB(ctx context.Context, tx sqlx.ExtContext, batchSize int, - status *fleet.MDMDeliveryStatus) ([]string, bool, error) { + status *fleet.MDMDeliveryStatus, +) ([]string, bool, error) { // once all the declarations are in place, compute the desired state // and find which hosts need a DDM sync. changedDeclarations, err := mdmAppleGetHostsWithChangedDeclarationsDB(ctx, tx) diff --git a/server/fleet/apple_mdm.go b/server/fleet/apple_mdm.go index 9a3bb005f8d3..832ee5d237a1 100644 --- a/server/fleet/apple_mdm.go +++ b/server/fleet/apple_mdm.go @@ -311,10 +311,10 @@ type MDMAppleProfilePayload struct { CommandUUID string `db:"command_uuid"` } -// FailedToInstallOnHost indicates whether this profile failed to be installed on the host (and +// DidNotInstallOnHost indicates whether this profile was not installed on the host (and // therefore is not, as far as Fleet knows, currently on the host). -func (p *MDMAppleProfilePayload) FailedToInstallOnHost() bool { - return p.Status != nil && *p.Status == MDMDeliveryFailed && p.OperationType == MDMOperationTypeInstall +func (p *MDMAppleProfilePayload) DidNotInstallOnHost() bool { + return p.Status != nil && (*p.Status == MDMDeliveryFailed || *p.Status == MDMDeliveryPending) && p.OperationType == MDMOperationTypeInstall } func (p MDMAppleProfilePayload) Equal(other MDMAppleProfilePayload) bool { diff --git a/server/service/apple_mdm.go b/server/service/apple_mdm.go index 99bfa2195dfd..4387367ef017 100644 --- a/server/service/apple_mdm.go +++ b/server/service/apple_mdm.go @@ -3298,8 +3298,8 @@ func ReconcileAppleProfiles( continue } - if p.FailedToInstallOnHost() { - // then we shouldn't send an additional remove command since it failed to install on the + if p.DidNotInstallOnHost() { + // then we shouldn't send an additional remove command since it wasn't installed on the // host. hostProfilesToCleanup = append(hostProfilesToCleanup, p) continue diff --git a/server/service/integration_mdm_profiles_test.go b/server/service/integration_mdm_profiles_test.go index f7fc2e2373f4..49a1f6eab0cf 100644 --- a/server/service/integration_mdm_profiles_test.go +++ b/server/service/integration_mdm_profiles_test.go @@ -1159,18 +1159,16 @@ func (s *integrationMDMTestSuite) TestPuppetMatchPreassignProfiles() { s.awaitTriggerProfileSchedule(t) // useful for debugging - //mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { - // mysql.DumpTable(t, q, "host_mdm_apple_profiles") - // return nil - //}) + // mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { + // mysql.DumpTable(t, q, "host_mdm_apple_profiles") + // return nil + // }) s.assertHostAppleConfigProfiles(map[*fleet.Host][]fleet.HostMDMAppleProfile{ mdmHost: { {Identifier: "i1", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryPending}, - {Identifier: "i2", OperationType: fleet.MDMOperationTypeRemove, Status: &fleet.MDMDeliveryPending}, {Identifier: "i4", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryPending}, {Identifier: mobileconfig.FleetdConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryPending}, {Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryPending}, - {Identifier: mobileconfig.FleetFileVaultPayloadIdentifier, OperationType: fleet.MDMOperationTypeRemove, Status: &fleet.MDMDeliveryPending}, }, }) diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index 2e7ef1f152ca..ce134a2bd5fe 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -9383,32 +9383,34 @@ func (s *integrationMDMTestSuite) TestRemoveFailedProfiles() { ident := uuid.NewString() + mdmDeviceRespond := func(device *mdmtest.TestAppleMDMClient) { + cmd, err := device.Idle() + require.NoError(t, err) + for cmd != nil { + if cmd.Command.RequestType == "InstallProfile" { + var fullCmd micromdm.CommandPayload + require.NoError(t, plist.Unmarshal(cmd.Raw, &fullCmd)) + + if strings.Contains(string(fullCmd.Command.InstallProfile.Payload), ident) { + var errChain []mdm.ErrorChain + errChain = append(errChain, mdm.ErrorChain{ErrorCode: -102, ErrorDomain: "CPProfile", USEnglishDescription: "The profile is either missing some required information, or contains information in an invalid format."}) + cmd, err = device.Err(cmd.CommandUUID, errChain) + require.NoError(t, err) + continue + } + } + cmd, err = device.Acknowledge(cmd.CommandUUID) + require.NoError(t, err) + } + } + globalProfiles := [][]byte{ mobileconfigForTest("N1", ident), mobileconfigForTest("N2", "I2"), } s.Do("POST", "/api/v1/fleet/mdm/apple/profiles/batch", batchSetMDMAppleProfilesRequest{Profiles: globalProfiles}, http.StatusNoContent) s.awaitTriggerProfileSchedule(t) - - cmd, err := mdmDevice.Idle() - require.NoError(t, err) - for cmd != nil { - if cmd.Command.RequestType == "InstallProfile" { - var fullCmd micromdm.CommandPayload - require.NoError(t, plist.Unmarshal(cmd.Raw, &fullCmd)) - - if strings.Contains(string(fullCmd.Command.InstallProfile.Payload), ident) { - var errChain []mdm.ErrorChain - errChain = append(errChain, mdm.ErrorChain{ErrorCode: -102, ErrorDomain: "CPProfile", USEnglishDescription: "The profile is either missing some required information, or contains information in an invalid format."}) - cmd, err = mdmDevice.Err(cmd.CommandUUID, errChain) - require.NoError(t, err) - continue - } - } - cmd, err = mdmDevice.Acknowledge(cmd.CommandUUID) - require.NoError(t, err) - } - + mdmDeviceRespond(mdmDevice) require.NoError(t, apple_mdm.VerifyHostMDMProfiles(context.Background(), s.ds, host, map[string]*fleet.HostMacOSProfile{ "I2": {Identifier: "I2", DisplayName: "I2", InstallDate: time.Now()}, "I1": {Identifier: "I1", DisplayName: "I1", InstallDate: time.Now()}, @@ -9416,24 +9418,7 @@ func (s *integrationMDMTestSuite) TestRemoveFailedProfiles() { // Do another trigger + command fetching cycle, since we retry when a profile fails on install. s.awaitTriggerProfileSchedule(t) - cmd, err = mdmDevice.Idle() - require.NoError(t, err) - for cmd != nil { - if cmd.Command.RequestType == "InstallProfile" { - var fullCmd micromdm.CommandPayload - require.NoError(t, plist.Unmarshal(cmd.Raw, &fullCmd)) - - if strings.Contains(string(fullCmd.Command.InstallProfile.Payload), ident) { - var errChain []mdm.ErrorChain - errChain = append(errChain, mdm.ErrorChain{ErrorCode: -102, ErrorDomain: "CPProfile", USEnglishDescription: "The profile is either missing some required information, or contains information in an invalid format."}) - cmd, err = mdmDevice.Err(cmd.CommandUUID, errChain) - require.NoError(t, err) - continue - } - } - cmd, err = mdmDevice.Acknowledge(cmd.CommandUUID) - require.NoError(t, err) - } + mdmDeviceRespond(mdmDevice) require.NoError(t, apple_mdm.VerifyHostMDMProfiles(context.Background(), s.ds, host, map[string]*fleet.HostMacOSProfile{ "I1": {Identifier: "I1", DisplayName: "I1", InstallDate: time.Now()}, @@ -9468,6 +9453,40 @@ func (s *integrationMDMTestSuite) TestRemoveFailedProfiles() { for _, hm := range *getHostResp.Host.MDM.Profiles { require.NotEqual(t, "N1", hm.Name) } + + // Test case where the profile never makes it to the host at all + host, _ = createHostThenEnrollMDM(s.ds, s.server.URL, t) + ident = uuid.NewString() + + globalProfiles = [][]byte{ + mobileconfigForTest("N3", ident), + } + s.Do("POST", "/api/v1/fleet/mdm/apple/profiles/batch", batchSetMDMAppleProfilesRequest{Profiles: globalProfiles}, http.StatusNoContent) + s.awaitTriggerProfileSchedule(t) + + getHostResp = getHostResponse{} + s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", host.ID), nil, http.StatusOK, &getHostResp) + require.NotNil(t, getHostResp.Host.MDM.Profiles) + require.Len(t, *getHostResp.Host.MDM.Profiles, 3) + var profUUID string + for _, hm := range *getHostResp.Host.MDM.Profiles { + require.Equal(t, fleet.MDMDeliveryPending, *hm.Status) + if hm.Name == "N3" { + profUUID = hm.ProfileUUID + } + } + + // delete the custom profile + s.Do("DELETE", fmt.Sprintf("/api/latest/fleet/mdm/profiles/%s", profUUID), &deleteMDMAppleConfigProfileRequest{}, http.StatusOK) + s.awaitTriggerProfileSchedule(t) + + getHostResp = getHostResponse{} + s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", host.ID), nil, http.StatusOK, &getHostResp) + require.NotNil(t, getHostResp.Host.MDM.Profiles) + require.Len(t, *getHostResp.Host.MDM.Profiles, 2) + for _, hm := range *getHostResp.Host.MDM.Profiles { + require.Equal(t, fleet.MDMDeliveryPending, *hm.Status) + } } func (s *integrationMDMTestSuite) TestABMAssetManagement() { From e2ac27e011d913eca5a6c6428ece4a25fba7b3b2 Mon Sep 17 00:00:00 2001 From: Luke Heath Date: Thu, 19 Sep 2024 13:35:17 -0500 Subject: [PATCH 19/81] Document 0-day macOS major version support process beginning with macOS 16 (#22243) Co-authored-by: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> --- handbook/engineering/README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/handbook/engineering/README.md b/handbook/engineering/README.md index 13f3d21c15c9..388a5c87243b 100644 --- a/handbook/engineering/README.md +++ b/handbook/engineering/README.md @@ -538,13 +538,25 @@ Upon receiving any device, follow these steps to process incoming equipment. Once the Digital Experience department approves inventory to be shipped from Fleet IT, follow these step to ship the equipment. 1. Compare the equipment request issue with the ["Company equipment" spreadsheet](https://docs.google.com/spreadsheets/d/1hFlymLlRWIaWeVh14IRz03yE-ytBLfUaqVz0VVmmoGI/edit#gid=0) and verify physical inventory. 2. Plug in the device and ensure inventory has been correctly processed and all components are present (e.g. charger cord, power converter). -3. package equipment for shipment and include Yubikeys (if requested). +3. Package equipment for shipment and include Yubikeys (if requested). 4. Change the "Company equipment" spreadsheet to reflect the new user. - If you encounter any issues, repeat the [process incoming equipment steps](https://fleetdm.com/handbook/engineering#process-incoming-equipment). If problems persist, create a ["💻 IT support issue](https://github.com/fleetdm/confidential/issues/new?assignees=%40spokanemac&labels=%3Ahelp-it&projects=&template=request-it-support.md&title=%F0%9F%92%BB+Request+IT+support) for IT to troubleshoot the device. 6. Ship via FedEx to the address listed in the equipment request. 7. Add a comment to the equipment request issue, at-mentioning the requestor with the FedEx tracking info and close the issue. +### Provide 0-day support for major version macOS releases + +Beginning with macOS 16, Fleet will offer 0-day support for all major version macOS releases. + +1. Install major version macOS beta release on test devices. +2. Create a new [QA release issue](https://github.com/fleetdm/fleet/issues/new?assignees=xpkoala%2Cpezhub&labels=%23g-mdm%2C%23g-endpoint-ops%2C%3Arelease&projects=&template=release-qa.md&title=Release+QA%3A+macOS+16) with the new major version in the issue title. +3. Complete all manual smoke tests in the issue and confirm they are passing. +4. Confirm all automated tests are passing. +5. [File bugs](https://github.com/fleetdm/fleet/issues/new?assignees=&labels=P1%2Cbug%2C%3Areproduce%2C%3Aincoming&projects=&template=bug-report.md&title=) with a `P1` label and assign to the appropriate [product group](https://fleetdm.com/handbook/company/product-groups#current-product-groups). +6. When all bugs are fixed, follow the [writing a feature guide](https://fleetdm.com/handbook/engineering#write-a-feature-guide) process to publish an article announcing Fleet 0-day support for the new major release. + + ## Rituals From d52335eb1326123326003d79dcf14fa1b0882160 Mon Sep 17 00:00:00 2001 From: Mike McNeil Date: Thu, 19 Sep 2024 15:51:44 -0500 Subject: [PATCH 20/81] Update link, clarify iOS (#22230) --- handbook/company/pricing-features-table.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/handbook/company/pricing-features-table.yml b/handbook/company/pricing-features-table.yml index c8b17d8ce36d..dcc3c26b5246 100644 --- a/handbook/company/pricing-features-table.yml +++ b/handbook/company/pricing-features-table.yml @@ -214,8 +214,8 @@ # ║ ╠╦╝║ ║╚═╗╚═╗───╠═╝║ ╠═╣ ║ ╠╣ ║ ║╠╦╝║║║ ║║║ ║║║║║ ╚═╗║ ║╠═╝╠═╝║ ║╠╦╝ ║ # ╚═╝╩╚═╚═╝╚═╝╚═╝ ╩ ╩═╝╩ ╩ ╩ ╚ ╚═╝╩╚═╩ ╩ ╩ ╩═╩╝╩ ╩ ╚═╝╚═╝╩ ╩ ╚═╝╩╚═ ╩ - industryName: Cross-platform MDM support - description: macOS, Windows, and Linux. - documentationUrl: https://fleetdm.com/announcements/fleet-introduces-windows-mdm + description: Apple, Windows, and Linux. + documentationUrl: https://fleetdm.com/announcements/debunk-the-cross-platform-myth tier: Premium jamfProHasFeature: appleOnly jamfProtectHasFeature: no From f247e57931a09b83d07b07d78306d5691d39e62a Mon Sep 17 00:00:00 2001 From: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:01:31 -0500 Subject: [PATCH 21/81] Add template response to hiring steps (#22255) --- handbook/company/leadership.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/handbook/company/leadership.md b/handbook/company/leadership.md index 3b5448f58078..05097bf552f6 100644 --- a/handbook/company/leadership.md +++ b/handbook/company/leadership.md @@ -380,6 +380,7 @@ Once the new team member replies and accepts their offer in writing, 🌐 Head o - **"Offer accepted?"** _(Set this to `TRUE`)_ - _[Create a "Hiring" issue](https://github.com/fleetdm/confidential/issues/new/choose)_ for the new team member. (This issue will keep track of the hiring tasks for the new team member.) - _Send a reply_ welcoming the team member to Fleet and letting them know to expect a separate email with next steps for getting the team member's laptop, Yubikeys, and agreement going ASAP so they can start on time. For example: + ``` \o/ It's official! @@ -387,15 +388,24 @@ Once the new team member replies and accepts their offer in writing, 🌐 Head o Thanks, and welcome to the team! - -Sam + Cheers, + Sam ``` -2. **Ask hiring manager to send rejections:** Post to the `hiring-xxxxx-yyyy` Slack channel to let folks know the offer was accepted, and at-mention the _hiring manager_ to ask them to communicate with [all other interviewees](https://fleetdm.com/handbook/company#empathy) who are still in the running and [let them know that we chose a different person](https://fleetdm.com/handbook/company/leadership#candidate-correspondence-email-templates). + +2. **Ask hiring manager to send rejections:** Post to the `hiring-xxxxx-yyyy` Slack channel to let folks know the offer was accepted, and at-mention the _hiring manager_ using the following template: + +``` +@HIRING_MANAGER, :astronaut: TEAM_MEMBER_NAME has accepted the offer :fleet: and this position is now filled :white_check_mark:. Please inform any other interviewees who are still in the running and let them know that we chose a different person. :thankyou-ty: +``` + +3. **Close Slack channel:** Then archive the channel. + >_**Note:** Send rejection emails quickly, within 1 business day. It only gets harder if you wait._ -3. **Remove open position:** Ensure the hiring manager removes the newly-filled position from the fleetdm.com website by [making a pull request](https://fleetdm.com/handbook/company/communications#making-a-pull-request) to delete it from the [open-positions.yml](https://github.com/fleetdm/fleet/blob/main/handbook/company/open-positions.yml) file. -4. **Create 30-60-90 day plan:** 🧑‍🚀 Hiring manager creates a 30-60-90 day plan outlining key role objectives. The plan is reviewed weekly in 1:1 meetings during the first three months of employment, ensuring continuous support and alignment with company goals. To create the 30-60-90 day plan, hiring manager will: +4. **Remove open position:** Ensure the hiring manager removes the newly-filled position from the fleetdm.com website by [making a pull request](https://fleetdm.com/handbook/company/communications#making-a-pull-request) to delete it from the [open-positions.yml](https://github.com/fleetdm/fleet/blob/main/handbook/company/open-positions.yml) file. +5. **Create 30-60-90 day plan:** 🧑‍🚀 Hiring manager creates a 30-60-90 day plan outlining key role objectives. The plan is reviewed weekly in 1:1 meetings during the first three months of employment, ensuring continuous support and alignment with company goals. To create the 30-60-90 day plan, hiring manager will: - Create a copy of the [30-60-90 day plan template](https://docs.google.com/document/d/1EztmPBuMFXbVoy4ZToXcxasNO38ooOh8Gh5hPXFvJhI/copy) and rename the copied file using the naming convention `[start date] - 30-60-90 day plan - [teammate full name]` and move it to the [30-60-90 day plan folder](https://drive.google.com/drive/u/0/folders/1QWiAbgBFuuofT_3M8oIoBsbEBmubQAj7) in Google Drive. - Follow the prompts in the template to fill out the 30-60-90 day plan for the new teammate before they start. -5. **Close Slack channel:** Then archive and close the channel. + Now what happens? 🌐 Head of Digital Experience will then follow the steps in the "Hiring" issue, which includes reaching out to the new team member within 1 business day from a separate email thread to get additional information as needed, prepare their agreement, add them to the company's payroll system, and get their new laptop and hardware security keys ordered so that everything is ready for them to start on their first day. From edec764a27a3a54e212ca4e40badc2497318c3e8 Mon Sep 17 00:00:00 2001 From: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:10:52 -0500 Subject: [PATCH 22/81] Remove AE position (#22256) --- handbook/company/open-positions.yml | 32 ----------------------------- 1 file changed, 32 deletions(-) diff --git a/handbook/company/open-positions.yml b/handbook/company/open-positions.yml index 36eb7e05dfb1..19ad611e9ee0 100644 --- a/handbook/company/open-positions.yml +++ b/handbook/company/open-positions.yml @@ -36,35 +36,3 @@ - 🛠️ Technical: You understand the software development processes. You understand that software quality matters. - 🟣 Openness: You are flexible and open to new ideas and ways of working. - ➕ Bonus: Cybersecurity or IT background. - -- jobTitle: 🐋 Account Executive - department: Customers - hiringManagerName: Alex Mitchell - hiringManagerLinkedInUrl: https://www.linkedin.com/in/alexandercmitchell/ - hiringManagerGithubUsername: alexmitchelliii - responsibilities: | - - 🎯 Direct and participate in prospecting target companies, identifying key decision makers and influencers, leading when assigned/necessary/appropriate. - - 📈 Use available data to identify opportunities and trends with individual prospects. - - 📣 Actively promote FleetDM product and services on social media. - - 🖥️ Actively present and demonstrate the value of FleetDM products and services and upgrades targeting customer expansion opportunities. - - ❔ Appropriately use and follow MEDDPPICC process to qualify and progress opportunities to best help prospects solve problems. - - 🤔 Anticipate market trends and identify new opportunities for growth. - - 🕴️ Utilize systems and tools such as salesforce to analyze pipeline and opportunity data and keep all information up to date for leadership reporting. - - 🚀 Work collaboratively with the product management, customer support, and engineering teams to facilitate feature development based on customer asks. - - 🧑‍💻 Collaborate with the marketing team to plan, execute and track impactful marketing campaigns, in order to meet and/or exceed quarterly pipeline and revenue targets. - - 🤝 Work with prospects to find win-win commercial agreements. - experience: | - - 🦉 5+ years experience selling to enterprise customers. - - 📣 Have excellent communication and interpersonal skills. - - 🧑‍💻 Love technology and can explain how things work in detail. - - 🧪 Extensive experience with Slack, Salesforce, Google Suite, and GitHub. - - ⏩ Thrive in a complex, fast-paced, results driven environment with the ability to pivot to organizational changes easily. - - 🤝 Decisive with the ability to shift gears between thinking and doing. - - 📈 Ability to partner with various teams and stakeholders to drive sales. - - 👀 Strong understanding of the enterprise procurement process. - - ➕ Bonus: Direct experience with Fleet, MDM, osquery or SQL query writing, and working with Client Platform Engineering, SRE, or Security Engineering teams. - - 💭 You know how to manage complex sales, difficult escalations, and challenging procurement processes with the utmost care and organization. - - 💖 You know how to manage your time and priorities between leads, opportunities other day-to-day responsibilities. - - ✍ You have the ability to effectively influence key stakeholders, from senior executives to day-to-day engineering contacts, and discuss Fleet's value with them. - - 🧬 You care about delivering an outstanding customer experience and advocating for the customer's needs within Fleet. - - ➕ Bonus: You are comfortable with concepts like DevOps/GitOps, APIs, and security. From 07a58266abd212b81ecf8de705716a60826b92b9 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Thu, 19 Sep 2024 19:11:00 -0400 Subject: [PATCH 23/81] fleetdm.com/start: suggested copy change for fleetctl install (#22251) - Suggesting capital "Linux" and "macOS" b/c it feels more official. --------- Co-authored-by: Eric --- website/assets/resources/install-fleetctl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/assets/resources/install-fleetctl.sh b/website/assets/resources/install-fleetctl.sh index 08fb7273854a..5f5d4a2774b4 100644 --- a/website/assets/resources/install-fleetctl.sh +++ b/website/assets/resources/install-fleetctl.sh @@ -28,8 +28,8 @@ version_gt() { OS="$(uname -s)" case "${OS}" in - Linux*) OS='linux';; - Darwin*) OS='macos';; + Linux*) OS='linux' OS_DISPLAY_NAME='Linux';; + Darwin*) OS='macos' OS_DISPLAY_NAME='macOS';; *) echo "Unsupported operating system: ${OS}"; exit 1;; esac @@ -41,7 +41,7 @@ mkdir -p "${FLEETCTL_INSTALL_DIR}" DOWNLOAD_URL="https://github.com/fleetdm/fleet/releases/download/fleet-v${latest_strippedVersion}/fleetctl_v${latest_strippedVersion}_${OS}.tar.gz" # Download the latest version of fleetctl and extract it. -echo "Downloading fleetctl ${latest_strippedVersion} for ${OS}..." +echo "Downloading fleetctl ${latest_strippedVersion} for ${OS_DISPLAY_NAME}..." curl -sSL "$DOWNLOAD_URL" | tar -xz -C "$FLEETCTL_INSTALL_DIR" --strip-components=1 fleetctl_v"${latest_strippedVersion}"_${OS}/ echo "fleetctl installed successfully in ${FLEETCTL_INSTALL_DIR}" echo From 2a88d5a21021f731ee9b061abaa34c53f3864741 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:06:06 -0400 Subject: [PATCH 24/81] Add Product Designer position (#22250) Co-authored-by: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> --- handbook/company/open-positions.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/handbook/company/open-positions.yml b/handbook/company/open-positions.yml index 19ad611e9ee0..71bcb2af6b3d 100644 --- a/handbook/company/open-positions.yml +++ b/handbook/company/open-positions.yml @@ -9,6 +9,30 @@ # experience: | # Add markdown content to this field. ################################################ +- jobTitle: 🦢 Product Designer + department: Product Design + hiringManagerName: Noah Talerman + hiringManagerLinkedInUrl: https://www.linkedin.com/in/noah-talerman/ + hiringManagerGithubUsername: noahtalerman + responsibilities: | + - ⏫ Engage with product management, engineering, business stakeholders, and customers to understand initiatives. + - 📣 Design consistent interactions across the Fleet user experience, including API and CLI. + - 🌡️ Drive the refinement process from concept to high-fidelity prototypes. + experience: | + - 💭 3 - 5 years of experience as a Product Designer. + - 💖 Proficient in visual design and wireframing tools (we use Figma). + - 🦉 Articulate the problem to be solved and create a compelling narrative around proposed solutions. + - 📖 Maintain a design system that enables speed for designers, PMs, and engineers. + - 🧑‍🔬 Develop an understanding of developer-first automation workflows, including API and CLI experiences. + - 🧪 Translate user insights into digital experiences that are well-crafted and easy to use. + - 🤝 Collaboration: You work best in a participatory, team-based environment. + - 🚀 Prototype-first: You embrace speed and failure as we iterate towards the right solution. You have hands-on experience in creating low and high-fidelity prototypes. You’re comfortable accepting suboptimal designs in favor of iteration. + - 🧬 Simplicity: You love complex questions and use your work to simplify that complexity for users. + - 🟣 Openness: You are flexible and open to new ideas and ways of working. + - ✍️ Experience designing CLI experiences for developers or willingness to learn. + - ➕ Bonus: YB2B SaaS background + - ➕ Bonus: cybersecurity or IT background + - jobTitle: 🚀 Software Engineer department: Engineering hiringManagerName: Luke Heath @@ -22,7 +46,7 @@ - 🚀 Actively participate in all engineering scrum meetings, including sprint planning, daily standups, sprint demos, sprint retrospectives, and estimation sessions. - 🌟 Contribute to the overall success of the [MDM](https://fleetdm.com/handbook/company/product-groups#mdm-group) product group by ensuring users receive valuable new features. experience: | - - 💭 3-5 years' of experience in backend/SaaS development. + - 💭 3-5 years of experience in backend/SaaS development. - 🦉 Proficient in backend development. You practice OOP design and are comfortable in a lean software development environment. - 🦉 Translate requirements into well-designed and functional software. - 🤝 Communicate regularly with stakeholders, project managers, quality assurance teams, and other developers regarding progress on long-term technology roadmap. @@ -36,3 +60,4 @@ - 🛠️ Technical: You understand the software development processes. You understand that software quality matters. - 🟣 Openness: You are flexible and open to new ideas and ways of working. - ➕ Bonus: Cybersecurity or IT background. + From e4b6fae72fdc3e63a866153b07b54ed63a8d6de0 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Fri, 20 Sep 2024 10:18:45 -0400 Subject: [PATCH 25/81] Update pricing-features-table.yml (#22235) - ACME in 2025 --- handbook/company/pricing-features-table.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handbook/company/pricing-features-table.yml b/handbook/company/pricing-features-table.yml index dcc3c26b5246..13e19b938880 100644 --- a/handbook/company/pricing-features-table.yml +++ b/handbook/company/pricing-features-table.yml @@ -269,7 +269,7 @@ productCategories: [Device management] pricingTableCategories: [Devices] waysToUse: - - description: Support ACME as a protocol for MDM certificate generation. Coming soon (2024-12-31) #customer-rosner + - description: Support ACME as a protocol for MDM certificate generation. Coming soon (2025-03-31) #customer-rosner moreInfoUrl: https://github.com/fleetdm/fleet/issues/15611 # # ╦ ╦╔═╗╔═╗╦═╗ ╔═╗╔═╗╔═╗╔═╗╦ ╦╔╗╔╔╦╗ ╔═╗╦ ╦╔╗╔╔═╗ From 2708988446ee28dbdf9aa5f1f97c7af92b678bf7 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Fri, 20 Sep 2024 07:50:10 -0700 Subject: [PATCH 26/81] Fleet UI: Fix observer persisting host_id when querying host from host details page (#22249) --- changes/20959-query-host-flow-fix-observer | 1 + .../QueryDetailsPage/QueryDetailsPage.tsx | 15 +++++++++++++-- frontend/pages/queries/edit/EditQueryPage.tsx | 9 ++++++++- frontend/router/paths.ts | 17 +++++++++++++---- 4 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 changes/20959-query-host-flow-fix-observer diff --git a/changes/20959-query-host-flow-fix-observer b/changes/20959-query-host-flow-fix-observer new file mode 100644 index 000000000000..f1db67c3e9af --- /dev/null +++ b/changes/20959-query-host-flow-fix-observer @@ -0,0 +1 @@ +- Fix UI flow for observers to easily query hosts from the host details page diff --git a/frontend/pages/queries/details/QueryDetailsPage/QueryDetailsPage.tsx b/frontend/pages/queries/details/QueryDetailsPage/QueryDetailsPage.tsx index 42a2413c99d0..cdaec1aebd69 100644 --- a/frontend/pages/queries/details/QueryDetailsPage/QueryDetailsPage.tsx +++ b/frontend/pages/queries/details/QueryDetailsPage/QueryDetailsPage.tsx @@ -49,7 +49,12 @@ interface IQueryDetailsPageProps { params: Params; location: { pathname: string; - query: { team_id?: string; order_key?: string; order_direction?: string }; + query: { + team_id?: string; + order_key?: string; + order_direction?: string; + host_id?: string; + }; search: string; }; } @@ -67,6 +72,12 @@ const QueryDetailsPage = ({ } const queryParams = location.query; + // Present when observer is redirected from host details > query + // since observer does not have access to edit page + const hostId = queryParams?.host_id + ? parseInt(queryParams.host_id, 10) + : undefined; + const { currentTeamId } = useTeamIdParam({ location, router, @@ -295,7 +306,7 @@ const QueryDetailsPage = ({ onClick={() => { queryId && router.push( - PATHS.LIVE_QUERY(queryId, currentTeamId) + PATHS.LIVE_QUERY(queryId, currentTeamId, hostId) ); }} disabled={isLiveQueryDisabled} diff --git a/frontend/pages/queries/edit/EditQueryPage.tsx b/frontend/pages/queries/edit/EditQueryPage.tsx index addfd6b06175..d2bc087b60c8 100644 --- a/frontend/pages/queries/edit/EditQueryPage.tsx +++ b/frontend/pages/queries/edit/EditQueryPage.tsx @@ -208,7 +208,14 @@ const EditQueryPage = ({ queryId > 0 && !canEditExistingQuery ) { - router.push(PATHS.QUERY_DETAILS(queryId)); + // Reroute to query report page still maintains query params for live query purposes + const baseUrl = PATHS.QUERY_DETAILS(queryId); + const queryParams = buildQueryStringFromParams({ + host_id: location.query.host_id, + team_id: location.query.team_id, + }); + + router.push(queryParams ? `${baseUrl}?${queryParams}` : baseUrl); } }, [queryId, isTeamMaintainerOrTeamAdmin, isStoredQueryLoading]); diff --git a/frontend/router/paths.ts b/frontend/router/paths.ts index faaa9f35b7a0..1db857b43231 100644 --- a/frontend/router/paths.ts +++ b/frontend/router/paths.ts @@ -1,3 +1,5 @@ +import { buildQueryStringFromParams } from "utilities/url"; + import { IPolicy } from "../interfaces/policy"; import URL_PREFIX from "./url_prefix"; @@ -95,10 +97,17 @@ export default { teamId ? `?team_id=${teamId}` : "" }`; }, - LIVE_QUERY: (queryId: number | null, teamId?: number): string => { - return `${URL_PREFIX}/queries/${queryId || "new"}/live${ - teamId ? `?team_id=${teamId}` : "" - }`; + LIVE_QUERY: ( + queryId: number | null, + teamId?: number, + hostId?: number + ): string => { + const baseUrl = `${URL_PREFIX}/queries/${queryId || "new"}/live`; + const queryParams = buildQueryStringFromParams({ + team_id: teamId, + host_id: hostId, + }); + return queryParams ? `${baseUrl}?${queryParams}` : baseUrl; }, QUERY_DETAILS: (queryId: number, teamId?: number): string => { return `${URL_PREFIX}/queries/${queryId}${ From 8d664bd4564abb7e3f8f005f15a4e26f9a27be9e Mon Sep 17 00:00:00 2001 From: Lucas Manuel Rodriguez Date: Fri, 20 Sep 2024 11:55:47 -0300 Subject: [PATCH 27/81] Make software batch endpoint asynchronous (#22258) #22069 API changes: https://github.com/fleetdm/fleet/pull/22259 QAd by applying 10 pieces of software on a team, which took 3+ minutes in total (which, before these changes was timing out at 100s.) With this approach, a GitOps CI run timing out might leave the background process running (which will eventually be applied to the database). The team discussed and agreed that we can fix this edge case later. - [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/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] Added/updated tests - [X] Manual QA for all new/changed functionality --- changes/22069-gitops-async-software-batch | 1 + cmd/fleet/serve.go | 2 + cmd/fleetctl/get_test.go | 4 +- cmd/fleetctl/gitops_test.go | 82 ++++- ee/server/service/mdm_external_test.go | 1 + ee/server/service/service.go | 3 + ee/server/service/software_installers.go | 281 +++++++++++++----- server/datastore/mysql/software_installers.go | 39 +-- .../mysql/software_installers_test.go | 24 +- server/fleet/datastore.go | 3 +- server/fleet/service.go | 26 +- server/mock/datastore_mock.go | 16 +- server/service/client_software.go | 33 +- server/service/client_teams.go | 7 +- server/service/handler.go | 3 + server/service/integration_enterprise_test.go | 179 +++++++++-- .../redis_key_value/redis_key_value.go | 58 ++++ .../redis_key_value/redis_key_value_test.go | 92 ++++++ server/service/software_installers.go | 49 ++- server/service/testing_utils.go | 9 + 20 files changed, 757 insertions(+), 155 deletions(-) create mode 100644 changes/22069-gitops-async-software-batch create mode 100644 server/service/redis_key_value/redis_key_value.go create mode 100644 server/service/redis_key_value/redis_key_value_test.go diff --git a/changes/22069-gitops-async-software-batch b/changes/22069-gitops-async-software-batch new file mode 100644 index 000000000000..35f0652fe209 --- /dev/null +++ b/changes/22069-gitops-async-software-batch @@ -0,0 +1 @@ +* Modified `POST /api/latest/fleet/software/batch` endpoint to be asynchronous and added a new endpoint `GET /api/latest/fleet/software/batch/{request_uuid}` to retrieve the result of the batch upload. diff --git a/cmd/fleet/serve.go b/cmd/fleet/serve.go index caf72413da65..eda0660a731d 100644 --- a/cmd/fleet/serve.go +++ b/cmd/fleet/serve.go @@ -49,6 +49,7 @@ import ( "github.com/fleetdm/fleet/v4/server/pubsub" "github.com/fleetdm/fleet/v4/server/service" "github.com/fleetdm/fleet/v4/server/service/async" + "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/service/redis_policy_set" "github.com/fleetdm/fleet/v4/server/sso" @@ -798,6 +799,7 @@ the way that the Fleet server works. softwareInstallStore, bootstrapPackageStore, distributedLock, + redis_key_value.New(redisPool), ) if err != nil { initFatal(err, "initial Fleet Premium service") diff --git a/cmd/fleetctl/get_test.go b/cmd/fleetctl/get_test.go index e775f4ea5fb4..f39ff1cd5551 100644 --- a/cmd/fleetctl/get_test.go +++ b/cmd/fleetctl/get_test.go @@ -2320,8 +2320,8 @@ func TestGetTeamsYAMLAndApply(t *testing.T) { declaration.DeclarationUUID = uuid.NewString() return declaration, nil } - ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { - return nil, nil + ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { + return nil } actualYaml := runAppForTest(t, []string{"get", "teams", "--yaml"}) diff --git a/cmd/fleetctl/gitops_test.go b/cmd/fleetctl/gitops_test.go index 64cb9fda19cc..b93496155999 100644 --- a/cmd/fleetctl/gitops_test.go +++ b/cmd/fleetctl/gitops_test.go @@ -182,7 +182,8 @@ func TestGitOpsBasicGlobalPremium(t *testing.T) { license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)} _, ds := runServerWithMockedDS( t, &service.TestServerOpts{ - License: license, + License: license, + KeyValueStore: newMemKeyValueStore(), }, ) @@ -229,7 +230,10 @@ func TestGitOpsBasicGlobalPremium(t *testing.T) { ds.NewJobFunc = func(ctx context.Context, job *fleet.Job) (*fleet.Job, error) { return &fleet.Job{}, nil } - ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { + ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { + return nil + } + ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) { return nil, nil } @@ -285,7 +289,8 @@ func TestGitOpsBasicTeam(t *testing.T) { license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)} _, ds := runServerWithMockedDS( t, &service.TestServerOpts{ - License: license, + License: license, + KeyValueStore: newMemKeyValueStore(), }, ) @@ -373,7 +378,10 @@ func TestGitOpsBasicTeam(t *testing.T) { ds.DeleteMDMAppleDeclarationByNameFunc = func(ctx context.Context, teamID *uint, name string) error { return nil } - ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { + ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { + return nil + } + ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) { return nil, nil } ds.ApplyEnrollSecretsFunc = func(ctx context.Context, teamID *uint, secrets []*fleet.EnrollSecret) error { @@ -644,6 +652,7 @@ func TestGitOpsFullTeam(t *testing.T) { MDMPusher: mockPusher{}, FleetConfig: &fleetCfg, NoCacheDatastore: true, + KeyValueStore: newMemKeyValueStore(), }, ) @@ -804,8 +813,11 @@ func TestGitOpsFullTeam(t *testing.T) { return nil } var appliedSoftwareInstallers []*fleet.UploadSoftwareInstallerPayload - ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { + ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { appliedSoftwareInstallers = installers + return nil + } + ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) { return nil, nil } ds.SetTeamVPPAppsFunc = func(ctx context.Context, teamID *uint, adamIDs []fleet.VPPAppTeam) error { @@ -937,7 +949,8 @@ func TestGitOpsBasicGlobalAndTeam(t *testing.T) { license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)} _, ds := runServerWithMockedDS( t, &service.TestServerOpts{ - License: license, + License: license, + KeyValueStore: newMemKeyValueStore(), }, ) @@ -1055,7 +1068,10 @@ func TestGitOpsBasicGlobalAndTeam(t *testing.T) { savedTeam = team return team, nil } - ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { + ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { + return nil + } + ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) { return nil, nil } ds.ListSoftwareTitlesFunc = func(ctx context.Context, opt fleet.SoftwareTitleListOptions, tmFilter fleet.TeamFilter) ([]fleet.SoftwareTitleListResult, int, *fleet.PaginationMetadata, error) { @@ -1201,7 +1217,8 @@ func TestGitOpsBasicGlobalAndNoTeam(t *testing.T) { license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)} _, ds := runServerWithMockedDS( t, &service.TestServerOpts{ - License: license, + License: license, + KeyValueStore: newMemKeyValueStore(), }, ) // Mock appConfig @@ -1317,7 +1334,10 @@ func TestGitOpsBasicGlobalAndNoTeam(t *testing.T) { savedTeam = team return team, nil } - ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { + ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { + return nil + } + ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) { return nil, nil } ds.ListSoftwareTitlesFunc = func(ctx context.Context, opt fleet.SoftwareTitleListOptions, tmFilter fleet.TeamFilter) ([]fleet.SoftwareTitleListResult, int, *fleet.PaginationMetadata, error) { @@ -1634,9 +1654,9 @@ func TestGitOpsTeamSofwareInstallers(t *testing.T) { file string wantErr string }{ - {"testdata/gitops/team_software_installer_not_found.yml", "Please make sure that URLs are publicy accessible to the internet."}, + {"testdata/gitops/team_software_installer_not_found.yml", "Please make sure that URLs are reachable from your Fleet server."}, {"testdata/gitops/team_software_installer_unsupported.yml", "The file should be .pkg, .msi, .exe or .deb."}, - {"testdata/gitops/team_software_installer_too_large.yml", "The maximum file size is 500 MB"}, + {"testdata/gitops/team_software_installer_too_large.yml", "The maximum file size is 500 MiB"}, {"testdata/gitops/team_software_installer_valid.yml", ""}, {"testdata/gitops/team_software_installer_valid_apply.yml", ""}, {"testdata/gitops/team_software_installer_pre_condition_multiple_queries.yml", "should have only one query."}, @@ -1668,10 +1688,13 @@ func TestGitOpsTeamSoftwareInstallersQueryEnv(t *testing.T) { t.Setenv("QUERY_VAR", "IT_WORKS") - ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { + ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { if installers[0].PreInstallQuery != "select IT_WORKS" { - return nil, fmt.Errorf("Missing env var, got %s", installers[0].PreInstallQuery) + return fmt.Errorf("Missing env var, got %s", installers[0].PreInstallQuery) } + return nil + } + ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) { return nil, nil } @@ -1686,9 +1709,9 @@ func TestGitOpsNoTeamSoftwareInstallers(t *testing.T) { noTeamFile string wantErr string }{ - {"testdata/gitops/no_team_software_installer_not_found.yml", "Please make sure that URLs are publicy accessible to the internet."}, + {"testdata/gitops/no_team_software_installer_not_found.yml", "Please make sure that URLs are reachable from your Fleet server."}, {"testdata/gitops/no_team_software_installer_unsupported.yml", "The file should be .pkg, .msi, .exe or .deb."}, - {"testdata/gitops/no_team_software_installer_too_large.yml", "The maximum file size is 500 MB"}, + {"testdata/gitops/no_team_software_installer_too_large.yml", "The maximum file size is 500 MiB"}, {"testdata/gitops/no_team_software_installer_valid.yml", ""}, {"testdata/gitops/no_team_software_installer_pre_condition_multiple_queries.yml", "should have only one query."}, {"testdata/gitops/no_team_software_installer_pre_condition_not_found.yml", "no such file or directory"}, @@ -2050,6 +2073,7 @@ func setupFullGitOpsPremiumServer(t *testing.T) (*mock.Store, **fleet.AppConfig, FleetConfig: &fleetCfg, License: license, NoCacheDatastore: true, + KeyValueStore: newMemKeyValueStore(), }, ) @@ -2181,7 +2205,10 @@ func setupFullGitOpsPremiumServer(t *testing.T) (*mock.Store, **fleet.AppConfig, declaration.DeclarationUUID = uuid.NewString() return declaration, nil } - ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { + ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { + return nil + } + ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) { return nil, nil } @@ -2890,3 +2917,26 @@ software: }) } } + +type memKeyValueStore struct { + m map[string]string +} + +func newMemKeyValueStore() *memKeyValueStore { + return &memKeyValueStore{ + m: make(map[string]string), + } +} + +func (m *memKeyValueStore) Set(ctx context.Context, key string, value string, expireTime time.Duration) error { + m.m[key] = value + return nil +} + +func (m *memKeyValueStore) Get(ctx context.Context, key string) (*string, error) { + v, ok := m.m[key] + if !ok { + return nil, nil + } + return &v, nil +} diff --git a/ee/server/service/mdm_external_test.go b/ee/server/service/mdm_external_test.go index 1d92d1ce3b43..760d046c9c5b 100644 --- a/ee/server/service/mdm_external_test.go +++ b/ee/server/service/mdm_external_test.go @@ -109,6 +109,7 @@ func setupMockDatastorePremiumService(t testing.TB) (*mock.Store, *eeservice.Ser nil, nil, nil, + nil, ) if err != nil { panic(err) diff --git a/ee/server/service/service.go b/ee/server/service/service.go index 7ef6f8b8a530..fb66f21136ad 100644 --- a/ee/server/service/service.go +++ b/ee/server/service/service.go @@ -30,6 +30,7 @@ type Service struct { softwareInstallStore fleet.SoftwareInstallerStore bootstrapPackageStore fleet.MDMBootstrapPackageStore distributedLock fleet.Lock + keyValueStore fleet.KeyValueStore } func NewService( @@ -46,6 +47,7 @@ func NewService( softwareInstallStore fleet.SoftwareInstallerStore, bootstrapPackageStore fleet.MDMBootstrapPackageStore, distributedLock fleet.Lock, + keyValueStore fleet.KeyValueStore, ) (*Service, error) { authorizer, err := authz.NewAuthorizer() if err != nil { @@ -67,6 +69,7 @@ func NewService( softwareInstallStore: softwareInstallStore, bootstrapPackageStore: bootstrapPackageStore, distributedLock: distributedLock, + keyValueStore: keyValueStore, } // Override methods that can't be easily overriden via diff --git a/ee/server/service/software_installers.go b/ee/server/service/software_installers.go index 5a1d67910665..ac4461a592b2 100644 --- a/ee/server/service/software_installers.go +++ b/ee/server/service/software_installers.go @@ -14,6 +14,7 @@ import ( "path/filepath" "regexp" "strings" + "time" "github.com/fleetdm/fleet/v4/pkg/file" "github.com/fleetdm/fleet/v4/pkg/fleethttp" @@ -24,6 +25,7 @@ import ( "github.com/fleetdm/fleet/v4/server/fleet" "github.com/fleetdm/fleet/v4/server/mdm/apple/vpp" "github.com/fleetdm/fleet/v4/server/ptr" + "github.com/go-kit/log" kitlog "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/google/uuid" @@ -1112,13 +1114,21 @@ func (svc *Service) addMetadataToSoftwarePayload(ctx context.Context, payload *f return meta.Extension, nil } -const maxInstallerSizeBytes int64 = 1024 * 1024 * 500 +const ( + maxInstallerSizeBytes int64 = 1024 * 1024 * 500 + batchSoftwarePrefix = "software_batch_" +) func (svc *Service) BatchSetSoftwareInstallers( ctx context.Context, tmName string, payloads []fleet.SoftwareInstallerPayload, dryRun bool, -) ([]fleet.SoftwarePackageResponse, error) { +) (string, error) { if err := svc.authz.Authorize(ctx, &fleet.Team{}, fleet.ActionRead); err != nil { - return nil, err + return "", err + } + + vc, ok := viewer.FromContext(ctx) + if !ok { + return "", fleet.ErrNoContext } var teamID *uint @@ -1127,98 +1137,165 @@ func (svc *Service) BatchSetSoftwareInstallers( if err != nil { // If this is a dry run, the team may not have been created yet if dryRun && fleet.IsNotFound(err) { - return nil, nil + return "", nil } - return nil, err + return "", err } teamID = &tm.ID } if err := svc.authz.Authorize(ctx, &fleet.SoftwareInstaller{TeamID: teamID}, fleet.ActionWrite); err != nil { - return nil, ctxerr.Wrap(ctx, err, "validating authorization") + return "", ctxerr.Wrap(ctx, err, "validating authorization") } + // Verify payloads first, to prevent starting the download+upload process if the data is invalid. for _, payload := range payloads { if len(payload.URL) > fleet.SoftwareInstallerURLMaxLength { - return nil, fleet.NewInvalidArgumentError( + return "", fleet.NewInvalidArgumentError( "software.url", "software URL is too long, must be less than 256 characters", ) } + if _, err := url.ParseRequestURI(payload.URL); err != nil { + return "", fleet.NewInvalidArgumentError( + "software.url", + fmt.Sprintf("Couldn't edit software. URL (%q) is invalid", payload.URL), + ) + } } - vc, ok := viewer.FromContext(ctx) - if !ok { - return nil, fleet.ErrNoContext + // keyExpireTime is the current maximum time supported for retrieving + // the result of a software by batch operation. + const keyExpireTime = 24 * time.Hour + + requestUUID := uuid.NewString() + if err := svc.keyValueStore.Set(ctx, batchSoftwarePrefix+requestUUID, batchSetProcessing, keyExpireTime); err != nil { + return "", ctxerr.Wrapf(ctx, err, "failed to set key as %s", batchSetProcessing) } - g, workerCtx := errgroup.WithContext(ctx) - g.SetLimit(3) - // critical to avoid data race, the slice is pre-allocated and each - // goroutine only writes to its index. - installers := make([]*fleet.UploadSoftwareInstallerPayload, len(payloads)) + svc.logger.Log( + "msg", "software batch start", + "request_uuid", requestUUID, + "team_id", teamID, + "payloads", len(payloads), + ) - for i, p := range payloads { - i, p := i, p + go svc.softwareBatchUpload( + requestUUID, + teamID, + vc.UserID(), + payloads, + dryRun, + ) - g.Go(func() error { - // validate the URL before doing the request - _, err := url.ParseRequestURI(p.URL) - if err != nil { - return fleet.NewInvalidArgumentError( + return requestUUID, nil +} + +const ( + batchSetProcessing = "processing" + batchSetCompleted = "completed" + batchSetFailedPrefix = "failed:" +) + +func (svc *Service) softwareBatchUpload( + requestUUID string, + teamID *uint, + userID uint, + payloads []fleet.SoftwareInstallerPayload, + dryRun bool, +) { + var batchErr error + + // We do not use the request ctx on purpose because this method runs in the background. + ctx := context.Background() + + defer func(start time.Time) { + status := batchSetCompleted + if batchErr != nil { + status = fmt.Sprintf("%s%s", batchSetFailedPrefix, batchErr) + } + logger := log.With(svc.logger, + "request_uuid", requestUUID, + "team_id", teamID, + "payloads", len(payloads), + "status", status, + "took", time.Since(start), + ) + logger.Log("msg", "software batch done") + // Give 10m for the client to read the result (it overrides the previos expiration time). + if err := svc.keyValueStore.Set(ctx, batchSoftwarePrefix+requestUUID, status, 10*time.Minute); err != nil { + logger.Log("msg", "failed to set result", "err", err) + } + }(time.Now()) + + downloadURLFn := func(ctx context.Context, url string) (http.Header, []byte, error) { + client := fleethttp.NewClient() + client.Transport = fleethttp.NewSizeLimitTransport(maxInstallerSizeBytes) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, nil, fmt.Errorf("creating request for URL %q: %w", url, err) + } + + resp, err := client.Do(req) + if err != nil { + var maxBytesErr *http.MaxBytesError + if errors.Is(err, fleethttp.ErrMaxSizeExceeded) || errors.As(err, &maxBytesErr) { + return nil, nil, fleet.NewInvalidArgumentError( "software.url", - fmt.Sprintf("Couldn't edit software. URL (%q) is invalid", p.URL), + fmt.Sprintf("Couldn't edit software. URL (%q). The maximum file size is %d MiB", url, maxInstallerSizeBytes/(1024*1024)), ) } - client := fleethttp.NewClient() - client.Transport = fleethttp.NewSizeLimitTransport(maxInstallerSizeBytes) - req, err := http.NewRequestWithContext(workerCtx, http.MethodGet, p.URL, nil) - if err != nil { - return ctxerr.Wrapf(ctx, err, "creating request for URL %s", p.URL) - } + return nil, nil, fmt.Errorf("performing request for URL %q: %w", url, err) + } + defer resp.Body.Close() - resp, err := client.Do(req) - if err != nil { - var maxBytesErr *http.MaxBytesError - if errors.Is(err, fleethttp.ErrMaxSizeExceeded) || errors.As(err, &maxBytesErr) { - return fleet.NewInvalidArgumentError( - "software.url", - fmt.Sprintf("Couldn't edit software. URL (%q). The maximum file size is %d MB", p.URL, maxInstallerSizeBytes/(1024*1024)), - ) - } + if resp.StatusCode == http.StatusNotFound { + return nil, nil, fleet.NewInvalidArgumentError( + "software.url", + fmt.Sprintf("Couldn't edit software. URL (%q) returned \"Not Found\". Please make sure that URLs are reachable from your Fleet server.", url), + ) + } - return ctxerr.Wrapf(ctx, err, "performing request for URL %s", p.URL) - } - defer resp.Body.Close() + // Allow all 2xx and 3xx status codes in this pass. + if resp.StatusCode >= 400 { + return nil, nil, fleet.NewInvalidArgumentError( + "software.url", + fmt.Sprintf("Couldn't edit software. URL (%q) received response status code %d.", url, resp.StatusCode), + ) + } - if resp.StatusCode == http.StatusNotFound { - return fleet.NewInvalidArgumentError( + bodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + // the max size error can be received either at client.Do or here when + // reading the body if it's caught via a limited body reader. + var maxBytesErr *http.MaxBytesError + if errors.Is(err, fleethttp.ErrMaxSizeExceeded) || errors.As(err, &maxBytesErr) { + return nil, nil, fleet.NewInvalidArgumentError( "software.url", - fmt.Sprintf("Couldn't edit software. URL (%q) doesn't exist. Please make sure that URLs are publicy accessible to the internet.", p.URL), + fmt.Sprintf("Couldn't edit software. URL (%q). The maximum file size is %d MiB", url, maxInstallerSizeBytes/(1024*1024)), ) } + return nil, nil, fmt.Errorf("reading installer %q contents: %w", url, err) + } - // Allow all 2xx and 3xx status codes in this pass. - if resp.StatusCode > 400 { - return fleet.NewInvalidArgumentError( - "software.url", - fmt.Sprintf("Couldn't edit software. URL (%q) received response status code %d.", p.URL, resp.StatusCode), - ) - } + return resp.Header, bodyBytes, nil + } + + var g errgroup.Group + g.SetLimit(3) + // critical to avoid data race, the slice is pre-allocated and each + // goroutine only writes to its index. + installers := make([]*fleet.UploadSoftwareInstallerPayload, len(payloads)) + + for i, p := range payloads { + i, p := i, p - bodyBytes, err := io.ReadAll(resp.Body) + g.Go(func() error { + headers, bodyBytes, err := downloadURLFn(ctx, p.URL) if err != nil { - // the max size error can be received either at client.Do or here when - // reading the body if it's caught via a limited body reader. - var maxBytesErr *http.MaxBytesError - if errors.Is(err, fleethttp.ErrMaxSizeExceeded) || errors.As(err, &maxBytesErr) { - return fleet.NewInvalidArgumentError( - "software.url", - fmt.Sprintf("Couldn't edit software. URL (%q). The maximum file size is %d MB", p.URL, maxInstallerSizeBytes/(1024*1024)), - ) - } - return ctxerr.Wrapf(ctx, err, "reading installer %q contents", p.URL) + return err } installer := &fleet.UploadSoftwareInstallerPayload{ @@ -1229,13 +1306,13 @@ func (svc *Service) BatchSetSoftwareInstallers( UninstallScript: p.UninstallScript, InstallerFile: bytes.NewReader(bodyBytes), SelfService: p.SelfService, - UserID: vc.UserID(), + UserID: userID, URL: p.URL, } // set the filename before adding metadata, as it is used as fallback var filename string - cdh, ok := resp.Header["Content-Disposition"] + cdh, ok := headers["Content-Disposition"] if ok && len(cdh) > 0 { _, params, err := mime.ParseMediaType(cdh[0]) if err == nil { @@ -1273,30 +1350,88 @@ func (svc *Service) BatchSetSoftwareInstallers( } if err := g.Wait(); err != nil { - // NOTE: intentionally not wrapping to avoid polluting user - // errors. - return nil, err + // NOTE: intentionally not wrapping to avoid polluting user errors. + batchErr = err + return } if dryRun { - return nil, nil + return } for _, payload := range installers { if err := svc.storeSoftware(ctx, payload); err != nil { - return nil, ctxerr.Wrap(ctx, err, "storing software installer") + batchErr = fmt.Errorf("storing software installer %q: %w", payload.Filename, err) + return } } - insertedSoftwareInstallers, err := svc.ds.BatchSetSoftwareInstallers(ctx, teamID, installers) - if err != nil { - return nil, ctxerr.Wrap(ctx, err, "batch set software installers") + if err := svc.ds.BatchSetSoftwareInstallers(ctx, teamID, installers); err != nil { + batchErr = fmt.Errorf("batch set software installers: %w", err) + return } // Note: per @noahtalerman we don't want activity items for CLI actions // anymore, so that's intentionally skipped. +} + +func (svc *Service) GetBatchSetSoftwareInstallersResult(ctx context.Context, tmName string, requestUUID string, dryRun bool) (string, string, []fleet.SoftwarePackageResponse, error) { + // We've already authorized in the POST /api/latest/fleet/software/batch, + // but adding it here so we don't need to worry about a special case endpoint. + if err := svc.authz.Authorize(ctx, &fleet.Team{}, fleet.ActionRead); err != nil { + return "", "", nil, err + } + + result, err := svc.keyValueStore.Get(ctx, batchSoftwarePrefix+requestUUID) + if err != nil { + return "", "", nil, ctxerr.Wrap(ctx, err, "failed to get result") + } + if result == nil { + return "", "", nil, ctxerr.Wrap(ctx, notFoundError{}, "request_uuid not found") + } + + switch { + case *result == batchSetCompleted: + if dryRun { + return fleet.BatchSetSoftwareInstallersStatusCompleted, "", nil, nil + } // this will fall through to retrieving software packages if not a dry run. + case *result == batchSetProcessing: + return fleet.BatchSetSoftwareInstallersStatusProcessing, "", nil, nil + case strings.HasPrefix(*result, batchSetFailedPrefix): + message := strings.TrimPrefix(*result, batchSetFailedPrefix) + return fleet.BatchSetSoftwareInstallersStatusFailed, message, nil, nil + default: + return "", "", nil, ctxerr.New(ctx, "invalid status") + } + + var ( + teamID uint // GetSoftwareInstallers uses 0 for "No team" + ptrTeamID *uint // Authorize uses *uint for "No team" teamID + ) + if tmName != "" { + team, err := svc.ds.TeamByName(ctx, tmName) + if err != nil { + return "", "", nil, ctxerr.Wrap(ctx, err, "load team by name") + } + teamID = team.ID + ptrTeamID = &team.ID + } + + // We've already authorized in the POST /api/latest/fleet/software/batch, + // but adding it here so we don't need to worry about a special case endpoint. + // + // We use fleet.ActionWrite because this method is the counterpart of the POST + // /api/latest/fleet/software/batch. + if err := svc.authz.Authorize(ctx, &fleet.SoftwareInstaller{TeamID: ptrTeamID}, fleet.ActionWrite); err != nil { + return "", "", nil, ctxerr.Wrap(ctx, err, "validating authorization") + } + + softwarePackages, err := svc.ds.GetSoftwareInstallers(ctx, teamID) + if err != nil { + return "", "", nil, ctxerr.Wrap(ctx, err, "get software installers") + } - return insertedSoftwareInstallers, nil + return fleet.BatchSetSoftwareInstallersStatusCompleted, "", softwarePackages, nil } func (svc *Service) SelfServiceInstallSoftwareTitle(ctx context.Context, host *fleet.Host, softwareTitleID uint) error { diff --git a/server/datastore/mysql/software_installers.go b/server/datastore/mysql/software_installers.go index 5aa7a2f11d51..7d7f0169e3ad 100644 --- a/server/datastore/mysql/software_installers.go +++ b/server/datastore/mysql/software_installers.go @@ -768,7 +768,7 @@ func (ds *Datastore) CleanupUnusedSoftwareInstallers(ctx context.Context, softwa return ctxerr.Wrap(ctx, err, "cleanup unused software installers") } -func (ds *Datastore) BatchSetSoftwareInstallers(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { +func (ds *Datastore) BatchSetSoftwareInstallers(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { const upsertSoftwareTitles = ` INSERT INTO software_titles (name, source, browser) @@ -878,23 +878,12 @@ ON DUPLICATE KEY UPDATE url = VALUES(url) ` - const loadInsertedSoftwareInstallers = ` -SELECT - team_id, - title_id, - url -FROM - software_installers -WHERE global_or_team_id = ? -` - // use a team id of 0 if no-team var globalOrTeamID uint if tmID != nil { globalOrTeamID = *tmID } - var insertedSoftwareInstallers []fleet.SoftwarePackageResponse if err := ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { // if no installers are provided, just delete whatever was in // the table @@ -1040,15 +1029,11 @@ WHERE global_or_team_id = ? } } - if err := sqlx.SelectContext(ctx, tx, &insertedSoftwareInstallers, loadInsertedSoftwareInstallers, globalOrTeamID); err != nil { - return ctxerr.Wrap(ctx, err, "load inserted software installers") - } - return nil }); err != nil { - return nil, err + return err } - return insertedSoftwareInstallers, nil + return nil } func (ds *Datastore) HasSelfServiceSoftwareInstallers(ctx context.Context, hostPlatform string, hostTeamID *uint) (bool, error) { @@ -1135,3 +1120,21 @@ func (ds *Datastore) UpdateSoftwareInstallerWithoutPackageIDs(ctx context.Contex } return nil } + +func (ds *Datastore) GetSoftwareInstallers(ctx context.Context, teamID uint) ([]fleet.SoftwarePackageResponse, error) { + const loadInsertedSoftwareInstallers = ` +SELECT + team_id, + title_id, + url +FROM + software_installers +WHERE global_or_team_id = ? +` + var softwarePackages []fleet.SoftwarePackageResponse + // Using ds.writer(ctx) on purpose because this method is to be called after applying software. + if err := sqlx.SelectContext(ctx, ds.writer(ctx), &softwarePackages, loadInsertedSoftwareInstallers, teamID); err != nil { + return nil, ctxerr.Wrap(ctx, err, "get software installers") + } + return softwarePackages, nil +} diff --git a/server/datastore/mysql/software_installers_test.go b/server/datastore/mysql/software_installers_test.go index 862d70063a07..178b85807148 100644 --- a/server/datastore/mysql/software_installers_test.go +++ b/server/datastore/mysql/software_installers_test.go @@ -630,11 +630,15 @@ func testBatchSetSoftwareInstallers(t *testing.T, ds *Datastore) { } // batch set with everything empty - softwareInstallers, err := ds.BatchSetSoftwareInstallers(ctx, &team.ID, nil) + err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, nil) + require.NoError(t, err) + softwareInstallers, err := ds.GetSoftwareInstallers(ctx, team.ID) require.NoError(t, err) require.Empty(t, softwareInstallers) assertSoftware(nil) - softwareInstallers, err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{}) + err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{}) + require.NoError(t, err) + softwareInstallers, err = ds.GetSoftwareInstallers(ctx, team.ID) require.NoError(t, err) require.Empty(t, softwareInstallers) assertSoftware(nil) @@ -642,7 +646,7 @@ func testBatchSetSoftwareInstallers(t *testing.T, ds *Datastore) { // add a single installer ins0 := "installer0" ins0File := bytes.NewReader([]byte("installer0")) - softwareInstallers, err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{{ + err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{{ InstallScript: "install", InstallerFile: ins0File, StorageID: ins0, @@ -656,6 +660,8 @@ func testBatchSetSoftwareInstallers(t *testing.T, ds *Datastore) { URL: "https://example.com", }}) require.NoError(t, err) + softwareInstallers, err = ds.GetSoftwareInstallers(ctx, team.ID) + require.NoError(t, err) require.Len(t, softwareInstallers, 1) require.NotNil(t, softwareInstallers[0].TeamID) require.Equal(t, team.ID, *softwareInstallers[0].TeamID) @@ -668,7 +674,7 @@ func testBatchSetSoftwareInstallers(t *testing.T, ds *Datastore) { // add a new installer + ins0 installer ins1 := "installer1" ins1File := bytes.NewReader([]byte("installer1")) - softwareInstallers, err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{ + err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{ { InstallScript: "install", InstallerFile: ins0File, @@ -698,6 +704,8 @@ func testBatchSetSoftwareInstallers(t *testing.T, ds *Datastore) { }, }) require.NoError(t, err) + softwareInstallers, err = ds.GetSoftwareInstallers(ctx, team.ID) + require.NoError(t, err) require.Len(t, softwareInstallers, 2) require.NotNil(t, softwareInstallers[0].TitleID) require.NotNil(t, softwareInstallers[0].TeamID) @@ -713,7 +721,7 @@ func testBatchSetSoftwareInstallers(t *testing.T, ds *Datastore) { }) // remove ins0 - softwareInstallers, err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{ + err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{ { InstallScript: "install", PostInstallScript: "post-install", @@ -728,6 +736,8 @@ func testBatchSetSoftwareInstallers(t *testing.T, ds *Datastore) { }, }) require.NoError(t, err) + softwareInstallers, err = ds.GetSoftwareInstallers(ctx, team.ID) + require.NoError(t, err) require.Len(t, softwareInstallers, 1) require.NotNil(t, softwareInstallers[0].TitleID) require.NotNil(t, softwareInstallers[0].TeamID) @@ -737,7 +747,9 @@ func testBatchSetSoftwareInstallers(t *testing.T, ds *Datastore) { }) // remove everything - softwareInstallers, err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{}) + err = ds.BatchSetSoftwareInstallers(ctx, &team.ID, []*fleet.UploadSoftwareInstallerPayload{}) + require.NoError(t, err) + softwareInstallers, err = ds.GetSoftwareInstallers(ctx, team.ID) require.NoError(t, err) require.Empty(t, softwareInstallers) assertSoftware([]fleet.SoftwareTitle{}) diff --git a/server/fleet/datastore.go b/server/fleet/datastore.go index 9f9a9de50479..99b2cdb7d27c 100644 --- a/server/fleet/datastore.go +++ b/server/fleet/datastore.go @@ -1711,7 +1711,8 @@ type Datastore interface { CleanupUnusedSoftwareInstallers(ctx context.Context, softwareInstallStore SoftwareInstallerStore, removeCreatedBefore time.Time) error // BatchSetSoftwareInstallers sets the software installers for the given team or no team. - BatchSetSoftwareInstallers(ctx context.Context, tmID *uint, installers []*UploadSoftwareInstallerPayload) ([]SoftwarePackageResponse, error) + BatchSetSoftwareInstallers(ctx context.Context, tmID *uint, installers []*UploadSoftwareInstallerPayload) error + GetSoftwareInstallers(ctx context.Context, tmID uint) ([]SoftwarePackageResponse, error) // HasSelfServiceSoftwareInstallers returns true if self-service software installers are available for the team or globally. HasSelfServiceSoftwareInstallers(ctx context.Context, platform string, teamID *uint) (bool, error) diff --git a/server/fleet/service.go b/server/fleet/service.go index 8599e464e1b5..24756ebb6d80 100644 --- a/server/fleet/service.go +++ b/server/fleet/service.go @@ -643,9 +643,15 @@ type Service interface { // GetSoftwareInstallResults gets the results for a particular software install attempt. GetSoftwareInstallResults(ctx context.Context, installUUID string) (*HostSoftwareInstallerResult, error) - // BatchSetSoftwareInstallers replaces the software installers for a specified team. - // Returns the metadata of inserted software installers. - BatchSetSoftwareInstallers(ctx context.Context, tmName string, payloads []SoftwareInstallerPayload, dryRun bool) ([]SoftwarePackageResponse, error) + // BatchSetSoftwareInstallers asynchronously replaces the software installers for a specified team. + // Returns a request UUID that can be used to track an ongoing batch request (with GetBatchSetSoftwareInstallersResult). + BatchSetSoftwareInstallers(ctx context.Context, tmName string, payloads []SoftwareInstallerPayload, dryRun bool) (string, error) + // GetBatchSetSoftwareInstallersResult polls for the status of a batch-apply started by BatchSetSoftwareInstallers. + // Return values: + // - 'status': status of the batch-apply which can be "processing", "completed" or "failed". + // - 'message': which contains error information when the status is "failed". + // - 'packages': Contains the list of the applied software packages (when status is "completed"). This is always empty for a dry run. + GetBatchSetSoftwareInstallersResult(ctx context.Context, tmName string, requestUUID string, dryRun bool) (status string, message string, packages []SoftwarePackageResponse, err error) // SelfServiceInstallSoftwareTitle installs a software title // initiated by the user @@ -1120,3 +1126,17 @@ type Service interface { // CalendarWebhook handles incoming calendar callback requests. CalendarWebhook(ctx context.Context, eventUUID string, channelID string, resourceState string) error } + +type KeyValueStore interface { + Set(ctx context.Context, key string, value string, expireTime time.Duration) error + Get(ctx context.Context, key string) (*string, error) +} + +const ( + // BatchSetSoftwareInstallerStatusProcessing is the value returned for an ongoing BatchSetSoftwareInstallers operation. + BatchSetSoftwareInstallersStatusProcessing = "processing" + // BatchSetSoftwareInstallerStatusCompleted is the value returned for a completed BatchSetSoftwareInstallers operation. + BatchSetSoftwareInstallersStatusCompleted = "completed" + // BatchSetSoftwareInstallerStatusFailed is the value returned for a failed BatchSetSoftwareInstallers operation. + BatchSetSoftwareInstallersStatusFailed = "failed" +) diff --git a/server/mock/datastore_mock.go b/server/mock/datastore_mock.go index bc009c4ea30d..a592559bdf5a 100644 --- a/server/mock/datastore_mock.go +++ b/server/mock/datastore_mock.go @@ -1070,7 +1070,9 @@ type GetSoftwareInstallResultsFunc func(ctx context.Context, resultsUUID string) type CleanupUnusedSoftwareInstallersFunc func(ctx context.Context, softwareInstallStore fleet.SoftwareInstallerStore, removeCreatedBefore time.Time) error -type BatchSetSoftwareInstallersFunc func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) +type BatchSetSoftwareInstallersFunc func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error + +type GetSoftwareInstallersFunc func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) type HasSelfServiceSoftwareInstallersFunc func(ctx context.Context, platform string, teamID *uint) (bool, error) @@ -2667,6 +2669,9 @@ type DataStore struct { BatchSetSoftwareInstallersFunc BatchSetSoftwareInstallersFunc BatchSetSoftwareInstallersFuncInvoked bool + GetSoftwareInstallersFunc GetSoftwareInstallersFunc + GetSoftwareInstallersFuncInvoked bool + HasSelfServiceSoftwareInstallersFunc HasSelfServiceSoftwareInstallersFunc HasSelfServiceSoftwareInstallersFuncInvoked bool @@ -6369,13 +6374,20 @@ func (s *DataStore) CleanupUnusedSoftwareInstallers(ctx context.Context, softwar return s.CleanupUnusedSoftwareInstallersFunc(ctx, softwareInstallStore, removeCreatedBefore) } -func (s *DataStore) BatchSetSoftwareInstallers(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) { +func (s *DataStore) BatchSetSoftwareInstallers(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error { s.mu.Lock() s.BatchSetSoftwareInstallersFuncInvoked = true s.mu.Unlock() return s.BatchSetSoftwareInstallersFunc(ctx, tmID, installers) } +func (s *DataStore) GetSoftwareInstallers(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) { + s.mu.Lock() + s.GetSoftwareInstallersFuncInvoked = true + s.mu.Unlock() + return s.GetSoftwareInstallersFunc(ctx, tmID) +} + func (s *DataStore) HasSelfServiceSoftwareInstallers(ctx context.Context, platform string, teamID *uint) (bool, error) { s.mu.Lock() s.HasSelfServiceSoftwareInstallersFuncInvoked = true diff --git a/server/service/client_software.go b/server/service/client_software.go index 413e6dc7e9d8..60a0911093f4 100644 --- a/server/service/client_software.go +++ b/server/service/client_software.go @@ -1,7 +1,10 @@ package service import ( + "errors" + "fmt" "net/url" + "time" "github.com/fleetdm/fleet/v4/server/fleet" ) @@ -29,14 +32,38 @@ func (c *Client) ListSoftwareTitles(query string) ([]fleet.SoftwareTitleListResu } func (c *Client) ApplyNoTeamSoftwareInstallers(softwareInstallers []fleet.SoftwareInstallerPayload, opts fleet.ApplySpecOptions) ([]fleet.SoftwarePackageResponse, error) { - verb, path := "POST", "/api/latest/fleet/software/batch" query, err := url.ParseQuery(opts.RawQuery()) if err != nil { return nil, err } + return c.applySoftwareInstallers(softwareInstallers, query, opts.DryRun) +} + +func (c *Client) applySoftwareInstallers(softwareInstallers []fleet.SoftwareInstallerPayload, query url.Values, dryRun bool) ([]fleet.SoftwarePackageResponse, error) { + path := "/api/latest/fleet/software/batch" var resp batchSetSoftwareInstallersResponse - if err := c.authenticatedRequestWithQuery(map[string]interface{}{"software": softwareInstallers}, verb, path, &resp, query.Encode()); err != nil { + if err := c.authenticatedRequestWithQuery(map[string]interface{}{"software": softwareInstallers}, "POST", path, &resp, query.Encode()); err != nil { return nil, err } - return resp.Packages, nil + if dryRun && resp.RequestUUID == "" { + return nil, nil + } + + requestUUID := resp.RequestUUID + for { + var resp batchSetSoftwareInstallersResultResponse + if err := c.authenticatedRequestWithQuery(nil, "GET", path+"/"+requestUUID, &resp, query.Encode()); err != nil { + return nil, err + } + switch { + case resp.Status == fleet.BatchSetSoftwareInstallersStatusProcessing: + time.Sleep(5 * time.Second) + case resp.Status == fleet.BatchSetSoftwareInstallersStatusFailed: + return nil, errors.New(resp.Message) + case resp.Status == fleet.BatchSetSoftwareInstallersStatusCompleted: + return resp.Packages, nil + default: + return nil, fmt.Errorf("unknown status: %q", resp.Status) + } + } } diff --git a/server/service/client_teams.go b/server/service/client_teams.go index 5c5180a6b700..5d541e903c9b 100644 --- a/server/service/client_teams.go +++ b/server/service/client_teams.go @@ -94,17 +94,12 @@ func (c *Client) ApplyTeamScripts(tmName string, scripts []fleet.ScriptPayload, } func (c *Client) ApplyTeamSoftwareInstallers(tmName string, softwareInstallers []fleet.SoftwareInstallerPayload, opts fleet.ApplySpecOptions) ([]fleet.SoftwarePackageResponse, error) { - verb, path := "POST", "/api/latest/fleet/software/batch" query, err := url.ParseQuery(opts.RawQuery()) if err != nil { return nil, err } query.Add("team_name", tmName) - var resp batchSetSoftwareInstallersResponse - if err := c.authenticatedRequestWithQuery(map[string]interface{}{"software": softwareInstallers}, verb, path, &resp, query.Encode()); err != nil { - return nil, err - } - return resp.Packages, nil + return c.applySoftwareInstallers(softwareInstallers, query, opts.DryRun) } func (c *Client) ApplyTeamAppStoreAppsAssociation(tmName string, vppBatchPayload []fleet.VPPBatchPayload, opts fleet.ApplySpecOptions) error { diff --git a/server/service/handler.go b/server/service/handler.go index 21bdd2f7ed57..7012393952bc 100644 --- a/server/service/handler.go +++ b/server/service/handler.go @@ -381,7 +381,10 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC ue.DELETE("/api/_version_/fleet/software/titles/{title_id:[0-9]+}/available_for_install", deleteSoftwareInstallerEndpoint, deleteSoftwareInstallerRequest{}) ue.GET("/api/_version_/fleet/software/install/{install_uuid}/results", getSoftwareInstallResultsEndpoint, getSoftwareInstallResultsRequest{}) + // POST /api/_version_/fleet/software/batch is asynchronous, meaning it will start the process of software download+upload in the background + // and will return a request UUID to be used in GET /api/_version_/fleet/software/batch/{request_uuid} to query for the status of the operation. ue.POST("/api/_version_/fleet/software/batch", batchSetSoftwareInstallersEndpoint, batchSetSoftwareInstallersRequest{}) + ue.GET("/api/_version_/fleet/software/batch/{request_uuid}", batchSetSoftwareInstallersResultEndpoint, batchSetSoftwareInstallersResultRequest{}) // App store software ue.GET("/api/_version_/fleet/software/app_store_apps", getAppStoreAppsEndpoint, getAppStoreAppsRequest{}) diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go index 9255e95beff0..cb2a97966846 100644 --- a/server/service/integration_enterprise_test.go +++ b/server/service/integration_enterprise_test.go @@ -10903,6 +10903,10 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallers() { // create an HTTP server to host the software installer handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/ruby.deb" { + w.WriteHeader(http.StatusNotFound) + return + } file, err := os.Open(filepath.Join("testdata", "software-installers", "ruby.deb")) require.NoError(t, err) defer file.Close() @@ -10914,11 +10918,28 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallers() { srv := httptest.NewServer(handler) t.Cleanup(srv.Close) + // do a request with a URL that returns a 404. + softwareToInstall = []fleet.SoftwareInstallerPayload{ + {URL: srv.URL + "/not_found.pkg"}, + } + var batchResponse batchSetSoftwareInstallersResponse + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", tm.Name) + message := waitBatchSetSoftwareInstallersFailed(t, s, tm.Name, batchResponse.RequestUUID) + require.NotEmpty(t, message) + require.Contains(t, message, fmt.Sprintf("validation failed: software.url Couldn't edit software. URL (\"%s/not_found.pkg\") returned \"Not Found\". Please make sure that URLs are reachable from your Fleet server.", srv.URL)) + // do a request with a valid URL + rubyURL := srv.URL + "/ruby.deb" softwareToInstall = []fleet.SoftwareInstallerPayload{ - {URL: srv.URL}, + {URL: rubyURL}, } - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, "team_name", tm.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", tm.Name) + packages := waitBatchSetSoftwareInstallersCompleted(t, s, tm.Name, batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.Equal(t, rubyURL, packages[0].URL) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, tm.ID, *packages[0].TeamID) // TODO(roberto): test with a variety of response codes @@ -10929,7 +10950,7 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallers() { require.Len(t, titlesResp.SoftwareTitles, 1) // Check that the URL is set to software installers uploaded via batch. require.NotNil(t, titlesResp.SoftwareTitles[0].SoftwarePackage.PackageURL) - require.Equal(t, srv.URL, *titlesResp.SoftwareTitles[0].SoftwarePackage.PackageURL) + require.Equal(t, rubyURL, *titlesResp.SoftwareTitles[0].SoftwarePackage.PackageURL) // check that platform is set when the installer is created mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { @@ -10942,14 +10963,26 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallers() { }) // same payload doesn't modify anything - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, "team_name", tm.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", tm.Name) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, tm.Name, batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.Equal(t, rubyURL, packages[0].URL) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, tm.ID, *packages[0].TeamID) newTitlesResp := listSoftwareTitlesResponse{} s.DoJSON("GET", "/api/v1/fleet/software/titles", nil, http.StatusOK, &newTitlesResp, "available_for_install", "true", "team_id", strconv.Itoa(int(tm.ID))) require.Equal(t, titlesResp, newTitlesResp) // setting self-service to true updates the software title metadata softwareToInstall[0].SelfService = true - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, "team_name", tm.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", tm.Name) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, tm.Name, batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.Equal(t, rubyURL, packages[0].URL) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, tm.ID, *packages[0].TeamID) newTitlesResp = listSoftwareTitlesResponse{} s.DoJSON("GET", "/api/v1/fleet/software/titles", nil, http.StatusOK, &newTitlesResp, "available_for_install", "true", "team_id", strconv.Itoa(int(tm.ID))) titlesResp.SoftwareTitles[0].SoftwarePackage.SelfService = ptr.Bool(true) @@ -10957,7 +10990,9 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallers() { // empty payload cleans the software items softwareToInstall = []fleet.SoftwareInstallerPayload{} - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, "team_name", tm.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", tm.Name) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, tm.Name, batchResponse.RequestUUID) + require.Empty(t, packages) titlesResp = listSoftwareTitlesResponse{} s.DoJSON("GET", "/api/v1/fleet/software/titles", nil, http.StatusOK, &titlesResp, "available_for_install", "true", "team_id", strconv.Itoa(int(tm.ID))) require.Equal(t, 0, titlesResp.Count) @@ -10967,9 +11002,14 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallers() { // Do a request with a valid URL with no team ////////////////////////// softwareToInstall = []fleet.SoftwareInstallerPayload{ - {URL: srv.URL}, + {URL: rubyURL}, } - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, "", batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.Equal(t, rubyURL, packages[0].URL) + require.Nil(t, packages[0].TeamID) // check the application status on team 0 titlesResp = listSoftwareTitlesResponse{} @@ -10978,14 +11018,24 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallers() { require.Len(t, titlesResp.SoftwareTitles, 1) // same payload doesn't modify anything - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, "", batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.Equal(t, rubyURL, packages[0].URL) + require.Nil(t, packages[0].TeamID) newTitlesResp = listSoftwareTitlesResponse{} s.DoJSON("GET", "/api/v1/fleet/software/titles", nil, http.StatusOK, &newTitlesResp, "available_for_install", "true", "team_id", strconv.Itoa(int(0))) require.Equal(t, titlesResp, newTitlesResp) // setting self-service to true updates the software title metadata softwareToInstall[0].SelfService = true - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, "", batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.Equal(t, rubyURL, packages[0].URL) + require.Nil(t, packages[0].TeamID) newTitlesResp = listSoftwareTitlesResponse{} s.DoJSON("GET", "/api/v1/fleet/software/titles", nil, http.StatusOK, &newTitlesResp, "available_for_install", "true", "team_id", strconv.Itoa(int(0))) titlesResp.SoftwareTitles[0].SoftwarePackage.SelfService = ptr.Bool(true) @@ -10993,13 +11043,50 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallers() { // empty payload cleans the software items softwareToInstall = []fleet.SoftwareInstallerPayload{} - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, "", batchResponse.RequestUUID) + require.Empty(t, packages) titlesResp = listSoftwareTitlesResponse{} s.DoJSON("GET", "/api/v1/fleet/software/titles", nil, http.StatusOK, &titlesResp, "available_for_install", "true", "team_id", strconv.Itoa(int(0))) require.Equal(t, 0, titlesResp.Count) require.Len(t, titlesResp.SoftwareTitles, 0) } +func waitBatchSetSoftwareInstallersCompleted(t *testing.T, s *integrationEnterpriseTestSuite, teamName string, requestUUID string) []fleet.SoftwarePackageResponse { + timeout := time.After(1 * time.Minute) + for { + var batchResultResponse batchSetSoftwareInstallersResultResponse + s.DoJSON("GET", "/api/latest/fleet/software/batch/"+requestUUID, nil, http.StatusOK, &batchResultResponse, "team_name", teamName) + if batchResultResponse.Status == fleet.BatchSetSoftwareInstallersStatusCompleted { + return batchResultResponse.Packages + } + select { + case <-timeout: + t.Fatalf("timeout: %s, %s", teamName, requestUUID) + case <-time.After(500 * time.Millisecond): + // OK, continue + } + } +} + +func waitBatchSetSoftwareInstallersFailed(t *testing.T, s *integrationEnterpriseTestSuite, teamName string, requestUUID string) string { + timeout := time.After(1 * time.Minute) + for { + var batchResultResponse batchSetSoftwareInstallersResultResponse + s.DoJSON("GET", "/api/latest/fleet/software/batch/"+requestUUID, nil, http.StatusOK, &batchResultResponse, "team_name", teamName) + if batchResultResponse.Status == fleet.BatchSetSoftwareInstallersStatusFailed { + require.Empty(t, batchResultResponse.Packages) + return batchResultResponse.Message + } + select { + case <-timeout: + t.Fatalf("timeout: %s, %s", teamName, requestUUID) + case <-time.After(500 * time.Millisecond): + // OK, continue + } + } +} + func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersSideEffects() { t := s.T() @@ -11030,7 +11117,14 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersSideEffec softwareToInstall := []fleet.SoftwareInstallerPayload{ {URL: srv.URL}, } - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, "team_name", tm.Name) + var batchResponse batchSetSoftwareInstallersResponse + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", tm.Name) + packages := waitBatchSetSoftwareInstallersCompleted(t, s, tm.Name, batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, tm.ID, *packages[0].TeamID) + require.Equal(t, srv.URL, packages[0].URL) titlesResp := listSoftwareTitlesResponse{} s.DoJSON("GET", "/api/v1/fleet/software/titles", nil, http.StatusOK, &titlesResp, "available_for_install", "true", "team_id", strconv.Itoa(int(tm.ID))) titleResponse := getSoftwareTitleResponse{} @@ -11068,7 +11162,13 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersSideEffec // Switch self-service flag softwareToInstall[0].SelfService = true - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, "team_name", tm.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", tm.Name) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, tm.Name, batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, tm.ID, *packages[0].TeamID) + require.Equal(t, srv.URL, packages[0].URL) newTitlesResp := listSoftwareTitlesResponse{} s.DoJSON("GET", "/api/v1/fleet/software/titles", nil, http.StatusOK, &newTitlesResp, "available_for_install", "true", "team_id", strconv.Itoa(int(tm.ID))) require.Equal(t, true, *newTitlesResp.SoftwareTitles[0].SoftwarePackage.SelfService) @@ -11082,7 +11182,13 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersSideEffec withUpdatedPreinstallQuery := []fleet.SoftwareInstallerPayload{ {URL: srv.URL, PreInstallQuery: "SELECT * FROM os_version"}, } - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: withUpdatedPreinstallQuery}, http.StatusOK, "team_name", tm.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: withUpdatedPreinstallQuery}, http.StatusOK, &batchResponse, "team_name", tm.Name) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, tm.Name, batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, tm.ID, *packages[0].TeamID) + require.Equal(t, srv.URL, packages[0].URL) titleResponse = getSoftwareTitleResponse{} s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/software/titles/%d", newTitlesResp.SoftwareTitles[0].ID), nil, http.StatusOK, &titleResponse, "team_id", strconv.Itoa(int(tm.ID))) require.Equal(t, "SELECT * FROM os_version", titleResponse.SoftwareTitle.SoftwarePackage.PreInstallQuery) @@ -11119,7 +11225,13 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersSideEffec withUpdatedInstallScript := []fleet.SoftwareInstallerPayload{ {URL: srv.URL, InstallScript: "apt install ruby"}, } - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: withUpdatedInstallScript}, http.StatusOK, "team_name", tm.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: withUpdatedInstallScript}, http.StatusOK, &batchResponse, "team_name", tm.Name) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, tm.Name, batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, tm.ID, *packages[0].TeamID) + require.Equal(t, srv.URL, packages[0].URL) // ensure install count is the same, and uploaded_at hasn't changed s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/software/titles/%d", newTitlesResp.SoftwareTitles[0].ID), nil, http.StatusOK, &titleResponse, "team_id", strconv.Itoa(int(tm.ID))) @@ -11134,7 +11246,13 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersSideEffec trailer = " " // add a character to the response for the installer HTTP call to ensure the file hashes differently // update package - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: withUpdatedInstallScript}, http.StatusOK, "team_name", tm.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: withUpdatedInstallScript}, http.StatusOK, &batchResponse, "team_name", tm.Name) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, tm.Name, batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, tm.ID, *packages[0].TeamID) + require.Equal(t, srv.URL, packages[0].URL) // ensure install count is zeroed and uploaded_at HAS changed s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/software/titles/%d", newTitlesResp.SoftwareTitles[0].ID), nil, http.StatusOK, &titleResponse, "team_id", strconv.Itoa(int(tm.ID))) @@ -11198,7 +11316,15 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersWithPolic URL: srv.URL + "/ruby.deb", }, } - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, "team_name", team1.Name) + var batchResponse batchSetSoftwareInstallersResponse + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", team1.Name) + packages := waitBatchSetSoftwareInstallersCompleted(t, s, team1.Name, batchResponse.RequestUUID) + require.Len(t, packages, 1) + require.NotNil(t, packages[0].TitleID) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, team1.ID, *packages[0].TeamID) + require.Equal(t, srv.URL+"/ruby.deb", packages[0].URL) + // team2 has dummy_installer.pkg and ruby.deb. softwareToInstall = []fleet.SoftwareInstallerPayload{ { @@ -11208,7 +11334,20 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersWithPolic URL: srv.URL + "/ruby.deb", }, } - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, "team_name", team2.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", team2.Name) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, team2.Name, batchResponse.RequestUUID) + sort.Slice(packages, func(i, j int) bool { + return packages[i].URL < packages[j].URL + }) + require.Len(t, packages, 2) + require.NotNil(t, packages[0].TitleID) + require.NotNil(t, packages[0].TeamID) + require.Equal(t, team2.ID, *packages[0].TeamID) + require.Equal(t, srv.URL+"/dummy_installer.pkg", packages[0].URL) + require.NotNil(t, packages[1].TitleID) + require.NotNil(t, packages[1].TeamID) + require.Equal(t, team2.ID, *packages[1].TeamID) + require.Equal(t, srv.URL+"/ruby.deb", packages[1].URL) // Associate ruby.deb to policy1Team1. resp := listSoftwareTitlesResponse{} @@ -11238,7 +11377,9 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersWithPolic // Get rid of all installers in team1. softwareToInstall = []fleet.SoftwareInstallerPayload{} - s.Do("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, "team_name", team1.Name) + s.DoJSON("POST", "/api/latest/fleet/software/batch", batchSetSoftwareInstallersRequest{Software: softwareToInstall}, http.StatusOK, &batchResponse, "team_name", team1.Name) + packages = waitBatchSetSoftwareInstallersCompleted(t, s, team1.Name, batchResponse.RequestUUID) + require.Len(t, packages, 0) // policy1Team1 should not be associated to any installer. policy1Team1, err = s.ds.Policy(ctx, policy1Team1.ID) diff --git a/server/service/redis_key_value/redis_key_value.go b/server/service/redis_key_value/redis_key_value.go new file mode 100644 index 000000000000..010c24c19cc0 --- /dev/null +++ b/server/service/redis_key_value/redis_key_value.go @@ -0,0 +1,58 @@ +// Package redis_key_value implements a most basic SET & GET key/value store +// where both the key and the value are strings. +package redis_key_value + +import ( + "context" + "errors" + "time" + + "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" + "github.com/fleetdm/fleet/v4/server/datastore/redis" + "github.com/fleetdm/fleet/v4/server/fleet" + redigo "github.com/gomodule/redigo/redis" +) + +// RedisKeyValue is a basic key/value store with SET and GET operations +// Items are removed via expiration (defined in the SET operation). +type RedisKeyValue struct { + pool fleet.RedisPool + testPrefix string // for tests, the key prefix to use to avoid conflicts +} + +// New creates a new RedisKeyValue store. +func New(pool fleet.RedisPool) *RedisKeyValue { + return &RedisKeyValue{pool: pool} +} + +// prefix is used to not collide with other key domains (like live queries or calendar locks). +const prefix = "key_value_" + +// Set creates or overrides the given key with the given value. +// Argument expireTime is used to set the expiration of the item +// (when updating, the expiration of the item is updated). +func (r *RedisKeyValue) Set(ctx context.Context, key string, value string, expireTime time.Duration) error { + conn := redis.ConfigureDoer(r.pool, r.pool.Get()) + defer conn.Close() + + if _, err := redigo.String(conn.Do("SET", r.testPrefix+prefix+key, value, "PX", expireTime.Milliseconds())); err != nil { + return ctxerr.Wrap(ctx, err, "redis failed to set") + } + return nil +} + +// Get returns the value for a given key. +// It returns (nil, nil) if the key doesn't exist. +func (r *RedisKeyValue) Get(ctx context.Context, key string) (*string, error) { + conn := redis.ConfigureDoer(r.pool, r.pool.Get()) + defer conn.Close() + + res, err := redigo.String(conn.Do("GET", r.testPrefix+prefix+key)) + if errors.Is(err, redigo.ErrNil) { + return nil, nil + } + if err != nil { + return nil, ctxerr.Wrap(ctx, err, "redis failed to get") + } + return &res, nil +} diff --git a/server/service/redis_key_value/redis_key_value_test.go b/server/service/redis_key_value/redis_key_value_test.go new file mode 100644 index 000000000000..5f410e4a4918 --- /dev/null +++ b/server/service/redis_key_value/redis_key_value_test.go @@ -0,0 +1,92 @@ +package redis_key_value + +import ( + "context" + "testing" + "time" + + "github.com/fleetdm/fleet/v4/server/datastore/redis/redistest" + "github.com/fleetdm/fleet/v4/server/fleet" + "github.com/fleetdm/fleet/v4/server/test" + "github.com/stretchr/testify/require" +) + +func TestRedisKeyValue(t *testing.T) { + for _, f := range []func(*testing.T, *RedisKeyValue){ + testSetGet, + } { + t.Run(test.FunctionName(f), func(t *testing.T) { + t.Run("standalone", func(t *testing.T) { + kv := setupRedis(t, false, false) + f(t, kv) + }) + t.Run("cluster", func(t *testing.T) { + kv := setupRedis(t, true, true) + f(t, kv) + }) + }) + } +} + +func setupRedis(t testing.TB, cluster, redir bool) *RedisKeyValue { + pool := redistest.SetupRedis(t, t.Name(), cluster, redir, true) + return newRedisKeyValueForTest(t, pool) +} + +type testName interface { + Name() string +} + +func newRedisKeyValueForTest(t testName, pool fleet.RedisPool) *RedisKeyValue { + return &RedisKeyValue{ + pool: pool, + testPrefix: t.Name() + ":", + } +} + +func testSetGet(t *testing.T, kv *RedisKeyValue) { + ctx := context.Background() + + result, err := kv.Get(ctx, "foo") + require.NoError(t, err) + require.Nil(t, result) + + err = kv.Set(ctx, "foo", "bar", 5*time.Second) + require.NoError(t, err) + + result, err = kv.Get(ctx, "foo") + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, "bar", *result) + + err = kv.Set(ctx, "foo", "zoo", 5*time.Second) + require.NoError(t, err) + + result, err = kv.Get(ctx, "foo") + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, "zoo", *result) + + err = kv.Set(ctx, "boo", "bar", 2*time.Second) + require.NoError(t, err) + result, err = kv.Get(ctx, "boo") + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, "bar", *result) + + time.Sleep(3 * time.Second) + result, err = kv.Get(ctx, "boo") + require.NoError(t, err) + require.Nil(t, result) + + // Updating an item, updates the expiration time. + err = kv.Set(ctx, "test", "foo", 2*time.Second) + require.NoError(t, err) + err = kv.Set(ctx, "test", "foo", 10*time.Second) + require.NoError(t, err) + time.Sleep(5 * time.Second) + result, err = kv.Get(ctx, "test") + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, "foo", *result) +} diff --git a/server/service/software_installers.go b/server/service/software_installers.go index 0542d769c805..b10b6a6f4c7f 100644 --- a/server/service/software_installers.go +++ b/server/service/software_installers.go @@ -546,27 +546,64 @@ type batchSetSoftwareInstallersRequest struct { } type batchSetSoftwareInstallersResponse struct { - Packages []fleet.SoftwarePackageResponse `json:"packages"` - Err error `json:"error,omitempty"` + RequestUUID string `json:"request_uuid"` + Err error `json:"error,omitempty"` } func (r batchSetSoftwareInstallersResponse) error() error { return r.Err } func batchSetSoftwareInstallersEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (errorer, error) { req := request.(*batchSetSoftwareInstallersRequest) - packages, err := svc.BatchSetSoftwareInstallers(ctx, req.TeamName, req.Software, req.DryRun) + requestUUID, err := svc.BatchSetSoftwareInstallers(ctx, req.TeamName, req.Software, req.DryRun) if err != nil { return batchSetSoftwareInstallersResponse{Err: err}, nil } - return batchSetSoftwareInstallersResponse{Packages: packages}, nil + return batchSetSoftwareInstallersResponse{RequestUUID: requestUUID}, nil } -func (svc *Service) BatchSetSoftwareInstallers(ctx context.Context, tmName string, payloads []fleet.SoftwareInstallerPayload, dryRun bool) ([]fleet.SoftwarePackageResponse, error) { +func (svc *Service) BatchSetSoftwareInstallers(ctx context.Context, tmName string, payloads []fleet.SoftwareInstallerPayload, dryRun bool) (string, error) { // skipauth: No authorization check needed due to implementation returning // only license error. svc.authz.SkipAuthorization(ctx) - return nil, fleet.ErrMissingLicense + return "", fleet.ErrMissingLicense +} + +type batchSetSoftwareInstallersResultRequest struct { + RequestUUID string `url:"request_uuid"` + TeamName string `query:"team_name,optional"` + DryRun bool `query:"dry_run,optional"` // if true, apply validation but do not save changes +} + +type batchSetSoftwareInstallersResultResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Packages []fleet.SoftwarePackageResponse `json:"packages"` + + Err error `json:"error,omitempty"` +} + +func (r batchSetSoftwareInstallersResultResponse) error() error { return r.Err } + +func batchSetSoftwareInstallersResultEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (errorer, error) { + req := request.(*batchSetSoftwareInstallersResultRequest) + status, message, packages, err := svc.GetBatchSetSoftwareInstallersResult(ctx, req.TeamName, req.RequestUUID, req.DryRun) + if err != nil { + return batchSetSoftwareInstallersResultResponse{Err: err}, nil + } + return batchSetSoftwareInstallersResultResponse{ + Status: status, + Message: message, + Packages: packages, + }, nil +} + +func (svc *Service) GetBatchSetSoftwareInstallersResult(ctx context.Context, tmName string, requestUUID string, dryRun bool) (string, string, []fleet.SoftwarePackageResponse, error) { + // skipauth: No authorization check needed due to implementation returning + // only license error. + svc.authz.SkipAuthorization(ctx) + + return "", "", nil, fleet.ErrMissingLicense } ////////////////////////////////////////////////////////////////////////////// diff --git a/server/service/testing_utils.go b/server/service/testing_utils.go index 674f6c4441a7..7e5937c56c1e 100644 --- a/server/service/testing_utils.go +++ b/server/service/testing_utils.go @@ -34,6 +34,7 @@ import ( "github.com/fleetdm/fleet/v4/server/ptr" "github.com/fleetdm/fleet/v4/server/service/async" "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" @@ -72,6 +73,7 @@ func newTestServiceWithConfig(t *testing.T, ds fleet.Datastore, fleetConfig conf softwareInstallStore fleet.SoftwareInstallerStore bootstrapPackageStore fleet.MDMBootstrapPackageStore distributedLock fleet.Lock + keyValueStore fleet.KeyValueStore ) if len(opts) > 0 { if opts[0].Clock != nil { @@ -79,6 +81,10 @@ func newTestServiceWithConfig(t *testing.T, ds fleet.Datastore, fleetConfig conf } } + if len(opts) > 0 && opts[0].KeyValueStore != nil { + keyValueStore = opts[0].KeyValueStore + } + task := async.NewTask(ds, nil, c, config.OsqueryConfig{}) if len(opts) > 0 { if opts[0].Task != nil { @@ -99,6 +105,7 @@ func newTestServiceWithConfig(t *testing.T, ds fleet.Datastore, fleetConfig conf 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 @@ -203,6 +210,7 @@ func newTestServiceWithConfig(t *testing.T, ds fleet.Datastore, fleetConfig conf softwareInstallStore, bootstrapPackageStore, distributedLock, + keyValueStore, ) if err != nil { panic(err) @@ -317,6 +325,7 @@ type TestServerOpts struct { NoCacheDatastore bool SoftwareInstallStore fleet.SoftwareInstallerStore BootstrapPackageStore fleet.MDMBootstrapPackageStore + KeyValueStore fleet.KeyValueStore } func RunServerForTestsWithDS(t *testing.T, ds fleet.Datastore, opts ...*TestServerOpts) (map[string]fleet.User, *httptest.Server) { From 92d3b708d7114f2f86ce080e9c5131aba13ff39e Mon Sep 17 00:00:00 2001 From: Brock Walters <153771548+nonpunctual@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:04:37 -0400 Subject: [PATCH 28/81] Update discovering-chrome-ai-using-fleet.md (#22268) It's 1 letter. I waited days to do this. :) --- articles/discovering-chrome-ai-using-fleet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/discovering-chrome-ai-using-fleet.md b/articles/discovering-chrome-ai-using-fleet.md index 126894c5652d..3c39b370b34a 100644 --- a/articles/discovering-chrome-ai-using-fleet.md +++ b/articles/discovering-chrome-ai-using-fleet.md @@ -50,7 +50,7 @@ In this case, `jq` is used to locate and read the value of the `tab_organization ### Step 3: Query the JSON file with Fleet -To detect Chrome AI features in Fleet, use SQL query like the following: +To detect Chrome AI features in Fleet, use a SQL query like the following: ``` SELECT fullkey,path FROM parse_json WHERE path LIKE '/Users/%/Library/Application Support/Google/Chrome/Default/Preferences' AND fullkey='optimization_guide/tab_organization_setting_state'; From eeb0579763dcc048bc62d051ea7fbbc1f2a80372 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:16:41 -0400 Subject: [PATCH 29/81] Dogfood: remove "Explore data (fleetdm.com)" team (#22246) --- it-and-security/lib/explore-data.queries.yml | 3210 ------------------ it-and-security/teams/explore-data.yml | 44 - 2 files changed, 3254 deletions(-) delete mode 100644 it-and-security/lib/explore-data.queries.yml delete mode 100644 it-and-security/teams/explore-data.yml diff --git a/it-and-security/lib/explore-data.queries.yml b/it-and-security/lib/explore-data.queries.yml deleted file mode 100644 index deb070644dc7..000000000000 --- a/it-and-security/lib/explore-data.queries.yml +++ /dev/null @@ -1,3210 +0,0 @@ -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - account_policy_data' - observer_can_run: false - platform: "" - query: SELECT * FROM account_policy_data; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ad_config' - observer_can_run: false - platform: "" - query: SELECT * FROM ad_config; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - alf' - observer_can_run: false - platform: "" - query: SELECT * FROM alf; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - alf_exceptions' - observer_can_run: false - platform: "" - query: SELECT * FROM alf_exceptions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - alf_explicit_auths' - observer_can_run: false - platform: "" - query: SELECT * FROM alf_explicit_auths; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - apfs_physical_stores' - observer_can_run: false - platform: "" - query: SELECT * FROM apfs_physical_stores; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - apfs_volumes' - observer_can_run: false - platform: "" - query: SELECT * FROM apfs_volumes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - app_icons' - observer_can_run: false - platform: "" - query: SELECT * FROM app_icons; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - app_schemes' - observer_can_run: false - platform: "" - query: SELECT * FROM app_schemes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - apparmor_events' - observer_can_run: false - platform: "" - query: SELECT * FROM apparmor_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - apparmor_profiles' - observer_can_run: false - platform: "" - query: SELECT * FROM apparmor_profiles; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - appcompat_shims' - observer_can_run: false - platform: "" - query: SELECT * FROM appcompat_shims; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - apps' - observer_can_run: false - platform: "" - query: SELECT * FROM apps; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - apt_sources' - observer_can_run: false - platform: "" - query: SELECT * FROM apt_sources; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - arp_cache' - observer_can_run: false - platform: "" - query: SELECT * FROM arp_cache; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - asl' - observer_can_run: false - platform: "" - query: SELECT * FROM asl; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - atom_packages' - observer_can_run: false - platform: "" - query: SELECT * FROM atom_packages; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - augeas' - observer_can_run: false - platform: "" - query: SELECT * FROM augeas; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - authdb' - observer_can_run: false - platform: "" - query: SELECT * FROM authdb; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - authenticode' - observer_can_run: false - platform: "" - query: SELECT * FROM authenticode; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - authorization_mechanisms' - observer_can_run: false - platform: "" - query: SELECT * FROM authorization_mechanisms; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - authorizations' - observer_can_run: false - platform: "" - query: SELECT * FROM authorizations; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - authorized_keys' - observer_can_run: false - platform: "" - query: SELECT * FROM authorized_keys; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - autoexec' - observer_can_run: false - platform: "" - query: SELECT * FROM autoexec; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - azure_instance_metadata' - observer_can_run: false - platform: "" - query: SELECT * FROM azure_instance_metadata; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - azure_instance_tags' - observer_can_run: false - platform: "" - query: SELECT * FROM azure_instance_tags; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - background_activities_moderator' - observer_can_run: false - platform: "" - query: SELECT * FROM background_activities_moderator; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - battery' - observer_can_run: false - platform: "" - query: SELECT * FROM battery; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - bitlocker_info' - observer_can_run: false - platform: "" - query: SELECT * FROM bitlocker_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - block_devices' - observer_can_run: false - platform: "" - query: SELECT * FROM block_devices; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - bpf_process_events' - observer_can_run: false - platform: "" - query: SELECT * FROM bpf_process_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - bpf_socket_events' - observer_can_run: false - platform: "" - query: SELECT * FROM bpf_socket_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - carbon_black_info' - observer_can_run: false - platform: "" - query: SELECT * FROM carbon_black_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - carves' - observer_can_run: false - platform: "" - query: SELECT * FROM carves; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - certificates' - observer_can_run: false - platform: "" - query: SELECT * FROM certificates; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - chassis_info' - observer_can_run: false - platform: "" - query: SELECT * FROM chassis_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - chocolatey_packages' - observer_can_run: false - platform: "" - query: SELECT * FROM chocolatey_packages; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - chrome_extension_content_scripts' - observer_can_run: false - platform: "" - query: SELECT * FROM chrome_extension_content_scripts; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - chrome_extensions' - observer_can_run: false - platform: "" - query: SELECT * FROM chrome_extensions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - cis_audit' - observer_can_run: false - platform: "" - query: SELECT * FROM cis_audit; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - connected_displays' - observer_can_run: false - platform: "" - query: SELECT * FROM connected_displays; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - connectivity' - observer_can_run: false - platform: "" - query: SELECT * FROM connectivity; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - corestorage_logical_volume_families' - observer_can_run: false - platform: "" - query: SELECT * FROM corestorage_logical_volume_families; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - corestorage_logical_volumes' - observer_can_run: false - platform: "" - query: SELECT * FROM corestorage_logical_volumes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - cpu_info' - observer_can_run: false - platform: "" - query: SELECT * FROM cpu_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - cpu_time' - observer_can_run: false - platform: "" - query: SELECT * FROM cpu_time; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - cpuid' - observer_can_run: false - platform: "" - query: SELECT * FROM cpuid; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - crashes' - observer_can_run: false - platform: "" - query: SELECT * FROM crashes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - crontab' - observer_can_run: false - platform: "" - query: SELECT * FROM crontab; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - cryptoinfo' - observer_can_run: false - platform: "" - query: SELECT * FROM cryptoinfo; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - cryptsetup_status' - observer_can_run: false - platform: "" - query: SELECT * FROM cryptsetup_status; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - csrutil_info' - observer_can_run: false - platform: "" - query: SELECT * FROM csrutil_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - cups_destinations' - observer_can_run: false - platform: "" - query: SELECT * FROM cups_destinations; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - cups_jobs' - observer_can_run: false - platform: "" - query: SELECT * FROM cups_jobs; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - curl' - observer_can_run: false - platform: "" - query: SELECT * FROM curl; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - curl_certificate' - observer_can_run: false - platform: "" - query: SELECT * FROM curl_certificate; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - deb_packages' - observer_can_run: false - platform: "" - query: SELECT * FROM deb_packages; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - default_environment' - observer_can_run: false - platform: "" - query: SELECT * FROM default_environment; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - device_file' - observer_can_run: false - platform: "" - query: SELECT * FROM device_file; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - device_firmware' - observer_can_run: false - platform: "" - query: SELECT * FROM device_firmware; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - device_hash' - observer_can_run: false - platform: "" - query: SELECT * FROM device_hash; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - device_partitions' - observer_can_run: false - platform: "" - query: SELECT * FROM device_partitions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - disk_encryption' - observer_can_run: false - platform: "" - query: SELECT * FROM disk_encryption; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - disk_events' - observer_can_run: false - platform: "" - query: SELECT * FROM disk_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - disk_info' - observer_can_run: false - platform: "" - query: SELECT * FROM disk_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - dns_cache' - observer_can_run: false - platform: "" - query: SELECT * FROM dns_cache; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - dns_resolvers' - observer_can_run: false - platform: "" - query: SELECT * FROM dns_resolvers; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_container_envs' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_container_envs; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_container_fs_changes' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_container_fs_changes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_container_labels' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_container_labels; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_container_mounts' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_container_mounts; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_container_networks' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_container_networks; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_container_ports' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_container_ports; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_container_processes' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_container_processes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_container_stats' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_container_stats; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_containers' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_containers; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_image_history' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_image_history; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_image_labels' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_image_labels; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_image_layers' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_image_layers; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_images' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_images; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_info' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_network_labels' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_network_labels; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_networks' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_networks; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_version' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_version; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_volume_labels' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_volume_labels; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - docker_volumes' - observer_can_run: false - platform: "" - query: SELECT * FROM docker_volumes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - drivers' - observer_can_run: false - platform: "" - query: SELECT * FROM drivers; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - dscl' - observer_can_run: false - platform: "" - query: SELECT * FROM dscl; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ec2_instance_metadata' - observer_can_run: false - platform: "" - query: SELECT * FROM ec2_instance_metadata; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ec2_instance_tags' - observer_can_run: false - platform: "" - query: SELECT * FROM ec2_instance_tags; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - es_process_events' - observer_can_run: false - platform: "" - query: SELECT * FROM es_process_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - es_process_file_events' - observer_can_run: false - platform: "" - query: SELECT * FROM es_process_file_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - etc_hosts' - observer_can_run: false - platform: "" - query: SELECT * FROM etc_hosts; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - etc_protocols' - observer_can_run: false - platform: "" - query: SELECT * FROM etc_protocols; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - etc_services' - observer_can_run: false - platform: "" - query: SELECT * FROM etc_services; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - event_taps' - observer_can_run: false - platform: "" - query: SELECT * FROM event_taps; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - extended_attributes' - observer_can_run: false - platform: "" - query: SELECT * FROM extended_attributes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - falcon_kernel_check' - observer_can_run: false - platform: "" - query: SELECT * FROM falcon_kernel_check; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - falconctl_options' - observer_can_run: false - platform: "" - query: SELECT * FROM falconctl_options; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - fan_speed_sensors' - observer_can_run: false - platform: "" - query: SELECT * FROM fan_speed_sensors; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - file' - observer_can_run: false - platform: "" - query: SELECT * FROM file; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - file_events' - observer_can_run: false - platform: "" - query: SELECT * FROM file_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - file_lines' - observer_can_run: false - platform: "" - query: SELECT * FROM file_lines; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - filevault_prk' - observer_can_run: false - platform: "" - query: SELECT * FROM filevault_prk; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - filevault_status' - observer_can_run: false - platform: "" - query: SELECT * FROM filevault_status; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - filevault_users' - observer_can_run: false - platform: "" - query: SELECT * FROM filevault_users; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - find_cmd' - observer_can_run: false - platform: "" - query: SELECT * FROM find_cmd; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - firefox_addons' - observer_can_run: false - platform: "" - query: SELECT * FROM firefox_addons; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - firefox_preferences' - observer_can_run: false - platform: "" - query: SELECT * FROM firefox_preferences; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - firmware_eficheck_integrity_check' - observer_can_run: false - platform: "" - query: SELECT * FROM firmware_eficheck_integrity_check; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - firmwarepasswd' - observer_can_run: false - platform: "" - query: SELECT * FROM firmwarepasswd; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - gatekeeper' - observer_can_run: false - platform: "" - query: SELECT * FROM gatekeeper; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - gatekeeper_approved_apps' - observer_can_run: false - platform: "" - query: SELECT * FROM gatekeeper_approved_apps; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - geolocation' - observer_can_run: false - platform: "" - query: SELECT * FROM geolocation; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - google_chrome_profiles' - observer_can_run: false - platform: "" - query: SELECT * FROM google_chrome_profiles; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - groups' - observer_can_run: false - platform: "" - query: SELECT * FROM groups; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - hardware_events' - observer_can_run: false - platform: "" - query: SELECT * FROM hardware_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - hash' - observer_can_run: false - platform: "" - query: SELECT * FROM hash; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - homebrew_packages' - observer_can_run: false - platform: "" - query: SELECT * FROM homebrew_packages; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - hvci_status' - observer_can_run: false - platform: "" - query: SELECT * FROM hvci_status; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ibridge_info' - observer_can_run: false - platform: "" - query: SELECT * FROM ibridge_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - icloud_private_relay' - observer_can_run: false - platform: "" - query: SELECT * FROM icloud_private_relay; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ie_extensions' - observer_can_run: false - platform: "" - query: SELECT * FROM ie_extensions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - intel_me_info' - observer_can_run: false - platform: "" - query: SELECT * FROM intel_me_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - interface_addresses' - observer_can_run: false - platform: "" - query: SELECT * FROM interface_addresses; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - interface_details' - observer_can_run: false - platform: "" - query: SELECT * FROM interface_details; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - interface_ipv6' - observer_can_run: false - platform: "" - query: SELECT * FROM interface_ipv6; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - iokit_devicetree' - observer_can_run: false - platform: "" - query: SELECT * FROM iokit_devicetree; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - iokit_registry' - observer_can_run: false - platform: "" - query: SELECT * FROM iokit_registry; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ioreg' - observer_can_run: false - platform: "" - query: SELECT * FROM ioreg; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - kernel_extensions' - observer_can_run: false - platform: "" - query: SELECT * FROM kernel_extensions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - kernel_info' - observer_can_run: false - platform: "" - query: SELECT * FROM kernel_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - kernel_keys' - observer_can_run: false - platform: "" - query: SELECT * FROM kernel_keys; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - kernel_modules' - observer_can_run: false - platform: "" - query: SELECT * FROM kernel_modules; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - kernel_panics' - observer_can_run: false - platform: "" - query: SELECT * FROM kernel_panics; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - keychain_acls' - observer_can_run: false - platform: "" - query: SELECT * FROM keychain_acls; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - keychain_items' - observer_can_run: false - platform: "" - query: SELECT * FROM keychain_items; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - known_hosts' - observer_can_run: false - platform: "" - query: SELECT * FROM known_hosts; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - kva_speculative_info' - observer_can_run: false - platform: "" - query: SELECT * FROM kva_speculative_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - last' - observer_can_run: false - platform: "" - query: SELECT * FROM last; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - launchd' - observer_can_run: false - platform: "" - query: SELECT * FROM launchd; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - launchd_overrides' - observer_can_run: false - platform: "" - query: SELECT * FROM launchd_overrides; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - listening_ports' - observer_can_run: false - platform: "" - query: SELECT * FROM listening_ports; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - load_average' - observer_can_run: false - platform: "" - query: SELECT * FROM load_average; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - location_services' - observer_can_run: false - platform: "" - query: SELECT * FROM location_services; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - logged_in_users' - observer_can_run: false - platform: "" - query: SELECT * FROM logged_in_users; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - logical_drives' - observer_can_run: false - platform: "" - query: SELECT * FROM logical_drives; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - logon_sessions' - observer_can_run: false - platform: "" - query: SELECT * FROM logon_sessions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - lxd_certificates' - observer_can_run: false - platform: "" - query: SELECT * FROM lxd_certificates; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - lxd_cluster' - observer_can_run: false - platform: "" - query: SELECT * FROM lxd_cluster; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - lxd_cluster_members' - observer_can_run: false - platform: "" - query: SELECT * FROM lxd_cluster_members; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - lxd_images' - observer_can_run: false - platform: "" - query: SELECT * FROM lxd_images; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - lxd_instance_config' - observer_can_run: false - platform: "" - query: SELECT * FROM lxd_instance_config; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - lxd_instance_devices' - observer_can_run: false - platform: "" - query: SELECT * FROM lxd_instance_devices; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - lxd_instances' - observer_can_run: false - platform: "" - query: SELECT * FROM lxd_instances; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - lxd_networks' - observer_can_run: false - platform: "" - query: SELECT * FROM lxd_networks; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - lxd_storage_pools' - observer_can_run: false - platform: "" - query: SELECT * FROM lxd_storage_pools; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - macadmins_unified_log' - observer_can_run: false - platform: "" - query: SELECT * FROM macadmins_unified_log; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - macos_profiles' - observer_can_run: false - platform: "" - query: SELECT * FROM macos_profiles; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - macos_rsr' - observer_can_run: false - platform: "" - query: SELECT * FROM macos_rsr; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - magic' - observer_can_run: false - platform: "" - query: SELECT * FROM magic; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - managed_policies' - observer_can_run: false - platform: "" - query: SELECT * FROM managed_policies; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - md_devices' - observer_can_run: false - platform: "" - query: SELECT * FROM md_devices; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - md_drives' - observer_can_run: false - platform: "" - query: SELECT * FROM md_drives; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - md_personalities' - observer_can_run: false - platform: "" - query: SELECT * FROM md_personalities; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - mdfind' - observer_can_run: false - platform: "" - query: SELECT * FROM mdfind; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - mdls' - observer_can_run: false - platform: "" - query: SELECT * FROM mdls; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - mdm' - observer_can_run: false - platform: "" - query: SELECT * FROM mdm; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - mdm_bridge' - observer_can_run: false - platform: "" - query: SELECT * FROM mdm_bridge; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - memory_array_mapped_addresses' - observer_can_run: false - platform: "" - query: SELECT * FROM memory_array_mapped_addresses; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - memory_arrays' - observer_can_run: false - platform: "" - query: SELECT * FROM memory_arrays; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - memory_device_mapped_addresses' - observer_can_run: false - platform: "" - query: SELECT * FROM memory_device_mapped_addresses; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - memory_devices' - observer_can_run: false - platform: "" - query: SELECT * FROM memory_devices; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - memory_error_info' - observer_can_run: false - platform: "" - query: SELECT * FROM memory_error_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - memory_info' - observer_can_run: false - platform: "" - query: SELECT * FROM memory_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - memory_map' - observer_can_run: false - platform: "" - query: SELECT * FROM memory_map; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - mounts' - observer_can_run: false - platform: "" - query: SELECT * FROM mounts; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - msr' - observer_can_run: false - platform: "" - query: SELECT * FROM msr; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - munki_info' - observer_can_run: false - platform: "" - query: SELECT * FROM munki_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - munki_installs' - observer_can_run: false - platform: "" - query: SELECT * FROM munki_installs; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - network_interfaces' - observer_can_run: false - platform: "" - query: SELECT * FROM network_interfaces; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - nfs_shares' - observer_can_run: false - platform: "" - query: SELECT * FROM nfs_shares; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - npm_packages' - observer_can_run: false - platform: "" - query: SELECT * FROM npm_packages; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ntdomains' - observer_can_run: false - platform: "" - query: SELECT * FROM ntdomains; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ntfs_acl_permissions' - observer_can_run: false - platform: "" - query: SELECT * FROM ntfs_acl_permissions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ntfs_journal_events' - observer_can_run: false - platform: "" - query: SELECT * FROM ntfs_journal_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - nvram' - observer_can_run: false - platform: "" - query: SELECT * FROM nvram; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - nvram_info' - observer_can_run: false - platform: "" - query: SELECT * FROM nvram_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - oem_strings' - observer_can_run: false - platform: "" - query: SELECT * FROM oem_strings; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - office_mru' - observer_can_run: false - platform: "" - query: SELECT * FROM office_mru; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - orbit_info' - observer_can_run: false - platform: "" - query: SELECT * FROM orbit_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - os_version' - observer_can_run: false - platform: "" - query: SELECT * FROM os_version; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - osquery_events' - observer_can_run: false - platform: "" - query: SELECT * FROM osquery_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - osquery_extensions' - observer_can_run: false - platform: "" - query: SELECT * FROM osquery_extensions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - osquery_flags' - observer_can_run: false - platform: "" - query: SELECT * FROM osquery_flags; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - osquery_info' - observer_can_run: false - platform: "" - query: SELECT * FROM osquery_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - osquery_packs' - observer_can_run: false - platform: "" - query: SELECT * FROM osquery_packs; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - osquery_registry' - observer_can_run: false - platform: "" - query: SELECT * FROM osquery_registry; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - osquery_schedule' - observer_can_run: false - platform: "" - query: SELECT * FROM osquery_schedule; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - package_bom' - observer_can_run: false - platform: "" - query: SELECT * FROM package_bom; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - package_install_history' - observer_can_run: false - platform: "" - query: SELECT * FROM package_install_history; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - package_receipts' - observer_can_run: false - platform: "" - query: SELECT * FROM package_receipts; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - password_policy' - observer_can_run: false - platform: "" - query: SELECT * FROM password_policy; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - patches' - observer_can_run: false - platform: "" - query: SELECT * FROM patches; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - pci_devices' - observer_can_run: false - platform: "" - query: SELECT * FROM pci_devices; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - physical_disk_performance' - observer_can_run: false - platform: "" - query: SELECT * FROM physical_disk_performance; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - pipes' - observer_can_run: false - platform: "" - query: SELECT * FROM pipes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - platform_info' - observer_can_run: false - platform: "" - query: SELECT * FROM platform_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - plist' - observer_can_run: false - platform: "" - query: SELECT * FROM plist; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - pmset' - observer_can_run: false - platform: "" - query: SELECT * FROM pmset; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - portage_keywords' - observer_can_run: false - platform: "" - query: SELECT * FROM portage_keywords; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - portage_packages' - observer_can_run: false - platform: "" - query: SELECT * FROM portage_packages; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - portage_use' - observer_can_run: false - platform: "" - query: SELECT * FROM portage_use; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - power_sensors' - observer_can_run: false - platform: "" - query: SELECT * FROM power_sensors; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - powershell_events' - observer_can_run: false - platform: "" - query: SELECT * FROM powershell_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - preferences' - observer_can_run: false - platform: "" - query: SELECT * FROM preferences; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - prefetch' - observer_can_run: false - platform: "" - query: SELECT * FROM prefetch; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - privacy_preferences' - observer_can_run: false - platform: "" - query: SELECT * FROM privacy_preferences; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - process_envs' - observer_can_run: false - platform: "" - query: SELECT * FROM process_envs; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - process_etw_events' - observer_can_run: false - platform: "" - query: SELECT * FROM process_etw_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - process_events' - observer_can_run: false - platform: "" - query: SELECT * FROM process_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - process_file_events' - observer_can_run: false - platform: "" - query: SELECT * FROM process_file_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - process_memory_map' - observer_can_run: false - platform: "" - query: SELECT * FROM process_memory_map; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - process_namespaces' - observer_can_run: false - platform: "" - query: SELECT * FROM process_namespaces; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - process_open_files' - observer_can_run: false - platform: "" - query: SELECT * FROM process_open_files; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - process_open_pipes' - observer_can_run: false - platform: "" - query: SELECT * FROM process_open_pipes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - process_open_sockets' - observer_can_run: false - platform: "" - query: SELECT * FROM process_open_sockets; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - processes' - observer_can_run: false - platform: "" - query: SELECT * FROM processes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - programs' - observer_can_run: false - platform: "" - query: SELECT * FROM programs; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - prometheus_metrics' - observer_can_run: false - platform: "" - query: SELECT * FROM prometheus_metrics; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - puppet_info' - observer_can_run: false - platform: "" - query: SELECT * FROM puppet_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - puppet_logs' - observer_can_run: false - platform: "" - query: SELECT * FROM puppet_logs; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - puppet_state' - observer_can_run: false - platform: "" - query: SELECT * FROM puppet_state; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - pwd_policy' - observer_can_run: false - platform: "" - query: SELECT * FROM pwd_policy; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - python_packages' - observer_can_run: false - platform: "" - query: SELECT * FROM python_packages; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - quicklook_cache' - observer_can_run: false - platform: "" - query: SELECT * FROM quicklook_cache; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - registry' - observer_can_run: false - platform: "" - query: SELECT * FROM registry; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - routes' - observer_can_run: false - platform: "" - query: SELECT * FROM routes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - rpm_package_files' - observer_can_run: false - platform: "" - query: SELECT * FROM rpm_package_files; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - rpm_packages' - observer_can_run: false - platform: "" - query: SELECT * FROM rpm_packages; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - running_apps' - observer_can_run: false - platform: "" - query: SELECT * FROM running_apps; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - safari_extensions' - observer_can_run: false - platform: "" - query: SELECT * FROM safari_extensions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - sandboxes' - observer_can_run: false - platform: "" - query: SELECT * FROM sandboxes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - scheduled_tasks' - observer_can_run: false - platform: "" - query: SELECT * FROM scheduled_tasks; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - screenlock' - observer_can_run: false - platform: "" - query: SELECT * FROM screenlock; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - seccomp_events' - observer_can_run: false - platform: "" - query: SELECT * FROM seccomp_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - secureboot' - observer_can_run: false - platform: "" - query: SELECT * FROM secureboot; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - security_profile_info' - observer_can_run: false - platform: "" - query: SELECT * FROM security_profile_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - selinux_events' - observer_can_run: false - platform: "" - query: SELECT * FROM selinux_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - selinux_settings' - observer_can_run: false - platform: "" - query: SELECT * FROM selinux_settings; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - services' - observer_can_run: false - platform: "" - query: SELECT * FROM services; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - shadow' - observer_can_run: false - platform: "" - query: SELECT * FROM shadow; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - shared_folders' - observer_can_run: false - platform: "" - query: SELECT * FROM shared_folders; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - shared_memory' - observer_can_run: false - platform: "" - query: SELECT * FROM shared_memory; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - shared_resources' - observer_can_run: false - platform: "" - query: SELECT * FROM shared_resources; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - sharing_preferences' - observer_can_run: false - platform: "" - query: SELECT * FROM sharing_preferences; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - shell_history' - observer_can_run: false - platform: "" - query: SELECT * FROM shell_history; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - shellbags' - observer_can_run: false - platform: "" - query: SELECT * FROM shellbags; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - shimcache' - observer_can_run: false - platform: "" - query: SELECT * FROM shimcache; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - signature' - observer_can_run: false - platform: "" - query: SELECT * FROM signature; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - sip_config' - observer_can_run: false - platform: "" - query: SELECT * FROM sip_config; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - smbios_tables' - observer_can_run: false - platform: "" - query: SELECT * FROM smbios_tables; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - smc_keys' - observer_can_run: false - platform: "" - query: SELECT * FROM smc_keys; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - sntp_request' - observer_can_run: false - platform: "" - query: SELECT * FROM sntp_request; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - socket_events' - observer_can_run: false - platform: "" - query: SELECT * FROM socket_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - software_update' - observer_can_run: false - platform: "" - query: SELECT * FROM software_update; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ssh_configs' - observer_can_run: false - platform: "" - query: SELECT * FROM ssh_configs; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - startup_items' - observer_can_run: false - platform: "" - query: SELECT * FROM startup_items; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - sudo_info' - observer_can_run: false - platform: "" - query: SELECT * FROM sudo_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - sudoers' - observer_can_run: false - platform: "" - query: SELECT * FROM sudoers; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - suid_bin' - observer_can_run: false - platform: "" - query: SELECT * FROM suid_bin; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - syslog_events' - observer_can_run: false - platform: "" - query: SELECT * FROM syslog_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - system_controls' - observer_can_run: false - platform: "" - query: SELECT * FROM system_controls; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - system_extensions' - observer_can_run: false - platform: "" - query: SELECT * FROM system_extensions; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - system_info' - observer_can_run: false - platform: "" - query: SELECT * FROM system_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - system_state' - observer_can_run: false - platform: "" - query: SELECT * FROM system_state; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - systemd_units' - observer_can_run: false - platform: "" - query: SELECT * FROM systemd_units; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - temperature_sensors' - observer_can_run: false - platform: "" - query: SELECT * FROM temperature_sensors; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - time' - observer_can_run: false - platform: "" - query: SELECT * FROM time; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - time_machine_backups' - observer_can_run: false - platform: "" - query: SELECT * FROM time_machine_backups; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - time_machine_destinations' - observer_can_run: false - platform: "" - query: SELECT * FROM time_machine_destinations; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - tpm_info' - observer_can_run: false - platform: "" - query: SELECT * FROM tpm_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ulimit_info' - observer_can_run: false - platform: "" - query: SELECT * FROM ulimit_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - unified_log' - observer_can_run: false - platform: "" - query: SELECT * FROM unified_log; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - uptime' - observer_can_run: false - platform: "" - query: SELECT * FROM uptime; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - usb_devices' - observer_can_run: false - platform: "" - query: SELECT * FROM usb_devices; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - user_events' - observer_can_run: false - platform: "" - query: SELECT * FROM user_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - user_groups' - observer_can_run: false - platform: "" - query: SELECT * FROM user_groups; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - user_interaction_events' - observer_can_run: false - platform: "" - query: SELECT * FROM user_interaction_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - user_login_settings' - observer_can_run: false - platform: "" - query: SELECT * FROM user_login_settings; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - user_ssh_keys' - observer_can_run: false - platform: "" - query: SELECT * FROM user_ssh_keys; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - userassist' - observer_can_run: false - platform: "" - query: SELECT * FROM userassist; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - users' - observer_can_run: false - platform: "" - query: SELECT * FROM users; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - video_info' - observer_can_run: false - platform: "" - query: SELECT * FROM video_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - virtual_memory_info' - observer_can_run: false - platform: "" - query: SELECT * FROM virtual_memory_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - wifi_networks' - observer_can_run: false - platform: "" - query: SELECT * FROM wifi_networks; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - wifi_status' - observer_can_run: false - platform: "" - query: SELECT * FROM wifi_status; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - wifi_survey' - observer_can_run: false - platform: "" - query: SELECT * FROM wifi_survey; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - winbaseobj' - observer_can_run: false - platform: "" - query: SELECT * FROM winbaseobj; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_crashes' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_crashes; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_eventlog' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_eventlog; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_events' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_firewall_rules' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_firewall_rules; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_optional_features' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_optional_features; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_search' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_search; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_security_center' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_security_center; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_security_products' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_security_products; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_update_history' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_update_history; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - windows_updates' - observer_can_run: false - platform: "" - query: SELECT * FROM windows_updates; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - wmi_bios_info' - observer_can_run: false - platform: "" - query: SELECT * FROM wmi_bios_info; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - wmi_cli_event_consumers' - observer_can_run: false - platform: "" - query: SELECT * FROM wmi_cli_event_consumers; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - wmi_event_filters' - observer_can_run: false - platform: "" - query: SELECT * FROM wmi_event_filters; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - wmi_filter_consumer_binding' - observer_can_run: false - platform: "" - query: SELECT * FROM wmi_filter_consumer_binding; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - wmi_script_event_consumers' - observer_can_run: false - platform: "" - query: SELECT * FROM wmi_script_event_consumers; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - xprotect_entries' - observer_can_run: false - platform: "" - query: SELECT * FROM xprotect_entries; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - xprotect_meta' - observer_can_run: false - platform: "" - query: SELECT * FROM xprotect_meta; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - xprotect_reports' - observer_can_run: false - platform: "" - query: SELECT * FROM xprotect_reports; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - yara' - observer_can_run: false - platform: "" - query: SELECT * FROM yara; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - yara_events' - observer_can_run: false - platform: "" - query: SELECT * FROM yara_events; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - ycloud_instance_metadata' - observer_can_run: false - platform: "" - query: SELECT * FROM ycloud_instance_metadata; -- automations_enabled: true - description: "" - discard_data: false - interval: 3600 - logging: snapshot - min_osquery_version: "" - name: '[Explore data] - yum_sources' - observer_can_run: false - platform: "" - query: SELECT * FROM yum_sources; diff --git a/it-and-security/teams/explore-data.yml b/it-and-security/teams/explore-data.yml deleted file mode 100644 index eecc64965d06..000000000000 --- a/it-and-security/teams/explore-data.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: "Explore data (fleetdm.com)" -team_settings: - features: - enable_host_users: true - enable_software_inventory: true - host_expiry_settings: - host_expiry_enabled: false - host_expiry_window: 0 - secrets: - - secret: $DOGFOOD_EXPLORE_DATA_ENROLL_SECRET -agent_options: - config: - decorators: - load: - - SELECT uuid AS host_uuid FROM system_info; - - SELECT hostname AS hostname FROM system_info; - options: - disable_distributed: false - distributed_interval: 5 - distributed_plugin: tls - distributed_tls_max_attempts: 3 - logger_tls_endpoint: /api/v1/osquery/log - pack_delimiter: / -controls: - enable_disk_encryption: false - macos_settings: - custom_settings: - macos_setup: - bootstrap_package: null - enable_end_user_authentication: false - macos_setup_assistant: null - macos_updates: - deadline: null - minimum_version: null - windows_settings: - custom_settings: null - windows_updates: - deadline_days: null - grace_period_days: null - scripts: -policies: -queries: - - path: ../lib/explore-data.queries.yml -software: From 16777830643af7252f5a6e82b8a842dc9f523b23 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:21:52 -0400 Subject: [PATCH 30/81] GitOps & API design: Add multiple Apple Business Manager and Volume Purchasing Program connections (#21043) GitOps and API changes for the following story: - #9956 DONE: - ~~Contributor API endpoints to support best practice GitOps (`fleetctl gitops`) and backwards compatibility GitOps (`fleetctl apply`)~~ - https://github.com/fleetdm/fleet/pull/21043#issuecomment-2338218929 --------- Co-authored-by: Martin Angers Co-authored-by: Dante Catalfamo <43040593+dantecatalfamo@users.noreply.github.com> Co-authored-by: Marko Lisica <83164494+marko-lisica@users.noreply.github.com> Co-authored-by: George Karr Co-authored-by: Gabriel Hernandez Co-authored-by: Rachael Shaw --- docs/Configuration/yaml-files.md | 34 ++- docs/Contributing/API-for-contributors.md | 282 +++++++++++++++++++++- docs/REST API/rest-api.md | 94 ++++++-- website/config/routes.js | 3 + 4 files changed, 381 insertions(+), 32 deletions(-) diff --git a/docs/Configuration/yaml-files.md b/docs/Configuration/yaml-files.md index 937408ec2c52..f66c79f1e751 100644 --- a/docs/Configuration/yaml-files.md +++ b/docs/Configuration/yaml-files.md @@ -585,16 +585,44 @@ Can only be configured for all teams (`org_settings`). #### mdm -The `mdm` section lets you enable MDM features in Fleet. +##### apple_business_manager -- `apple_bm_default_team` - is name of the team that macOS hosts in Apple Business Manager automatically enroll to when they're first set up. If empty, hosts will enroll to "No team" (default: `""`). +- `organization_name` is the organization name associated with the Apple Business Manager account. +- `macos_team` is the team where macOS hosts are automatically added when they appear in Apple Business Manager. +- `ios_team` is the the team where iOS hosts are automatically added when they appear in Apple Business Manager. +- `ipados_team` is the team where iPadOS hosts are automatically added when they appear in Apple Business Manager. ##### Example ```yaml org_settings: mdm: - apple_bm_default_team: "Workstations" # Available in Fleet Premium + apple_business_manager: # Available in Fleet Premium + - organization_name: Fleet Device Management Inc. + macos_team: "💻 Workstations" + ios_team: "📱🏢 Company-owned iPhones" + ipados_team: "🔳🏢 Company-owned iPads" +``` + +> Apple Business Manager settings can only be configured for all teams (`org_settings`). + +##### volume_purchasing_program + +- `location` is the name of the location in the Apple Business Manager account. +- `teams` is a list of team names. If you choose specific teams, App Store apps in this VPP account will only be available to install on hosts in these teams. If not specified, App Store apps are available to install on hosts in all teams. + +##### Example + +```yaml +org_settings: + mdm: + volume_purchasing_program: # Available in Fleet Premium + - location: Fleet Device Management Inc. + teams: + - "💻 Workstations" + - "💻🐣 Workstations (canary)" + - "📱🏢 Company-owned iPhones" + - "🔳🏢 Company-owned iPads" ``` Can only be configured for all teams (`org_settings`). diff --git a/docs/Contributing/API-for-contributors.md b/docs/Contributing/API-for-contributors.md index 3e75c98e58c4..ec39149199a1 100644 --- a/docs/Contributing/API-for-contributors.md +++ b/docs/Contributing/API-for-contributors.md @@ -531,9 +531,15 @@ The MDM endpoints exist to support the related command-line interface sub-comman - [Generate Apple Business Manager public key (ADE)](#generate-apple-business-manager-public-key-ade) - [Request Certificate Signing Request (CSR)](#request-certificate-signing-request-csr) - [Upload APNS certificate](#upload-apns-certificate) -- [Upload ABM Token](#upload-abm-token) +- [Add ABM token](#add-abm-token) - [Turn off Apple MDM](#turn-off-apple-mdm) -- [Disable automatic enrollment (ADE)](#disable-automatic-enrollment-ade) +- [Update ABM token's teams](#update-abm-tokens-teams) +- [Renew ABM token](#renew-abm-token) +- [Delete ABM token](#delete-abm-token) +- [Add VPP token](#add-VPP-token) +- [Update VPP token's teams](#update-vpp-tokens-teams) +- [Renew VPP token](#renew-vpp-token) +- [Delete VPP token](#delete-vpp-token) - [Batch-apply MDM custom settings](#batch-apply-mdm-custom-settings) - [Initiate SSO during DEP enrollment](#initiate-sso-during-dep-enrollment) - [Complete SSO during DEP enrollment](#complete-sso-during-dep-enrollment) @@ -620,9 +626,9 @@ Content-Type: application/octet-stream `Status: 200` -### Upload ABM Token +### Add ABM token -`POST /api/v1/fleet/mdm/apple/abm_token` +`POST /api/v1/fleet/abm_tokens` #### Parameters @@ -632,7 +638,7 @@ Content-Type: application/octet-stream #### Example -`POST /api/v1/fleet/mdm/apple/abm_token` +`POST /api/v1/fleet/abm_tokens` ##### Request header @@ -653,11 +659,23 @@ Content-Type: application/octet-stream --------------------------f02md47480und42y ``` - ##### Default response `Status: 200` +```json +"abm_token": { + "id": 1, + "apple_id": "apple@example.com", + "org_name": "Fleet Device Management Inc.", + "mdm_server_url": "https://example.com/mdm/apple/mdm", + "renew_date": "2024-10-20T00:00:00Z", + "terms_expired": false, + "macos_team": null, + "ios_team": null, + "ipados_team": null +} +``` ### Turn off Apple MDM @@ -671,19 +689,265 @@ Content-Type: application/octet-stream `Status: 204` +### Update ABM token's teams + +`PATCH /api/v1/fleet/abm_tokens/:id/teams` -### Disable automatic enrollment (ADE) +#### Parameters -`DELETE /api/v1/fleet/mdm/apple/abm_token` +| Name | Type | In | Description | +| ---- | ---- | -- | ----------- | +| id | integer | path | *Required* The ABM token's ID | +| macos_team_id | integer | body | macOS hosts are automatically added to this team in Fleet when they appear in Apple Business Manager. If not specified, defaults to "No team" | +| ios_team_id | integer | body | iOS hosts are automatically added to this team in Fleet when they appear in Apple Business Manager. If not specified, defaults to "No team" | +| ipados_team_id | integer | body | iPadOS hosts are automatically added to this team in Fleet when they appear in Apple Business Manager. If not specified, defaults to "No team" | #### Example -`DELETE /api/v1/fleet/mdm/apple/abm_token` +`PATCH /api/v1/fleet/abm_tokens/1/teams` + +##### Request body + +```json +{ + "macos_team_id": 1, + "ios_team_id": 2, + "ipados_team_id": 3 +} +``` + +##### Default response + +`Status: 200` + +```json +"abm_token": { + "id": 1, + "apple_id": "apple@example.com", + "org_name": "Fleet Device Management Inc.", + "mdm_server_url": "https://example.com/mdm/apple/mdm", + "renew_date": "2024-11-29T00:00:00Z", + "terms_expired": false, + "macos_team": 1, + "ios_team": 2, + "ipados_team": 3 +} +``` + +### Renew ABM token + +`PATCH /api/v1/fleet/abm_tokens/:id/renew` + +#### Parameters + +| Name | Type | In | Description | +| ---- | ---- | -- | ----------- | +| id | integer | path | *Required* The ABM token's ID | + +#### Example + +`PATCH /api/v1/fleet/abm_tokens/1/renew` + +##### Request header + +```http +Content-Length: 850 +Content-Type: multipart/form-data; boundary=------------------------f02md47480und42y +``` + +##### Request body + +```http +--------------------------f02md47480und42y +Content-Disposition: form-data; name="token"; filename="server_token_abm.p7m" +Content-Type: application/octet-stream + + + +--------------------------f02md47480und42y +``` + +##### Default response + +`Status: 200` + +```json +"abm_token": { + "id": 1, + "apple_id": "apple@example.com", + "org_name": "Fleet Device Management Inc.", + "mdm_server_url": "https://example.com/mdm/apple/mdm", + "renew_date": "2025-10-20T00:00:00Z", + "terms_expired": false, + "macos_team": null, + "ios_team": null, + "ipados_team": null +} +``` + +### Delete ABM token + +`DELETE /api/v1/fleet/abm_tokens/:id` + +#### Parameters + +| Name | Type | In | Description | +| ---- | ---- | -- | ----------- | +| id | integer | path | *Required* The ABM token's ID | + +#### Example + +`DELETE /api/v1/fleet/abm_tokens/1` ##### Default response `Status: 204` +### Add VPP token + +`POST /api/v1/fleet/vpp_tokens` + +#### Parameters + +| Name | Type | In | Description | +| ---- | ---- | -- | ----------- | +| token | file | form | *Required* The file containing the content token (.vpptoken) from Apple Business Manager | + +#### Example + +`POST /api/v1/fleet/vpp_tokens` + +##### Request header + +```http +Content-Length: 850 +Content-Type: multipart/form-data; boundary=------------------------f02md47480und42y +``` + +##### Request body + +```http +--------------------------f02md47480und42y +Content-Disposition: form-data; name="token"; filename="sToken_for_Acme.vpptoken" +Content-Type: application/octet-stream + +--------------------------f02md47480und42y +``` + +##### Default response + +`Status: 200` + +```json +"vpp_token": { + "id": 1, + "org_name": "Fleet Device Management Inc.", + "location": "https://example.com/mdm/apple/mdm", + "renew_date": "2024-10-20T00:00:00Z", + "terms_expired": false, + "teams": null +} +``` + +### Update VPP token's teams + +`PATCH /api/v1/fleet/vpp_tokens/:id/teams` + +#### Parameters + +| Name | Type | In | Description | +| ---- | ---- | -- | ----------- | +| id | integer | path | *Required* The ABM token's ID | +| team_ids | list | body | If you choose specific teams, App Store apps in this VPP account will only be available to install on hosts in these teams. If not specified, defaults to all teams. | + +#### Example + +`PATCH /api/v1/fleet/vpp_tokens/1/teams` + +##### Request body + +```json +{ + "team_ids": [1, 2, 3] +} +``` + +##### Default response + +`Status: 200` + +```json +"vpp_token": { + "id": 1, + "org_name": "Fleet Device Management Inc.", + "location": "https://example.com/mdm/apple/mdm", + "renew_date": "2024-10-20T00:00:00Z", + "terms_expired": false, + "teams": [1, 2, 3] +} +``` + +### Renew VPP token + +`PATCH /api/v1/fleet/vpp_tokens/:id/renew` + +#### Parameters + +| Name | Type | In | Description | +| ---- | ---- | -- | ----------- | +| id | integer | path | *Required* The VPP token's ID | + +##### Request header + +```http +Content-Length: 850 +Content-Type: multipart/form-data; boundary=------------------------f02md47480und42y +``` + +##### Request body + +```http +--------------------------f02md47480und42y +Content-Disposition: form-data; name="token"; filename="sToken_for_Acme.vpptoken" +Content-Type: application/octet-stream + + + +--------------------------f02md47480und42y +``` + +##### Default response + +`Status: 200` + +```json +"vpp_token": { + "id": 1, + "org_name": "Fleet Device Management Inc.", + "location": "https://example.com/mdm/apple/mdm", + "renew_date": "2025-10-20T00:00:00Z", + "terms_expired": false, + "teams": [1, 2, 3] +} +``` + +### Delete VPP token + +`DELETE /api/v1/fleet/vpp_token/:id` + +#### Parameters + +| Name | Type | In | Description | +| ---- | ---- | -- | ----------- | +| id | integer | path | *Required* The VPP token's ID | + +#### Example + +`DELETE /api/v1/fleet/vpp_tokens/1` + +##### Default response + +`Status: 204` ### Batch-apply MDM custom settings diff --git a/docs/REST API/rest-api.md b/docs/REST API/rest-api.md index e31703b6fb6d..c160aac679ff 100644 --- a/docs/REST API/rest-api.md +++ b/docs/REST API/rest-api.md @@ -878,9 +878,6 @@ None. "additional_queries": null }, "mdm": { - "apple_bm_default_team": "", - "apple_bm_terms_expired": false, - "enabled_and_configured": true, "windows_enabled_and_configured": true, "enable_disk_encryption": true, "macos_updates": { @@ -1170,9 +1167,6 @@ Modifies the Fleet's configuration with the supplied information. "expiration": "0001-01-01T00:00:00Z" }, "mdm": { - "apple_bm_default_team": "", - "apple_bm_terms_expired": false, - "apple_bm_enabled_and_configured": false, "enabled_and_configured": false, "windows_enabled_and_configured": false, "enable_disk_encryption": true, @@ -1694,7 +1688,6 @@ _Available in Fleet Premium._ | Name | Type | Description | | --------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| apple_bm_default_team | string | _Available in Fleet Premium._ The default team to use with Apple Business Manager. | | windows_enabled_and_configured | boolean | Enables Windows MDM support. | | enable_disk_encryption | boolean | _Available in Fleet Premium._ Hosts that belong to no team will have disk encryption enabled if set to true. | | macos_updates | object | See [`mdm.macos_updates`](#mdm-macos-updates). | @@ -1811,7 +1804,6 @@ _Available in Fleet Premium._ ```json { "mdm": { - "apple_bm_default_team": "", "windows_enabled_and_configured": false, "enable_disk_encryption": true, "macos_updates": { @@ -6261,8 +6253,8 @@ This endpoint returns the list of custom MDM commands that have been executed. ## Integrations - [Get Apple Push Notification service (APNs)](#get-apple-push-notification-service-apns) -- [Get Apple Business Manager (ABM)](#get-apple-business-manager-abm) -- [Get Volume Purchasing Program (VPP)](#get-volume-purchasing-program-vpp) +- [List Apple Business Manager (ABM) tokens](#list-apple-business-manager-abm-tokens) +- [List Volume Purchasing Program (VPP) tokens](#list-volume-purchasing-program-vpp-tokens) ### Get Apple Push Notification service (APNs) @@ -6289,11 +6281,11 @@ None. } ``` -### Get Apple Business Manager (ABM) +### List Apple Business Manager (ABM) tokens _Available in Fleet Premium_ -`GET /api/v1/fleet/abm` +`GET /api/v1/fleet/abm_tokens` #### Parameters @@ -6301,20 +6293,82 @@ None. #### Example -`GET /api/v1/fleet/abm` +`GET /api/v1/fleet/abm_tokens` ##### Default response `Status: 200` ```json -{ - "apple_id": "apple@example.com", - "org_name": "Fleet Device Management", - "mdm_server_url": "https://example.com/mdm/apple/mdm", - "renew_date": "2023-11-29T00:00:00Z", - "default_team": "" -} +"abm_tokens": [ + { + "id": 1, + "apple_id": "apple@example.com", + "org_name": "Fleet Device Management Inc.", + "mdm_server_url": "https://example.com/mdm/apple/mdm", + "renew_date": "2023-11-29T00:00:00Z", + "terms_expired": false, + "macos_team": { + "name": "💻 Workstations", + "id" 1 + }, + "ios_team": { + "name": "📱🏢 Company-owned iPhones", + "id": 2 + }, + "ipados_team": { + "name": "🔳🏢 Company-owned iPads", + "id": 3 + } + } +] +``` + +### List Volume Purchasing Program (VPP) tokens + +_Available in Fleet Premium_ + +`GET /api/v1/fleet/vpp_tokens` + +#### Parameters + +None. + +#### Example + +`GET /api/v1/fleet/vpp_tokens` + +##### Default response + +`Status: 200` + +```json +"vpp_tokens": [ + { + "id": 1, + "org_name": "Fleet Device Management Inc.", + "location": "https://example.com/mdm/apple/mdm", + "renew_date": "2023-11-29T00:00:00Z", + "teams": [ + { + "name": "💻 Workstations", + "id": 1 + }, + { + "name": "💻🐣 Workstations (canary)", + "id": 2 + }, + { + "name": "📱🏢 Company-owned iPhones", + "id": 3 + }, + { + "name": "🔳🏢 Company-owned iPads", + "id" 4 + } + ], + } +] ``` Get Volume Purchasing Program (VPP) diff --git a/website/config/routes.js b/website/config/routes.js index 2252a7072945..8c9991200f3a 100644 --- a/website/config/routes.js +++ b/website/config/routes.js @@ -559,6 +559,9 @@ module.exports.routes = { 'GET /learn-more-about/host-identifiers': '/docs/rest-api/rest-api#get-host-by-identifier', 'GET /learn-more-about/uninstall-fleetd': '/docs/using-fleet/faq#how-can-i-uninstall-fleetd', 'GET /learn-more-about/vulnerability-processing': '/docs/using-fleet/vulnerability-processing', + 'GET /learn-more-about/apple-business-manager-tokens-api': '/docs/rest-api/rest-api#list-apple-business-manager-abm-tokens', + 'GET /learn-more-about/apple-business-manager-teams-api': 'https://github.com/fleetdm/fleet/blob/main/docs/Contributing/API-for-contributors.md#update-abm-tokens-teams', + 'GET /learn-more-about/apple-business-manager-gitops': '/docs/using-fleet/gitops#apple-business-manager', 'GET /learn-more-about/s3-bootstrap-package': '/docs/configuration/fleet-server-configuration#s-3-software-installers-bucket', // Sitemap From 84473c273502a42483ec79555f6fe80d0f269c64 Mon Sep 17 00:00:00 2001 From: Jahziel Villasana-Espinoza Date: Fri, 20 Sep 2024 15:39:16 -0400 Subject: [PATCH 31/81] feat: update MDM migration guide with new UX (#22128) > Related issue: #22097 # 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/Committing-Changes.md#changes-files) for more information. - [x] Manual QA for all new/changed functionality --------- Co-authored-by: spokanemac Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Co-authored-by: Noah Talerman Co-authored-by: JD --- articles/mdm-migration.md | 199 +- changes/22097-mdm-migration-guide | 1 + website/.sailsrc | 17395 ++++++++++++++++++++++++++++ 3 files changed, 17448 insertions(+), 147 deletions(-) create mode 100644 changes/22097-mdm-migration-guide diff --git a/articles/mdm-migration.md b/articles/mdm-migration.md index ce24ab283a59..b28f6febd094 100644 --- a/articles/mdm-migration.md +++ b/articles/mdm-migration.md @@ -6,185 +6,102 @@ This guide provides instructions for migrating devices from your current MDM sol ## Requirements - - A [deployed Fleet instance](https://fleetdm.com/docs/deploy/deploy-fleet) - Fleet is connected to Apple Push Notification service (APNs) and Apple Business Manager (ABM). [See macOS MDM setup](https://fleetdm.com/guides/macos-mdm-setup) +## Migrate hosts -## Migrate manually enrolled hosts - -1. [Enroll](https://fleetdm.com/guides/enroll-hosts) your hosts to Fleet with [Fleetd and Fleet Desktop](https://fleetdm.com/guides/enroll-hosts#fleet-desktop) -2. Ensure your end users have access to an admin account on their Mac. End users won't be able to migrate on their own if they have a standard account. -3. In your old MDM solution, unenroll the hosts to be migrated. MacOS does not allow multiple MDMs to be installed at once. -4. Send [these guided instructions](#how-to-turn-on-mdm) to your end users to complete the final few steps via Fleet Desktop. - * Note that there will be a gap in MDM coverage between when the host is unenrolled from the old MDM and when the host turns on MDM in Fleet. - -### End user experience - -1. On their **My device** page, once an end user's device is unenrolled from the old MDM solution, the end user will be given the option to manually download the MDM enrollment profile. - -2. Once downloaded, the user will receive a system notification that the Device Enrollment profile needs to be installed in their **System Settings > Profiles** section. - -3. After installation, the MDM enrollment profile can be removed by the end user at any time. - -### How to turn on MDM - -1. Select the Fleet icon in your menu bar and select **My device**. - -![Fleet icon in menu bar](https://raw.githubusercontent.com/fleetdm/fleet/main/website/assets/images/articles/fleet-desktop-says-hello-world-cover-1600x900@2x.jpg) - -2. On your **My device** page, select the **Turn on MDM** button in the yellow banner and follow the instructions. - - If you don’t see the yellow banner or the **Turn on MDM** button, select the purple **Refetch** button at the top of the page. - - If you still don't see the **Turn on MDM** button or the **My device** page presents you with an error, please contact your IT administrator. - -My device page - turn on MDM +To migrate hosts, we will do the following steps: -## Migrate automatically enrolled (ADE) hosts +1. Enroll hosts to Fleet +2. Assign hosts in Apple Business Manager (ABM) to Fleet +3. Choose migration workflow and migrate hosts -> Automatic enrollment is available in Fleet Premium or Ultimate +### Step 1: enroll hosts to Fleet -To migrate automatically enrolled hosts, we will do the following steps: +1. First, enroll your hosts to Fleet by installing Fleet's agent (fleetd). Learn how [here](https://fleetdm.com/guides/enroll-hosts). +2. Ensure your end users have access to an admin account on their Mac. End users won't be able to migrate on their own if they have a standard account. -1. Prepare to migrate hosts -2. Choose migration workflow and migrate hosts +### Step 2: assign hosts in Apple Business Manager (ABM) to Fleet -### Step 1: prepare to migrate hosts +1. In ABM, unassign your hosts from your current MDM solution by selecting **Devices** and then selecting **All Devices**. Then, select **Edit** next to **Edit MDM Server**, select **Unassign from the current MDM**, and select **Continue**. -1. Connect Fleet to Apple Business Manager (ABM). Learn how [here](https://fleetdm.com/guides/macos-mdm-setup#apple-business-manager-abm). -2. [Enroll](https://fleetdm.com/guides/enroll-hosts) your hosts to Fleet with [Fleetd and Fleet Desktop](https://fleetdm.com/guides/enroll-hosts#fleet-desktop) -3. Ensure your end users have access to an admin account on their Mac. End users won't be able to migrate on their own if they have a standard account. -4. Migrate your hosts to Fleet in ABM: - 1. In ABM, unassign the existing hosts' MDM server from the old MDM solution: In ABM, select **Devices** and then select **All Devices**. Then, select **Edit** next to **Edit MDM Server**, select **Unassign from the current MDM**, and select **Continue**. - 2. In ABM, assign these hosts' MDM server to Fleet: In ABM, select **Devices** and then select **All Devices**. Then, select **Edit** next to **Edit MDM Server**, select **Assign to the following MDM:**, select your Fleet server in the dropdown, and select **Continue**. +2. Assign these hosts to Fleet: select **Devices** and then select **All Devices**. Then, select **Edit** next to **Edit MDM Server**, select **Assign to the following MDM:**, select your Fleet server in the dropdown, and select **Continue**. -### Step 2: choose migration workflow and migrate hosts +### Step 3: choose migration workflow and migrate hosts There are two migration workflows in Fleet: default and end user. The default migration workflow requires that the IT admin unenrolls hosts from the old MDM solution before the end user can complete migration. This will result in a gap in MDM coverage until the end user completes migration. -The end user migration workflow allows the end user to kick-off migration by unenrolling from the old MDM solution on their own. Once the user is unenrolled, they're prompted to turn on MDM features in Fleet. This reduces the gap in MDM coverage. - -Configuring the end user migration workflow requires a few additional steps. +The end user migration workflow allows the user to kick off migration by unenrolling from the old MDM solution on their own. Once the user is unenrolled, they're prompted to turn on MDM features in Fleet, reducing the gap in MDM coverage. #### Default workflow -1. In your old MDM solution, unenroll the hosts to be migrated. MacOS does not allow multiple MDMs to be installed at once. - -2. Send [these guided instructions](#how-to-turn-on-mdm-default) to your end users to complete the final few steps via Fleet Desktop. - * Note that there will be a gap in MDM coverage between when the host is unenrolled from the old MDM and when the host turns on MDM in Fleet. +End user experience: -##### End user experience - -1. The end user will receive a "Device Enrollment: <organization> can automatically configure your Mac." system notification within the macOS Notifications Center. - -2. After the end user clicks on the system notification, macOS will open the **System Setting > Profiles** and ask the user to "Allow Device Enrollment: <organization> can automatically configure your Mac based on settings provided by your System Administrator." - -3. If the end user does not install the profile, the system notification will continue to prompt the end user until the setting has been allowed. - -4. Once this setting has been approved, the MDM enrollment profile cannot be removed by the end user. - -##### How to turn on MDM (default) - -1. Select the Fleet icon in your menu bar and select **My device**. - -![Fleet icon in menu bar](https://raw.githubusercontent.com/fleetdm/fleet/main/website/assets/images/articles/fleet-desktop-says-hello-world-cover-1600x900@2x.jpg) +- After a host is unenrolled from your current MDM solution, the end user will be prompted with Apple's **Remote Management** full-screen popup if the host is assigned to Fleet in ABM. +macOS Remote Management popup +- If the host is not assigned to Fleet in ABM (manual enrollment), the end user will be given the option to download the MDM enrollment profile on their **My device page**. +Fleet icon in menu bar +My device page - turn on MDM -2. On your **My device** page, select the **Turn on MDM** button in the yellow banner and follow the instructions. - * If you don’t see the yellow banner or the **Turn on MDM** button, select the purple **Refetch** button at the top of the page. - * If you still don't see the **Turn on MDM** button or the **My device** page presents you with an error, please contact your IT administrator. +Configuration: -My device page - turn on MDM +- To kick off the default workflow, unenroll the hosts to be migrated in your current MDM solution. MacOS does not allow a host to be connected to multiple MDM solutions at once. #### End user workflow -> Available in Fleet Premium or Ultimate +> Available in Fleet Premium -The end user migration workflow is supported for automatically enrolled (ADE) hosts. +End user experience: -To watch a GIF that walks through the end user experience during the migration workflow, in the Fleet UI, head to **Settings > Integrations > Mobile device management (MDM)**, and scroll down to the **End user migration workflow** section. +- To watch an animation of the end user experience during the migration workflow, head to **Settings > Integrations > Mobile device management (MDM)** in the Fleet UI, and scroll down to the **End user migration workflow** section. -In Fleet, you can configure the end user workflow using the Fleet UI or fleetctl command-line tool. +Configuration: -Fleet UI: +- In Fleet, you can configure the end user workflow using the Fleet UI, Fleet API, or Fleet's GitOps workflow. -1. Select the avatar on the right side of the top navigation and select **Settings > Integrations > Mobile device management (MDM)**. +- After configuring the end user workflow, instruct your end users to select the Fleet icon in their menu bar, select **Migrate to Fleet** and follow the on-screen instructions to migrate to Fleet. +- Fleet UI: +1. Select the avatar on the right side of the top navigation and select **Settings > Integrations > Mobile device management (MDM)**. 2. Scroll down to the **End user migration workflow** section and select the toggle to enable the workflow. +3. Under **Mode**, choose a mode, enter the webhook URL for your automation tool (e.g., Tines) under **Webhook URL**, and select **Save**. +4. During the end user migration workflow, an end user's device will have its selected system theme (light or dark) applied. If your logo is not easy to see on both light and dark backgrounds, you can optionally set a logo for each theme: +Head to **Settings** > **Organization settings** > **Organization info**, add URLs to your logos in the **Organization avatar URL (for dark backgrounds)** and **Organization avatar URL (for light backgrounds)** fields, and select **Save**. +- Fleet API: API documentation is [here](https://fleetdm.com/docs/rest-api/rest-api#mdm-macos-migration) +- GitOps: + - To manage macOS MDM migration configuration using Fleet's best practice GitOps, check out the `macos_migration` key in the [GitOps reference documentation](https://fleetdm.com/docs/configuration/yaml-files#macos-migration). + - To manage your organization's logo for dark and light backgrounds using Fleet's best practice GitOps, check out the `org_info` key in the [GitOps reference documentation](https://fleetdm.com/docs/configuration/yaml-files#org-info). -3. Under **Mode** choose a mode and enter the webhook URL for you automation tool (ex. Tines) under **Webhook URL** and select **Save**. - -4. During the end user migration workflow, an end user's device will have their selected system theme (light or dark) applied. If your logo is not easy to see on both light and dark backgrounds, you can optionally set a logo for each theme: -Head to **Settings** > **Organization settings** > -**Organization info**, add URLs to your logos in the **Organization avatar URL (for dark backgrounds)** and **Organization avatar URL (for light backgrounds)** fields, and select **Save**. - -fleetctl CLI: - -1. Create `fleet-config.yaml` file or add to your existing `config` YAML file: - -```yaml -apiVersion: v1 -kind: config -spec: - mdm: - macos_migration: - enable: true - mode: "voluntary" - webhook_url: "https://example.com" - ... -``` - -2. Fill in the above keys under the `mdm.macos_migration` key. - -To learn about each option, in the Fleet UI, select the avatar on the right side of the top navigation, select **Settings > Integrations > Mobile device management (MDM)**, and scroll down to the **End user migration workflow** section. - -3. During the end user migration workflow, the window will show the Fleet logo on top of a dark and light background (appearance configured by end user). - -If want to add a your organization's logo, you can optionally set a logo for each background: - -```yaml -apiVersion: v1 -kind: config -spec: - org_info: - org_logo_url: https://fleetdm.com/images/press-kit/fleet-blue-logo.png - org_logo_url_light_background: https://fleetdm.com/images/press-kit/fleet-white-logo.png - ... -``` - -Add URLs to your logos that are visible on a dark background and light background in the `org_logo_url` and `org_logo_url_light_background` keys respectively. If you only set a logo for one, the Fleet logo will be used for the other. - -4. Run the fleetctl `apply -f fleet-config.yml` command to add your configuration. - -5. Confirm that your configuration was saved by running `fleetctl get config`. - -6. Send [these guided instructions](#how-to-turn-on-mdm-end-user) to your end users to complete the final few steps via Fleet Desktop. +## Check migration progress -##### How to turn on MDM (end user) +To see a report of which hosts have successfully migrated to Fleet, have MDM features off, or are still enrolled to your old MDM solution head to the **Dashboard** page by clicking the icon on the left side of the top navigation bar. -1. Select the Fleet icon in your menu bar and select **Migrate to Fleet**. +Then, scroll down to the **Mobile device management (MDM)** section of the Dashboard. You'll see a breakdown of which hosts have successfully migrated to Fleet, which have MDM features disabled, and which are still enrolled in the previous MDM solution. -2. Select **Start** in the **Migrate to Fleet** popup. +## FileVault recovery keys -2. On your **My device** page, select the **Turn on MDM** button in the yellow banner and follow the instructions. - * If you don’t see the yellow banner or the **Turn on MDM** button, select the purple **Refetch** button at the top of the page. - * If you still don't see the **Turn on MDM** button or the **My device** page presents you with an error, please contact your IT administrator. +_Available in Fleet Premium_ -## Check migration progress +When migrating from a previous MDM, end users must restart or log out of their device to escrow FileVault keys to Fleet. The **My device** page in Fleet Desktop will present users with instructions on how to reset their key. -To see a report of which hosts have successfully migrated to Fleet, have MDM features off, or are still enrolled to your old MDM solution head to the **Dashboard** page by clicking the icon on the left side of the top navigation bar. +To start, enforce FileVault disk encryption and escrow recovery keys in Fleet. Learn how [here](https://fleetdm.com/guides/enforce-disk-encryption). -Then, scroll down to the **Mobile device management (MDM)** section. +After turning on disk encryption in Fleet, share [these guided instructions](#how-to-turn-on-disk-encryption) with your end users. -## FileVault recovery keys +### How to turn on disk encryption -_Available in Fleet Premium_ +1. Select the Fleet icon in your menu bar and select **My device**. -When migrating from a previous MDM, end users need to restart or logout of their device to escrow FileVault keys to Fleet. The **My device** page in Fleet Desktop will present users with instructions to reset their key. +![Fleet icon in menu bar](https://raw.githubusercontent.com/fleetdm/fleet/main/website/assets/images/articles/fleet-desktop-says-hello-world-cover-1600x900@2x.jpg) -To start, enforce FileVault (disk encryption) and escrow in Fleet. Learn how [here](https://fleetdm.com/guides/enforce-disk-encryption). +2. On your **My device** page, follow the disk encryption instructions in the yellow banner. + - If you don’t see the yellow banner, select the purple **Refetch** button at the top of the page. + - If you still don't see the yellow banner after a couple minutes or if the **My device** page presents you with an error, please contact your IT administrator. -After turning on disk encryption in Fleet, share [these guided instructions](#how-to-turn-on-disk-encryption) with your end users. +My device page - turn on disk encryption ## Activation Lock @@ -194,21 +111,9 @@ In 2024, Apple added the ability to manage activation lock in Apple Business Man If a device is not available in ABM and has Activation Lock enabled, we recommend asking the end user to follow these instructions to disable Activation Lock before migrating the device to Fleet: https://support.apple.com/en-us/HT208987. -This is because if the Activation Lock is enabled, you will need the Activation Lock bypass code to successfully wipe and reuse the Mac. +If the Activation Lock is enabled, you will need the Activation Lock bypass code to wipe and reuse the Mac successfully. However, Activation Lock bypass codes can only be retrieved from the Mac up to 30 days after the device is enrolled. This means that when migrating from your old MDM solution, it’s likely that you’ll be unable to retrieve the Activation Lock bypass code. - -### How to turn on disk encryption - -1. Select the Fleet icon in your menu bar and select **My device**. - -![Fleet icon in menu bar](https://raw.githubusercontent.com/fleetdm/fleet/main/website/assets/images/articles/fleet-desktop-says-hello-world-cover-1600x900@2x.jpg) - -2. On your **My device** page, follow the disk encryption instructions in the yellow banner. - - If you don’t see the yellow banner, select the purple **Refetch** button at the top of the page. - - If you still don't see the yellow banner after a couple minutes or if the **My device** page presents you with an error, please contact your IT administrator. - -My device page - turn on disk encryption diff --git a/changes/22097-mdm-migration-guide b/changes/22097-mdm-migration-guide new file mode 100644 index 000000000000..0177cf49b6b5 --- /dev/null +++ b/changes/22097-mdm-migration-guide @@ -0,0 +1 @@ +- Updates the guide for MDM migration to include the new UX in fleetd. \ No newline at end of file diff --git a/website/.sailsrc b/website/.sailsrc index 391fdf869cce..0cd59c071452 100644 --- a/website/.sailsrc +++ b/website/.sailsrc @@ -7,5 +7,17400 @@ "_generatedWith": { "sails": "1.2.5", "sails-generate": "2.0.0" + }, + "builtStaticContent": { + "queries": [ + { + "name": "Get OpenSSL versions", + "platform": "linux", + "description": "Retrieves the OpenSSL version.", + "query": "SELECT name AS name, version AS version, 'deb_packages' AS source FROM deb_packages WHERE name LIKE 'openssl%' UNION SELECT name AS name, version AS version, 'apt_sources' AS source FROM apt_sources WHERE name LIKE 'openssl%' UNION SELECT name AS name, version AS version, 'rpm_packages' AS source FROM rpm_packages WHERE name LIKE 'openssl%';", + "purpose": "Informational", + "tags": [ + "inventory" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-open-ssl-versions", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get authorized SSH keys", + "platform": "darwin, linux", + "description": "Presence of authorized SSH keys may be unusual on laptops. Could be completely normal on servers, but may be worth auditing for unusual keys and/or changes.", + "query": "SELECT username, authorized_keys. * FROM users CROSS JOIN authorized_keys USING (uid);", + "purpose": "Informational", + "remediation": "Check out the linked table (https://github.com/fleetdm/fleet/blob/32b4d53e7f1428ce43b0f9fa52838cbe7b413eed/handbook/queries/detect-hosts-with-high-severity-vulnerable-versions-of-openssl.md#table-of-vulnerable-openssl-versions) to determine if the installed version is a high severity vulnerability and view the corresponding CVE(s)", + "tags": [ + "built-in", + "ssh" + ], + "contributors": [ + { + "name": "mike-j-thomas", + "handle": "mike-j-thomas", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/mike-j-thomas" + } + ], + "kind": "query", + "slug": "get-authorized-ssh-keys", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get authorized keys for Domain Joined Accounts", + "platform": "darwin, linux", + "description": "List authorized_keys for each user on the system.", + "query": "SELECT * FROM users CROSS JOIN authorized_keys USING(uid) WHERE username IN (SELECT distinct(username) FROM last);", + "purpose": "Informational", + "tags": [ + "active directory", + "ssh" + ], + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-authorized-keys-for-domain-joined-accounts", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get crashes", + "platform": "darwin", + "description": "Retrieve application, system, and mobile app crash logs.", + "query": "SELECT uid, datetime, responsible, exception_type, identifier, version, crash_path FROM users CROSS JOIN crashes USING (uid);", + "purpose": "Informational", + "tags": [ + "troubleshooting" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-crashes", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get installed Chrome Extensions", + "platform": "darwin, linux, windows", + "description": "List installed Chrome Extensions for all users.", + "query": "SELECT * FROM users CROSS JOIN chrome_extensions USING (uid);", + "purpose": "Informational", + "tags": [ + "browser", + "built-in", + "inventory" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-installed-chrome-extensions", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get installed Linux software", + "platform": "linux", + "description": "Get all software installed on a Linux computer, including browser plugins and installed packages. Note that this does not include other running processes in the processes table.", + "query": "SELECT name AS name, version AS version, 'Package (APT)' AS type, 'apt_sources' AS source FROM apt_sources UNION SELECT name AS name, version AS version, 'Package (deb)' AS type, 'deb_packages' AS source FROM deb_packages UNION SELECT package AS name, version AS version, 'Package (Portage)' AS type, 'portage_packages' AS source FROM portage_packages UNION SELECT name AS name, version AS version, 'Package (RPM)' AS type, 'rpm_packages' AS source FROM rpm_packages UNION SELECT name AS name, '' AS version, 'Package (YUM)' AS type, 'yum_sources' AS source FROM yum_sources UNION SELECT name AS name, version AS version, 'Package (NPM)' AS type, 'npm_packages' AS source FROM npm_packages UNION SELECT name AS name, version AS version, 'Package (Python)' AS type, 'python_packages' AS source FROM python_packages;", + "purpose": "Informational", + "tags": [ + "inventory", + "built-in" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-installed-linux-software", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get installed macOS software", + "platform": "darwin", + "description": "Get all software installed on a macOS computer, including apps, browser plugins, and installed packages. Note that this does not include other running processes in the processes table.", + "query": "SELECT name AS name, bundle_short_version AS version, 'Application (macOS)' AS type, 'apps' AS source FROM apps UNION SELECT name AS name, version AS version, 'Package (Python)' AS type, 'python_packages' AS source FROM python_packages UNION SELECT name AS name, version AS version, 'Browser plugin (Chrome)' AS type, 'chrome_extensions' AS source FROM chrome_extensions UNION SELECT name AS name, version AS version, 'Browser plugin (Firefox)' AS type, 'firefox_addons' AS source FROM firefox_addons UNION SELECT name As name, version AS version, 'Browser plugin (Safari)' AS type, 'safari_extensions' AS source FROM safari_extensions UNION SELECT name AS name, version AS version, 'Package (Homebrew)' AS type, 'homebrew_packages' AS source FROM homebrew_packages;", + "purpose": "Informational", + "tags": [ + "inventory", + "built-in" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-installed-mac-os-software", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get installed Safari extensions", + "platform": "darwin", + "description": "Retrieves the list of installed Safari Extensions for all users in the target system.", + "query": "SELECT safari_extensions.* FROM users join safari_extensions USING (uid);", + "purpose": "Informational", + "tags": [ + "browser", + "built-in", + "inventory" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-installed-safari-extensions", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get installed Windows software", + "platform": "windows", + "description": "Get all software installed on a Windows computer, including programs, browser plugins, and installed packages. Note that this does not include other running processes in the processes table.", + "query": "SELECT name AS name, version AS version, 'Program (Windows)' AS type, 'programs' AS source FROM programs UNION SELECT name AS name, version AS version, 'Package (Python)' AS type, 'python_packages' AS source FROM python_packages UNION SELECT name AS name, version AS version, 'Browser plugin (IE)' AS type, 'ie_extensions' AS source FROM ie_extensions UNION SELECT name AS name, version AS version, 'Browser plugin (Chrome)' AS type, 'chrome_extensions' AS source FROM chrome_extensions UNION SELECT name AS name, version AS version, 'Browser plugin (Firefox)' AS type, 'firefox_addons' AS source FROM firefox_addons UNION SELECT name AS name, version AS version, 'Package (Chocolatey)' AS type, 'chocolatey_packages' AS source FROM chocolatey_packages;", + "purpose": "Informational", + "tags": [ + "inventory", + "built-in" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-installed-windows-software", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get laptops with failing batteries", + "platform": "darwin", + "description": "Lists all laptops with under-performing or failing batteries.", + "query": "SELECT * FROM battery WHERE health != 'Good' AND condition NOT IN ('', 'Normal');", + "purpose": "Informational", + "tags": [ + "troubleshooting", + "hardware", + "inventory" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-laptops-with-failing-batteries", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get current users with active shell/console on the system", + "platform": "darwin, linux, windows", + "description": "Get current users with active shell/console on the system and associated process", + "query": "SELECT user,host,time, p.name, p.cmdline, p.cwd, p.root FROM logged_in_users liu, processes p WHERE liu.pid = p.pid and liu.type='user' and liu.user <> '' ORDER BY time;", + "purpose": "Informational", + "tags": [ + "hunting", + "built-in" + ], + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-current-users-with-active-shell-console-on-the-system", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get unencrypted SSH keys for local accounts", + "platform": "darwin, linux, windows", + "description": "Identify SSH keys created without a passphrase which can be used in Lateral Movement (MITRE. TA0008)", + "query": "SELECT uid, username, description, path, encrypted FROM users CROSS JOIN user_ssh_keys using (uid) WHERE encrypted=0;", + "purpose": "Informational", + "tags": [ + "inventory", + "compliance", + "ssh", + "built-in" + ], + "remediation": "First, make the user aware about the impact of SSH keys. Then rotate the unencrypted keys detected.", + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-unencrypted-ssh-keys-for-local-accounts", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get unencrypted SSH keys for domain-joined accounts", + "platform": "darwin, linux, windows", + "description": "Identify SSH keys created without a passphrase which can be used in Lateral Movement (MITRE. TA0008)", + "query": "SELECT uid, username, description, path, encrypted FROM users CROSS JOIN user_ssh_keys using (uid) WHERE encrypted=0 and username in (SELECT distinct(username) FROM last);", + "purpose": "Informational", + "tags": [ + "inventory", + "compliance", + "ssh", + "active directory" + ], + "remediation": "First, make the user aware about the impact of SSH keys. Then rotate the unencrypted keys detected.", + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-unencrypted-ssh-keys-for-domain-joined-accounts", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get dynamic linker hijacking on Linux (MITRE. T1574.006)", + "platform": "linux", + "description": "Detect any processes that run with LD_PRELOAD environment variable", + "query": "SELECT env.pid, env.key, env.value, p.name,p.path, p.cmdline, p.cwd FROM process_envs env join processes p USING (pid) WHERE key='LD_PRELOAD';", + "purpose": "Informational", + "tags": [ + "hunting", + "attack", + "t1574" + ], + "remediation": "Identify the process/binary detected and confirm with the system's owner.", + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-dynamic-linker-hijacking-on-linux-mitre-t-1574-006", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get dynamic linker hijacking on macOS (MITRE. T1574.006)", + "platform": "darwin", + "description": "Detect any processes that run with DYLD_INSERT_LIBRARIES environment variable", + "query": "SELECT env.pid, env.key, env.value, p.name,p.path, p.cmdline, p.cwd FROM process_envs env join processes p USING (pid) WHERE key='DYLD_INSERT_LIBRARIES';", + "purpose": "Informational", + "tags": [ + "hunting", + "attack", + "t1574" + ], + "remediation": "Identify the process/binary detected and confirm with the system's owner.", + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-dynamic-linker-hijacking-on-mac-os-mitre-t-1574-006", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get etc hosts entries", + "platform": "darwin, linux", + "description": "Line-parsed /etc/hosts", + "query": "SELECT * FROM etc_hosts WHERE address not in ('127.0.0.1', '::1');", + "purpose": "informational", + "tags": [ + "hunting", + "inventory" + ], + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-etc-hosts-entries", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get network interfaces", + "platform": "darwin, linux, windows", + "description": "Network interfaces MAC address", + "query": "SELECT a.interface, a.address, d.mac FROM interface_addresses a JOIN interface_details d USING (interface) WHERE address not in ('127.0.0.1', '::1');", + "purpose": "informational", + "tags": [ + "hunting", + "inventory" + ], + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-network-interfaces", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get local user accounts", + "platform": "darwin, linux, windows", + "description": "Local user accounts (including domain accounts that have logged on locally (Windows)).", + "query": "SELECT uid, gid, username, description, directory, shell FROM users;", + "purpose": "informational", + "tags": [ + "hunting", + "inventory" + ], + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-local-user-accounts", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get active user accounts on servers", + "platform": "linux", + "description": "Domain Joined environments normally have root or other service only accounts and users are SSH-ing using their Domain Accounts.", + "query": "SELECT * FROM shadow WHERE password_status='active' and username!='root';", + "purpose": "informational", + "tags": [ + "hunting", + "inventory", + "active directory" + ], + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-active-user-accounts-on-servers", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get Nmap scanner", + "platform": "darwin, linux, windows", + "description": "Get Nmap scanner process, as well as its user, parent, and process details.", + "query": "SELECT p.pid, name, p.path, cmdline, cwd, start_time, parent, (SELECT name FROM processes WHERE pid=p.parent) AS parent_name, (SELECT username FROM users WHERE uid=p.uid) AS username FROM processes as p WHERE cmdline like 'nmap%';", + "purpose": "Informational", + "tags": [ + "hunting", + "attack", + "t1046" + ], + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-nmap-scanner", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get Docker contained processes on a system", + "platform": "darwin, linux", + "description": "Docker containers Processes, can be used on normal systems or a kubenode.", + "query": "SELECT c.id, c.name, c.image, c.image_id, c.command, c.created, c.state, c.status, p.cmdline FROM docker_containers c CROSS JOIN docker_container_processes p using(id);", + "purpose": "Informational", + "tags": [ + "built-in", + "containers", + "inventory" + ], + "contributors": [ + { + "name": "anelshaer", + "handle": "anelshaer", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/anelshaer" + } + ], + "kind": "query", + "slug": "get-docker-contained-processes-on-a-system", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get Windows print spooler remote code execution vulnerability", + "platform": "windows", + "description": "Detects devices that are potentially vulnerable to CVE-2021-1675 because the print spooler service is not disabled.", + "query": "SELECT CASE cnt WHEN 2 THEN \"TRUE\" ELSE \"FALSE\" END \"Vulnerable\" FROM (SELECT name start_type, COUNT(name) AS cnt FROM services WHERE name = 'NTDS' or (name = 'Spooler' and start_type <> 'DISABLED')) WHERE cnt = 2;", + "purpose": "Informational", + "tags": [ + "vulnerability" + ], + "contributors": [ + { + "name": "maravedi", + "handle": "maravedi", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/maravedi" + } + ], + "kind": "query", + "slug": "get-windows-print-spooler-remote-code-execution-vulnerability", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get local users and their privileges", + "platform": "darwin, linux, windows", + "description": "Collects the local user accounts and their respective user group.", + "query": "SELECT uid, username, type, groupname FROM users u JOIN groups g ON g.gid = u.gid;", + "purpose": "informational", + "tags": [ + "inventory" + ], + "contributors": [ + { + "name": "noahtalerman", + "handle": "noahtalerman", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/noahtalerman" + } + ], + "kind": "query", + "slug": "get-local-users-and-their-privileges", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get processes that no longer exist on disk", + "platform": "linux, darwin, windows", + "description": "Lists all processes of which the binary which launched them no longer exists on disk. Attackers often delete files from disk after launching a process to mask presence.", + "query": "SELECT name, path, pid FROM processes WHERE on_disk = 0;", + "purpose": "Incident response", + "tags": [ + "hunting", + "built-in" + ], + "contributors": [ + { + "name": "alphabrevity", + "handle": "alphabrevity", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/alphabrevity" + } + ], + "kind": "query", + "slug": "get-processes-that-no-longer-exist-on-disk", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get user files matching a specific hash", + "platform": "darwin, linux", + "description": "Looks for specific hash in the Users/ directories for files that are less than 50MB (osquery file size limitation.)", + "query": "SELECT path, sha256 FROM hash WHERE path IN (SELECT path FROM file WHERE size < 50000000 AND path LIKE '/Users/%/Documents/%%') AND sha256 = '16d28cd1d78b823c4f961a6da78d67a8975d66cde68581798778ed1f98a56d75';", + "purpose": "Informational", + "tags": [ + "hunting", + "built-in" + ], + "contributors": [ + { + "name": "alphabrevity", + "handle": "alphabrevity", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/alphabrevity" + } + ], + "kind": "query", + "slug": "get-user-files-matching-a-specific-hash", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get local administrator accounts on macOS", + "platform": "darwin", + "description": "The query allows you to check macOS systems for local administrator accounts.", + "query": "SELECT uid, username, type FROM users u JOIN groups g ON g.gid = u.gid;", + "purpose": "Informational", + "tags": [ + "hunting", + "inventory" + ], + "contributors": [ + { + "name": "alphabrevity", + "handle": "alphabrevity", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/alphabrevity" + } + ], + "kind": "query", + "slug": "get-local-administrator-accounts-on-mac-os", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get all listening ports, by process", + "platform": "linux, darwin, windows", + "description": "List ports that are listening on all interfaces, along with the process to which they are attached.", + "query": "SELECT lp.address, lp.pid, lp.port, lp.protocol, p.name, p.path, p.cmdline FROM listening_ports lp JOIN processes p ON lp.pid = p.pid WHERE lp.address = \"0.0.0.0\";", + "purpose": "Informational", + "tags": [ + "hunting", + "network" + ], + "contributors": [ + { + "name": "alphabrevity", + "handle": "alphabrevity", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/alphabrevity" + } + ], + "kind": "query", + "slug": "get-all-listening-ports-by-process", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get whether TeamViewer is installed/running", + "platform": "windows", + "description": "Looks for the TeamViewer service running on machines. This is often used when attackers gain access to a machine, running TeamViewer to allow them to access a machine.", + "query": "SELECT display_name,status,s.pid,p.path FROM services AS s JOIN processes AS p USING(pid) WHERE s.name LIKE \"%teamviewer%\";", + "purpose": "Informational", + "tags": [ + "hunting", + "inventory" + ], + "contributors": [ + { + "name": "alphabrevity", + "handle": "alphabrevity", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/alphabrevity" + } + ], + "kind": "query", + "slug": "get-whether-team-viewer-is-installed-running", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get malicious Python backdoors", + "platform": "darwin, linux, windows", + "description": "Watches for the backdoored Python packages installed on the system. See (http://www.nbu.gov.sk/skcsirt-sa-20170909-pypi/index.html)", + "query": "SELECT CASE cnt WHEN 0 THEN \"NONE_INSTALLED\" ELSE \"INSTALLED\" END AS \"Malicious Python Packages\", package_name, package_version FROM (SELECT COUNT(name) AS cnt, name AS package_name, version AS package_version, path AS package_path FROM python_packages WHERE package_name IN ('acquisition', 'apidev-coop', 'bzip', 'crypt', 'django-server', 'pwd', 'setup-tools', 'telnet', 'urlib3', 'urllib'));", + "purpose": "Informational", + "tags": [ + "hunting", + "inventory", + "malware" + ], + "contributors": [ + { + "name": "alphabrevity", + "handle": "alphabrevity", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/alphabrevity" + } + ], + "kind": "query", + "slug": "get-malicious-python-backdoors", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Check for artifacts of the Floxif trojan", + "platform": "windows", + "description": "Checks for artifacts from the Floxif trojan on Windows machines.", + "query": "SELECT * FROM registry WHERE path LIKE 'HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Piriform\\\\Agomo%';", + "purpose": "Informational", + "tags": [ + "hunting", + "malware" + ], + "contributors": [ + { + "name": "micheal-o", + "handle": "micheal-o", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/micheal-o" + } + ], + "kind": "query", + "slug": "check-for-artifacts-of-the-floxif-trojan", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get Shimcache table", + "platform": "windows", + "description": "Returns forensic data showing evidence of likely file execution, in addition to the last modified timestamp of the file, order of execution, full file path order of execution, and the order in which files were executed.", + "query": "select * from Shimcache", + "purpose": "Informational", + "tags": [ + "hunting" + ], + "contributors": [ + { + "name": "puffyCid", + "handle": "puffyCid", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/puffyCid" + } + ], + "kind": "query", + "slug": "get-shimcache-table", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get running docker containers", + "platform": "darwin, linux", + "description": "Returns the running Docker containers", + "query": "SELECT id, name, image, image_id, state, status FROM docker_containers WHERE state = \"running\";", + "purpose": "Informational", + "tags": [ + "containers", + "inventory" + ], + "contributors": [ + { + "name": "DominusKelvin", + "handle": "DominusKelvin", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/DominusKelvin" + } + ], + "kind": "query", + "slug": "get-running-docker-containers", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get applications hogging memory", + "platform": "darwin, linux, windows", + "description": "Returns top 10 applications or processes hogging memory the most.", + "query": "SELECT pid, name, ROUND((total_size * '10e-7'), 2) AS memory_used FROM processes ORDER BY total_size DESC LIMIT 10;", + "purpose": "Informational", + "tags": [ + "troubleshooting" + ], + "contributors": [ + { + "name": "DominusKelvin", + "handle": "DominusKelvin", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/DominusKelvin" + } + ], + "kind": "query", + "slug": "get-applications-hogging-memory", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get servers with root login in the last 24 hours", + "platform": "darwin, linux, windows", + "description": "Returns servers with root login in the last 24 hours and the time the users were logged in.", + "query": "SELECT * FROM last WHERE username = \"root\" AND time > (( SELECT unix_time FROM time ) - 86400 );", + "purpose": "Informational", + "tags": [ + "hunting" + ], + "contributors": [ + { + "name": "DominusKelvin", + "handle": "DominusKelvin", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/DominusKelvin" + } + ], + "kind": "query", + "slug": "get-servers-with-root-login-in-the-last-24-hours", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Detect active processes with Log4j running", + "platform": "darwin, linux", + "description": "Returns a list of active processes and the Jar paths which are using Log4j. Version numbers are usually within the Jar filename. Note: This query is resource intensive and has caused problems on systems with limited swap space. Test on some systems before running this widely.", + "query": "WITH target_jars AS (\n SELECT DISTINCT path\n FROM (\n WITH split(word, str) AS(\n SELECT '', cmdline || ' '\n FROM processes\n UNION ALL\n SELECT substr(str, 0, instr(str, ' ')), substr(str, instr(str, ' ') + 1)\n FROM split\n WHERE str != '')\n SELECT word AS path\n FROM split\n WHERE word LIKE '%.jar'\n UNION ALL\n SELECT path\n FROM process_open_files\n WHERE path LIKE '%.jar'\n )\n)\nSELECT path, matches\nFROM yara\nWHERE path IN (SELECT path FROM target_jars)\n AND count > 0\n AND sigrule IN (\n 'rule log4jJndiLookup {\n strings:\n $jndilookup = \"JndiLookup\"\n condition:\n $jndilookup\n }',\n 'rule log4jJavaClass {\n strings:\n $javaclass = \"org/apache/logging/log4j\"\n condition:\n $javaclass\n }'\n );\n", + "purpose": "Detection", + "tags": [ + "vulnerability" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + }, + { + "name": "tgauda", + "handle": "tgauda", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/tgauda" + } + ], + "kind": "query", + "slug": "detect-active-processes-with-log-4-j-running", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get applications that were opened within the last 24 hours", + "platform": "darwin", + "description": "Returns applications that were opened within the last 24 hours starting with the last opened application.", + "query": "SELECT * FROM apps WHERE last_opened_time > (( SELECT unix_time FROM time ) - 86400 ) ORDER BY last_opened_time DESC;", + "purpose": "Informational", + "tags": [ + "inventory" + ], + "contributors": [ + { + "name": "DominusKelvin", + "handle": "DominusKelvin", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/DominusKelvin" + } + ], + "kind": "query", + "slug": "get-applications-that-were-opened-within-the-last-24-hours", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get applications that are not in the Applications directory", + "platform": "darwin", + "description": "Returns applications that are not in the `/Applications` directory", + "query": "SELECT * FROM apps WHERE path NOT LIKE '/Applications/%';", + "purpose": "Informational", + "tags": [ + "hunting", + "inventory" + ], + "contributors": [ + { + "name": "DominusKelvin", + "handle": "DominusKelvin", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/DominusKelvin" + } + ], + "kind": "query", + "slug": "get-applications-that-are-not-in-the-applications-directory", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get subscription-based applications that have not been opened for the last 30 days", + "platform": "darwin", + "description": "Returns applications that are subscription-based and have not been opened for the last 30 days. You can replace the list of applications with those specific to your use case.", + "query": "SELECT * FROM apps WHERE path LIKE '/Applications/%' AND name IN (\"Photoshop.app\", \"Adobe XD.app\", \"Sketch.app\", \"Illustrator.app\") AND last_opened_time < (( SELECT unix_time FROM time ) - 2592000000000 );", + "purpose": "Informational", + "tags": [ + "inventory" + ], + "contributors": [ + { + "name": "DominusKelvin", + "handle": "DominusKelvin", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/DominusKelvin" + } + ], + "kind": "query", + "slug": "get-subscription-based-applications-that-have-not-been-opened-for-the-last-30-days", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get operating system information", + "platform": "darwin, windows, linux", + "description": "Returns the operating system name and version on the device.", + "query": "SELECT name, version FROM os_version;", + "purpose": "Informational", + "tags": [ + "inventory", + "built-in" + ], + "contributors": [ + { + "name": "noahtalerman", + "handle": "noahtalerman", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/noahtalerman" + } + ], + "kind": "query", + "slug": "get-operating-system-information", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Gatekeeper enabled (macOS)", + "query": "SELECT 1 FROM gatekeeper WHERE assessments_enabled = 1;", + "description": "Checks to make sure that the Gatekeeper feature is enabled on macOS devices. Gatekeeper tries to ensure only trusted software is run on a mac machine.", + "resolution": "To enable Gatekeeper, on the failing device, run the following command in the Terminal app: /usr/sbin/spctl --master-enable.", + "tags": [ + "compliance", + "hardening", + "built-in", + "cis", + "cis2.5.2.1" + ], + "platform": "darwin", + "contributors": [ + { + "name": "groob", + "handle": "groob", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/groob" + } + ], + "kind": "policy", + "slug": "gatekeeper-enabled-mac-os", + "requiresMdm": false, + "critical": true + }, + { + "name": "Full disk encryption enabled (Windows)", + "query": "SELECT 1 FROM bitlocker_info WHERE drive_letter='C:' AND protection_status=1;", + "description": "Checks to make sure that full disk encryption is enabled on Windows devices.", + "resolution": "To get additional information, run the following osquery query on the failing device: SELECT * FROM bitlocker_info. In the query results, if protection_status is 2, then the status cannot be determined. If it is 0, it is considered unprotected. Use the additional results (percent_encrypted, conversion_status, etc.) to help narrow down the specific reason why Windows considers the volume unprotected.", + "platform": "windows", + "tags": [ + "compliance", + "hardening", + "built-in" + ], + "contributors": [ + { + "name": "defensivedepth", + "handle": "defensivedepth", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/defensivedepth" + } + ], + "kind": "policy", + "slug": "full-disk-encryption-enabled-windows", + "requiresMdm": false, + "critical": true + }, + { + "name": "Full disk encryption enabled (macOS)", + "query": "SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT \"\" AND filevault_status = 'on' LIMIT 1;", + "description": "Checks to make sure that full disk encryption (FileVault) is enabled on macOS devices.", + "resolution": "To enable full disk encryption, on the failing device, select System Preferences > Security & Privacy > FileVault > Turn On FileVault.", + "tags": [ + "compliance", + "hardening", + "built-in", + "cis", + "cis2.5.1.1" + ], + "platform": "darwin", + "contributors": [ + { + "name": "groob", + "handle": "groob", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/groob" + } + ], + "kind": "policy", + "slug": "full-disk-encryption-enabled-mac-os", + "requiresMdm": false, + "critical": true + }, + { + "name": "Full disk encryption enabled (Linux)", + "query": "SELECT 1 FROM disk_encryption WHERE encrypted=1 AND name LIKE '/dev/dm-1';", + "description": "Checks if the root drive is encrypted. There are many ways to encrypt Linux systems. This is the default on distributions such as Ubuntu.", + "resolution": "Ensure the image deployed to your Linux workstation includes full disk encryption.", + "platform": "linux", + "tags": [ + "compliance", + "hardening", + "built-in" + ], + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "full-disk-encryption-enabled-linux", + "requiresMdm": false, + "critical": true + }, + { + "name": "System Integrity Protection enabled (macOS)", + "query": "SELECT 1 FROM sip_config WHERE config_flag = 'sip' AND enabled = 1;", + "description": "Checks to make sure that the System Integrity Protection feature is enabled.", + "resolution": "To enable System Integrity Protection, on the failing device, run the following command in the Terminal app: /usr/sbin/spctl --master-enable.", + "tags": [ + "compliance", + "malware", + "hardening", + "built-in", + "cis", + "cis5.1.2" + ], + "platform": "darwin", + "contributors": [ + { + "name": "groob", + "handle": "groob", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/groob" + } + ], + "kind": "policy", + "slug": "system-integrity-protection-enabled-mac-os", + "requiresMdm": false + }, + { + "name": "Automatic login disabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain = 'com.apple.loginwindow' AND name = 'com.apple.login.mcx.DisableAutoLoginClient' AND value = 1 LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to prevent login in without a password.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that disables automatic login.", + "tags": [ + "compliance", + "hardening", + "built-in" + ], + "platform": "darwin", + "contributors": [ + { + "name": "groob", + "handle": "groob", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/groob" + } + ], + "kind": "policy", + "slug": "automatic-login-disabled-mac-os", + "requiresMdm": true, + "critical": true + }, + { + "name": "Secure keyboard entry for Terminal application enabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain = 'com.apple.Terminal' AND name = 'SecureKeyboardEntry' AND value = 1 LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to enabled secure keyboard entry for the Terminal application.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables secure keyboard entry for the Terminal application.", + "tags": [ + "compliance", + "hardening", + "built-in" + ], + "platform": "darwin", + "contributors": [ + { + "name": "groob", + "handle": "groob", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/groob" + } + ], + "kind": "policy", + "slug": "secure-keyboard-entry-for-terminal-application-enabled-mac-os", + "requiresMdm": true + }, + { + "name": "Get built-in antivirus status on macOS", + "platform": "darwin", + "query": "SELECT path, value AS version FROM plist WHERE (key = 'CFBundleShortVersionString' AND path = '/Library/Apple/System/Library/CoreServices/MRT.app/Contents/Info.plist') OR (key = 'CFBundleShortVersionString' AND path = '/Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Info.plist');", + "description": "Reads the version numbers from the Malware Removal Tool (MRT) and built-in antivirus (XProtect) plists", + "purpose": "Informational", + "tags": [ + "compliance", + "malware", + "hardening", + "built-in" + ], + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "query", + "slug": "get-built-in-antivirus-status-on-mac-os", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get antivirus status from the Windows Security Center", + "platform": "windows", + "query": "SELECT antivirus, signatures_up_to_date from windows_security_center CROSS JOIN windows_security_products WHERE type = 'Antivirus';", + "description": "Selects the antivirus and signatures status from Windows Security Center.", + "purpose": "Informational", + "tags": [ + "compliance", + "malware", + "hardening", + "built-in" + ], + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "query", + "slug": "get-antivirus-status-from-the-windows-security-center", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get antivirus (ClamAV/clamd) and updater (freshclam) process status", + "platform": "linux", + "query": "SELECT pid, state, cmdline, name FROM processes WHERE name='clamd' OR name='freshclam';", + "description": "Selects the clamd and freshclam processes to ensure AV and its updater are running", + "purpose": "Informational", + "tags": [ + "compliance", + "malware", + "hardening", + "built-in" + ], + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "query", + "slug": "get-antivirus-clam-av-clamd-and-updater-freshclam-process-status", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Antivirus healthy (macOS)", + "query": "SELECT score FROM (SELECT case when COUNT(*) = 2 then 1 ELSE 0 END AS score FROM plist WHERE (key = 'CFBundleShortVersionString' AND path = '/Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Info.plist' AND value>=2162) OR (key = 'CFBundleShortVersionString' AND path = '/Library/Apple/System/Library/CoreServices/MRT.app/Contents/Info.plist' and value>=1.93)) WHERE score == 1;", + "description": "Checks the version of Malware Removal Tool (MRT) and the built-in macOS AV (Xprotect). Replace version numbers with the latest version regularly.", + "resolution": "To enable automatic security definition updates, on the failing device, select System Preferences > Software Update > Advanced > Turn on Install system data files and security updates.", + "tags": [ + "compliance", + "malware", + "hardening", + "built-in", + "template" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "antivirus-healthy-mac-os", + "requiresMdm": false + }, + { + "name": "Antivirus healthy (Windows)", + "query": "SELECT 1 from windows_security_center wsc CROSS JOIN windows_security_products wsp WHERE antivirus = 'Good' AND type = 'Antivirus' AND signatures_up_to_date=1;", + "description": "Checks the status of antivirus and signature updates from the Windows Security Center.", + "resolution": "Ensure Windows Defender or your third-party antivirus is running, up to date, and visible in the Windows Security Center.", + "tags": [ + "compliance", + "malware", + "hardening", + "built-in" + ], + "platform": "windows", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "antivirus-healthy-windows", + "requiresMdm": false + }, + { + "name": "Antivirus healthy (Linux)", + "query": "SELECT score FROM (SELECT case when COUNT(*) = 2 then 1 ELSE 0 END AS score FROM processes WHERE (name = 'clamd') OR (name = 'freshclam')) WHERE score == 1;", + "description": "Checks that both ClamAV's daemon and its updater service (freshclam) are running.", + "resolution": "Ensure ClamAV and Freshclam are installed and running.", + "tags": [ + "compliance", + "malware", + "hardening", + "built-in" + ], + "platform": "linux", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "antivirus-healthy-linux", + "requiresMdm": false + }, + { + "name": "MDM enrolled (macOS)", + "query": "SELECT 1 from mdm WHERE enrolled='true';", + "description": "Required: osquery deployed with Orbit, or manual installation of macadmins/osquery-extension. Checks that a mac is enrolled to MDM. Add a AND on identity_certificate_uuid to check for a specific MDM.", + "resolution": "Enroll device to MDM", + "tags": [ + "compliance", + "hardening", + "built-in" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "mdm-enrolled-mac-os", + "requiresMdm": false, + "critical": true + }, + { + "name": "Docker application is up to date or not present (macOS)", + "query": "SELECT 1 WHERE EXISTS (SELECT 1 FROM apps a1 WHERE a1.bundle_identifier = 'com.electron.dockerdesktop' AND a1.bundle_short_version>='4.6.1') OR NOT EXISTS (SELECT 1 FROM apps a2 WHERE a2.bundle_identifier = 'com.electron.dockerdesktop');", + "description": "Checks if the application (Docker Desktop example) is installed and up to date, or not installed. Fails if the application is installed and on a lower version. You can copy this query and replace the bundle_identifier and bundle_version values to apply the same type of policy to other applications.", + "resolution": "Update Docker or remove it if not used.", + "tags": [ + "inventory", + "vulnerability", + "built-in" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "docker-application-is-up-to-date-or-not-present-mac-os", + "requiresMdm": false + }, + { + "name": "SSH keys encrypted", + "query": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM users CROSS JOIN user_ssh_keys USING (uid) WHERE encrypted='0');", + "description": "Required: osquery must have Full Disk Access. Policy passes if all keys are encrypted, including if no keys are present.", + "resolution": "Use this command to encrypt existing SSH keys by providing the path to the file: ssh-keygen -o -p -f /path/to/file", + "tags": [ + "compliance", + "ssh", + "built-in" + ], + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "platform": "darwin,linux,windows", + "kind": "policy", + "slug": "ssh-keys-encrypted", + "requiresMdm": false + }, + { + "name": "Suspicious autostart (Windows)", + "query": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM startup_items WHERE path = \"regsvr32\" AND args LIKE \"%http%\");", + "description": "Checks for an autostart that is attempting to load a dynamic link library (DLL) from the internet.", + "resolution": "Remove the suspicious startup entry.", + "tags": [ + "malware", + "hunting" + ], + "platform": "windows", + "contributors": [ + { + "name": "kswagler-rh", + "handle": "kswagler-rh", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/kswagler-rh" + } + ], + "kind": "policy", + "slug": "suspicious-autostart-windows", + "requiresMdm": false + }, + { + "name": "Firewall enabled (macOS)", + "query": "SELECT 1 FROM alf WHERE global_state >= 1;", + "description": "Checks if the firewall is enabled.", + "resolution": "In System Preferences, open Security & Privacy, navigate to the Firewall tab and click Turn On Firewall.", + "tags": [ + "hardening", + "compliance", + "built-in", + "cis", + "cis2.5.2.2" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "firewall-enabled-mac-os", + "requiresMdm": false + }, + { + "name": "Screen lock enabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE name='askForPassword' AND value='1';", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to enable screen lock.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables screen lock.", + "tags": [ + "compliance", + "hardening", + "built-in" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "screen-lock-enabled-mac-os", + "requiresMdm": true + }, + { + "name": "Screen lock enabled (Windows)", + "query": "SELECT 1 FROM registry WHERE path = 'HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\InactivityTimeoutSecs' AND CAST(data as INTEGER) <= 1800;", + "description": "Checks if the screen lock is enabled and configured to lock the system within 30 minutes or less.", + "resolution": "Contact your IT administrator to enable the Interactive Logon: Machine inactivity limit setting with a value of 1800 seconds or lower.", + "tags": [ + "compliance", + "hardening", + "built-in" + ], + "platform": "windows", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "screen-lock-enabled-windows", + "requiresMdm": false + }, + { + "name": "Password requires 10 or more characters (macOS)", + "query": "SELECT 1 FROM (SELECT cast(lengthtxt as integer(2)) minlength FROM (SELECT SUBSTRING(length, 1, 2) AS lengthtxt FROM (SELECT policy_description, policy_identifier, split(policy_content, '{', 1) AS length FROM password_policy WHERE policy_identifier LIKE '%minLength')) WHERE minlength >= 10);", + "description": "Checks that the password policy requires at least 10 characters. Requires osquery 5.4.0 or newer.", + "resolution": "Contact your IT administrator to make sure your Mac is receiving configuration profiles for password length.", + "platform": "darwin", + "tags": [ + "compliance", + "hardening", + "built-in", + "cis", + "cis5.2.2" + ], + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "password-requires-10-or-more-characters-mac-os", + "requiresMdm": false + }, + { + "name": "Operating system up to date (macOS)", + "query": "SELECT 1 FROM os_version WHERE version >= '14.1.1';", + "description": "Checks that the operating system is up to date.", + "resolution": "From the Apple menu () in the corner of your screen choose System Preferences. Then select Software Update and select Upgrade Now. You might be asked to restart or enter your password.", + "tags": [ + "compliance", + "cis", + "template", + "cis1.1" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "operating-system-up-to-date-mac-os", + "requiresMdm": false, + "critical": true + }, + { + "name": "Automatic updates enabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.SoftwareUpdate' AND name='AutomaticCheckEnabled' AND value=1 LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to automatically check for updates.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables automatic updates.", + "tags": [ + "compliance", + "cis", + "cis1.2" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "automatic-updates-enabled-mac-os", + "requiresMdm": true + }, + { + "name": "Automatic update downloads enabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.SoftwareUpdate' AND name='AutomaticDownload' AND value=1 LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to automatically download updates.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables automatic update downloads.", + "tags": [ + "compliance", + "cis", + "cis1.3" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "automatic-update-downloads-enabled-mac-os", + "requiresMdm": true + }, + { + "name": "Automatic installation of application updates is enabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.SoftwareUpdate' AND name='AutomaticallyInstallAppUpdates' AND value=1 LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to automatically install updates to App Store applications.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables automatic installation of application updates.", + "tags": [ + "compliance", + "cis", + "cis1.4" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "automatic-installation-of-application-updates-is-enabled-mac-os", + "requiresMdm": true + }, + { + "name": "Automatic security and data file updates is enabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.SoftwareUpdate' AND name='CriticalUpdateInstall' AND value=1 LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to automatically download updates to built-in macOS security tools such as malware removal tools.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables automatic security and data update installation.", + "tags": [ + "compliance", + "cis", + "cis1.5" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "automatic-security-and-data-file-updates-is-enabled-mac-os", + "requiresMdm": true + }, + { + "name": "Automatic installation of operating system updates is enabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.SoftwareUpdate' AND name='AutomaticallyInstallMacOSUpdates' AND value=1 LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to automatically install operating system updates.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables automatic installation of operating system updates.", + "tags": [ + "compliance", + "cis", + "cis1.6" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "automatic-installation-of-operating-system-updates-is-enabled-mac-os", + "requiresMdm": true + }, + { + "name": "Time and date are configured to be updated automatically (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.applicationaccess' AND name='forceAutomaticDateAndTime' AND value=1 LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to automatically update the time and date.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables automatic time and date configuration.", + "tags": [ + "compliance", + "cis", + "cis2.2.1" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "time-and-date-are-configured-to-be-updated-automatically-mac-os", + "requiresMdm": true + }, + { + "name": "Lock screen after inactivity of 20 minutes or less (macOS)", + "query": "SELECT 1 WHERE EXISTS (SELECT CAST(value as integer(4)) valueint from managed_policies WHERE domain = 'com.apple.screensaver' AND name = 'askForPasswordDelay' AND valueint <= 60 LIMIT 1) AND EXISTS (SELECT CAST(value as integer(4)) valueint from managed_policies WHERE domain = 'com.apple.screensaver' AND name = 'idleTime' AND valueint <= 1140 LIMIT 1) AND EXISTS (SELECT 1 from managed_policies WHERE domain='com.apple.screensaver' AND name='askForPassword' AND value=1 LIMIT 1);", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to lock the screen after 20 minutes or less.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables the screen saver after inactivity of 20 minutes or less.", + "tags": [ + "compliance", + "cis", + "cis2.3.1", + "cis5.8" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "lock-screen-after-inactivity-of-20-minutes-or-less-mac-os", + "requiresMdm": true + }, + { + "name": "Internet sharing is blocked (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.MCX' AND name='forceInternetSharingOff' AND value='1' LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to prevent Internet sharing.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that prevents Internet sharing.", + "tags": [ + "compliance", + "cis", + "cis2.4.2" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "internet-sharing-is-blocked-mac-os", + "requiresMdm": true + }, + { + "name": "Content caching is disabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.applicationaccess' AND name='allowContentCaching' AND value='0' LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to disable content caching.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that disables content caching.", + "tags": [ + "compliance", + "cis", + "cis2.4.10" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "content-caching-is-disabled-mac-os", + "requiresMdm": true + }, + { + "name": "Ad tracking is limited (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.AdLib' AND name='forceLimitAdTracking' AND value='1' LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to limit advertisement tracking.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that disables advertisement tracking.", + "tags": [ + "compliance", + "cis", + "cis2.5.6" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "ad-tracking-is-limited-mac-os", + "requiresMdm": true + }, + { + "name": "iCloud Desktop and Document sync is disabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.icloud.managed' AND name='DisableCloudSync' AND value='1' LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to prevent iCloud Desktop and Documents sync.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile to prevent iCloud Desktop and Documents sync.", + "tags": [ + "compliance", + "cis", + "cis2.6.1.4" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "i-cloud-desktop-and-document-sync-is-disabled-mac-os", + "requiresMdm": true + }, + { + "name": "Firewall logging is enabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.security.firewall' AND name='EnableLogging' AND value='1' LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to log firewall activity.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that enables firewall logging.", + "tags": [ + "compliance", + "cis", + "cis3.6" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "firewall-logging-is-enabled-mac-os", + "requiresMdm": true + }, + { + "name": "Guest account disabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.loginwindow' AND name='DisableGuestAccount' AND value='1' LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to prevent the use of a guest account.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that disables the guest account.", + "tags": [ + "compliance", + "cis", + "cis6.1.3" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "guest-account-disabled-mac-os", + "requiresMdm": true + }, + { + "name": "Guest access to shared folders is disabled (macOS)", + "query": "SELECT 1 FROM managed_policies WHERE domain='com.apple.AppleFileServer' AND name='guestAccess' AND value='0' LIMIT 1;", + "description": "Checks that a mobile device management (MDM) solution configures the Mac to prevent guest access to shared folders.", + "resolution": "Contact your IT administrator to ensure your Mac is receiving a profile that prevents guest access to shared folders.", + "tags": [ + "compliance", + "cis", + "cis6.1.4" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "guest-access-to-shared-folders-is-disabled-mac-os", + "requiresMdm": true + }, + { + "name": "No 1Password emergency kit stored in desktop, documents, or downloads folders (macOS)", + "query": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM file WHERE filename LIKE '%Emergency Kit%.pdf' AND (path LIKE '/Users/%/Desktop/%' OR path LIKE '/Users/%/Documents/%' OR path LIKE '/Users/%/Downloads/%' OR path LIKE '/Users/Shared/%'));", + "description": "Looks for PDF files with file names typically used by 1Password for emergency recovery kits. To protect the performance of your devices, the search is one level deep and limited to the Desktop, Documents, Downloads, and Shared folders.", + "resolution": "Delete 1Password emergency kits from your computer, and empty the trash. 1Password emergency kits should only be printed and stored in a physically secure location.", + "platform": "darwin", + "tags": [ + "compliance", + "built-in" + ], + "contributors": [ + { + "name": "nonpunctual", + "handle": "nonpunctual", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/nonpunctual" + } + ], + "kind": "policy", + "slug": "no-1-password-emergency-kit-stored-in-desktop-documents-or-downloads-folders-mac-os", + "requiresMdm": false + }, + { + "name": "Discover TLS certificates", + "platform": "linux, windows, darwin", + "description": "Retrieves metadata about TLS certificates for servers listening on the local machine. Enables mTLS adoption analysis and cert expiration notifications.", + "query": "SELECT * FROM curl_certificate WHERE hostname IN (SELECT DISTINCT 'localhost:'||port FROM listening_ports WHERE protocol=6 AND address!='127.0.0.1' AND address!='::1');", + "purpose": "Informational", + "tags": [ + "network", + "tls" + ], + "contributors": [ + { + "name": "nabilschear", + "handle": "nabilschear", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/nabilschear" + } + ], + "kind": "query", + "slug": "discover-tls-certificates", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Discover Python Packages from Running Python Interpreters", + "platform": "linux, darwin", + "description": "Attempt to discover Python environments (in cwd, path to the python binary, and process command line) from running python interpreters and collect Python packages from those environments.", + "query": "SELECT * FROM python_packages WHERE directory IN (SELECT DISTINCT directory FROM (SELECT SUBSTR(path,0,INSTR(path,'/bin/'))||'/lib' AS directory FROM processes WHERE path LIKE '%/bin/%' AND path LIKE '%python%' UNION SELECT SUBSTR(cmdline,0,INSTR(cmdline,'/bin/'))||'/lib' AS directory FROM processes WHERE cmdline LIKE '%python%' AND cmdline LIKE '%/bin/%' AND path LIKE '%python%' UNION SELECT cwd||'/lib' AS directory FROM processes WHERE path LIKE '%python%'));", + "purpose": "Informational", + "tags": [ + "compliance", + "hunting" + ], + "contributors": [ + { + "name": "nabilschear", + "handle": "nabilschear", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/nabilschear" + } + ], + "kind": "query", + "slug": "discover-python-packages-from-running-python-interpreters", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Identify the default mail, http and ftp applications", + "platforms": "macOS", + "platform": "darwin", + "description": "Lists the currently enabled applications configured to handle mailto, http and ftp schemes.", + "query": "SELECT * FROM app_schemes WHERE (scheme='mailto' OR scheme='http' OR scheme='ftp') AND enabled='1';", + "purpose": "Informational", + "tags": [ + "compliance", + "hunting" + ], + "contributors": [ + { + "name": "brunerd", + "handle": "brunerd", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/brunerd" + } + ], + "kind": "query", + "slug": "identify-the-default-mail-http-and-ftp-applications", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Firewall enabled, domain profile (Windows)", + "query": "SELECT 1 FROM registry WHERE path LIKE 'HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\WindowsFirewall\\DomainProfile\\EnableFirewall' AND CAST(data as integer) = 1;", + "description": "Checks if a Group Policy configures the computer to enable the domain profile for Windows Firewall. The domain profile applies to networks where the host system can authenticate to a domain controller. Some auditors requires that this setting is configured by a Group Policy.", + "resolution": "Contact your IT administrator to ensure your computer is receiving a Group Policy that enables the domain profile for Windows Firewall.", + "platforms": "Windows", + "tags": [ + "compliance", + "cis", + "cis9.1.1" + ], + "platform": "windows", + "contributors": [ + { + "name": "defensivedepth", + "handle": "defensivedepth", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/defensivedepth" + } + ], + "kind": "policy", + "slug": "firewall-enabled-domain-profile-windows", + "requiresMdm": false + }, + { + "name": "Firewall enabled, private profile (Windows)", + "query": "SELECT 1 FROM registry WHERE path LIKE 'HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\WindowsFirewall\\PrivateProfile\\EnableFirewall' AND CAST(data as integer) = 1;", + "description": "Checks if a Group Policy configures the computer to enable the private profile for Windows Firewall. The private profile applies to networks where the host system is connected to a private or home network. Some auditors requires that this setting is configured by a Group Policy.", + "resolution": "Contact your IT administrator to ensure your computer is receiving a Group Policy that enables the private profile for Windows Firewall.", + "platforms": "Windows", + "tags": [ + "compliance", + "cis", + "cis9.2.1" + ], + "platform": "windows", + "contributors": [ + { + "name": "defensivedepth", + "handle": "defensivedepth", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/defensivedepth" + } + ], + "kind": "policy", + "slug": "firewall-enabled-private-profile-windows", + "requiresMdm": false + }, + { + "name": "Firewall enabled, public profile (Windows)", + "query": "SELECT 1 FROM registry WHERE path LIKE 'HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\WindowsFirewall\\PublicProfile\\EnableFirewall' AND CAST(data as integer) = 1;", + "description": "Checks if a Group Policy configures the computer to enable the public profile for Windows Firewall. The public profile applies to networks where the host system is connected to public networks such as Wi-Fi hotspots at coffee shops and airports. Some auditors requires that this setting is configured by a Group Policy.", + "resolution": "Contact your IT administrator to ensure your computer is receiving a Group Policy that enables the public profile for Windows Firewall.", + "platforms": "Windows", + "tags": [ + "compliance", + "cis", + "cis9.3.1" + ], + "platform": "windows", + "contributors": [ + { + "name": "defensivedepth", + "handle": "defensivedepth", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/defensivedepth" + } + ], + "kind": "policy", + "slug": "firewall-enabled-public-profile-windows", + "requiresMdm": false + }, + { + "name": "SMBv1 client driver disabled (Windows)", + "query": "SELECT 1 FROM windows_optional_features WHERE name = 'SMB1Protocol-Client' AND state != 1;", + "description": "Checks that the SMBv1 client is disabled.", + "resolution": "Contact your IT administrator to discuss disabling SMBv1 on your system.", + "platforms": "Windows", + "tags": [ + "compliance", + "cis", + "cis18.3.2", + "built-in" + ], + "platform": "windows", + "contributors": [ + { + "name": "defensivedepth", + "handle": "defensivedepth", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/defensivedepth" + } + ], + "kind": "policy", + "slug": "sm-bv-1-client-driver-disabled-windows", + "requiresMdm": false + }, + { + "name": "SMBv1 server disabled (Windows)", + "query": "SELECT 1 FROM windows_optional_features WHERE name = 'SMB1Protocol-Server' AND state != 1", + "description": "Checks that the SMBv1 server is disabled.", + "resolution": "Contact your IT administrator to discuss disabling SMBv1 on your system.", + "platforms": "Windows", + "tags": [ + "compliance", + "cis", + "cis18.3.3", + "built-in" + ], + "platform": "windows", + "contributors": [ + { + "name": "defensivedepth", + "handle": "defensivedepth", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/defensivedepth" + } + ], + "kind": "policy", + "slug": "sm-bv-1-server-disabled-windows", + "requiresMdm": false + }, + { + "name": "Link-Local Multicast Name Resolution (LLMNR) disabled (Windows)", + "query": "SELECT 1 FROM registry WHERE path LIKE 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\DNSClient\\EnableMulticast' AND CAST(data as integer) = 0;", + "description": "Checks if a Group Policy configures the computer to disable LLMNR. Disabling LLMNR can prevent malicious actors from gaining access to the computer's credentials. Some auditors require that this setting is configured by a Group Policy.", + "resolution": "Contact your IT administrator to ensure your computer is receiving a Group Policy that disables LLMNR on your system.", + "platforms": "Windows", + "tags": [ + "compliance", + "cis", + "cis18.5.4.2" + ], + "platform": "windows", + "contributors": [ + { + "name": "defensivedepth", + "handle": "defensivedepth", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/defensivedepth" + } + ], + "kind": "policy", + "slug": "link-local-multicast-name-resolution-llmnr-disabled-windows", + "requiresMdm": false + }, + { + "name": "Automatic updates enabled (Windows)", + "query": "SELECT 1 FROM registry WHERE path LIKE 'HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU\\NoAutoUpdate' AND CAST(data as integer) = 0;", + "description": "Checks if a Group Policy configures the computer to enable Automatic Updates. When enabled, the computer downloads and installs security and other important updates automatically. Some auditors require that this setting is configured by a Group Policy.", + "resolution": "Contact your IT administrator to ensure your computer is receiving a Group policy that enables Automatic Updates.", + "platforms": "Windows", + "tags": [ + "compliance", + "cis", + "cis18.9.108.2.1" + ], + "platform": "windows", + "contributors": [ + { + "name": "defensivedepth", + "handle": "defensivedepth", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/defensivedepth" + } + ], + "kind": "policy", + "slug": "automatic-updates-enabled-windows", + "requiresMdm": false + }, + { + "name": "Identify Apple development secrets (macOS)", + "query": "SELECT * FROM keychain_items WHERE label LIKE '%ABCDEFG%';", + "description": "Identifies certificates associated with Apple development signing and notarization. Replace ABCDEFG with your company's identifier.", + "resolution": "Ensure your official Apple builds, signing and notarization happen on a centralized system, and remove these certificates from workstations.", + "tags": [ + "compliance", + "inventory", + "built-in" + ], + "platform": "darwin", + "contributors": [ + { + "name": "GuillaumeRoss", + "handle": "GuillaumeRoss", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/GuillaumeRoss" + } + ], + "kind": "policy", + "slug": "identify-apple-development-secrets-mac-os", + "requiresMdm": false + }, + { + "name": "Geolocate via ipapi.co", + "platform": "darwin, linux, windows", + "description": "Geolocate a host using the [ipapi.co](https://ipapi.co) in an emergency. Requires the curl table. [Learn more](https://fleetdm.com/guides/locate-assets-with-osquery).", + "query": "SELECT JSON_EXTRACT(result, '$.ip') AS ip, JSON_EXTRACT(result, '$.city') AS city, JSON_EXTRACT(result, '$.region') AS region, JSON_EXTRACT(result, '$.country') AS country, JSON_EXTRACT(result, '$.latitude') AS latitude, JSON_EXTRACT(result, '$.longitude') AS longitude FROM curl WHERE url = 'http://ipapi.co/json';", + "purpose": "inventory", + "tags": [ + "inventory" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "geolocate-via-ipapi-co", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get Crowdstrike Falcon network content filter status", + "platform": "darwin", + "description": "Get the status of the Crowdstrike Falcon network content filter (as in \"System Settings\" > \"Network > \"Filters\").", + "query": "/* Load up the plist */ WITH extensions_plist AS (SELECT *, rowid FROM plist WHERE path = '/Library/Preferences/com.apple.networkextension.plist') /* Find the first \"Enabled\" key after the key indicating the crowdstrike app */ SELECT value AS enabled FROM extensions_plist WHERE subkey = 'Enabled' AND rowid > (SELECT rowid FROM extensions_plist WHERE value = 'com.crowdstrike.falcon.App') LIMIT 1;", + "purpose": "Informational", + "tags": [ + "crowdstrike", + "plist", + "network", + "content filter" + ], + "contributors": [ + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-crowdstrike-falcon-network-content-filter-status", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "Get a list of Visual Studio Code extensions", + "platform": "darwin, linux, windows", + "description": "Get a list of installed VS Code extensions (requires osquery > 5.11.0).", + "query": "SELECT u.username, vs.* FROM users u CROSS JOIN vscode_extensions vs USING (uid);\n", + "purpose": "Informational", + "tags": [ + "inventory" + ], + "contributors": [ + { + "name": "lucasmrod", + "handle": "lucasmrod", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/lucasmrod" + }, + { + "name": "sharon-fdm", + "handle": "sharon-fdm", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/sharon-fdm" + }, + { + "name": "zwass", + "handle": "zwass", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/zwass" + } + ], + "kind": "query", + "slug": "get-a-list-of-visual-studio-code-extensions", + "resolution": "N/A", + "requiresMdm": false + }, + { + "name": "List osquery table names", + "platform": "darwin, linux, windows", + "description": "List all table names in the schema of the currently installed version of osquery", + "query": "SELECT DISTINCT name FROM osquery_registry;", + "purpose": "Informational", + "tags": [ + "fleet", + "osquery", + "table", + "schema" + ], + "contributors": [ + { + "name": "nonpunctual", + "handle": "nonpunctual", + "avatarUrl": "https://placekitten.com/200/200", + "htmlUrl": "https://github.com/nonpunctual" + } + ], + "kind": "query", + "slug": "list-osquery-table-names", + "resolution": "N/A", + "requiresMdm": false + } + ], + "queryLibraryYmlRepoPath": "docs/01-Using-Fleet/standard-query-library/standard-query-library.yml", + "pricingTable": [ + { + "industryName": "Managed cloud", + "description": "Have Fleet host it for you (currently only available for customers with 700+ hosts. PS. Wish we could host for you? We're working on it! Please let us know if you know of a good partner. In the meantime, join fleetdm.com/support and we're happy to help you deploy Fleet yourself.)", + "pricingTableCategories": [ + "Deployment" + ], + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Managed cloud" + }, + { + "industryName": "Self-hosted", + "friendlyName": "Host it yourself", + "description": "Deploy Fleet anywhere and host it yourself, even in air-gapped environments except where technologically impossible.", + "pricingTableCategories": [ + "Deployment" + ], + "documentationUrl": "https://fleetdm.com/docs/deploy/introduction", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "buzzwords": [ + "Self-hosted" + ], + "name": "Self-hosted" + }, + { + "industryName": "Multi-tenancy", + "description": "For managed service providers to use a single instance of Fleet for multiple customers.", + "documentationUrl": "https://github.com/fleetdm/fleet/issues/9956", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Deployment" + ], + "usualDepartment": "IT", + "buzzwords": [ + "OEM", + "Private label", + "House brand", + "Clear label", + "Multi-tenancy" + ], + "tier": "Premium", + "name": "Multi-tenancy" + }, + { + "industryName": "Deployment tools", + "description": "Pre-built Terraform modules and Helm charts to help you get up and running.", + "documentationUrl": "https://fleetdm.com/docs/deploy/introduction", + "usualDepartment": "IT", + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Deployment" + ], + "name": "Deployment tools" + }, + { + "industryName": "Private update registry", + "friendlyName": "Update agents from a secret URL", + "description": "Load agent code from a secret URL that you manage.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/update-agents", + "tier": "Premium", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Configuration" + ], + "usualDepartment": "Security", + "name": "Private update registry" + }, + { + "industryName": "Control agent versions", + "description": "Manage agents remotely by setting different versions per-baseline.", + "documentationUrl": "https://fleetdm.com/docs/configuration/agent-configuration#configure-fleetd-update-channels", + "tier": "Premium", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Configuration" + ], + "usualDepartment": "IT", + "waysToUse": [ + { + "description": "Supply-chain Levels for Software Artifacts (SLSA) attestations for the fleetd binary artifacts and server container image to enable verification that the binaries are built and uploaded using GitHub Actions from the Fleet repository at a particular commit SHA coming soon (2024-12-31)." + }, + { + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/20219" + } + ], + "name": "Control agent versions" + }, + { + "industryName": "Command line tool (CLI)", + "friendlyName": "fleetctl", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/fleetctl-cli", + "productCategories": [ + "Endpoint operations", + "Device management" + ], + "pricingTableCategories": [ + "Configuration" + ], + "usualDepartment": "IT", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Command line tool (CLI)" + }, + { + "industryName": "GitOps", + "friendlyName": "Manage endpoints in git", + "documentationUrl": "https://github.com/fleetdm/fleet-gitops", + "description": "Fork the best practices GitHub repo and use the included GitHub Actions to quickly automate Fleet console and configuration workflow management.", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Configuration" + ], + "usualDepartment": "IT", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "demos": { + "description": "A top savings and investment company wanted workflows and automation so that one bad actor can't brick their fleet. This way, they have to make a pull request first.", + "quote": "I don't want one bad actor to brick my fleet. I want them to make a pull request first.", + "moreInfoUrl": "https://docs.google.com/document/d/1hAQL6P--Tt3syq1MTRONAxhQA_2Vjt3oOJJt_O4xbiE/edit?disco=AAABAVnYvns&usp_dm=true#heading=h.7en766pueek4" + }, + "name": "GitOps" + }, + { + "industryName": "Two-factor authentication", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/5478", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Configuration" + ], + "usualDepartment": "IT", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "waysToUse": [ + { + "description": "Enforce two-factor authentication when logging in to Fleet for added security." + } + ], + "comingSoonOn": "2024-12-31", + "name": "Two-factor authentication", + "comingSoon": true + }, + { + "industryName": "Role-based access control", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/manage-access#manage-access", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Configuration" + ], + "usualDepartment": "IT", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Role-based access control" + }, + { + "industryName": "Audit logging", + "description": "Log all activity, including queries, scripts, access, etc.", + "documentationUrl": "https://fleetdm.com/docs/rest-api/rest-api#list-activities", + "productCategories": [ + "Endpoint operations", + "Device management" + ], + "pricingTableCategories": [ + "Configuration" + ], + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "usualDepartment": "Security", + "waysToUse": [ + { + "description": "Export activity of Fleet admins to your SIEM or data lake" + } + ], + "name": "Audit logging" + }, + { + "industryName": "Scope transparency", + "description": "Let end users see the source code for exactly how they are being monitored, and set clear expectations about what is and isn’t acceptable use of work computers.", + "tier": "Free", + "documentationUrl": "https://fleetdm.com/transparency", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Configuration" + ], + "name": "Scope transparency" + }, + { + "industryName": "Cross-platform MDM support", + "description": "macOS, Windows, and Linux.", + "documentationUrl": "https://fleetdm.com/announcements/fleet-introduces-windows-mdm", + "tier": "Premium", + "jamfProHasFeature": "appleOnly", + "jamfProtectHasFeature": "no", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "name": "Cross-platform MDM support" + }, + { + "industryName": "MDM migration", + "description": "Easily move your devices from your current MDM solution to Fleet.", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/mdm-migration-guide", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "name": "MDM migration" + }, + { + "industryName": "Zero-touch setup", + "description": "Zero-touch setup for macOS, iOS/iPadOS, and Windows.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/mdm-macos-setup-experience", + "tier": "Premium", + "jamfProHasFeature": "appleOnly", + "jamfProtectHasFeature": "no", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "waysToUse": [ + { + "description": "Ship a macOS, iOS, or iPadOS device to the end user's home and have them automatically enroll to Fleet during out-of-the-box setup." + }, + { + "description": "Ship a Windows workstation to the end user's home and have them automatically enroll to Fleet during out-of-the-box setup." + }, + { + "description": "Customize the out-of-the-box setup experience for your end users." + }, + { + "description": "Install a bootstrap package to run custom scripts during the setup experience. Store the bootstrap package outside the Fleet database coming soon (2024-09-15)", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/19037" + }, + { + "description": "Require end users to authenticate with your identity provider (IdP) and agree to an end user license agreement (EULA) before they can use their new workstation" + } + ], + "name": "Zero-touch setup" + }, + { + "industryName": "Bring your own device (BYOD) enrollment", + "description": "BYOD enrollment for macOS, iOS/iPadOS (coming soon), Windows, and Android (coming soon) devices.", + "documentationUrl": "https://fleetdm.com/guides/sysadmin-diaries-device-enrollment#byod-enrollment", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "waysToUse": [ + { + "description": "Support ACME as a protocol for MDM certificate generation. Coming soon (2024-12-31)", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/15611" + } + ], + "name": "Bring your own device (BYOD) enrollment" + }, + { + "industryName": "User account sync", + "description": "Sync user accounts via Okta, AD, or any IDP.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/mdm-macos-setup-experience", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "IT", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "waysToUse": [ + { + "description": "Automatically set admin access to Fleet based on your IDP" + } + ], + "name": "User account sync" + }, + { + "industryName": "Human-endpoint mapping", + "friendlyName": "See who logs in on every computer", + "description": "Identify who logs in to any system, including login history and current sessions. Look up any host by the email address of the person using it.", + "documentationUrl": "https://fleetdm.com/docs/rest-api/rest-api#get-hosts-google-chrome-profiles", + "screenshotSrc": null, + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "IT", + "buzzwords": [ + "Device users", + "human-to-device mapping" + ], + "dri": "mikermcneil", + "demos": [ + { + "description": "Security engineers at a top gaming company wanted to get demographics off their macOS, Windows, and Linux machines about who the user is and who's logged in.", + "moreInfoUrl": "https://docs.google.com/document/d/1qFYtMoKh3zyERLhbErJOEOo2me6Bc7KOOkjKn482Sqc/edit" + }, + { + "description": "Data engineers at a top biotech corporation needed to know who is logged into their devices.", + "quote": "So we don't know exactly what's going on after we deploy the device, we know that they are compliant with the security because we are running these stuff, but we don't know certainly who is running, who is logging in the device?", + "moreInfoUrl": "https://docs.google.com/document/d/17MNI5ykzlFjdVmQ8SPMrT1oR_hY_vkYAJx31F7l7Pv8/edit#heading=h.7en766pueek4" + } + ], + "waysToUse": [ + { + "description": "Look up computer by ActiveDirectory account" + }, + { + "description": "Find device by Google Chrome user" + }, + { + "description": "Identify who logs in to any system, including login history and current sessions." + }, + { + "description": "Look up any host by the email address of the person using it." + }, + { + "description": "Check user login history", + "moreInfoUrl": "https://www.lepide.com/how-to/audit-who-logged-into-a-computer-and-when.html#:~:text=To%20find%20out%20the%20details,logs%20in%20%E2%80%9CWindows%20Logs%E2%80%9D." + }, + { + "description": "See currently logged in users", + "moreInfoUrl": "https://www.top-password.com/blog/see-currently-logged-in-users-in-windows/" + }, + { + "description": "Get demographics off of our machines about who the user is and who's logged in", + "moreInfoUrl": "https://docs.google.com/document/d/1qFYtMoKh3zyERLhbErJOEOo2me6Bc7KOOkjKn482Sqc/edit" + }, + { + "description": "See what servers someone is logged-in on", + "moreInfoUrl": "https://community.spiceworks.com/topic/138171-is-there-a-way-to-see-what-servers-someone-is-logged-in-on" + } + ], + "name": "Human-endpoint mapping" + }, + { + "industryName": "Device inventory", + "description": "Includes a list of all devices and all hardware and software attributes for each device.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/understanding-host-vitals", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/14415", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "usualDepartment": "IT", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "waysToUse": [ + { + "description": "Implement software inventory recommendations from the SANS 20 / CIS 18.", + "moreInfoUrl": "https://docs.google.com/document/d/1E6EQMMqrsRc6Z3YsR6Q33OaF9eAa8zLNaz4K2YzFdyo/edit#heading=h.7en766pueek4" + }, + { + "description": "View a list of all hardware attributes of a device.", + "moreInfoUrl": "https://fleetdm.com/tables/system_info" + }, + { + "description": "View a list of all software and their versions installed on all your hosts.", + "moreInfoUrl": "https://fleetdm.com/docs/get-started/anatomy#software-library" + }, + { + "description": "View a list of software rolled up by title.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/14674" + }, + { + "description": "Implement hardware and infrastructure inventory recommendations from the SANS 20 / CIS 18.", + "moreInfoUrl": "https://docs.google.com/document/d/1E6EQMMqrsRc6Z3YsR6Q33OaF9eAa8zLNaz4K2YzFdyo/edit#heading=h.7en766pueek4" + } + ], + "name": "Device inventory" + }, + { + "industryName": "Search inventory", + "description": "Search devices by IP, serial, hostname, and UUID.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/learn-how-to-use-fleet#how-to-ask-questions-about-your-device", + "productCategories": [ + "Endpoint operations", + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "IT", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Search inventory" + }, + { + "industryName": "Targeted device scoping", + "description": "Organize devices with Teams and Labels.", + "documentationUrl": "https://fleetdm.com/guides/managing-labels-in-fleet", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "name": "Targeted device scoping" + }, + { + "industryName": "Enforce disk encryption", + "description": "Encrypt system drives on macOS and Windows computers, manage escrowed encryption keys, and report on disk encryption status (FileVault, BitLocker).", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/mdm-disk-encryption", + "friendlyName": "Ensure hard disks are encrypted", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "Security", + "tier": "Premium", + "jamfProHasFeature": "appleOnly", + "jamfProtectHasFeature": "no", + "waysToUse": [ + { + "description": "Report on disk encryption status" + }, + { + "description": "Encrypt hard disks on macOS with FileVault" + }, + { + "description": "Escrow FileVault keys on macOS" + }, + { + "description": "Encrypt hard disks on Windows with BitLocker." + } + ], + "name": "Enforce disk encryption" + }, + { + "industryName": "Enforce operating system (OS) updates", + "description": "Keep operating systems up to date for macOS, iOS/iPadOS, Windows, and Android (coming soon) devices.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/mdm-macos-updates", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "usualDepartment": "IT", + "productCategories": [ + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "waysToUse": [ + { + "description": "Enforce macOS updates via Nudge." + }, + { + "description": "Progressively enhance from Nudge to DDM-based OS updates.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/17295" + }, + { + "description": "Automatically update Windows after the end user reaches a deadline." + } + ], + "name": "Enforce operating system (OS) updates" + }, + { + "industryName": "Enforce OS settings", + "description": "MDM support for macOS, iOS/iPadOS, Windows, and Android (coming soon) devices. Management support for Linux.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/mdm-custom-os-settings", + "usualDepartment": "IT", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "waysToUse": [ + { + "description": "Deploy configuration profiles on macOS and Windows and verify that they're installed.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/13281" + }, + { + "description": "Deploy custom declaration (DDM) profiles on macOS.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/14550" + }, + { + "description": "Target profiles to specific hosts using SQL.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/17315" + }, + { + "description": "Automatically re-deploy configuration profiles when they're not installed." + }, + { + "description": "Deploy configuration profiles on iOS/iPadOS." + }, + { + "description": "See a list of the upcoming MDM commands and scripts in unified queue. Coming soon (2024-07-15)", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/15920" + }, + { + "description": "Send MDM commands to tell end users to update their OS.", + "moreInfoUrl": "https://developer.apple.com/documentation/devicemanagement/schedule_an_os_update" + }, + { + "description": "Configure agent options remotely, over the air. (Includes osquery config, and osquery startup flags.).", + "moreInfoUrl": "https://fleetdm.com/docs/configuration/agent-configuration" + } + ], + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "name": "Enforce OS settings" + }, + { + "industryName": "Declarative Device Management (DDM) support for configuration profiles", + "description": "Full support for Apple DDM configuration profiles.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/mdm-os-updates#macos", + "tier": "Free", + "jamfProHasFeature": "cloudOnly", + "jamfProtectHasFeature": "cloudOnly", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "name": "Declarative Device Management (DDM) support for configuration profiles" + }, + { + "industryName": "Device health", + "friendlyName": "Automate device health", + "description": "Automatically report system health issues using webhooks or integrations, to notify or quarantine outdated or misconfigured systems that are at higher risk of vulnerabilities or theft.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/automations#automations", + "screenshotSrc": null, + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "yes", + "productCategories": [ + "Device management", + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "IT", + "dri": "mikermcneil", + "demos": [ + { + "description": "A large tech company used the Fleet API to block access to corporate apps for outdated operating system versions with certain \"celebrity\" vulnerabilities.", + "quote": null, + "moreInfoUrl": "https://play.goconsensus.com/s4e490bb9" + } + ], + "buzzwords": [ + "Device trust", + "Zero trust", + "Layer 7 device trust", + "Beyondcorp", + "Device attestation", + "Conditional access" + ], + "waysToUse": [ + { + "description": "Automatically manage the behavior of endpoints that are at higher risk of vulnerabilities or data loss due to their configuration or patch level." + }, + { + "description": "Block access to corporate apps for users whose devices with unexpected settings, like disabled screen lock, passwords that are too short, unencrypted hard disks, and more" + }, + { + "description": "Quickly implement conditional access based on device health using osquery and a simple device health REST API.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/14920" + }, + { + "description": "Control and restore access to applications by automatically restricting access when devices do not meet particular security requirements.", + "moreInfoUrl": "https://duo.com/docs/device-health" + }, + { + "description": "Control which laptop and desktop devices can access corporate apps and websites based on what vulnerabilities it might be exposed to based on how the device is configured, whether it's up to date, its MDM enrollment status, and anything else you can build in a SQL query of Fleet's 300 data tables representing information about enrolled host systems. Coming soon (2024-09-30).", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/16236" + }, + { + "description": "Implement multivariate device trust", + "moreInfoUrl": "https://youtu.be/5sFOdpMLXQg?feature=shared&t=1445" + }, + { + "description": "Implement your own version of Google's zero trust model (BeyondCorp)", + "moreInfoUrl": "https://cloud.google.com/beyondcorp" + }, + { + "description": "Get endpoint data into ServiceNow and make your asset management teams happy", + "moreInfoUrl": "https://www.youtube.com/watch?v=aVbU6_9JoM0" + }, + { + "description": "Monitor devices that don't meet your organization's custom security policies" + }, + { + "description": "Quickly report your posture and vulnerabilities to auditors, showing remediation status and timing." + }, + { + "description": "Keep your devices compliant with customizable baselines, or use common benchmarks like CIS." + }, + { + "description": "Discover security misconfigurations that increase attack surface." + }, + { + "description": "Detect suspcious services listening on open ports that should not be connected to the internet, such as Remote Desktop Protocol (RDP).", + "moreInfoUrl": "https://paraflare.com/articles/vulnerability-management-via-osquery/#:~:text=WHERE%20statename%20%3D%20%E2%80%9CEnabled%E2%80%9D-,OPEN%20SOCKETS,-Lastly%2C%20an%20examination" + }, + { + "description": "Discover potentially unwanted programs that increase attack surface.", + "moreInfoUrl": "https://paraflare.com/articles/vulnerability-management-via-osquery/" + }, + { + "description": "Detect self-signed certifcates" + }, + { + "description": "Detect legacy protocols with safer versions", + "moreInfoUrl": "https://paraflare.com/articles/vulnerability-management-via-osquery/#:~:text=WHERE%20self_signed%20%3D%201%3B-,LEGACY%20PROTOCOLS,-This%20section%20will" + }, + { + "description": "Detect exposed secrets on the command line", + "moreInfoUrl": "https://paraflare.com/articles/vulnerability-management-via-osquery/#:~:text=WDigest%20is%20disabled.-,EXPOSED%20SECRETS,-Often%2C%20to%20create" + }, + { + "description": "Detect and surface issues with devices" + }, + { + "description": "Share device health reports" + }, + { + "description": "Align endpoints with your security policies", + "moreInfoUrl": "https://www.axonius.com/use-cases/cmdb-reconciliation" + }, + { + "description": "Maximize security control coverage" + }, + { + "description": "Uncover gaps in security policies, configurations, and hygiene", + "moreInfoUrl": "https://www.axonius.com/use-cases/coverage-gap-discovery" + }, + { + "description": "Automatically apply security policies to protect endpoints against attack." + }, + { + "description": "Surface security issues in all your deployed endpoints even data centers and factories." + }, + { + "description": "Continually validate controls and policies" + }, + { + "description": "Block access to corporate apps if your end users are failing a specific number of critical policies.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/16206" + } + ], + "name": "Device health" + }, + { + "industryName": "Application deployment", + "description": "Deploy applications and security agents on macOS, iOS/iPadOS, Linux, Windows, and Android (coming soon) devices. Additionally, install macOS and iOS/iPadOS apps from the App Store (coming soon).", + "tier": "Premium", + "jamfProHasFeature": "appleOnly", + "jamfProtectHasFeature": "no", + "isExperimental": "yes", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/18867", + "waysToUse": [ + { + "description": "Easily configure and install SentinelOne, Crowdstrike, and other security tools.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/14921" + }, + { + "description": "Offer licenses for Photoshop and other App Sore apps for your end users." + }, + { + "description": "iOS/iPadOS coming soon (2024-08-11).", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/14899" + } + ], + "name": "Application deployment" + }, + { + "industryName": "Self-service application installation", + "description": "Allow end users to install apps through Fleet Desktop for macOS, Linux, and Windows.", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "isExperimental": "yes", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/17587", + "waysToUse": [ + { + "description": "Build scripts for Ansible deployments", + "moreInfoUrl": "https://www.youtube.com/watch?v=qflUfLQCnwY&list=PL6-FgoWOoK2YUR4ADGsxTSL3onb-GzCnM&index=4" + }, + { + "description": "Deploy osquery to macOS via Jamf", + "moreInfoUrl": "https://www.youtube.com/watch?v=qflUfLQCnwY&list=PL6-FgoWOoK2YUR4ADGsxTSL3onb-GzCnM&index=4" + }, + { + "description": "Package osquery for Linux servers via Workspace One and Windows servers via group policies", + "moreInfoUrl": "https://www.youtube.com/watch?v=qflUfLQCnwY&list=PL6-FgoWOoK2YUR4ADGsxTSL3onb-GzCnM&index=4" + } + ], + "name": "Self-service application installation" + }, + { + "industryName": "Application management", + "description": "Manage updates and patches for apps on macOS, Windows, and Linux computers.", + "tier": "Premium", + "jamfProHasFeature": "appleOnly", + "jamfProtectHasFeature": "no", + "comingSoonOn": "2024-08-25", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/18865", + "name": "Application management", + "comingSoon": true + }, + { + "industryName": "Script execution", + "friendlyName": "Safely execute custom scripts (macOS, Windows, and Linux)", + "description": "Deploy and execute custom scripts using a REST API, and manage your library of scripts in the UI or a git repo.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/scripts", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "dri": "mikermcneil", + "usualDepartment": "IT", + "productCategories": [ + "Endpoint operations", + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "demos": [ + { + "description": "A large tech company used scripts to fix issues with their security and compliance agents on workstations." + } + ], + "buzzwords": [ + "Remote script execution", + "PowerShell scripts", + "Bash scripts" + ], + "waysToUse": [ + { + "description": "Execute custom macOS scripts (client platform engineering)", + "moreInfoUrl": "https://www.hexnode.com/blogs/executing-custom-mac-scripts-via-mdm/" + }, + { + "description": "Execute custom Windows scripts (client platform engineering)", + "moreInfoUrl": "https://www.hexnode.com/blogs/executing-custom-windows-scripts-via-mdm/" + }, + { + "description": "Use PowerShell scripts on Windows devices", + "moreInfoUrl": "https://learn.microsoft.com/en-us/mem/intune/apps/intune-management-extension" + }, + { + "description": "Run PowerShell scripts for remediations (security engineering)", + "moreInfoUrl": "https://learn.microsoft.com/en-us/mem/intune/fundamentals/powershell-scripts-remediation" + }, + { + "description": "Download and run remediation scripts", + "moreInfoUrl": "https://help.zscaler.com/deception/downloading-and-running-remediation-script" + }, + { + "description": "Deploy custom scripts", + "moreInfoUrl": "https://scalefusion.com/custom-scripting" + }, + { + "description": "Run scripts on online/offline hosts", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/15529" + }, + { + "description": "Only maintainers and admins can run scripts.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/19055" + } + ], + "name": "Script execution" + }, + { + "industryName": "Device remediation", + "description": "Use Fleet Policies to detect the device state. Automate remediations for issues or allow users to remediate problems in self-service.", + "documentationUrl": "https://fleetdm.com/securing/end-user-self-remediation", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "usualDepartment": "IT", + "productCategories": [ + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "waysToUse": [ + { + "description": "Send software vulnerability emails to end users to encourage self-remediation." + } + ], + "name": "Device remediation" + }, + { + "industryName": "Maintenance windows", + "friendlyName": "Fleet in your calendar", + "description": "Create a calendar event to auto-remediate failing policies when your end users are free.", + "documentationUrl": "https://github.com/fleetdm/fleet/issues/17230", + "tier": "Premium", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "isExperimental": "yes", + "productCategories": [ + "Device management", + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "name": "Maintenance windows" + }, + { + "industryName": "Send lock and wipe commands", + "description": "Secure your devices with remote lock and wipe commands if lost or stolen.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/mdm-commands", + "waysToUse": [ + { + "description": "High-level remote lock for macOS, Windows, and Linux.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/9949" + }, + { + "description": "High-level remote wipe for macOS, Windows, and Linux.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/9951" + } + ], + "tier": "Premium", + "jamfProHasFeature": "appleOnly", + "jamfProtectHasFeature": "no", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Devices" + ], + "name": "Send lock and wipe commands" + }, + { + "industryName": "Queries", + "description": "Scheduled or saved queries with optional AI-generated descriptions, and, live queries for real-time data collection.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/fleet-ui", + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "IT", + "demos": [ + { + "description": "A top financial services company needed to set up rolling deployments for changes to osquery agents running on their production servers.", + "moreInfoUrl": "https://docs.google.com/document/d/1UdzZMyBLbs9SUXfSXN2x2wZQCbjZZUetYlNWH6-ryqQ/edit#heading=h.2lh6ehprpvl6" + } + ], + "name": "Queries" + }, + { + "industryName": "Query performance monitoring", + "documentationUrl": "https://fleetdm.com/docs/get-started/faq#will-fleet-slow-down-my-servers-what-about-my-employee-laptops", + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "demos": [ + { + "description": "A top software company needed to understand the performance impact of osquery queries before running them on all of their production Linux servers.", + "moreInfoUrl": "https://docs.google.com/document/d/1WzMc8GJCRU6tTBb6gLsSTzFysqtXO8CtP2sXMPKgYSk/edit?disco=AAAA6xuVxGg" + }, + { + "description": "A top software company wanted to detect regressions when adding/changing queries and fail builds if queries were too expensive.", + "moreInfoUrl": "https://docs.google.com/document/d/1WzMc8GJCRU6tTBb6gLsSTzFysqtXO8CtP2sXMPKgYSk/edit?disco=AAAA6xuVxGg" + } + ], + "waysToUse": [ + { + "description": "Monitor performance for automated queries." + }, + { + "description": "Monitor performance for live queries.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/467" + } + ], + "name": "Query performance monitoring" + }, + { + "industryName": "Custom tables", + "friendlyName": "Add tables to osquery with extensions", + "description": "Create your own osquery tables, extensions & automatic table configurations or disable existing tables to maintain PII or privacy.", + "documentationUrl": "https://fleetdm.com/docs/configuration/agent-configuration#extensions", + "moreInfoUrl": "https://github.com/trailofbits/osquery-extensions/blob/3df2b72ad78549e25344c79dbc9bce6808c4d92a/README.md#extensions", + "tier": "Premium", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "IT", + "name": "Custom tables" + }, + { + "industryName": "Remote settings", + "description": "Configure agent options remotely, over the air. (Includes osquery config, and osquery startup flags.).", + "documentationUrl": "https://fleetdm.com/docs/configuration/agent-configuration", + "moreInfoUrl": "https://github.com/fleetdm/fleet/issues/13825", + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "Security", + "name": "Remote settings" + }, + { + "industryName": "Teams", + "friendlyName": "Manage different endpoints differently", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/segment-hosts", + "description": "Teams are what Fleet calls baselines, kinda like security groups or images. Every host in a team matches the same baseline, with minor exceptions. This makes it faster and less risky to maintain computers, leading to faster timelines and fewer tickets.", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "waysToUse": [ + { + "description": "Automate remediation for different applications with different security postures (cloud security engineering)" + } + ], + "name": "Teams" + }, + { + "industryName": "Labels", + "documentationUrl": "https://fleetdm.com/docs/rest-api/rest-api#add-label", + "friendlyName": "Filter hosts using SQL", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "IT", + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "name": "Labels" + }, + { + "industryName": "Policies", + "description": "A policy is a specific “yes” or “no” query. Use policies to manage security compliance in your organization.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/fleet-ui", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "IT", + "demos": [ + { + "description": "A top financial services company needed to set up rolling deployments for changes to osquery agents running on their production servers.", + "moreInfoUrl": "https://docs.google.com/document/d/1UdzZMyBLbs9SUXfSXN2x2wZQCbjZZUetYlNWH6-ryqQ/edit#heading=h.2lh6ehprpvl6" + } + ], + "waysToUse": [ + { + "description": "Trigger a workflow based on a failing policy", + "moreInfoUrl": "https://fleetdm.com/docs/using-fleet/automations#policy-automations" + } + ], + "name": "Policies" + }, + { + "industryName": "File integrity monitoring (FIM)", + "friendlyName": "Detect changes to critical files", + "description": "Specify files to monitor for changes or deletions, then log those events to your SIEM or data lake, including key information such as filepath and checksum.", + "documentationUrl": "https://fleetdm.com/guides/osquery-evented-tables-overview#file-integrity-monitoring-fim", + "screenshotSrc": "", + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "yes", + "usualDepartment": "Security", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "dri": "mikermcneil", + "demos": [ + { + "description": "A top gaming company needed a way to monitor critical files on production Debian servers.", + "quote": "The FIM features are kind of a top priority.", + "moreInfoUrl": "https://docs.google.com/document/d/1pE9U-1E4YDiy6h4TorszrTOiFAauFiORikSUFUqW7Pk/edit" + } + ], + "buzzwords": [ + "File integrity monitoring (FIM)", + "Host-based intrusion detection system (HIDS)", + "Anomaly detection" + ], + "waysToUse": [ + { + "description": "Monitor critical files on production Debian servers" + }, + { + "description": "Detect anomalous filesystem activity", + "moreInfoUrl": "https://www.beyondtrust.com/resources/glossary/file-integrity-monitoring" + }, + { + "description": "Detect unintended changes", + "moreInfoUrl": "https://www.beyondtrust.com/resources/glossary/file-integrity-monitoring" + }, + { + "description": "Verify update status and monitor system health", + "moreInfoUrl": "https://www.beyondtrust.com/resources/glossary/file-integrity-monitoring" + }, + { + "description": "Meet compliance mandates", + "moreInfoUrl": "https://www.beyondtrust.com/resources/glossary/file-integrity-monitoring" + } + ], + "name": "File integrity monitoring (FIM)" + }, + { + "industryName": "File carving", + "description": "Write the results of complex queries to AWS S3.", + "documentationUrl": "https://fleetdm.com/docs/configuration/fleet-server-configuration#s-3-file-carving-backend", + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "usualDepartment": "Security", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "name": "File carving" + }, + { + "industryName": "Binary authorization", + "friendlyName": "Restrict what programs can run, and what files running programs can access.", + "description": null, + "documentationUrl": null, + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "dri": "mikermcneil", + "usualDepartment": "Security", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "comingSoonOn": "2025-06-30", + "buzzwords": [ + "Mandatory Access Control (MAC)", + "Privilege confinement", + "Binary authorization", + "Santa", + "Binary allowlisting", + "Binary whitelisting" + ], + "demos": [ + { + "description": null, + "moreInfoUrl": null + } + ], + "waysToUse": [ + { + "description": "Confine programs to a limited set of resources." + }, + { + "description": "Report on AppArmor events", + "moreInfoUrl": "https://fleetdm.com/tables/apparmor_events" + }, + { + "description": "Confine programs according to a set of rules that specify which files a program can access.", + "moreInfoUrl": "https://wiki.debian.org/AppArmor" + }, + { + "description": "Proactively protect the system against both known and unknown vulnerabilities." + } + ], + "name": "Binary authorization", + "comingSoon": true + }, + { + "industryName": "Reporting", + "description": "Generate reports based on searchable device attributes", + "documentationUrl": "https://fleetdm.com/docs/rest-api/rest-api#get-query-report", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "IT", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Reporting" + }, + { + "industryName": "Incident response", + "friendlyName": "Interrogate hosts in real time", + "description": "Live query, triage, figuring out scope of impact, remediate using scripts or MDM commands (e.g. remote wipe), and quarantine or reimage using other systems and APIs (e.g. remove from network, decommission container)", + "documentationUrl": "https://fleetdm.com/securing/how-osquery-can-help-cyber-responders#simplifying-endpoint-visibility-with-osquery-and-fleet", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "dri": "mikermcneil", + "usualDepartment": "Security", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "buzzwords": [], + "demos": [ + { + "description": null, + "moreInfoUrl": null + } + ], + "waysToUse": [ + { + "description": null + } + ], + "name": "Incident response" + }, + { + "industryName": "Custom logging", + "description": "Flexible, configurable logging destinations (AWS Kinesis, Lambda, GCP, Kafka).", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/log-destinations#log-destinations", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "usualDepartment": "Security", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Devices" + ], + "buzzwords": [ + "Real-time export", + "Ship logs" + ], + "name": "Custom logging" + }, + { + "industryName": "Malware detection (YARA/custom IoCs)", + "friendlyName": "Scan files for zero days and malware signatures", + "description": "Use YARA signatures to report and trigger automations when zero days, malware, or unexpected files are detected on a host.", + "documentationUrl": "https://fleetdm.com/tables/yara", + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "yes", + "dri": "mikermcneil", + "usualDepartment": "Security", + "productCategories": [ + "Endpoint operations", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "buzzwords": [ + "YARA scanning", + "Cyber Threat Intelligence (CTI)", + "Indicators of compromise (IOCs)", + "Antivirus (AV)", + "Endpoint protection platform (EPP)", + "Endpoint detection and response (EDR)", + "Malware detection", + "Signature-based malware detection", + "Malware scanning", + "Malware analysis", + "Anomaly detection" + ], + "demos": [ + { + "description": "A top media company used Fleet policies with YARA rules to continuously scan host filesystems for malware signatures provided by internal and external threat intelligence teams.", + "moreInfoUrl": null + } + ], + "waysToUse": [ + { + "description": "Detect suspicious bytecode in JAR files" + }, + { + "description": "Identify suspicious patterns in binaries using YARA signatures" + }, + { + "description": "Continuously scan host filesystems for malware signatures.", + "moreInfoUrl": "https://yara.readthedocs.io/en/stable/writingrules.html" + }, + { + "description": "Monitor for relevent filesystem changes (YARA events) and on-demand YARA signature scans.", + "moreInfoUrl": "https://osquery.readthedocs.io/en/stable/deployment/yara/" + }, + { + "description": "Use YARA for malware detection", + "moreInfoUrl": "https://www.cisa.gov/sites/default/files/FactSheets/NCCIC%20ICS_FactSheet_YARA_S508C.pdf" + }, + { + "description": "Scan for indicators of compromise (IoC) for common malware.", + "moreInfoUrl": "https://github.com/Cisco-Talos/osquery_queries" + }, + { + "description": "Analyze malware using data from osquery, such as endpoint certificates and launch daemons (launchd).", + "moreInfoUrl": "https://medium.com/hackernoon/malware-analysis-using-osquery-part-3-9dc805b67d16" + }, + { + "description": "Detect persistent malware (e.g. WireLurker) in endpoints by generating simple policies that search for their static indicators of compromise (IoCs).", + "moreInfoUrl": "https://osquery.readthedocs.io/en/stable/deployment/anomaly-detection/" + }, + { + "description": "Run a targeted YARA scan with osquery as a lightweight approach to scan anything on a host filesystem, with minimal performance impact. Unlike full system YARA scans which consume considerable CPU resources, an equivalent YARA scan targeted in Fleet can be 8x cheaper (CPU %).", + "moreInfoUrl": "https://www.tripwire.com/state-of-security/signature-socket-based-malware-detection-osquery-yara" + } + ], + "name": "Malware detection (YARA/custom IoCs)" + }, + { + "industryName": "Continuous scanning", + "friendlyName": "Detect vulnerable software", + "documentationUrl": "https://fleetdm.com/vulnerability-management", + "productCategories": [ + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "usualDepartment": "Security", + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "yes", + "buzzwords": [ + "Stakeholder-specific vulnerability categorization (SSVC)", + "Continuous scanning", + "Continuous vulnerability scanning", + "Risk-based vulnerability management" + ], + "waysToUse": [ + { + "description": "Use an SSVC decision tree model to prioritize relevant vulnerabilities into four possible decisions: \"Track\", \"Track*\", \"Attend\", and \"Act\".", + "moreInfoUrl": "https://www.cisa.gov/stakeholder-specific-vulnerability-categorization-ssvc" + }, + { + "description": "Balint Fazakas: I think what offers a better use of CVSS if you break it down to vectors. You may find that a DoS (High Availability Impact) not as relevant for you, or equally a vulnerability requiring user interaction has a very low likelihood of exploit in another scenario. If you want to fine tune your SSVC, it worth using the vectors you care about instead of the score itself. But ultimately you would want to read the description of the vulnerabilities to determine the risk they are posing to your environment. SSVC can assist you to do that in a more efficient way.", + "moreInfoUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7162614115025215488?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A7162614115025215488%2C7162681703918985216%29&dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287162681703918985216%2Curn%3Ali%3Aactivity%3A7162614115025215488%29" + }, + { + "description": "Melissa Bischoping: CVSS is never enough to contextualize the urgency or risk of a vulnerability in your environment. It is one metric that needs to be part of an overall risk calculus, but a CVSS of 6 can be a greater threat in your organization than a CVSS of 10 based on the environmental variables and mitigations. Only two 10.0s here, but several lower severity that are resulting in high-impact breaches. Getting a handle on managing that public facing infrastructure and being able to rapidly patch the apps and devices with such exposure needs to be part of an overall plan, but must go hand in hand with mitigations and layers of a zero trust design. CVSS isn’t the sole determination of risk, it’s only one partial piece of data to understand the impact of a vulnerability if exploited.", + "moreInfoUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7162614115025215488?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A7162614115025215488%2C7162629486344159232%29&dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287162629486344159232%2Curn%3Ali%3Aactivity%3A7162614115025215488%29" + } + ], + "demos": [ + { + "description": "A top gaming company wanted to replace Qualys for infrastructure vulnerability detection.", + "quote": "So we have some stuff today through Qualys, but it's just not very good. A lot of it is...it's just really noisy. I'm trying to find out specifically, actually what packages are installed where, and then the ability to live query them.", + "moreInfoUrl": "https://docs.google.com/document/d/1JWtRsW1FUTCkZEESJj9-CvXjLXK4219by-C6vvVVyBY/edit" + }, + { + "description": "One of the world's largest, top transportation companies uses Fleet's API to email relevant, actually-installed vulnerabilities to responsible teams so they can fix them.", + "moreInfoUrl": "https://docs.google.com/document/d/1oeCmT077o_5nxzLhnxs7kcg_4Qn1Pn1F5zx10nQOAp8/edit" + } + ], + "name": "Continuous scanning" + }, + { + "industryName": "Vulnerability scores", + "friendlyName": "EPSS and CVSS", + "documentationUrl": "https://fleetdm.com/vulnerability-management", + "tier": "Premium", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "yes", + "usualDepartment": "Security", + "productCategories": [ + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "buzzwords": [ + "Risk scores", + "Cyber risk", + "Risk reduction", + "Security operations effectiveness", + "Peer benchmarking", + "Security program effectiveness", + "Risk-based exposure scoring", + "Threat context", + "Cyber exposure", + "Exposure quantification and benchmarking", + "Optimize security investments", + "Vulnerability assessment" + ], + "demos": [ + { + "description": "Fleet enables a more modern, threat-first prioritization approach to vulnerability management.", + "quote": "In reality, across our inventory of devices, it's unlikely to ever be exploited. I'd rather do that legwork on my team and then go and ask and prioritize work on these infrastructure teams that are already busy with things that could or could not be vulnerable. Being able to be more exact allows us to go to these teams less, which saves everybody time.", + "moreInfoUrl": "https://www.youtube.com/watch?v=G5Ry_vQPaYc&t=131s" + } + ], + "waysToUse": [ + { + "description": "By leveraging EPSS (Exploit Prediction Scoring System), security professionals gain insight on the true risk behind rated CVEs." + }, + { + "description": "An Introduction to EPSS, The Exploit Prediction Scoring System" + }, + { + "moreInfoUrl": "https://www.youtube.com/watch?v=vw1RlZCSRcQ" + }, + { + "description": "By extracting metadata from the National Vulnerability Database (NVD) and Microsoft Security Response Center (MSRC), we can determine which version of software is no longer vulnerable." + } + ], + "name": "Vulnerability scores" + }, + { + "industryName": "CISA KEVs", + "description": "Known exploited vulnerabilities", + "documentationUrl": "https://fleetdm.com/vulnerability-management", + "tier": "Premium", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "yes", + "usualDepartment": "Security", + "productCategories": [ + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "demos": [ + { + "description": null, + "moreInfoUrl": null + } + ], + "waysToUse": [ + { + "description": "Help teams work on vulnerabilities that have actually been exploited (CISA KEVs) or have a high probability of being exploited (EPSS), or whatever is important in your environment." + }, + { + "description": "Use CISA KEVs for vulnerability management" + }, + { + "moreInfoUrl": "https://www.youtube.com/watch?v=Z3mw2oxssYk" + } + ], + "name": "CISA KEVs" + }, + { + "industryName": "Asset discovery", + "documentationUrl": null, + "tier": "Premium", + "comingSoonOn": "2025-06-30", + "usualDepartment": "Security", + "productCategories": [ + "Vulnerability management" + ], + "pricingTableCategories": [ + "Devices" + ], + "name": "Asset discovery", + "comingSoon": true + }, + { + "industryName": "REST API", + "friendlyName": "Automate any feature", + "description": null, + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Integrations" + ], + "usualDepartment": "IT", + "documentationUrl": "https://fleetdm.com/docs/rest-api/rest-api", + "screenshotSrc": null, + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "dri": "rachaelshaw", + "name": "REST API" + }, + { + "industryName": "Webhooks", + "friendlyName": "Automations", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/automations#automations", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Integrations" + ], + "usualDepartment": "IT", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Webhooks" + }, + { + "industryName": "Grant API-only access", + "description": "Grant API-only access to accounts exclusively for automation.", + "documentationUrl": "https://fleetdm.com/docs/using-fleet/fleetctl-cli#using-fleetctl-with-an-api-only-user", + "productCategories": [ + "Endpoint operations" + ], + "pricingTableCategories": [ + "Integrations" + ], + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Grant API-only access" + }, + { + "industryName": "Single sign on", + "description": "SSO, SAML", + "documentationUrl": "https://fleetdm.com/docs/deploy/single-sign-on-sso#single-sign-on-sso", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Integrations" + ], + "usualDepartment": "IT", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Single sign on" + }, + { + "industryName": "Automatic user creation (JIT, SCIM)", + "description": "Auto-create and manipulate Fleet users from Okta, etc with just-in-time (JIT) provisioning.", + "documentationUrl": "https://fleetdm.com/docs/deploy/single-sign-on-sso#just-in-time-jit-user-provisioning", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Integrations" + ], + "usualDepartment": "IT", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "no", + "name": "Automatic user creation (JIT, SCIM)" + }, + { + "industryName": "Third-party automation", + "friendlyName": "Borrow off-the-shelf tactics from the community", + "documentationUrl": "https://fleetdm.com/integrations", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Integrations" + ], + "usualDepartment": "IT", + "description": "Plug Fleet into other frameworks and tools like Tines, Snowflake, Terraform, Chronicle, Jira, Zendesk, etc", + "moreInfoUrl": "https://fleetdm.com/integrations", + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "waysToUse": [ + { + "description": "(ActiveDirectory) Know who opened your computer and check their device posture before you let them log into anything." + }, + { + "description": "(Ansible) Easily issue MDM commands and standardize data across operating systems." + }, + { + "description": "(AWS) Deploy your own self-managed Fleet in any AWS environment in minutes." + }, + { + "description": "(Azure) Deploy your own self-managed Fleet in the Microsoft Cloud in minutes." + }, + { + "description": "(Chef) Easily issue MDM commands and standardize data across operating systems." + }, + { + "description": "(Elastic) Ingest osquery data and monitor for important changes or events." + }, + { + "description": "(GitHub) Version control using git, enabling collaboration and a GitOps workflow." + }, + { + "description": "(GitLab) Version control using git, enabling collaboration and a GitOps workflow." + }, + { + "description": "(Chronicle) Ingest osquery data and monitor for important changes or events." + }, + { + "description": "(Google Cloud) Deploy your own self-managed Fleet in any GCP environment in minutes." + }, + { + "description": "(Munki) Easily issue MDM commands and standardize data across operating systems." + }, + { + "description": "(Okta) Know who opened your computer and check their device posture before you let them log into anything." + }, + { + "description": "(Snowflake) Ingest osquery data and monitor for important changes or events." + }, + { + "description": "(Splunk) Ingest osquery data and monitor for important changes or events." + }, + { + "description": "(Tines) Build custom workflows that trigger in various situations." + }, + { + "description": "(Webhooks) Configure automations that send webhooks to specific URLs when Fleet detects changes to host, policy, and CVE statuses." + }, + { + "description": "(Zendesk) Automatically create Zendesk tickets in various situations." + }, + { + "description": "(Jira) Automatically create Jira tickets in various situations, including exporting vulnerabilities to Jira and syncing tickets." + } + ], + "buzzwords": [ + "Snowflake", + "Okta", + "Tines", + "Splunk", + "Elastic", + "AWS", + "ActiveDirectory", + "Ansible", + "GitHub", + "GitLab", + "Chronicle", + "Google Cloud", + "Munki", + "Vanta", + "Chef", + "Zendesk", + "Jira" + ], + "name": "Third-party automation" + }, + { + "industryName": "Third-party orchestration", + "friendlyName": "Borrow off-the-shelf tactics from legendary brands", + "documentationUrl": "https://fleetdm.com/integrations", + "description": "Plug Fleet into other frameworks and tools like Puppet, Vanta, etc.", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Integrations" + ], + "usualDepartment": "IT", + "moreInfoUrl": "https://fleetdm.com/integrations", + "tier": "Premium", + "waysToUse": [ + { + "description": "(Vanta) Trigger a workflow based on a failing policy." + }, + { + "description": "(Puppet) Easily issue MDM commands, standardize data across operating systems, and map macOS+Windows settings to computers with the Puppet module." + }, + { + "description": "(Torq) Build custom workflows that trigger in various situations." + }, + { + "description": "(Custom IdP) Manage access to Fleet single sign-on (SSO) through any IdP (using SAML)." + } + ], + "buzzwords": [ + "Vanta", + "Puppet", + "Custom IdP" + ], + "name": "Third-party orchestration" + }, + { + "industryName": "Munki compatibility + visibility", + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "usualDepartment": "IT", + "productCategories": [ + "Device management" + ], + "pricingTableCategories": [ + "Integrations" + ], + "name": "Munki compatibility + visibility" + }, + { + "industryName": "Open-source issue tracker (GitHub)", + "documentationUrl": "https://fleetdm.com/support", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Support" + ], + "tier": "Free", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "name": "Open-source issue tracker (GitHub)" + }, + { + "industryName": "Community Slack channel", + "documentationUrl": "https://fleetdm.com/support", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Support" + ], + "tier": "Free", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Community Slack channel" + }, + { + "industryName": "Unlimited email support (confidential)", + "documentationUrl": "https://fleetdm.com/support", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Support" + ], + "tier": "Premium", + "jamfProHasFeature": "yes", + "jamfProtectHasFeature": "yes", + "name": "Unlimited email support (confidential)" + }, + { + "industryName": "Phone and video call support", + "documentationUrl": "https://fleetdm.com/support", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "pricingTableCategories": [ + "Support" + ], + "tier": "Premium", + "jamfProHasFeature": "no", + "jamfProtectHasFeature": "no", + "name": "Phone and video call support" + } + ], + "markdownPages": [ + { + "url": "/docs", + "title": "Readme.md", + "lastModifiedAt": 1726839803427, + "htmlId": "docs--readme--51292620cf", + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "README.md", + "meta": {} + }, + { + "url": "/docs/rest-api/rest-api", + "title": "REST API", + "lastModifiedAt": 1726839804830, + "htmlId": "docs--rest-api--aa8babd202", + "pageOrderInSectionPath": 30, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "REST API/rest-api.md", + "meta": { + "description": "Documentation for Fleet's REST API. See example requests and responses for each API endpoint." + } + }, + { + "url": "/docs/configuration/agent-configuration", + "title": "Agent configuration", + "lastModifiedAt": 1726839804835, + "htmlId": "docs--agent-configuration--ac988306ab", + "pageOrderInSectionPath": 300, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Configuration/agent-configuration.md", + "meta": { + "description": "Learn how to use configuration files and the fleetctl command line tool to configure agent options." + } + }, + { + "url": "/docs/configuration", + "title": "Configuration", + "lastModifiedAt": 1726839804836, + "htmlId": "docs--readme--71f5513034", + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Configuration/README.md", + "meta": {} + }, + { + "url": "/docs/configuration/fleet-server-configuration", + "title": "Fleet server configuration", + "lastModifiedAt": 1726839804850, + "htmlId": "docs--fleet-server-configu--51d934dc8a", + "pageOrderInSectionPath": 100, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Configuration/fleet-server-configuration.md", + "meta": { + "description": "This page includes resources for configuring the Fleet binary, managing osquery configurations, and running with systemd." + } + }, + { + "url": "/docs/configuration/yaml-files", + "title": "YAML files", + "lastModifiedAt": 1726839804856, + "htmlId": "docs--yaml-files--1c08b93d5e", + "pageOrderInSectionPath": 1500, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Configuration/yaml-files.md", + "meta": { + "description": "Reference documentation for Fleet's GitOps workflow. See examples and configuration options." + } + }, + { + "url": "/docs/rest-api", + "title": "REST API", + "lastModifiedAt": 1726839804857, + "htmlId": "docs--readme--1c430dc120", + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "REST API/README.md", + "meta": {} + }, + { + "url": "/docs/deploy/reference-architectures", + "title": "Reference architectures", + "lastModifiedAt": 1726839804860, + "htmlId": "docs--reference-architectu--1e6f63e559", + "pageOrderInSectionPath": 400, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Deploy/Reference-Architectures.md", + "meta": { + "description": "An opinionated view of running Fleet in a production environment, and configuration strategies to enable high availability." + } + }, + { + "url": "/docs/deploy", + "title": "Deploy", + "lastModifiedAt": 1726839804861, + "htmlId": "docs--readme--926e990cf4", + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Deploy/README.md", + "meta": { + "description": "An overview of the deployment documentation for Fleet." + } + }, + { + "url": "/docs/deploy/deploy-fleet", + "title": "Deploy Fleet", + "lastModifiedAt": 1726839804863, + "htmlId": "docs--deploy-fleet--82212f6ffe", + "pageOrderInSectionPath": 100, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Deploy/deploy-fleet.md", + "meta": { + "description": "Learn how to easily deploy Fleet on Render or AWS with Terraform." + } + }, + { + "url": "/docs/deploy/single-sign-on-sso", + "title": "Single sign-on (SSO)", + "lastModifiedAt": 1726839804865, + "htmlId": "docs--single-sign-on-sso--89a4f43390", + "pageOrderInSectionPath": 200, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Deploy/single-sign-on-sso.md", + "meta": { + "description": "Learn how to configure single sign-on (SSO)" + } + }, + { + "url": "/docs/get-started/faq", + "title": "FAQ", + "lastModifiedAt": 1726839804868, + "htmlId": "docs--faq--abab6eff91", + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Get started/FAQ.md", + "meta": { + "description": "Commonly asked questions and answers about deployment from the Fleet community." + } + }, + { + "url": "/docs/get-started", + "title": "Get started", + "lastModifiedAt": 1726839804869, + "htmlId": "docs--readme--3568e93d97", + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Get started/README.md", + "meta": {} + }, + { + "url": "/docs/get-started/anatomy", + "title": "Anatomy", + "lastModifiedAt": 1726839804869, + "htmlId": "docs--anatomy--1f83ca9de5", + "pageOrderInSectionPath": 200, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Get started/anatomy.md", + "meta": {} + }, + { + "url": "/docs/get-started/why-fleet", + "title": "Why Fleet", + "lastModifiedAt": 1726839804870, + "htmlId": "docs--why-fleet--9ea776ea58", + "pageOrderInSectionPath": 100, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Get started/why-fleet.md", + "meta": {} + }, + { + "url": "/docs/deploy/upgrading-fleet", + "title": "Upgrading Fleet", + "lastModifiedAt": 1726839804871, + "htmlId": "docs--upgrading-fleet--a39ae08550", + "pageOrderInSectionPath": 300, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Deploy/Upgrading-Fleet.md", + "meta": { + "description": "Learn how to upgrade your Fleet instance to the latest version." + } + }, + { + "url": "/docs/get-started/tutorials-and-guides", + "title": "Tutorials and guides", + "lastModifiedAt": 1726839804872, + "htmlId": "docs--tutorials-and-guides--27a7cc6bcf", + "pageOrderInSectionPath": 300, + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Get started/tutorials-and-guides.md", + "meta": { + "description": "Links to deployment tutorials and guides for using Fleet." + } + }, + { + "url": "/docs/using-fleet", + "title": "Using Fleet", + "lastModifiedAt": 1726839804873, + "htmlId": "docs--readme--d3ac87c2d1", + "docNavCategory": "Uncategorized", + "sectionRelativeRepoPath": "Using Fleet/README.md", + "meta": {} + }, + { + "url": "/handbook", + "title": "Readme.md", + "lastModifiedAt": 1726839804876, + "htmlId": "handbook--readme--58c6582576", + "sectionRelativeRepoPath": "README.md", + "meta": { + "maintainedBy": "mikermcneil" + }, + "linksForHandbookIndex": [ + { + "headingText": "Introduction", + "hashLink": "/handbook#introduction" + } + ] + }, + { + "url": "/handbook/company", + "title": "🔭 Company", + "lastModifiedAt": 1726839804878, + "htmlId": "handbook--readme--e464663acc", + "sectionRelativeRepoPath": "company/README.md", + "meta": { + "maintainedBy": "mikermcneil" + }, + "linksForHandbookIndex": [ + { + "headingText": "Purpose", + "hashLink": "/handbook/company#purpose" + }, + { + "headingText": "Culture", + "hashLink": "/handbook/company#culture" + }, + { + "headingText": "Open positions", + "hashLink": "/handbook/company#open-positions" + }, + { + "headingText": "Values", + "hashLink": "/handbook/company#values" + }, + { + "headingText": "History", + "hashLink": "/handbook/company#history" + }, + { + "headingText": "Org chart", + "hashLink": "/handbook/company#org-chart" + }, + { + "headingText": "Advisors", + "hashLink": "/handbook/company#advisors" + } + ] + }, + { + "url": "/handbook/company/handbook", + "title": "Handbook", + "lastModifiedAt": 1726839804879, + "htmlId": "handbook--handbook--9ae510ce56", + "sectionRelativeRepoPath": "company/handbook.md", + "meta": { + "maintainedBy": "mike-j-thomas" + }, + "linksForHandbookIndex": [ + { + "headingText": "Contributing to the handbook", + "hashLink": "/handbook/company/handbook#contributing-to-the-handbook" + } + ] + }, + { + "url": "/handbook/company/communications", + "title": "🛰️ Communications", + "lastModifiedAt": 1726839804891, + "htmlId": "handbook--communications--f0d5a4a053", + "sectionRelativeRepoPath": "company/communications.md", + "meta": { + "maintainedBy": "mikermcneil" + }, + "linksForHandbookIndex": [ + { + "headingText": "All hands", + "hashLink": "/handbook/company/communications#all-hands" + }, + { + "headingText": "Strategy", + "hashLink": "/handbook/company/communications#strategy" + }, + { + "headingText": "Directly responsible individuals (DRIs)", + "hashLink": "/handbook/company/communications#directly-responsible-individuals-dr-is" + }, + { + "headingText": "Tech stack admins", + "hashLink": "/handbook/company/communications#tech-stack-admins" + }, + { + "headingText": "Fleetdm.com", + "hashLink": "/handbook/company/communications#fleetdm-com" + }, + { + "headingText": "Marketing programs", + "hashLink": "/handbook/company/communications#marketing-programs" + }, + { + "headingText": "Meetings", + "hashLink": "/handbook/company/communications#meetings" + }, + { + "headingText": "Skip-level 1:1 meetings ", + "hashLink": "/handbook/company/communications#skip-level-1-1-meetings" + }, + { + "headingText": "Zoom", + "hashLink": "/handbook/company/communications#zoom" + }, + { + "headingText": "Levels of confidentiality", + "hashLink": "/handbook/company/communications#levels-of-confidentiality" + }, + { + "headingText": "Google Drive", + "hashLink": "/handbook/company/communications#google-drive" + }, + { + "headingText": "Email relays", + "hashLink": "/handbook/company/communications#email-relays" + }, + { + "headingText": "Slack", + "hashLink": "/handbook/company/communications#slack" + }, + { + "headingText": "GitHub", + "hashLink": "/handbook/company/communications#git-hub" + }, + { + "headingText": "High priority user stories and bugs", + "hashLink": "/handbook/company/communications#high-priority-user-stories-and-bugs" + }, + { + "headingText": "Figma", + "hashLink": "/handbook/company/communications#figma" + }, + { + "headingText": "Spending company money", + "hashLink": "/handbook/company/communications#spending-company-money" + }, + { + "headingText": "Travel", + "hashLink": "/handbook/company/communications#travel" + }, + { + "headingText": "SOC 2", + "hashLink": "/handbook/company/communications#soc-2" + }, + { + "headingText": "Vendor questionnaires ", + "hashLink": "/handbook/company/communications#vendor-questionnaires" + }, + { + "headingText": "Getting a contract signed", + "hashLink": "/handbook/company/communications#getting-a-contract-signed" + }, + { + "headingText": "Getting a contract reviewed", + "hashLink": "/handbook/company/communications#getting-a-contract-reviewed" + }, + { + "headingText": "Trust", + "hashLink": "/handbook/company/communications#trust" + }, + { + "headingText": "Benefits", + "hashLink": "/handbook/company/communications#benefits" + }, + { + "headingText": "Compensation", + "hashLink": "/handbook/company/communications#compensation" + }, + { + "headingText": "Team member onboarding", + "hashLink": "/handbook/company/communications#team-member-onboarding" + }, + { + "headingText": "Performance feedback", + "hashLink": "/handbook/company/communications#performance-feedback" + }, + { + "headingText": "Equipment", + "hashLink": "/handbook/company/communications#equipment" + }, + { + "headingText": "Writing", + "hashLink": "/handbook/company/communications#writing" + }, + { + "headingText": "Writing in Fleet-flavored Markdown", + "hashLink": "/handbook/company/communications#writing-in-fleet-flavored-markdown" + }, + { + "headingText": "Things", + "hashLink": "/handbook/company/communications#things" + }, + { + "headingText": "Commonly used terms", + "hashLink": "/handbook/company/communications#commonly-used-terms" + } + ] + }, + { + "url": "/handbook/company/leadership", + "title": "🛠️ Leadership", + "lastModifiedAt": 1726839804898, + "htmlId": "handbook--leadership--7d8a02ee64", + "sectionRelativeRepoPath": "company/leadership.md", + "meta": { + "maintainedBy": "mikermcneil" + }, + "linksForHandbookIndex": [ + { + "headingText": "CEO flaws", + "hashLink": "/handbook/company/leadership#ceo-flaws" + }, + { + "headingText": "Contact the CEO", + "hashLink": "/handbook/company/leadership#contact-the-ceo" + }, + { + "headingText": "CEO responsibilities", + "hashLink": "/handbook/company/leadership#ceo-responsibilities" + }, + { + "headingText": "Outline of departmental page structure", + "hashLink": "/handbook/company/leadership#outline-of-departmental-page-structure" + }, + { + "headingText": "Key reviews", + "hashLink": "/handbook/company/leadership#key-reviews" + }, + { + "headingText": "Hiring", + "hashLink": "/handbook/company/leadership#hiring" + }, + { + "headingText": "CEO shadow program", + "hashLink": "/handbook/company/leadership#ceo-shadow-program" + }, + { + "headingText": "Tracking hours", + "hashLink": "/handbook/company/leadership#tracking-hours" + }, + { + "headingText": "Communicating departures", + "hashLink": "/handbook/company/leadership#communicating-departures" + }, + { + "headingText": "Changing someone's position", + "hashLink": "/handbook/company/leadership#changing-someone-s-position" + }, + { + "headingText": "Delivering performance feedback", + "hashLink": "/handbook/company/leadership#delivering-performance-feedback" + } + ] + }, + { + "url": "/handbook/company/product-groups", + "title": "🛩️ Product groups", + "lastModifiedAt": 1726839804907, + "htmlId": "handbook--product-groups--44ec471e19", + "sectionRelativeRepoPath": "company/product-groups.md", + "meta": { + "maintainedBy": "lukeheath" + }, + "linksForHandbookIndex": [ + { + "headingText": "Product roadmap", + "hashLink": "/handbook/company/product-groups#product-roadmap" + }, + { + "headingText": "What are product groups?", + "hashLink": "/handbook/company/product-groups#what-are-product-groups" + }, + { + "headingText": "Current product groups", + "hashLink": "/handbook/company/product-groups#current-product-groups" + }, + { + "headingText": "Making changes", + "hashLink": "/handbook/company/product-groups#making-changes" + }, + { + "headingText": "Outages", + "hashLink": "/handbook/company/product-groups#outages" + }, + { + "headingText": "Scaling Fleet", + "hashLink": "/handbook/company/product-groups#scaling-fleet" + }, + { + "headingText": "Load testing", + "hashLink": "/handbook/company/product-groups#load-testing" + }, + { + "headingText": "Version support", + "hashLink": "/handbook/company/product-groups#version-support" + }, + { + "headingText": "Release testing", + "hashLink": "/handbook/company/product-groups#release-testing" + }, + { + "headingText": "Feature fest", + "hashLink": "/handbook/company/product-groups#feature-fest" + }, + { + "headingText": "Quality", + "hashLink": "/handbook/company/product-groups#quality" + }, + { + "headingText": "How to reach the developer on-call", + "hashLink": "/handbook/company/product-groups#how-to-reach-the-developer-on-call" + }, + { + "headingText": "Wireframes", + "hashLink": "/handbook/company/product-groups#wireframes" + }, + { + "headingText": "Meetings", + "hashLink": "/handbook/company/product-groups#meetings" + }, + { + "headingText": "Development best practices", + "hashLink": "/handbook/company/product-groups#development-best-practices" + }, + { + "headingText": "Product design conventions", + "hashLink": "/handbook/company/product-groups#product-design-conventions" + }, + { + "headingText": "Scrum at Fleet", + "hashLink": "/handbook/company/product-groups#scrum-at-fleet" + }, + { + "headingText": "Sprints", + "hashLink": "/handbook/company/product-groups#sprints" + }, + { + "headingText": "Outside contributions", + "hashLink": "/handbook/company/product-groups#outside-contributions" + } + ] + }, + { + "url": "/handbook/company/why-this-way", + "title": "💭 Why this way?", + "lastModifiedAt": 1726839804912, + "htmlId": "handbook--why-this-way--52ff9aa8d3", + "sectionRelativeRepoPath": "company/why-this-way.md", + "meta": { + "maintainedBy": "mikermcneil" + }, + "linksForHandbookIndex": [ + { + "headingText": "Why open source?", + "hashLink": "/handbook/company/why-this-way#why-open-source" + }, + { + "headingText": "Why handbook-first strategy?", + "hashLink": "/handbook/company/why-this-way#why-handbook-first-strategy" + }, + { + "headingText": "Why read documentation?", + "hashLink": "/handbook/company/why-this-way#why-read-documentation" + }, + { + "headingText": "Why the emphasis on training?", + "hashLink": "/handbook/company/why-this-way#why-the-emphasis-on-training" + }, + { + "headingText": "Why direct responsibility?", + "hashLink": "/handbook/company/why-this-way#why-direct-responsibility" + }, + { + "headingText": "Why do we use a wireframe-first approach?", + "hashLink": "/handbook/company/why-this-way#why-do-we-use-a-wireframe-first-approach" + }, + { + "headingText": "Why do we use one repo?", + "hashLink": "/handbook/company/why-this-way#why-do-we-use-one-repo" + }, + { + "headingText": "Why not continuously generate REST API reference docs from javadoc-style code comments?", + "hashLink": "/handbook/company/why-this-way#why-not-continuously-generate-rest-api-reference-docs-from-javadoc-style-code-comments" + }, + { + "headingText": "Why group Slack channels?", + "hashLink": "/handbook/company/why-this-way#why-group-slack-channels" + }, + { + "headingText": "Why make work visible?", + "hashLink": "/handbook/company/why-this-way#why-make-work-visible" + }, + { + "headingText": "Why agile?", + "hashLink": "/handbook/company/why-this-way#why-agile" + }, + { + "headingText": "Why a three-week cadence?", + "hashLink": "/handbook/company/why-this-way#why-a-three-week-cadence" + }, + { + "headingText": "Why spend so much energy responding to every potential production incident?", + "hashLink": "/handbook/company/why-this-way#why-spend-so-much-energy-responding-to-every-potential-production-incident" + }, + { + "headingText": "Why make it obvious when stuff breaks?", + "hashLink": "/handbook/company/why-this-way#why-make-it-obvious-when-stuff-breaks" + }, + { + "headingText": "Why keep issue templates simple?", + "hashLink": "/handbook/company/why-this-way#why-keep-issue-templates-simple" + }, + { + "headingText": "Why spend less?", + "hashLink": "/handbook/company/why-this-way#why-spend-less" + }, + { + "headingText": "Why don't we sell like everyone else?", + "hashLink": "/handbook/company/why-this-way#why-don-t-we-sell-like-everyone-else" + }, + { + "headingText": "Why does Fleet support query packs?", + "hashLink": "/handbook/company/why-this-way#why-does-fleet-support-query-packs" + }, + { + "headingText": "Why does Fleet use sentence case?", + "hashLink": "/handbook/company/why-this-way#why-does-fleet-use-sentence-case" + }, + { + "headingText": "Why not use superlatives?", + "hashLink": "/handbook/company/why-this-way#why-not-use-superlatives" + }, + { + "headingText": "Why does Fleet use \"MDM on/off\" instead of \"MDM enrolled/unenrolled\"?", + "hashLink": "/handbook/company/why-this-way#why-does-fleet-use-mdm-on-off-instead-of-mdm-enrolled-unenrolled" + }, + { + "headingText": "Why not mention the CEO in Slack threads?", + "hashLink": "/handbook/company/why-this-way#why-not-mention-the-ceo-in-slack-threads" + } + ] + }, + { + "url": "/handbook/customer-success", + "title": "🌦️ Customer Success", + "lastModifiedAt": 1726839804915, + "htmlId": "handbook--readme--f00a4291b8", + "sectionRelativeRepoPath": "customer-success/README.md", + "meta": { + "maintainedBy": "zayhanlon" + }, + "linksForHandbookIndex": [ + { + "headingText": "Team", + "hashLink": "/handbook/customer-success#team" + }, + { + "headingText": "Contact us", + "hashLink": "/handbook/customer-success#contact-us" + }, + { + "headingText": "Responsibilities", + "hashLink": "/handbook/customer-success#responsibilities" + }, + { + "headingText": "Rituals", + "hashLink": "/handbook/customer-success#rituals" + } + ] + }, + { + "url": "/handbook/engineering/debugging", + "title": "Debugging", + "lastModifiedAt": 1726839804916, + "htmlId": "handbook--debugging--72906ebdd6", + "sectionRelativeRepoPath": "engineering/Debugging.md", + "meta": { + "maintainedBy": "lukeheath", + "description": "A guide to triaging and diagnosing issues in Fleet." + }, + "linksForHandbookIndex": [ + { + "headingText": "Goals of this guide", + "hashLink": "/handbook/engineering/debugging#goals-of-this-guide" + }, + { + "headingText": "Basic data that is needed", + "hashLink": "/handbook/engineering/debugging#basic-data-that-is-needed" + }, + { + "headingText": "Triaging the issue", + "hashLink": "/handbook/engineering/debugging#triaging-the-issue" + } + ] + }, + { + "url": "/handbook/engineering/load-testing", + "title": "Load testing", + "lastModifiedAt": 1726839804917, + "htmlId": "handbook--load-testing--5fd9ee04e0", + "sectionRelativeRepoPath": "engineering/Load-testing.md", + "meta": { + "maintainedBy": "lukeheath", + "description": "This page outlines the most recent results of a semi-annual load test of the Fleet server." + }, + "linksForHandbookIndex": [ + { + "headingText": "Test parameters", + "hashLink": "/handbook/engineering/load-testing#test-parameters" + }, + { + "headingText": "Results", + "hashLink": "/handbook/engineering/load-testing#results" + }, + { + "headingText": "How we are simulating osquery", + "hashLink": "/handbook/engineering/load-testing#how-we-are-simulating-osquery" + }, + { + "headingText": "Infrastructure setup", + "hashLink": "/handbook/engineering/load-testing#infrastructure-setup" + }, + { + "headingText": "Limitations", + "hashLink": "/handbook/engineering/load-testing#limitations" + } + ] + }, + { + "url": "/handbook/engineering", + "title": "🚀 Engineering", + "lastModifiedAt": 1726839804924, + "htmlId": "handbook--readme--777ccc3e11", + "sectionRelativeRepoPath": "engineering/README.md", + "meta": { + "maintainedBy": "lukeheath" + }, + "linksForHandbookIndex": [ + { + "headingText": "Team", + "hashLink": "/handbook/engineering#team" + }, + { + "headingText": "Contact us", + "hashLink": "/handbook/engineering#contact-us" + }, + { + "headingText": "Responsibilities", + "hashLink": "/handbook/engineering#responsibilities" + }, + { + "headingText": "Rituals", + "hashLink": "/handbook/engineering#rituals" + } + ] + }, + { + "url": "/handbook/engineering/scaling-fleet", + "title": "Scaling Fleet", + "lastModifiedAt": 1726839804925, + "htmlId": "handbook--scaling-fleet--7496895e6e", + "sectionRelativeRepoPath": "engineering/scaling-fleet.md", + "meta": { + "maintainedBy": "lukeheath" + } + }, + { + "url": "/handbook/finance", + "title": "💸 Finance", + "lastModifiedAt": 1726839804931, + "htmlId": "handbook--readme--adb6ad624d", + "sectionRelativeRepoPath": "finance/README.md", + "meta": { + "maintainedBy": "jostableford" + }, + "linksForHandbookIndex": [ + { + "headingText": "Team", + "hashLink": "/handbook/finance#team" + }, + { + "headingText": "Contact us", + "hashLink": "/handbook/finance#contact-us" + }, + { + "headingText": "Responsibilities", + "hashLink": "/handbook/finance#responsibilities" + }, + { + "headingText": "Rituals", + "hashLink": "/handbook/finance#rituals" + } + ] + }, + { + "url": "/handbook/demand", + "title": "🫧 Demand", + "lastModifiedAt": 1726839804935, + "htmlId": "handbook--readme--5f95cdc89d", + "sectionRelativeRepoPath": "demand/README.md", + "meta": { + "maintainedBy": "Drew-P-Drawers" + }, + "linksForHandbookIndex": [ + { + "headingText": "Team", + "hashLink": "/handbook/demand#team" + }, + { + "headingText": "Contact us", + "hashLink": "/handbook/demand#contact-us" + }, + { + "headingText": "Responsibilities", + "hashLink": "/handbook/demand#responsibilities" + }, + { + "headingText": "Rituals", + "hashLink": "/handbook/demand#rituals" + } + ] + }, + { + "url": "/handbook/product-design", + "title": "🦢 Product design", + "lastModifiedAt": 1726839804937, + "htmlId": "handbook--readme--5ce44066f3", + "sectionRelativeRepoPath": "product-design/README.md", + "meta": { + "maintainedBy": "noahtalerman" + }, + "linksForHandbookIndex": [ + { + "headingText": "Team", + "hashLink": "/handbook/product-design#team" + }, + { + "headingText": "Contact us", + "hashLink": "/handbook/product-design#contact-us" + }, + { + "headingText": "Responsibilities", + "hashLink": "/handbook/product-design#responsibilities" + }, + { + "headingText": "Rituals", + "hashLink": "/handbook/product-design#rituals" + } + ] + }, + { + "url": "/handbook/digital-experience/application-security", + "title": "Application security", + "lastModifiedAt": 1726839804939, + "htmlId": "handbook--application-security--60a7adaa5a", + "sectionRelativeRepoPath": "digital-experience/application-security.md", + "meta": { + "description": "Explore Fleet's application security practices, including secure coding, SQL injection prevention, authentication, data encryption, access controls, and more.", + "maintainedBy": "hollidayn" + } + }, + { + "url": "/handbook/digital-experience", + "title": "🌐 Digital Experience", + "lastModifiedAt": 1726839804945, + "htmlId": "handbook--readme--7c78659bd2", + "sectionRelativeRepoPath": "digital-experience/README.md", + "meta": { + "maintainedBy": "Sampfluger88" + }, + "linksForHandbookIndex": [ + { + "headingText": "Team", + "hashLink": "/handbook/digital-experience#team" + }, + { + "headingText": "Contact us", + "hashLink": "/handbook/digital-experience#contact-us" + }, + { + "headingText": "Responsibilities", + "hashLink": "/handbook/digital-experience#responsibilities" + }, + { + "headingText": "Rituals", + "hashLink": "/handbook/digital-experience#rituals" + } + ] + }, + { + "url": "/handbook/digital-experience/security-audits", + "title": "Security audits", + "lastModifiedAt": 1726839804948, + "htmlId": "handbook--security-audits--b0d65992c5", + "sectionRelativeRepoPath": "digital-experience/security-audits.md", + "meta": { + "description": "Explanations of the latest external security audits performed on Fleet software.", + "maintainedBy": "hollidayn" + }, + "linksForHandbookIndex": [ + { + "headingText": "June 2024 penetration testing of Fleet 4.50.1", + "hashLink": "/handbook/digital-experience/security-audits#june-2024-penetration-testing-of-fleet-4-50-1" + }, + { + "headingText": "June 2023 penetration testing of Fleet 4.32 ", + "hashLink": "/handbook/digital-experience/security-audits#june-2023-penetration-testing-of-fleet-4-32" + }, + { + "headingText": "April 2022 penetration testing of Fleet 4.12 ", + "hashLink": "/handbook/digital-experience/security-audits#april-2022-penetration-testing-of-fleet-4-12" + }, + { + "headingText": "August 2021 security of Orbit auto-updater", + "hashLink": "/handbook/digital-experience/security-audits#august-2021-security-of-orbit-auto-updater" + } + ] + }, + { + "url": "/handbook/digital-experience/security-policies", + "title": "📜 Security policies", + "lastModifiedAt": 1726839804955, + "htmlId": "handbook--security-policies--96158a5cf6", + "sectionRelativeRepoPath": "digital-experience/security-policies.md", + "meta": { + "maintainedBy": "jostableford" + }, + "linksForHandbookIndex": [ + { + "headingText": "Information security policy and acceptable use policy", + "hashLink": "/handbook/digital-experience/security-policies#information-security-policy-and-acceptable-use-policy" + }, + { + "headingText": "Access control policy", + "hashLink": "/handbook/digital-experience/security-policies#access-control-policy" + }, + { + "headingText": "Asset management policy", + "hashLink": "/handbook/digital-experience/security-policies#asset-management-policy" + }, + { + "headingText": "Business continuity and disaster recovery policy", + "hashLink": "/handbook/digital-experience/security-policies#business-continuity-and-disaster-recovery-policy" + }, + { + "headingText": "Data management policy", + "hashLink": "/handbook/digital-experience/security-policies#data-management-policy" + }, + { + "headingText": "Encryption policy", + "hashLink": "/handbook/digital-experience/security-policies#encryption-policy" + }, + { + "headingText": "Human resources security policy", + "hashLink": "/handbook/digital-experience/security-policies#human-resources-security-policy" + }, + { + "headingText": "Incident response policy", + "hashLink": "/handbook/digital-experience/security-policies#incident-response-policy" + }, + { + "headingText": "Network and system hardening standards", + "hashLink": "/handbook/digital-experience/security-policies#network-and-system-hardening-standards" + }, + { + "headingText": "Operations security and change management policy", + "hashLink": "/handbook/digital-experience/security-policies#operations-security-and-change-management-policy" + }, + { + "headingText": "Risk management policy", + "hashLink": "/handbook/digital-experience/security-policies#risk-management-policy" + }, + { + "headingText": "Secure software development and product security policy ", + "hashLink": "/handbook/digital-experience/security-policies#secure-software-development-and-product-security-policy" + }, + { + "headingText": "Security policy management policy", + "hashLink": "/handbook/digital-experience/security-policies#security-policy-management-policy" + }, + { + "headingText": "Third-party management policy", + "hashLink": "/handbook/digital-experience/security-policies#third-party-management-policy" + }, + { + "headingText": "Anti-corruption policy", + "hashLink": "/handbook/digital-experience/security-policies#anti-corruption-policy" + } + ] + }, + { + "url": "/handbook/digital-experience/vendor-questionnaires", + "title": "📃 Vendor questionnaires", + "lastModifiedAt": 1726839804956, + "htmlId": "handbook--vendor-questionnaire--46cac642a1", + "sectionRelativeRepoPath": "digital-experience/vendor-questionnaires.md", + "meta": { + "maintainedBy": "dherder" + }, + "linksForHandbookIndex": [ + { + "headingText": "Scoping", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#scoping" + }, + { + "headingText": "Application security", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#application-security" + }, + { + "headingText": "Data security", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#data-security" + }, + { + "headingText": "Service monitoring and logging", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#service-monitoring-and-logging" + }, + { + "headingText": "Encryption and key management", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#encryption-and-key-management" + }, + { + "headingText": "Governance and risk management", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#governance-and-risk-management" + }, + { + "headingText": "Business continuity", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#business-continuity" + }, + { + "headingText": "Network security", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#network-security" + }, + { + "headingText": "Privacy", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#privacy" + }, + { + "headingText": "Sub-processors", + "hashLink": "/handbook/digital-experience/vendor-questionnaires#sub-processors" + } + ] + }, + { + "url": "/handbook/digital-experience/security", + "title": "Security", + "lastModifiedAt": 1726839804965, + "htmlId": "handbook--security--585b03364d", + "sectionRelativeRepoPath": "digital-experience/security.md", + "meta": { + "maintainedBy": "hollidayn" + }, + "linksForHandbookIndex": [ + { + "headingText": "Security policies", + "hashLink": "/handbook/digital-experience/security#security-policies" + }, + { + "headingText": "Account recovery process", + "hashLink": "/handbook/digital-experience/security#account-recovery-process" + }, + { + "headingText": "How we protect end-user devices", + "hashLink": "/handbook/digital-experience/security#how-we-protect-end-user-devices" + }, + { + "headingText": "Hardware security keys", + "hashLink": "/handbook/digital-experience/security#hardware-security-keys" + }, + { + "headingText": "GitHub security", + "hashLink": "/handbook/digital-experience/security#git-hub-security" + }, + { + "headingText": "Google Workspace security", + "hashLink": "/handbook/digital-experience/security#google-workspace-security" + }, + { + "headingText": "Vulnerability management", + "hashLink": "/handbook/digital-experience/security#vulnerability-management" + }, + { + "headingText": "Trust report", + "hashLink": "/handbook/digital-experience/security#trust-report" + }, + { + "headingText": "Securtiy audits", + "hashLink": "/handbook/digital-experience/security#securtiy-audits" + }, + { + "headingText": "Application security", + "hashLink": "/handbook/digital-experience/security#application-security" + } + ] + }, + { + "url": "/handbook/sales", + "title": "🐋 Sales", + "lastModifiedAt": 1726839804968, + "htmlId": "handbook--readme--4fe57c451a", + "sectionRelativeRepoPath": "sales/README.md", + "meta": { + "maintainedBy": "alexmitchelliii" + }, + "linksForHandbookIndex": [ + { + "headingText": "Team", + "hashLink": "/handbook/sales#team" + }, + { + "headingText": "Contact us", + "hashLink": "/handbook/sales#contact-us" + }, + { + "headingText": "Responsibilities", + "hashLink": "/handbook/sales#responsibilities" + }, + { + "headingText": "Rituals", + "hashLink": "/handbook/sales#rituals" + } + ] + }, + { + "url": "/engineering/tips-for-github-actions-usability", + "title": "Tips for github actions usability", + "lastModifiedAt": 1726839804972, + "htmlId": "articles--4-tips-for-github-ac--c93d8d672b", + "sectionRelativeRepoPath": "4-tips-for-github-actions-usability.md", + "meta": { + "category": "engineering", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-01-03", + "articleTitle": "4 tips for GitHub Actions usability (+2 bonus tips for debugging)", + "articleImageUrl": "/images/articles/4-tips-for-github-actions-usability-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/apple-developer-certificates-on-linux-for-configuration-profile-signing", + "title": "Apple developer certificates on linux for configuration profile signing", + "lastModifiedAt": 1726839804973, + "htmlId": "articles--apple-developer-cert--3d7bfdf01f", + "sectionRelativeRepoPath": "apple-developer-certificates-on-linux-for-configuration-profile-signing.md", + "meta": { + "articleTitle": "Apple developer certificates on Linux for configuration profile signing", + "authorFullName": "Brock Walters", + "authorGitHubUsername": "nonpunctual", + "category": "guides", + "publishedOn": "2024-03-06", + "articleImageUrl": "/images/articles/apple-developer-certificates-on-linux-for-configuration-profile-signing-1600x900@2x.png", + "description": "This guide walks through the process of adding an Apple signing certificate to a Linux host." + } + }, + { + "url": "/announcements/a-new-fleet", + "title": "A new Fleet", + "lastModifiedAt": 1726839804974, + "htmlId": "articles--a-new-fleet--0c5af0e434", + "sectionRelativeRepoPath": "a-new-fleet.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2020-01-05", + "articleTitle": "A new Fleet", + "articleImageUrl": "/images/articles/a-new-fleet-cover-700x340@2x.jpeg" + } + }, + { + "url": "/securing/apply-byod-to-soothe-supply-chain-pain", + "title": "Apply byod to soothe supply chain pain", + "lastModifiedAt": 1726839804976, + "htmlId": "articles--apply-byod-to-soothe--866604b091", + "sectionRelativeRepoPath": "apply-byod-to-soothe-supply-chain-pain.md", + "meta": { + "category": "security", + "authorGitHubUsername": "GuillaumeRoss", + "authorFullName": "Guillaume Ross", + "publishedOn": "2022-02-10", + "articleTitle": "Apply BYOD to soothe supply chain pain", + "articleImageUrl": "/images/articles/apply-byod-to-soothe-supply-chain-pain-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/automations", + "title": "Automations", + "lastModifiedAt": 1726839804976, + "htmlId": "articles--automations--ff5e8024a5", + "sectionRelativeRepoPath": "automations.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-07-03", + "articleTitle": "Automations", + "description": "Configure Fleet automations to trigger webhooks or create tickets in Jira and Zendesk for vulnerability, policy, and host status events." + } + }, + { + "url": "/guides/building-webhook-flows-with-fleet-and-tines", + "title": "Building webhook flows with Fleet and tines", + "lastModifiedAt": 1726839804978, + "htmlId": "articles--building-webhook-flo--3ffb4a9791", + "sectionRelativeRepoPath": "building-webhook-flows-with-fleet-and-tines.md", + "meta": { + "articleTitle": "Building webhook flows with Fleet and Tines", + "authorFullName": "Victor Lyuboslavsky", + "authorGitHubUsername": "getvictor", + "category": "guides", + "publishedOn": "2024-05-30", + "articleImageUrl": "/images/articles/building-webhook-flows-with-fleet-and-tines-1600x900@2x.png", + "description": "A guide to workflows using Tines and Fleet via webhook to update outdated OS versions." + } + }, + { + "url": "/guides/building-an-effective-dashboard-with-fleet-rest-api-flask-and-plotly", + "title": "Building an effective dashboard with Fleet REST API flask and plotly", + "lastModifiedAt": 1726839804979, + "htmlId": "articles--building-an-effectiv--d3c30b5cf6", + "sectionRelativeRepoPath": "building-an-effective-dashboard-with-fleet-rest-api-flask-and-plotly.md", + "meta": { + "articleTitle": "Building an effective dashboard with Fleet's REST API, Flask, and Plotly: A step-by-step guide", + "authorFullName": "Dave Herder", + "authorGitHubUsername": "dherder", + "category": "guides", + "publishedOn": "2023-05-22", + "articleImageUrl": "/images/articles/building-an-effective-dashboard-with-fleet-rest-api-flask-and-plotly@2x.jpg", + "description": "Step-by-step guide on building a dynamic dashboard with Fleet's REST API, Flask, and Plotly. Master data visualization with open-source tools!" + } + }, + { + "url": "/guides/certificates-in-fleetd", + "title": "Certificates in fleetd", + "lastModifiedAt": 1726839804980, + "htmlId": "articles--certificates-in-flee--f860411dcf", + "sectionRelativeRepoPath": "certificates-in-fleetd.md", + "meta": { + "articleTitle": "Certificates in fleetd", + "authorFullName": "Lucas Manuel Rodriguez", + "authorGitHubUsername": "lucasmrod", + "category": "guides", + "publishedOn": "2024-07-09", + "articleImageUrl": "/images/articles/apple-developer-certificates-on-linux-for-configuration-profile-signing-1600x900@2x.png", + "description": "TLS certificates in fleetd" + } + }, + { + "url": "/guides/chrome-os", + "title": "Chrome os", + "lastModifiedAt": 1726839804981, + "htmlId": "articles--chrome-os--8f9e4f0cca", + "sectionRelativeRepoPath": "chrome-os.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "zhumo", + "authorFullName": "Mo Zhu", + "publishedOn": "2023-11-21", + "articleTitle": "ChromeOS", + "description": "Learn about ChromeOS and Fleet." + } + }, + { + "url": "/guides/catch-missed-authorization-checks-during-software-development", + "title": "Catch missed authorization checks during software development", + "lastModifiedAt": 1726839804981, + "htmlId": "articles--catch-missed-authori--74d449dae1", + "sectionRelativeRepoPath": "catch-missed-authorization-checks-during-software-development.md", + "meta": { + "articleTitle": "Catch missed authorization checks during software development", + "authorFullName": "Victor Lyuboslavsky", + "authorGitHubUsername": "getvictor", + "category": "guides", + "publishedOn": "2023-12-04", + "description": "How to perform authorization checks in a golang codebase for cybersecurity" + } + }, + { + "url": "/guides/cis-benchmarks", + "title": "Cis benchmarks", + "lastModifiedAt": 1726839804982, + "htmlId": "articles--cis-benchmarks--c493697884", + "sectionRelativeRepoPath": "cis-benchmarks.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "lucasmrod", + "authorFullName": "Lucas Rodriguez", + "publishedOn": "2024-04-02", + "articleTitle": "CIS Benchmarks", + "description": "Read about how Fleet's implementation of CIS Benchmarks offers consensus-based cybersecurity guidance." + } + }, + { + "url": "/announcements/comparative-look-at-ws1-and-fleet", + "title": "Comparative look at ws1 and Fleet", + "lastModifiedAt": 1726839804983, + "htmlId": "articles--comparative-look-at---d3aff5bdd7", + "sectionRelativeRepoPath": "comparative-look-at-ws1-and-fleet.md", + "meta": { + "category": "announcements", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-02-01", + "articleTitle": "A comparative look at VMware Workspace ONE and Fleet Device Management", + "articleImageUrl": "/images/articles/comparative-look-at-ws1-and-fleet-1600x900@2x.png" + } + }, + { + "url": "/guides/config-less-fleetd-agent-deployment", + "title": "Config less fleetd agent deployment", + "lastModifiedAt": 1726839804984, + "htmlId": "articles--config-less-fleetd-a--e5546949d5", + "sectionRelativeRepoPath": "config-less-fleetd-agent-deployment.md", + "meta": { + "articleTitle": "Config-less fleetd agent deployment", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "category": "guides", + "publishedOn": "2024-01-31", + "articleImageUrl": "/images/articles/config-less-fleetd-agent-deployment-1600x900@2x.png", + "description": "Config-less `fleetd` agent deployment" + } + }, + { + "url": "/guides/configuring-default-teams-for-devices-in-fleet", + "title": "Configuring default teams for devices in Fleet", + "lastModifiedAt": 1726839804985, + "htmlId": "articles--configuring-default---d9b024f2b7", + "sectionRelativeRepoPath": "configuring-default-teams-for-devices-in-fleet.md", + "meta": { + "articleTitle": "Configuring default teams for macOS, iOS, and iPadOS devices in Fleet", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "category": "guides", + "publishedOn": "2024-09-12", + "description": "This guide will walk you through configuring default teams for devices using the Fleet web UI." + } + }, + { + "url": "/guides/converting-unix-timestamps-with-osquery", + "title": "Converting unix timestamps with osquery", + "lastModifiedAt": 1726839804986, + "htmlId": "articles--converting-unix-time--ace81a16aa", + "sectionRelativeRepoPath": "converting-unix-timestamps-with-osquery.md", + "meta": { + "category": "guides", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2021-06-15", + "articleTitle": "Converting unix timestamps with osquery", + "articleImageUrl": "/images/articles/converting-unix-timestamps-with-osquery-cover-800x450@2x.jpeg" + } + }, + { + "url": "/guides/correlate-network-connections-with-community-id-in-osquery", + "title": "Correlate network connections with community id in osquery", + "lastModifiedAt": 1726839804987, + "htmlId": "articles--correlate-network-co--10ea0b1641", + "sectionRelativeRepoPath": "correlate-network-connections-with-community-id-in-osquery.md", + "meta": { + "category": "guides", + "authorFullName": "Zach Wasserman", + "authorGitHubUsername": "zwass", + "publishedOn": "2021-06-02", + "articleTitle": "Correlate network connections with community ID in osquery.", + "articleImageUrl": "/images/articles/correlate-network-connections-with-community-id-in-osquery-cover-800x502@2x.jpeg" + } + }, + { + "url": "/guides/custom-os-settings", + "title": "Custom os settings", + "lastModifiedAt": 1726839804988, + "htmlId": "articles--custom-os-settings--5e97a43205", + "sectionRelativeRepoPath": "custom-os-settings.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-07-27", + "articleTitle": "Custom OS settings", + "description": "Learn how to enforce custom settings on macOS and Window hosts using Fleet's configuration profiles." + } + }, + { + "url": "/announcements/debunk-the-cross-platform-myth", + "title": "Debunk the cross platform myth", + "lastModifiedAt": 1726839804989, + "htmlId": "articles--debunk-the-cross-pla--d46aac3cb4", + "sectionRelativeRepoPath": "debunk-the-cross-platform-myth.md", + "meta": { + "category": "announcements", + "authorFullName": "Mike McNeil", + "authorGitHubUsername": "mikermcneil", + "publishedOn": "2024-08-27", + "articleTitle": "Debunk the cross-platform myth", + "description": "Debunk the cross-platform myth with MDM" + } + }, + { + "url": "/guides/delivering-data-to-snowflake-from-fleet-and-osquery", + "title": "Delivering data to snowflake from Fleet and osquery", + "lastModifiedAt": 1726839804991, + "htmlId": "articles--delivering-data-to-s--9677bbe81b", + "sectionRelativeRepoPath": "delivering-data-to-snowflake-from-fleet-and-osquery.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "t-lark", + "authorFullName": "Tom Larkin", + "publishedOn": "2022-02-01", + "articleTitle": "Delivering data to Snowflake from Fleet and osquery.", + "articleImageUrl": "/images/articles/delivering-data-to-snowflake-from-fleet-and-osquery-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/deploy-fleet-on-aws-ecs", + "title": "Deploy Fleet on aws ecs", + "lastModifiedAt": 1726839804992, + "htmlId": "articles--deploy-fleet-on-aws---ca8c5b2fc4", + "sectionRelativeRepoPath": "deploy-fleet-on-aws-ecs.md", + "meta": { + "articleTitle": "Deploy Fleet on AWS ECS", + "authorGitHubUsername": "edwardsb", + "authorFullName": "Ben Edwards", + "publishedOn": "2021-10-06", + "category": "guides", + "articleImageUrl": "/images/articles/deploy-fleet-on-aws-ecs-800x450@2x.png", + "description": "Information for deploying Fleet on AWS ECS." + } + }, + { + "url": "/guides/deploy-fleet-on-aws-with-terraform", + "title": "Deploy Fleet on aws with terraform", + "lastModifiedAt": 1726839804993, + "htmlId": "articles--deploy-fleet-on-aws---8b2a9168ab", + "sectionRelativeRepoPath": "deploy-fleet-on-aws-with-terraform.md", + "meta": { + "articleTitle": "Deploy Fleet on AWS with Terraform", + "authorGitHubUsername": "edwardsb", + "authorFullName": "Ben Edwards", + "publishedOn": "2021-11-30", + "category": "guides", + "articleImageUrl": "/images/articles/deploy-fleet-on-aws-with-terraform-800x450@2x.png", + "description": "Learn how to deploy Fleet on AWS." + } + }, + { + "url": "/guides/deploy-fleet-on-centos", + "title": "Deploy Fleet on centos", + "lastModifiedAt": 1726839804994, + "htmlId": "articles--deploy-fleet-on-cent--4841e96234", + "sectionRelativeRepoPath": "deploy-fleet-on-centos.md", + "meta": { + "articleTitle": "Deploy Fleet on CentOS", + "authorGitHubUsername": "marpaia", + "authorFullName": "Mike Arpaia", + "publishedOn": "2017-09-22", + "category": "guides", + "articleImageUrl": "/images/articles/deploy-fleet-on-centos-800x450@2x.png", + "description": "A guide to deploy Fleet on CentOS." + } + }, + { + "url": "/guides/deploy-fleet-on-cloudgov", + "title": "Deploy Fleet on cloudgov", + "lastModifiedAt": 1726839804995, + "htmlId": "articles--deploy-fleet-on-clou--ecdaaf656b", + "sectionRelativeRepoPath": "deploy-fleet-on-cloudgov.md", + "meta": { + "articleTitle": "Deploy Fleet on Cloud.gov", + "authorGitHubUsername": "JJediny", + "authorFullName": "John Jediny", + "publishedOn": "2022-09-08", + "category": "guides", + "articleImageUrl": "/images/articles/deploy-fleet-on-cloudgov-800x450@2x.png", + "description": "Information for deploying Fleet on Cloud.gov." + } + }, + { + "url": "/guides/deploy-fleet-on-hetzner-cloud", + "title": "Deploy Fleet on hetzner cloud", + "lastModifiedAt": 1726839804999, + "htmlId": "articles--deploy-fleet-on-hetz--ab40dd3e5f", + "sectionRelativeRepoPath": "deploy-fleet-on-hetzner-cloud.md", + "meta": { + "articleTitle": "Deploy Fleet on Hetzner Cloud", + "authorGitHubUsername": "ksatter", + "authorFullName": "Kathy Satterlee", + "publishedOn": "2022-06-27", + "category": "guides", + "articleImageUrl": "/images/articles/deploy-fleet-on-hetzner-cloud-800x450@2x.png", + "description": "Learn how to deploy Fleet on Hetzner Cloud using cloud-init and Docker." + } + }, + { + "url": "/guides/deploy-fleet-on-kubernetes", + "title": "Deploy Fleet on kubernetes", + "lastModifiedAt": 1726839805000, + "htmlId": "articles--deploy-fleet-on-kube--b62fcc97c7", + "sectionRelativeRepoPath": "deploy-fleet-on-kubernetes.md", + "meta": { + "articleTitle": "Deploy Fleet on Kubernetes", + "authorGitHubUsername": "marpaia", + "authorFullName": "Mike Arpaia", + "publishedOn": "2017-11-18", + "category": "guides", + "articleImageUrl": "/images/articles/deploy-fleet-on-kubernetes-800x450@2x.png", + "description": "Learn how to deploy Fleet on Kubernetes." + } + }, + { + "url": "/guides/deploy-fleet-on-render", + "title": "Deploy Fleet on render", + "lastModifiedAt": 1726839805001, + "htmlId": "articles--deploy-fleet-on-rend--175bce353f", + "sectionRelativeRepoPath": "deploy-fleet-on-render.md", + "meta": { + "articleTitle": "Deploy Fleet on Render", + "authorGitHubUsername": "edwardsb", + "authorFullName": "Ben Edwards", + "publishedOn": "2021-11-21", + "category": "guides", + "articleImageUrl": "/images/articles/deploy-fleet-on-render-800x450@2x.png", + "description": "Learn how to deploy Fleet on Render." + } + }, + { + "url": "/guides/deploy-fleet-on-ubuntu-with-elastic", + "title": "Deploy Fleet on ubuntu with elastic", + "lastModifiedAt": 1726839805004, + "htmlId": "articles--deploy-fleet-on-ubun--db33029e1f", + "sectionRelativeRepoPath": "deploy-fleet-on-ubuntu-with-elastic.md", + "meta": { + "articleTitle": "Deploy Fleet on Ubuntu", + "authorGitHubUsername": "defensivedepth", + "authorFullName": "Josh Brower", + "publishedOn": "2024-06-12", + "category": "guides", + "description": "A guide to deploy Fleet and Elastic on Ubuntu.", + "articleImageUrl": "/images/articles/deploy-fleet-on-ubuntu-with-elastic-1600x900@2x.png" + } + }, + { + "url": "/guides/deploy-security-agents", + "title": "Deploy security agents", + "lastModifiedAt": 1726839805005, + "htmlId": "articles--deploy-security-agen--a3a93c715b", + "sectionRelativeRepoPath": "deploy-security-agents.md", + "meta": { + "articleTitle": "Deploy security agents", + "authorFullName": "Roberto Dip", + "authorGitHubUsername": "roperzh", + "category": "guides", + "publishedOn": "2024-08-05", + "articleImageUrl": "/images/articles/deploy-security-agents-1600x900@2x.png", + "description": "This guide will walk you through adding software to Fleet." + } + }, + { + "url": "/securing/detect-log4j-with-osquery-and-fleet", + "title": "Detect log4j with osquery and Fleet", + "lastModifiedAt": 1726839805006, + "htmlId": "articles--detect-log4j-with-os--812eb5ba15", + "sectionRelativeRepoPath": "detect-log4j-with-osquery-and-fleet.md", + "meta": { + "category": "security", + "authorFullName": "Zach Wasserman", + "authorGitHubUsername": "zwass", + "publishedOn": "2021-12-15", + "articleTitle": "Detect Log4j with osquery (and Fleet)", + "articleImageUrl": "/images/articles/detect-log4j-with-osquery-and-fleet-1600x900@2x.jpg" + } + }, + { + "url": "/guides/discovering-chrome-ai-using-fleet", + "title": "Discovering chrome ai using Fleet", + "lastModifiedAt": 1726839805007, + "htmlId": "articles--discovering-chrome-a--4de87d4fb6", + "sectionRelativeRepoPath": "discovering-chrome-ai-using-fleet.md", + "meta": { + "articleTitle": "Discovering Chrome AI using Fleet", + "authorFullName": "Brock Walters", + "authorGitHubUsername": "nonpunctual", + "category": "guides", + "publishedOn": "2024-09-06", + "articleImageUrl": "/images/articles/discovering-chrome-ai-using-fleet-1600x900@2x.jpg", + "description": "Use Fleet to detect and monitor settings enabled in Google Chrome by querying Chrome's preferences JSON file." + } + }, + { + "url": "/guides/discovering-geacon-using-fleet", + "title": "Discovering geacon using Fleet", + "lastModifiedAt": 1726839805008, + "htmlId": "articles--discovering-geacon-u--bab06239aa", + "sectionRelativeRepoPath": "discovering-geacon-using-fleet.md", + "meta": { + "articleTitle": "Discovering Geacon using Fleet", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "category": "guides", + "publishedOn": "2023-05-18", + "articleImageUrl": "/images/articles/discovering-geacon-using-fleet-1600x900@2x.jpg", + "description": "Enterprise security teams can use Fleet to identify and locate Geacon payloads and protect their macOS devices from this threat." + } + }, + { + "url": "/guides/discovering-xz-vulnerability-with-fleet", + "title": "Discovering xz vulnerability with Fleet", + "lastModifiedAt": 1726839805010, + "htmlId": "articles--discovering-xz-vulne--0a7dc5a7f8", + "sectionRelativeRepoPath": "discovering-xz-vulnerability-with-fleet.md", + "meta": { + "articleTitle": "Discovering xz vulnerability with Fleet", + "authorFullName": "Brock Walters", + "authorGitHubUsername": "nonpunctual", + "category": "guides", + "publishedOn": "2024-06-03", + "articleImageUrl": "/images/articles/discovering-geacon-using-fleet-1600x900@2x.jpg", + "description": "Discover and create a comprehensive end-to-end remediation workflow for the xz vulnerability (CVE-2024-3094) with Fleet." + } + }, + { + "url": "/securing/does-osquery-violate-the-new-york-employee-monitoring-law", + "title": "Does osquery violate the new york employee monitoring law", + "lastModifiedAt": 1726839805011, + "htmlId": "articles--does-osquery-violate--fcac4cc8a5", + "sectionRelativeRepoPath": "does-osquery-violate-the-new-york-employee-monitoring-law.md", + "meta": { + "category": "security", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-04-18", + "articleTitle": "Does osquery violate the New York employee monitoring law?" + } + }, + { + "url": "/guides/downgrade-fleet", + "title": "Downgrade Fleet", + "lastModifiedAt": 1726839805012, + "htmlId": "articles--downgrade-fleet--76de2fe679", + "sectionRelativeRepoPath": "downgrade-fleet.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "eashaw", + "authorFullName": "Eric Shaw", + "publishedOn": "2024-01-09", + "articleTitle": "Downgrade from Fleet Premium", + "description": "Learn how to downgrade from Fleet Premium." + } + }, + { + "url": "/guides/driving-company-culture-through-ai-haiku-poetry", + "title": "Driving company culture through ai haiku poetry", + "lastModifiedAt": 1726839805013, + "htmlId": "articles--driving-company-cult--52db9708d4", + "sectionRelativeRepoPath": "driving-company-culture-through-ai-haiku-poetry.md", + "meta": { + "articleTitle": "Driving company culture through AI haiku poetry", + "authorFullName": "Luke Heath", + "authorGitHubUsername": "lukeheath", + "category": "guides", + "publishedOn": "2024-04-17", + "articleImageUrl": "/images/articles/driving-company-culture-through-ai-haiku-poetry-1600x900@2x.png", + "description": "Code and verse entwine, Silicon sparks, haikus shine, Art meets design line." + } + }, + { + "url": "/securing/ebpf-the-future-of-osquery-on-linux", + "title": "Ebpf the future of osquery on linux", + "lastModifiedAt": 1726839805014, + "htmlId": "articles--ebpf-the-future-of-o--cd30e84170", + "sectionRelativeRepoPath": "ebpf-the-future-of-osquery-on-linux.md", + "meta": { + "category": "security", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2021-01-25", + "articleTitle": "eBPF & the future of osquery on Linux", + "articleImageUrl": "/images/articles/ebpf-the-future-of-osquery-on-linux-cover-700x394@2x.png" + } + }, + { + "url": "/announcements/embracing-the-future-declarative-device-management", + "title": "Embracing the future declarative device management", + "lastModifiedAt": 1726839805015, + "htmlId": "articles--embracing-the-future--b3151457e1", + "sectionRelativeRepoPath": "embracing-the-future-declarative-device-management.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "spokanemac", + "authorFullName": "JD Strong", + "publishedOn": "2023-07-06", + "articleTitle": "Embracing the future: Declarative Device Management", + "articleImageUrl": "/images/articles/embracing-the-future-declarative-device-management@2x.png", + "description": "Explore the transformative impact of Declarative Device Management (DDM), Fleet, and osquery for MacAdmins." + } + }, + { + "url": "/securing/end-user-self-remediation", + "title": "End user self remediation", + "lastModifiedAt": 1726839805016, + "htmlId": "articles--end-user-self-remedi--1ebc67c784", + "sectionRelativeRepoPath": "end-user-self-remediation.md", + "meta": { + "category": "security", + "authorFullName": "Chris McGillicuddy", + "authorGitHubUsername": "chris-mcgillicuddy", + "publishedOn": "2022-12-15", + "articleTitle": "End-user self remediation: empower your employees to fix security issues with Fleet" + } + }, + { + "url": "/announcements/endpoint-managements-crucial-role-in-healthcare", + "title": "Endpoint managements crucial role in healthcare", + "lastModifiedAt": 1726839805017, + "htmlId": "articles--endpoint-managements--ec90fcd20a", + "sectionRelativeRepoPath": "endpoint-managements-crucial-role-in-healthcare.md", + "meta": { + "category": "announcements", + "authorFullName": "Alex Mitchell", + "authorGitHubUsername": "alexmitchelliii", + "publishedOn": "2024-05-24", + "articleTitle": "Endpoint management's crucial role in healthcare", + "articleImageUrl": "/images/articles/endpoint-managements-crucial-role-in-healthcare-1600x900@2x.png", + "description": "Discover how robust endpoint management is essential for securing healthcare data, ensuring compliance, and building patient trust." + } + }, + { + "url": "/guides/enforce-disk-encryption", + "title": "Enforce disk encryption", + "lastModifiedAt": 1726839805018, + "htmlId": "articles--enforce-disk-encrypt--0ab61200c1", + "sectionRelativeRepoPath": "enforce-disk-encryption.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-08-14", + "articleTitle": "Enforce disk encryption", + "description": "Learn how to enforce disk encryption on macOS and Windows hosts and manage encryption keys with Fleet Premium." + } + }, + { + "url": "/guides/enforce-os-updates", + "title": "Enforce os updates", + "lastModifiedAt": 1726839805019, + "htmlId": "articles--enforce-os-updates--0ddd6f9117", + "sectionRelativeRepoPath": "enforce-os-updates.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-08-10", + "articleTitle": "Enforce OS updates", + "description": "Learn how to manage OS updates on macOS, Windows, iOS, and iPadOS devices." + } + }, + { + "url": "/announcements/enhancing-fleets-vulnerability-management-with-vulncheck-integration", + "title": "Enhancing fleets vulnerability management with vulncheck integration", + "lastModifiedAt": 1726839805020, + "htmlId": "articles--enhancing-fleets-vul--3cc4d5cb3a", + "sectionRelativeRepoPath": "enhancing-fleets-vulnerability-management-with-vulncheck-integration.md", + "meta": { + "category": "announcements", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-04-23", + "articleTitle": "Enhancing Fleet's vulnerability management with VulnCheck integration", + "articleImageUrl": "/images/articles/enhancing-fleets-vulnerability-management-with-vulncheck-integration-1600x900@2x.png" + } + }, + { + "url": "/announcements/enhancing-k-12-cybersecurity-with-fcc-funds-and-fleet", + "title": "Enhancing k 12 cybersecurity with fcc funds and Fleet", + "lastModifiedAt": 1726839805021, + "htmlId": "articles--enhancing-k-12-cyber--90c76b24ef", + "sectionRelativeRepoPath": "enhancing-k-12-cybersecurity-with-fcc-funds-and-fleet.md", + "meta": { + "category": "announcements", + "authorFullName": "Alex Mitchell", + "authorGitHubUsername": "alexmitchelliii", + "publishedOn": "2024-07-25", + "articleTitle": "Enhancing K-12 cybersecurity with FCC funds and Fleet", + "articleImageUrl": "/images/articles/enhancing-k-12-cybersecurity-with-fcc-funds-and-fleet-1600x900@2x.png" + } + }, + { + "url": "/guides/enroll-hosts", + "title": "Enroll hosts", + "lastModifiedAt": 1726839805023, + "htmlId": "articles--enroll-hosts--72fecd86ff", + "sectionRelativeRepoPath": "enroll-hosts.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-08-08", + "articleTitle": "Enroll hosts", + "description": "Learn how to enroll hosts to Fleet." + } + }, + { + "url": "/guides/enrolling-a-digital-ocean-droplet-on-a-fleet-instance", + "title": "Enrolling a digital ocean droplet on a Fleet instance", + "lastModifiedAt": 1726839805025, + "htmlId": "articles--enrolling-a-digital---6fbc5a61b0", + "sectionRelativeRepoPath": "enrolling-a-digital-ocean-droplet-on-a-fleet-instance.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "DominusKelvin", + "authorFullName": "Kelvin Omereshone", + "publishedOn": "2022-05-26", + "articleTitle": "Enrolling a DigitalOcean Droplet on a Fleet instance", + "articleImageUrl": "/images/articles/enrolling-a-digitalocean-droplet-server-on-a-fleet-instance-cover-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/expeditioners-bradley-chambers", + "title": "Expeditioners bradley chambers", + "lastModifiedAt": 1726839805026, + "htmlId": "articles--expeditioners-bradle--434ed8f62f", + "sectionRelativeRepoPath": "expeditioners-bradley-chambers.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2023-07-20", + "articleTitle": "ExpedITioners podcast with Bradley Chambers", + "articleImageUrl": "/images/articles/expeditioners-podcast-ep1-1600x900@2x.png" + } + }, + { + "url": "/podcasts/expeditioners-charles-edge", + "title": "Expeditioners charles edge", + "lastModifiedAt": 1726839805027, + "htmlId": "articles--expeditioners-charle--078e2e677d", + "sectionRelativeRepoPath": "expeditioners-charles-edge.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2023-10-23", + "articleTitle": "ExpedITioners podcast with Charles Edge", + "articleImageUrl": "/images/articles/expeditioners-podcast-ep5-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/expeditioners-huxley-barbee", + "title": "Expeditioners huxley barbee", + "lastModifiedAt": 1726839805027, + "htmlId": "articles--expeditioners-huxley--59793f39c1", + "sectionRelativeRepoPath": "expeditioners-huxley-barbee.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2024-01-30", + "articleTitle": "ExpedITioners podcast with Huxley Barbee", + "articleImageUrl": "/images/articles/expeditioners-podcast-ep8-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/expeditioners-jeff-chao", + "title": "Expeditioners jeff chao", + "lastModifiedAt": 1726839805028, + "htmlId": "articles--expeditioners-jeff-c--69f6b2fce1", + "sectionRelativeRepoPath": "expeditioners-jeff-chao.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2023-11-15", + "articleTitle": "ExpedITioners podcast with Jeff Chao", + "articleImageUrl": "/images/articles/expeditioners-podcast-ep6-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/expeditioners-john-reynolds", + "title": "Expeditioners john reynolds", + "lastModifiedAt": 1726839805029, + "htmlId": "articles--expeditioners-john-r--2abfb47f0e", + "sectionRelativeRepoPath": "expeditioners-john-reynolds.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2023-09-21", + "articleTitle": "ExpedITioners podcast with John Reynolds", + "articleImageUrl": "/images/articles/expeditioners-podcast-ep4-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/expeditioners-niels-hofmans", + "title": "Expeditioners niels hofmans", + "lastModifiedAt": 1726839805030, + "htmlId": "articles--expeditioners-niels---d1c8e645af", + "sectionRelativeRepoPath": "expeditioners-niels-hofmans.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2023-08-22", + "articleTitle": "ExpedITioners podcast with Niels Hofmans", + "articleImageUrl": "/images/articles/expeditioners-podcast-ep2-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/expeditioners-podcast-with-marcus-ransom", + "title": "Expeditioners podcast with marcus ransom", + "lastModifiedAt": 1726839805031, + "htmlId": "articles--expeditioners-podcas--98c32a782f", + "sectionRelativeRepoPath": "expeditioners-podcast-with-marcus-ransom.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2023-12-11", + "articleTitle": "ExpedITioners podcast with Marcus Ransom", + "articleImageUrl": "/images/articles/expeditioners-podcast-ep7-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/expeditioners-rich-trouton", + "title": "Expeditioners rich trouton", + "lastModifiedAt": 1726839805032, + "htmlId": "articles--expeditioners-rich-t--c394f4ba38", + "sectionRelativeRepoPath": "expeditioners-rich-trouton.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2023-08-31", + "articleTitle": "ExpedITioners podcast with Rich Trouton", + "articleImageUrl": "/images/articles/expeditioners-podcast-ep3-1600x900@2x.jpg" + } + }, + { + "url": "/guides/filtering-software-by-vulnerability", + "title": "Filtering software by vulnerability", + "lastModifiedAt": 1726839805033, + "htmlId": "articles--filtering-software-b--900d8b7307", + "sectionRelativeRepoPath": "filtering-software-by-vulnerability.md", + "meta": { + "articleTitle": "Filtering software by vulnerability in Fleet", + "authorFullName": "Tim Lee", + "authorGitHubUsername": "mostlikelee", + "category": "guides", + "publishedOn": "2024-08-30", + "articleImageUrl": "/images/articles/discovering-geacon-using-fleet-1600x900@2x.jpg", + "description": "Filter software by vulnerability in Fleet to prioritize critical patches and enhance your organization's security posture." + } + }, + { + "url": "/releases/fleet-3.10.0", + "title": "Fleet 3.10.0", + "lastModifiedAt": 1726839805034, + "htmlId": "articles--fleet-3100--09d2002dcd", + "sectionRelativeRepoPath": "fleet-3.10.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-04-01", + "articleTitle": "Fleet 3.10.0 released with agent auto-updates beta", + "articleImageUrl": "/images/articles/fleet-3.10.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-3.11.0", + "title": "Fleet 3.11.0", + "lastModifiedAt": 1726839805035, + "htmlId": "articles--fleet-3110--ad56a464f5", + "sectionRelativeRepoPath": "fleet-3.11.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-04-29", + "articleTitle": "Fleet 3.11.0 released with software inventory", + "articleImageUrl": "/images/articles/fleet-3.11.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-3.12.0", + "title": "Fleet 3.12.0", + "lastModifiedAt": 1726839805036, + "htmlId": "articles--fleet-3120--8f3c795b51", + "sectionRelativeRepoPath": "fleet-3.12.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-05-20", + "articleTitle": "Fleet 3.12.0", + "articleImageUrl": "/images/articles/fleet-3.12.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-3.5.0", + "title": "Fleet 3.5.0", + "lastModifiedAt": 1726839805037, + "htmlId": "articles--fleet-350--0912885a04", + "sectionRelativeRepoPath": "fleet-3.5.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2020-12-12", + "articleTitle": "Fleet 3.5.0", + "articleImageUrl": "/images/articles/fleet-3.5.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-3.6.0", + "title": "Fleet 3.6.0", + "lastModifiedAt": 1726839805039, + "htmlId": "articles--fleet-360--b415aaaf59", + "sectionRelativeRepoPath": "fleet-3.6.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-01-09", + "articleTitle": "Fleet 3.6.0", + "articleImageUrl": "/images/articles/fleet-3.6.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-3.13.0", + "title": "Fleet 3.13.0", + "lastModifiedAt": 1726839805041, + "htmlId": "articles--fleet-3130--6a4b26ee04", + "sectionRelativeRepoPath": "fleet-3.13.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-06-04", + "articleTitle": "Fleet 3.13.0", + "articleImageUrl": "/images/articles/fleet-3.13.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-3.7.1", + "title": "Fleet 3.7.1", + "lastModifiedAt": 1726839805042, + "htmlId": "articles--fleet-371--a3099c00cb", + "sectionRelativeRepoPath": "fleet-3.7.1.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-02-04", + "articleTitle": "Fleet 3.7.1", + "articleImageUrl": "/images/articles/fleet-3.7.1-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-3.8.0", + "title": "Fleet 3.8.0", + "lastModifiedAt": 1726839805042, + "htmlId": "articles--fleet-380--681019a9ad", + "sectionRelativeRepoPath": "fleet-3.8.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-02-26", + "articleTitle": "Fleet 3.8.0", + "articleImageUrl": "/images/articles/fleet-3.8.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-3.9.0", + "title": "Fleet 3.9.0", + "lastModifiedAt": 1726839805043, + "htmlId": "articles--fleet-390--7ceb277f2f", + "sectionRelativeRepoPath": "fleet-3.9.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-03-10", + "articleTitle": "Fleet 3.9.0", + "articleImageUrl": "/images/articles/fleet-3.9.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.0.0", + "title": "Fleet 4.0.0", + "lastModifiedAt": 1726839805044, + "htmlId": "articles--fleet-400--33d96e46d6", + "sectionRelativeRepoPath": "fleet-4.0.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-06-30", + "articleTitle": "Fleet 4.0.0 released with Role-based access control and Teams features", + "articleImageUrl": "/images/articles/fleet-4.0.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.1.0", + "title": "Fleet 4.1.0", + "lastModifiedAt": 1726839805045, + "htmlId": "articles--fleet-410--2f2a288a79", + "sectionRelativeRepoPath": "fleet-4.1.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-07-27", + "articleTitle": "Fleet 4.1.0 released with Schedule and Activity feed features", + "articleImageUrl": "/images/articles/fleet-4.1.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.10.0", + "title": "Fleet 4.10.0", + "lastModifiedAt": 1726839805046, + "htmlId": "articles--fleet-4100--dd259b5e42", + "sectionRelativeRepoPath": "fleet-4.10.0.md", + "meta": { + "category": "releases", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2022-02-14", + "articleTitle": "Fleet 4.10.0 brings new features and improvements for vulnerability analysts.", + "articleImageUrl": "/images/articles/fleet-4.10.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.12.0", + "title": "Fleet 4.12.0", + "lastModifiedAt": 1726839805047, + "htmlId": "articles--fleet-4120--150c6e2731", + "sectionRelativeRepoPath": "fleet-4.12.0.md", + "meta": { + "category": "releases", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2022-03-25", + "articleTitle": "Fleet 4.12.0 | Platform-specific policies, and improved query results", + "articleImageUrl": "/images/articles/fleet-4.12.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.13.0", + "title": "Fleet 4.13.0", + "lastModifiedAt": 1726839805047, + "htmlId": "articles--fleet-4130--771b1f08ac", + "sectionRelativeRepoPath": "fleet-4.13.0.md", + "meta": { + "category": "releases", + "authorFullName": "Fleet", + "authorGitHubUsername": "fleetdm", + "publishedOn": "2022-04-19", + "articleTitle": "Fleet 4.13.0 | Security fixes, policy automations for teams, and aggregated macOS versions for MacAdmins.", + "articleImageUrl": "/images/articles/fleet-4.13.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.11.0", + "title": "Fleet 4.11.0", + "lastModifiedAt": 1726839805048, + "htmlId": "articles--fleet-4110--a057b8896f", + "sectionRelativeRepoPath": "fleet-4.11.0.md", + "meta": { + "category": "releases", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2022-03-07", + "articleTitle": "Fleet 4.11.0 brings impact clarity, improvements to vulnerability processing, and performance updates.", + "articleImageUrl": "/images/articles/fleet-4.11.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.14.0", + "title": "Fleet 4.14.0", + "lastModifiedAt": 1726839805049, + "htmlId": "articles--fleet-4140--e58b7a34f3", + "sectionRelativeRepoPath": "fleet-4.14.0.md", + "meta": { + "category": "releases", + "authorFullName": "Kathy Satterlee", + "authorGitHubUsername": "ksatter", + "publishedOn": "2022-05-06", + "articleTitle": "Fleet 4.14.0 adds beta support for automatic ticket creation and improves the live query experience.", + "articleImageUrl": "/images/articles/fleet-4.14.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.16.0", + "title": "Fleet 4.16.0", + "lastModifiedAt": 1726839805051, + "htmlId": "articles--fleet-4160--ac79cd8c59", + "sectionRelativeRepoPath": "fleet-4.16.0.md", + "meta": { + "category": "releases", + "authorFullName": "Kathy Satterlee", + "authorGitHubUsername": "ksatter", + "publishedOn": "2022-06-16", + "articleTitle": "Fleet 4.16.0 | more customization, beefed up vuln management, Jira added to integrations.", + "articleImageUrl": "/images/articles/fleet-4.16.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.17.0", + "title": "Fleet 4.17.0", + "lastModifiedAt": 1726839805052, + "htmlId": "articles--fleet-4170--a276e12e2a", + "sectionRelativeRepoPath": "fleet-4.17.0.md", + "meta": { + "category": "releases", + "authorFullName": "Kathy Satterlee", + "authorGitHubUsername": "ksatter", + "publishedOn": "2022-07-11", + "articleTitle": "Fleet 4.17.0 | Better osquery management, user engagement, improved host vitals.", + "articleImageUrl": "/images/articles/fleet-4.17.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.15.0", + "title": "Fleet 4.15.0", + "lastModifiedAt": 1726839805053, + "htmlId": "articles--fleet-4150--3865641c1c", + "sectionRelativeRepoPath": "fleet-4.15.0.md", + "meta": { + "category": "releases", + "authorFullName": "Kathy Satterlee", + "authorGitHubUsername": "ksatter", + "publishedOn": "2022-05-30", + "articleTitle": "Fleet 4.15.0 adds beta support for Self-service, Scope transparency, and brings Zendesk to the party.", + "articleImageUrl": "/images/articles/fleet-4.15.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.18.0", + "title": "Fleet 4.18.0", + "lastModifiedAt": 1726839805054, + "htmlId": "articles--fleet-4180--9e4ce6c31b", + "sectionRelativeRepoPath": "fleet-4.18.0.md", + "meta": { + "category": "releases", + "authorFullName": "Kathy Satterlee", + "authorGitHubUsername": "ksatter", + "publishedOn": "2022-08-03", + "articleTitle": "Fleet 4.18.0 | Better security and user messaging in Fleet Desktop", + "articleImageUrl": "/images/articles/fleet-4.18.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.19.0", + "title": "Fleet 4.19.0", + "lastModifiedAt": 1726839805055, + "htmlId": "articles--fleet-4190--450188c15f", + "sectionRelativeRepoPath": "fleet-4.19.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2022-08-22", + "articleTitle": "Fleet 4.19.0 | Just-in-time (JIT) user provisioning, remaining disk space, aggregate Windows and mobile device management (MDM) data", + "articleImageUrl": "/images/articles/fleet-4.19.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.2.0", + "title": "Fleet 4.2.0", + "lastModifiedAt": 1726839805055, + "htmlId": "articles--fleet-420--ead484f1f9", + "sectionRelativeRepoPath": "fleet-4.2.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2021-08-12", + "articleTitle": "Fleet 4.2.0", + "articleImageUrl": "/images/articles/fleet-4.2.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.20.0", + "title": "Fleet 4.20.0", + "lastModifiedAt": 1726839805057, + "htmlId": "articles--fleet-4200--3a3e9234b6", + "sectionRelativeRepoPath": "fleet-4.20.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2022-09-09", + "articleTitle": "Fleet 4.20.0 | Aggregate Munki issues, test features on canary teams, improved macOS vulnerability detection", + "articleImageUrl": "/images/articles/fleet-4.20.0-1600x900.jpg" + } + }, + { + "url": "/releases/fleet-4.21.0", + "title": "Fleet 4.21.0", + "lastModifiedAt": 1726839805058, + "htmlId": "articles--fleet-4210--ef1f69ba72", + "sectionRelativeRepoPath": "fleet-4.21.0.md", + "meta": { + "category": "releases", + "authorFullName": "Chris McGillicuddy", + "authorGitHubUsername": "chris-mcgillicuddy", + "publishedOn": "2022-10-05", + "articleTitle": "Fleet 4.21.0 | Validate config and teams YAML documents, manage osquery flags remotely with Orbit, view team and global policy compliance", + "articleImageUrl": "/images/articles/fleet-4.21.0-1600x900@2x.jpeg" + } + }, + { + "url": "/releases/fleet-4.22.0", + "title": "Fleet 4.22.0", + "lastModifiedAt": 1726839805059, + "htmlId": "articles--fleet-4220--79ccc66c3c", + "sectionRelativeRepoPath": "fleet-4.22.0.md", + "meta": { + "category": "releases", + "authorFullName": "Chris McGillicuddy", + "authorGitHubUsername": "chris-mcgillicuddy", + "publishedOn": "2022-10-21", + "articleTitle": "Fleet 4.22.0 | Easier access to host information, better query console UX, and clearer display names", + "articleImageUrl": "/images/articles/fleet-4.22.0-cover-800x450@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.23.0", + "title": "Fleet 4.23.0", + "lastModifiedAt": 1726839805060, + "htmlId": "articles--fleet-4230--653ee52499", + "sectionRelativeRepoPath": "fleet-4.23.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2022-11-14", + "articleTitle": "Fleet 4.23.0 | Better insight into inherited policies, improved host vitals, and more configuration visibility", + "articleImageUrl": "/images/articles/fleet-4.23.0-800x450@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.24.0", + "title": "Fleet 4.24.0", + "lastModifiedAt": 1726839805061, + "htmlId": "articles--fleet-4240--19516bb4b8", + "sectionRelativeRepoPath": "fleet-4.24.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2022-12-06", + "articleTitle": "Fleet 4.24.0 | Live query notifications and navigation improvements", + "articleImageUrl": "/images/articles/fleet-4.24.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.25.0", + "title": "Fleet 4.25.0", + "lastModifiedAt": 1726839805063, + "htmlId": "articles--fleet-4250--9127fac1f2", + "sectionRelativeRepoPath": "fleet-4.25.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2023-01-03", + "articleTitle": "Fleet 4.25.0 | Extra security and MDM visibility", + "articleImageUrl": "/images/articles/fleet-4.25.0-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.26.0", + "title": "Fleet 4.26.0", + "lastModifiedAt": 1726839805064, + "htmlId": "articles--fleet-4260--3ecc26a58f", + "sectionRelativeRepoPath": "fleet-4.26.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2023-01-16", + "articleTitle": "Fleet 4.26.0 | Easier osquery extensions, external audit log destinations, and cleaner data lakes", + "articleImageUrl": "/images/articles/fleet-4.26.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.27.0", + "title": "Fleet 4.27.0", + "lastModifiedAt": 1726839805065, + "htmlId": "articles--fleet-4270--5def591f64", + "sectionRelativeRepoPath": "fleet-4.27.0.md", + "meta": { + "category": "releases", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "publishedOn": "2023-02-14", + "articleTitle": "Fleet 4.27.0 | Improved access management and improved search filters", + "articleImageUrl": "/images/articles/fleet-4.27.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.28.0", + "title": "Fleet 4.28.0", + "lastModifiedAt": 1726839805066, + "htmlId": "articles--fleet-4280--52f2441fa4", + "sectionRelativeRepoPath": "fleet-4.28.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-02-28", + "articleTitle": "Fleet 4.28.0 | CIS benchmarks for Ventura", + "articleImageUrl": "/images/articles/fleet-4.28.0-800x450@2x.png" + } + }, + { + "url": "/releases/fleet-4.29.0", + "title": "Fleet 4.29.0", + "lastModifiedAt": 1726839805067, + "htmlId": "articles--fleet-4290--507fc72ef3", + "sectionRelativeRepoPath": "fleet-4.29.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-03-22", + "articleTitle": "Fleet 4.29.0 | SSO provides JIT Fleet user roles", + "articleImageUrl": "/images/articles/fleet-4.29.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.3.0", + "title": "Fleet 4.3.0", + "lastModifiedAt": 1726839805068, + "htmlId": "articles--fleet-430--f231d44352", + "sectionRelativeRepoPath": "fleet-4.3.0.md", + "meta": { + "category": "releases", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2021-09-07", + "articleTitle": "Fleet 4.3.0", + "articleImageUrl": "/images/articles/fleet-4.3.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.30.0", + "title": "Fleet 4.30.0", + "lastModifiedAt": 1726839805069, + "htmlId": "articles--fleet-4300--0e053dac25", + "sectionRelativeRepoPath": "fleet-4.30.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-04-11", + "articleTitle": "Fleet 4.30.0 | MDM public beta, Observer+ role, Vulnerability publication dates", + "articleImageUrl": "/images/articles/fleet-4.30.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.31.0", + "title": "Fleet 4.31.0", + "lastModifiedAt": 1726839805071, + "htmlId": "articles--fleet-4310--439ea795b4", + "sectionRelativeRepoPath": "fleet-4.31.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-05-01", + "articleTitle": "Fleet 4.31.0 | MDM enrollment workflow, API user role.", + "articleImageUrl": "/images/articles/fleet-4.31.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.32.0", + "title": "Fleet 4.32.0", + "lastModifiedAt": 1726839805073, + "htmlId": "articles--fleet-4320--221d90689c", + "sectionRelativeRepoPath": "fleet-4.32.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-05-24", + "articleTitle": "Fleet 4.32.0 | User migration, customizing macOS Setup Assistant.", + "articleImageUrl": "/images/articles/fleet-4.32.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.33.0", + "title": "Fleet 4.33.0", + "lastModifiedAt": 1726839805074, + "htmlId": "articles--fleet-4330--3b965c130a", + "sectionRelativeRepoPath": "fleet-4.33.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-06-13", + "articleTitle": "Fleet 4.33.0 | ChromeOS support, new verified status", + "articleImageUrl": "/images/articles/fleet-4.33.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.34.0", + "title": "Fleet 4.34.0", + "lastModifiedAt": 1726839805075, + "htmlId": "articles--fleet-4340--aab74d16d2", + "sectionRelativeRepoPath": "fleet-4.34.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-07-12", + "articleTitle": "Fleet 4.34.0 | ChromeOS tables, CIS Benchmark load testing", + "articleImageUrl": "/images/articles/fleet-4.34.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.35.0", + "title": "Fleet 4.35.0", + "lastModifiedAt": 1726839805076, + "htmlId": "articles--fleet-4350--d4921e1140", + "sectionRelativeRepoPath": "fleet-4.35.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-08-01", + "articleTitle": "Fleet 4.35.0 | Improvements and bug fixes.", + "articleImageUrl": "/images/articles/fleet-4.35.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.37.0", + "title": "Fleet 4.37.0", + "lastModifiedAt": 1726839805077, + "htmlId": "articles--fleet-4370--56524e6b70", + "sectionRelativeRepoPath": "fleet-4.37.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-09-07", + "articleTitle": "Fleet 4.37.0 | Remote script execution & Puppet support.", + "articleImageUrl": "/images/articles/fleet-4.37.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.36.0", + "title": "Fleet 4.36.0", + "lastModifiedAt": 1726839805078, + "htmlId": "articles--fleet-4360--0167b9704b", + "sectionRelativeRepoPath": "fleet-4.36.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-08-18", + "articleTitle": "Fleet 4.36.0 | Saved and scheduled queries merge.", + "articleImageUrl": "/images/articles/fleet-4.36.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.38.0", + "title": "Fleet 4.38.0", + "lastModifiedAt": 1726839805080, + "htmlId": "articles--fleet-4380--8522df1a2e", + "sectionRelativeRepoPath": "fleet-4.38.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-09-25", + "articleTitle": "Fleet 4.38.0 | Profile redelivery, NVD details, and custom extension label support.", + "articleImageUrl": "/images/articles/fleet-4.38.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.39.0", + "title": "Fleet 4.39.0", + "lastModifiedAt": 1726839805081, + "htmlId": "articles--fleet-4390--ad9a535d1c", + "sectionRelativeRepoPath": "fleet-4.39.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-10-26", + "articleTitle": "Fleet 4.39.0 | Sonoma support, script library, query reports.", + "articleImageUrl": "/images/articles/fleet-4.39.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.4.0", + "title": "Fleet 4.4.0", + "lastModifiedAt": 1726839805082, + "htmlId": "articles--fleet-440--24061a1eff", + "sectionRelativeRepoPath": "fleet-4.4.0.md", + "meta": { + "category": "releases", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2021-10-07", + "articleTitle": "Fleet 4.4.0 releases aggregated software inventory, team policies, and improved team scheduling", + "articleImageUrl": "/images/articles/fleet-4.4.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.40.0", + "title": "Fleet 4.40.0", + "lastModifiedAt": 1726839805083, + "htmlId": "articles--fleet-4400--53f1a0954b", + "sectionRelativeRepoPath": "fleet-4.40.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-11-06", + "articleTitle": "Fleet 4.40.0 | More Data, Rapid Security Response, CIS Benchmark updates.", + "articleImageUrl": "/images/articles/fleet-4.40.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.41.0", + "title": "Fleet 4.41.0", + "lastModifiedAt": 1726839805084, + "htmlId": "articles--fleet-4410--f4c37d963b", + "sectionRelativeRepoPath": "fleet-4.41.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-11-28", + "articleTitle": "Fleet 4.41.0 | NVD API 2.0, Windows script library.", + "articleImageUrl": "/images/articles/fleet-4.41.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.42.0", + "title": "Fleet 4.42.0", + "lastModifiedAt": 1726839805086, + "htmlId": "articles--fleet-4420--8d6641fa28", + "sectionRelativeRepoPath": "fleet-4.42.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-12-21", + "articleTitle": "Fleet 4.42.0 | Query performance reporting, host targeting improvements.", + "articleImageUrl": "/images/articles/fleet-4.42.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.43.0", + "title": "Fleet 4.43.0", + "lastModifiedAt": 1726839805087, + "htmlId": "articles--fleet-4430--296526b139", + "sectionRelativeRepoPath": "fleet-4.43.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-01-09", + "articleTitle": "Fleet 4.43.0 | Query performance reporting, host targeting improvements.", + "articleImageUrl": "/images/articles/fleet-4.43.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.44.0", + "title": "Fleet 4.44.0", + "lastModifiedAt": 1726839805089, + "htmlId": "articles--fleet-4440--e0c9504248", + "sectionRelativeRepoPath": "fleet-4.44.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-02-05", + "articleTitle": "Fleet 4.44.0 | Script execution, host expiry, and host targeting improvements.", + "articleImageUrl": "/images/articles/fleet-4.44.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.45.0", + "title": "Fleet 4.45.0", + "lastModifiedAt": 1726839805090, + "htmlId": "articles--fleet-4450--525bed4841", + "sectionRelativeRepoPath": "fleet-4.45.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-02-21", + "articleTitle": "Fleet 4.45.0 | Remote lock, Linux script library, osquery storage location.", + "articleImageUrl": "/images/articles/fleet-4.45.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.46.0", + "title": "Fleet 4.46.0", + "lastModifiedAt": 1726839805091, + "htmlId": "articles--fleet-4460--2bc79fbeb9", + "sectionRelativeRepoPath": "fleet-4.46.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-02-26", + "articleTitle": "Fleet 4.46.0 | Automatic SCEP certificate renewal.", + "articleImageUrl": "/images/articles/fleet-4.46.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.47.0", + "title": "Fleet 4.47.0", + "lastModifiedAt": 1726839805092, + "htmlId": "articles--fleet-4470--d61e2e7199", + "sectionRelativeRepoPath": "fleet-4.47.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-03-12", + "articleTitle": "Fleet 4.47.0 | Cross-platform remote wipe, vulnerabilities page, and scripting improvements.", + "articleImageUrl": "/images/articles/fleet-4.47.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.48.0", + "title": "Fleet 4.48.0", + "lastModifiedAt": 1726839805094, + "htmlId": "articles--fleet-4480--ecbe7beab5", + "sectionRelativeRepoPath": "fleet-4.48.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-04-03", + "articleTitle": "Fleet 4.48.0 | IdP local account creation, VS Code extensions.", + "articleImageUrl": "/images/articles/fleet-4.48.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.49.0", + "title": "Fleet 4.49.0", + "lastModifiedAt": 1726839805095, + "htmlId": "articles--fleet-4490--c90f5fc656", + "sectionRelativeRepoPath": "fleet-4.49.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-04-23", + "articleTitle": "Fleet 4.49.0 | VulnCheck's NVD++, device health API, fleetd data parsing.", + "articleImageUrl": "/images/articles/fleet-4.49.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.5.0", + "title": "Fleet 4.5.0", + "lastModifiedAt": 1726839805096, + "htmlId": "articles--fleet-450--2c474c8040", + "sectionRelativeRepoPath": "fleet-4.5.0.md", + "meta": { + "category": "releases", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2021-11-02", + "articleTitle": "Fleet 4.5.0 with new team admin role, live OS compatibility checking, query performance impact, and a new-look dashboard", + "articleImageUrl": "/images/articles/fleet-4.5.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.50.0", + "title": "Fleet 4.50.0", + "lastModifiedAt": 1726839805098, + "htmlId": "articles--fleet-4500--44757c8700", + "sectionRelativeRepoPath": "fleet-4.50.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-05-22", + "articleTitle": "Fleet 4.50.0 | Security agent deployment, AI descriptions, and Mac Admins SOFA support.", + "articleImageUrl": "/images/articles/fleet-4.50.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.53.0", + "title": "Fleet 4.53.0", + "lastModifiedAt": 1726839805100, + "htmlId": "articles--fleet-4530--1cc540fb24", + "sectionRelativeRepoPath": "fleet-4.53.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-06-25", + "articleTitle": "Fleet 4.53.0 | Better vuln matching, multi-issue hosts, & `fleetd` logs as tables", + "articleImageUrl": "/images/articles/fleet-4.53.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.54.0", + "title": "Fleet 4.54.0", + "lastModifiedAt": 1726839805101, + "htmlId": "articles--fleet-4540--11b1c848f2", + "sectionRelativeRepoPath": "fleet-4.54.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-07-17", + "articleTitle": "Fleet 4.54.0 | Target hosts via label exclusion, script execution time.", + "articleImageUrl": "/images/articles/fleet-4.54.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.51.0", + "title": "Fleet 4.51.0", + "lastModifiedAt": 1726839805102, + "htmlId": "articles--fleet-4510--7274f6fa9d", + "sectionRelativeRepoPath": "fleet-4.51.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-06-10", + "articleTitle": "Fleet 4.51.0 | Global activity webhook, macOS TCC table, and software self-service.", + "articleImageUrl": "/images/articles/fleet-4.51.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.55.0", + "title": "Fleet 4.55.0", + "lastModifiedAt": 1726839805106, + "htmlId": "articles--fleet-4550--f7134a8007", + "sectionRelativeRepoPath": "fleet-4.55.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-08-09", + "articleTitle": "Fleet 4.55.0 | MySQL 8, arm64 support, FileVault improvements, VPP support.", + "articleImageUrl": "/images/articles/fleet-4.55.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.56.0", + "title": "Fleet 4.56.0", + "lastModifiedAt": 1726839805108, + "htmlId": "articles--fleet-4560--6f2f9c6451", + "sectionRelativeRepoPath": "fleet-4.56.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-09-07", + "articleTitle": "Fleet 4.56.0 | Enhanced MDM migration, Exact CVE Search, and Self-Service VPP Apps.", + "articleImageUrl": "/images/articles/fleet-4.56.0-1600x900@2x.png" + } + }, + { + "url": "/releases/fleet-4.6.0", + "title": "Fleet 4.6.0", + "lastModifiedAt": 1726839805109, + "htmlId": "articles--fleet-460--d71c3386e5", + "sectionRelativeRepoPath": "fleet-4.6.0.md", + "meta": { + "category": "releases", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2021-11-19", + "articleTitle": "Fleet 4.6.0 with osquery installer, enroll secret management, and improved host vitals", + "articleImageUrl": "/images/articles/fleet-4.6.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.7.0", + "title": "Fleet 4.7.0", + "lastModifiedAt": 1726839805110, + "htmlId": "articles--fleet-470--f6d85e866c", + "sectionRelativeRepoPath": "fleet-4.7.0.md", + "meta": { + "category": "releases", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2021-12-14", + "articleTitle": "Does Fleet 4.7.0 bring more power to your osquery compliance policies? Yes.", + "articleImageUrl": "/images/articles/fleet-4.7.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.8.0", + "title": "Fleet 4.8.0", + "lastModifiedAt": 1726839805111, + "htmlId": "articles--fleet-480--e0296e324b", + "sectionRelativeRepoPath": "fleet-4.8.0.md", + "meta": { + "category": "releases", + "authorFullName": "Drew Baker", + "authorGitHubUsername": "Drew-P-drawers", + "publishedOn": "2021-12-31", + "articleTitle": "Looking for policy automations, Google Chrome profile search, and Munki details from your hosts? Upgrade to Fleet 4.8.0", + "articleImageUrl": "/images/articles/fleet-4.8.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/releases/fleet-4.9.0", + "title": "Fleet 4.9.0", + "lastModifiedAt": 1726839805112, + "htmlId": "articles--fleet-490--d6149315ff", + "sectionRelativeRepoPath": "fleet-4.9.0.md", + "meta": { + "category": "releases", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2022-01-24", + "articleTitle": "Fleet 4.9.0 brings performance updates, paginated live query results, and policy YAML doc support.", + "articleImageUrl": "/images/articles/fleet-4.9.0-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/fleet-ai-assisted-policy-descriptions-and-resolutions", + "title": "Fleet ai assisted policy descriptions and resolutions", + "lastModifiedAt": 1726839805113, + "htmlId": "articles--fleet-ai-assisted-po--74a94535fe", + "sectionRelativeRepoPath": "fleet-ai-assisted-policy-descriptions-and-resolutions.md", + "meta": { + "articleTitle": "Fleet’s AI-assisted policy descriptions and resolutions", + "authorFullName": "Rachel Perkins", + "authorGitHubUsername": "rachelelysia", + "category": "guides", + "publishedOn": "2024-05-20", + "articleImageUrl": "/images/articles/fleet-ai-assisted-policy-descriptions-and-resolutions-1600x900@2x.png", + "description": "AI guides our way, Policies clear, secure paths, Compliance shines bright." + } + }, + { + "url": "/announcements/fleet-adds-support-for-chrome-os", + "title": "Fleet adds support for chrome os", + "lastModifiedAt": 1726839805114, + "htmlId": "articles--fleet-adds-support-f--e846968e31", + "sectionRelativeRepoPath": "fleet-adds-support-for-chrome-os.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "spokanemac", + "authorFullName": "JD Strong", + "publishedOn": "2023-06-13", + "articleTitle": "Fleet enhances device management with ChromeOS support", + "articleImageUrl": "/images/articles/fleet-adds-support-for-chrome-os-1600x900@2x.png", + "description": "We're thrilled to announce that Fleet has expanded support to include ChromeOS and ChromeOS Flex!" + } + }, + { + "url": "/announcements/fleet-desktop-says-hello-world", + "title": "Fleet desktop says hello world", + "lastModifiedAt": 1726839805115, + "htmlId": "articles--fleet-desktop-says-h--b773918322", + "sectionRelativeRepoPath": "fleet-desktop-says-hello-world.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "zhumo", + "authorFullName": "Mo Zhu", + "publishedOn": "2022-08-02", + "articleTitle": "Fleet Desktop says “Hello, world!”", + "articleImageUrl": "/images/articles/fleet-desktop-says-hello-world-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/fleet-desktop", + "title": "Fleet desktop", + "lastModifiedAt": 1726839805116, + "htmlId": "articles--fleet-desktop--9214a6a67a", + "sectionRelativeRepoPath": "fleet-desktop.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "zhumo", + "authorFullName": "Mo Zhu", + "publishedOn": "2024-04-19", + "articleTitle": "Fleet Desktop", + "description": "Learn about Fleet Desktop's features for self-remediation and transparency." + } + }, + { + "url": "/announcements/fleet-in-vegas-2023", + "title": "Fleet in vegas 2023", + "lastModifiedAt": 1726839805117, + "htmlId": "articles--fleet-in-vegas-2023--284818a7ab", + "sectionRelativeRepoPath": "fleet-in-vegas-2023.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "spokanemac", + "authorFullName": "JD Strong", + "publishedOn": "2023-08-02", + "articleTitle": "Fleet takes on Vegas: Exploring cybersecurity's future at Black Hat, B-Sides, and DEF CON 31", + "articleImageUrl": "/images/articles/fleet-in-vegas-2023@2x.jpg", + "description": "Explore cybersecurity's cutting edge with Fleet at three top-tier conferences - Black Hat, Security B-Sides, and DEF CON." + } + }, + { + "url": "/releases/fleet-introduces-mdm", + "title": "Fleet introduces mdm", + "lastModifiedAt": 1726839805118, + "htmlId": "articles--fleet-introduces-mdm--e7ec825f3a", + "sectionRelativeRepoPath": "fleet-introduces-mdm.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-04-11", + "articleTitle": "Fleet introduces MDM", + "articleImageUrl": "/images/articles/fleet-mdm-launch-cover-800x450@2x.jpg" + } + }, + { + "url": "/announcements/fleet-in-your-calendar-introducing-maintenance-windows", + "title": "Fleet in your calendar introducing maintenance windows", + "lastModifiedAt": 1726839805119, + "htmlId": "articles--fleet-in-your-calend--35d205d395", + "sectionRelativeRepoPath": "fleet-in-your-calendar-introducing-maintenance-windows.md", + "meta": { + "category": "announcements", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-04-30", + "articleTitle": "Fleet in your calendar: introducing maintenance windows", + "articleImageUrl": "/images/articles/fleet-in-your-calendar-introducing-maintenance-windows-cover-900x450@2x.png", + "description": "Like any good colleague, when Fleet needs some of your time, it puts it on your calendar." + } + }, + { + "url": "/announcements/fleet-introduces-windows-mdm", + "title": "Fleet introduces windows mdm", + "lastModifiedAt": 1726839805120, + "htmlId": "articles--fleet-introduces-win--c7cafc9ba6", + "sectionRelativeRepoPath": "fleet-introduces-windows-mdm.md", + "meta": { + "category": "announcements", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-01-24", + "articleTitle": "Fleet introduces Windows MDM", + "articleImageUrl": "/images/articles/fleet-win-mdm-launch-cover-800x450@2x.png" + } + }, + { + "url": "/announcements/fleet-is-abuzz-for-macdevops-yvr-2023", + "title": "Fleet is abuzz for macdevops yvr 2023", + "lastModifiedAt": 1726839805121, + "htmlId": "articles--fleet-is-abuzz-for-m--ad5da5f6fb", + "sectionRelativeRepoPath": "fleet-is-abuzz-for-macdevops-yvr-2023.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "spokanemac", + "authorFullName": "JD Strong", + "publishedOn": "2023-06-07", + "articleTitle": "Fleet is abuzz 🐝 for MacDevOps:YVR", + "articleImageUrl": "/images/articles/fleet-is-abuzz-for-macdevops-yvr-2023@2x.png", + "description": "Fleet is a proud sponsor of MacDevOps:YVR which is back in person in Vancouver, B.C. June 21-22, 2023" + } + }, + { + "url": "/securing/fleet-osquery-unlocking-the-value-of-axonius-with-open-source-telemetry", + "title": "Fleet osquery unlocking the value of axonius with open source telemetry", + "lastModifiedAt": 1726839805122, + "htmlId": "articles--fleet-osquery-unlock--3d8a42de76", + "sectionRelativeRepoPath": "fleet-osquery-unlocking-the-value-of-axonius-with-open-source-telemetry.md", + "meta": { + "category": "security", + "authorFullName": "Brad Macdowall", + "authorGitHubUsername": "BradMacd", + "publishedOn": "2023-12-28", + "articleTitle": "Fleet & osquery: Unlocking the value of Axonius with open-source telemetry", + "articleImageUrl": "/images/articles/fleet-osquery-unlocking-the-value-of-axonius-with-open-source-telemetry-1600x900@2x.png" + } + }, + { + "url": "/guides/fleet-quick-tips-querying-procdump-eula-has-been-accepted", + "title": "Fleet quick tips querying procdump eula has been accepted", + "lastModifiedAt": 1726839805123, + "htmlId": "articles--fleet-quick-tips-que--083c7ab95c", + "sectionRelativeRepoPath": "fleet-quick-tips-querying-procdump-eula-has-been-accepted.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "mike-j-thomas", + "authorFullName": "Mike Thomas", + "publishedOn": "2021-05-11", + "articleTitle": "Fleet quick tips — identify systems where the ProcDump EULA has been accepted", + "articleImageUrl": "/images/articles/fleet-quick-tips-querying-procdump-eula-has-been-accepted-cover-700x440@2x.png" + } + }, + { + "url": "/guides/fleet-terraform-byo-vpc-module", + "title": "Fleet terraform byo vpc module", + "lastModifiedAt": 1726839805124, + "htmlId": "articles--fleet-terraform-byo---dc914e6434", + "sectionRelativeRepoPath": "fleet-terraform-byo-vpc-module.md", + "meta": { + "category": "guides", + "authorFullName": "Robert Fairburn", + "authorGitHubUsername": "rfairburn", + "publishedOn": "2023-09-01", + "articleTitle": "Using the Fleet Terraform module with an existing VPC" + } + }, + { + "url": "/announcements/fleet-terraform-module", + "title": "Fleet terraform module", + "lastModifiedAt": 1726839805125, + "htmlId": "articles--fleet-terraform-modu--290ad35faf", + "sectionRelativeRepoPath": "fleet-terraform-module.md", + "meta": { + "category": "announcements", + "authorFullName": "Zachary Winnerman", + "authorGitHubUsername": "zwinnerman-fleetdm", + "publishedOn": "2023-01-09", + "articleTitle": "Keep Fleet running smoothly on AWS with the new Terraform module" + } + }, + { + "url": "/guides/fleet-usage-statistics", + "title": "Fleet usage statistics", + "lastModifiedAt": 1726839805126, + "htmlId": "articles--fleet-usage-statisti--8212e2baf7", + "sectionRelativeRepoPath": "fleet-usage-statistics.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-08-13", + "articleTitle": "Fleet usage statistics", + "description": "Learn about Fleet's usage statistics and what information is collected." + } + }, + { + "url": "/success-stories/fleet-user-stories-f100", + "title": "Fleet user stories f100", + "lastModifiedAt": 1726839805127, + "htmlId": "articles--fleet-user-stories-f--869652e2be", + "sectionRelativeRepoPath": "fleet-user-stories-f100.md", + "meta": { + "category": "success stories", + "authorGitHubUsername": "mike-j-thomas", + "authorFullName": "Mike Thomas", + "publishedOn": "2021-09-29", + "articleTitle": "Fleet user stories — F100", + "articleImageUrl": "/images/articles/fleet-user-stories-f100-cover-800x450@2x.png" + } + }, + { + "url": "/success-stories/fleet-user-stories-schrodinger", + "title": "Fleet user stories schrodinger", + "lastModifiedAt": 1726839805127, + "htmlId": "articles--fleet-user-stories-s--1486ea1812", + "sectionRelativeRepoPath": "fleet-user-stories-schrodinger.md", + "meta": { + "category": "success stories", + "authorGitHubUsername": "mike-j-thomas", + "authorFullName": "Mike Thomas", + "publishedOn": "2021-09-10", + "articleTitle": "Fleet user stories — Schrödinger", + "articleImageUrl": "/images/articles/fleet-user-stories-schrodinger-cover-800x450@2x.png" + } + }, + { + "url": "/success-stories/fleet-user-stories-wayfair", + "title": "Fleet user stories wayfair", + "lastModifiedAt": 1726839805128, + "htmlId": "articles--fleet-user-stories-w--c78d4fa6b9", + "sectionRelativeRepoPath": "fleet-user-stories-wayfair.md", + "meta": { + "category": "success stories", + "authorGitHubUsername": "mike-j-thomas", + "authorFullName": "Mike Thomas", + "publishedOn": "2021-08-20", + "articleTitle": "Fleet user stories — Wayfair", + "articleImageUrl": "/images/articles/fleet-user-stories-wayfair-cover-800x450@2x.png" + } + }, + { + "url": "/guides/fleetctl", + "title": "Fleetctl", + "lastModifiedAt": 1726839805129, + "htmlId": "articles--fleetctl--0cb8193ba2", + "sectionRelativeRepoPath": "fleetctl.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-07-04", + "articleTitle": "fleetctl", + "description": "Read about fleetctl, a CLI tool for managing Fleet and osquery configurations, running queries, generating Fleet's agent (fleetd) and more." + } + }, + { + "url": "/announcements/from-osquery-to-fleet-planting-the-seed", + "title": "From osquery to Fleet planting the seed", + "lastModifiedAt": 1726839805130, + "htmlId": "articles--from-osquery-to-flee--229a9b9742", + "sectionRelativeRepoPath": "from-osquery-to-fleet-planting-the-seed.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-01-20", + "articleTitle": "The next step for Fleet: our $5M seed round 🌱", + "articleImageUrl": "/images/articles/from-osquery-to-fleet-planting-the-seed-cover-800x450@2x.png" + } + }, + { + "url": "/guides/fleetd-updates", + "title": "Fleetd updates", + "lastModifiedAt": 1726839805131, + "htmlId": "articles--fleetd-updates--6d4aebafec", + "sectionRelativeRepoPath": "fleetd-updates.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-04-30", + "articleTitle": "Fleetd updates", + "description": "Information on how to manage and secure Fleet agent updates." + } + }, + { + "url": "/guides/generate-process-trees-with-osquery", + "title": "Generate process trees with osquery", + "lastModifiedAt": 1726839805132, + "htmlId": "articles--generate-process-tre--d1b0edcce1", + "sectionRelativeRepoPath": "generate-process-trees-with-osquery.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2020-03-17", + "articleTitle": "Generate process trees with osquery", + "articleImageUrl": "/images/articles/generate-process-trees-with-osquery-cover-700x393@2x.jpeg" + } + }, + { + "url": "/securing/get-and-stay-compliant-across-your-devices-with-fleet", + "title": "Get and stay compliant across your devices with Fleet", + "lastModifiedAt": 1726839805133, + "htmlId": "articles--get-and-stay-complia--2cb805730d", + "sectionRelativeRepoPath": "get-and-stay-compliant-across-your-devices-with-fleet.md", + "meta": { + "category": "security", + "authorFullName": "Drew Baker", + "authorGitHubUsername": "Drew-P-drawers", + "publishedOn": "2022-03-09", + "articleTitle": "Get and stay compliant across your devices with Fleet.", + "articleImageUrl": "/images/articles/get-and-stay-compliant-across-your-devices-with-fleet-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/get-current-telemetry-from-your-devices-with-live-queries", + "title": "Get current telemetry from your devices with live queries", + "lastModifiedAt": 1726839805134, + "htmlId": "articles--get-current-telemetr--019d64996a", + "sectionRelativeRepoPath": "get-current-telemetry-from-your-devices-with-live-queries.md", + "meta": { + "articleTitle": "Get current telemetry from your devices with live queries", + "authorFullName": "Victor Lyuboslavsky", + "authorGitHubUsername": "getvictor", + "category": "guides", + "publishedOn": "2023-12-27", + "description": "Learn how live queries work under the hood." + } + }, + { + "url": "/announcements/government-agencies-need-to-dith-the-mdm-thicket", + "title": "Government agencies need to dith the mdm thicket", + "lastModifiedAt": 1726839805135, + "htmlId": "articles--government-agencies---f0385b3f79", + "sectionRelativeRepoPath": "government-agencies-need-to-dith-the-mdm-thicket.md", + "meta": { + "category": "announcements", + "authorFullName": "Keith Barnes", + "authorGitHubUsername": "KAB703", + "publishedOn": "2024-02-09", + "articleTitle": "Government agencies need to ditch the MDM thicket: multiple solutions cost you more than you think", + "articleImageUrl": "/images/articles/government-agencies-need-to-dith-the-mdm-thicket-1600x900@2x.png" + } + }, + { + "url": "/announcements/happy-1st-anniversary-fleet", + "title": "Happy 1st anniversary Fleet", + "lastModifiedAt": 1726839805135, + "htmlId": "articles--happy-1st-anniversar--128480e14b", + "sectionRelativeRepoPath": "happy-1st-anniversary-fleet.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "mike-j-thomas", + "authorFullName": "Mike Thomas", + "publishedOn": "2021-10-08", + "articleTitle": "Happy 1st anniversary, Fleet.", + "articleImageUrl": "/images/articles/happy-1st-anniversary-fleet-cover-800x450@2x.png" + } + }, + { + "url": "/securing/how-fleet-helps-federal-agencies-meet-cisa-bod-23-01", + "title": "How Fleet helps federal agencies meet cisa bod 23 01", + "lastModifiedAt": 1726839805136, + "htmlId": "articles--how-fleet-helps-fede--82d74da10e", + "sectionRelativeRepoPath": "how-fleet-helps-federal-agencies-meet-cisa-bod-23-01.md", + "meta": { + "category": "security", + "authorFullName": "Chris McGillicuddy", + "authorGitHubUsername": "chris-mcgillicuddy", + "publishedOn": "2022-10-28", + "articleTitle": "How Fleet helps federal agencies meet CISA BOD 23-01", + "articleImageUrl": "/images/articles/BOD-23-01-800x450@2x.jpg" + } + }, + { + "url": "/securing/how-osquery-can-help-cyber-responders", + "title": "How osquery can help cyber responders", + "lastModifiedAt": 1726839805138, + "htmlId": "articles--how-osquery-can-help--eca2df006d", + "sectionRelativeRepoPath": "how-osquery-can-help-cyber-responders.md", + "meta": { + "category": "security", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-11-02", + "articleTitle": "How osquery can help cyber responders.", + "articleImageUrl": "/images/articles/osquery-for-cyber-responders-1600x900@2x.png" + } + }, + { + "url": "/guides/how-to-configure-logging-destinations", + "title": "How to configure logging destinations", + "lastModifiedAt": 1726839805139, + "htmlId": "articles--how-to-configure-log--e7ef58a2dc", + "sectionRelativeRepoPath": "how-to-configure-logging-destinations.md", + "meta": { + "category": "guides", + "authorFullName": "Grant Bilstad", + "authorGitHubUsername": "pacamaster", + "publishedOn": "2024-06-28", + "articleTitle": "How to configure logging destinations", + "articleImageUrl": "/images/articles/how-to-configure-logging-destinations-1600x900@2x.jpg" + } + }, + { + "url": "/guides/how-to-install-osquery-and-enroll-linux-devices-into-fleet", + "title": "How to install osquery and enroll linux devices into Fleet", + "lastModifiedAt": 1726839805140, + "htmlId": "articles--how-to-install-osque--7ef1932c39", + "sectionRelativeRepoPath": "how-to-install-osquery-and-enroll-linux-devices-into-fleet.md", + "meta": { + "category": "guides", + "authorFullName": "Kathy Satterlee", + "authorGitHubUsername": "ksatter", + "publishedOn": "2022-03-19", + "articleTitle": "How to install osquery and enroll Linux devices into Fleet", + "articleImageUrl": "/images/articles/install-osquery-and-enroll-linux-devices-into-fleet-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/how-to-install-osquery-and-enroll-macos-devices-into-fleet", + "title": "How to install osquery and enroll macos devices into Fleet", + "lastModifiedAt": 1726839805142, + "htmlId": "articles--how-to-install-osque--9584297736", + "sectionRelativeRepoPath": "how-to-install-osquery-and-enroll-macos-devices-into-fleet.md", + "meta": { + "category": "guides", + "authorFullName": "Kelvin Omereshone", + "authorGitHubUsername": "dominuskelvin", + "publishedOn": "2022-01-13", + "articleTitle": "How to install osquery and enroll macOS devices into Fleet", + "articleImageUrl": "/images/articles/install-osquery-and-enroll-macos-devices-into-fleet-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/how-to-install-osquery-and-enroll-windows-devices-into-fleet", + "title": "How to install osquery and enroll windows devices into Fleet", + "lastModifiedAt": 1726839805143, + "htmlId": "articles--how-to-install-osque--65750e792f", + "sectionRelativeRepoPath": "how-to-install-osquery-and-enroll-windows-devices-into-fleet.md", + "meta": { + "category": "guides", + "authorFullName": "Kelvin Omereshone", + "authorGitHubUsername": "dominuskelvin", + "publishedOn": "2022-02-03", + "articleTitle": "How to install osquery and enroll Windows devices into Fleet", + "articleImageUrl": "/images/articles/install-osquery-and-enroll-windows-devices-into-fleet-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/how-to-uninstall-osquery", + "title": "How to uninstall osquery", + "lastModifiedAt": 1726839805143, + "htmlId": "articles--how-to-uninstall-osq--7455ca45fc", + "sectionRelativeRepoPath": "how-to-uninstall-osquery.md", + "meta": { + "category": "guides", + "authorFullName": "Eric Shaw", + "authorGitHubUsername": "eashaw", + "publishedOn": "2021-09-08", + "articleTitle": "How to uninstall osquery", + "articleImageUrl": "/images/articles/how-to-uninstall-osquery-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/import-and-export-queries-in-fleet", + "title": "Import and export queries in Fleet", + "lastModifiedAt": 1726839805144, + "htmlId": "articles--import-and-export-qu--44b09ee020", + "sectionRelativeRepoPath": "import-and-export-queries-in-fleet.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2021-02-16", + "articleTitle": "Import and export queries in Fleet", + "articleImageUrl": "/images/articles/import-and-export-queries-in-Fleet-1600x900@2x.png" + } + }, + { + "url": "/guides/install-vpp-apps-on-macos-using-fleet", + "title": "Install vpp apps on macos using Fleet", + "lastModifiedAt": 1726839805145, + "htmlId": "articles--install-vpp-apps-on---4e6a161ea8", + "sectionRelativeRepoPath": "install-vpp-apps-on-macos-using-fleet.md", + "meta": { + "articleTitle": "Install VPP apps on macOS, iOS, and iPadOS using Fleet", + "authorFullName": "Jahziel Villasana-Espinoza", + "authorGitHubUsername": "jahzielv", + "category": "guides", + "publishedOn": "2024-08-12", + "articleImageUrl": "/images/articles/install-vpp-apps-on-macos-using-fleet-1600x900@2x.png", + "description": "This guide will walk you through installing VPP apps on macOS, iOS, and iPadOS using Fleet." + } + }, + { + "url": "/announcements/introducing-cross-platform-script-execution", + "title": "Introducing cross platform script execution", + "lastModifiedAt": 1726839805147, + "htmlId": "articles--introducing-cross-pl--f50031e3db", + "sectionRelativeRepoPath": "introducing-cross-platform-script-execution.md", + "meta": { + "category": "announcements", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-10-17", + "articleTitle": "Introducing cross-platform script execution", + "articleImageUrl": "/images/articles/introducing-cross-platform-script-execution-800x450@2x.png" + } + }, + { + "url": "/announcements/introducing-fleet-ultimate", + "title": "Introducing Fleet ultimate", + "lastModifiedAt": 1726839805147, + "htmlId": "articles--introducing-fleet-ul--caba265ec4", + "sectionRelativeRepoPath": "introducing-fleet-ultimate.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "jarodreyes", + "authorFullName": "Jarod Reyes", + "publishedOn": "2023-02-20", + "articleTitle": "Introducing CIS benchmarks, managed-cloud hosting and custom calculator in the new Fleet Ultimate plan.", + "articleImageUrl": "/images/articles/happy-1st-anniversary-fleet-cover-800x450@2x.png" + } + }, + { + "url": "/announcements/introducing-orbit-your-fleet-agent-manager", + "title": "Introducing orbit your Fleet agent manager", + "lastModifiedAt": 1726839805148, + "htmlId": "articles--introducing-orbit-yo--1de0ea07ab", + "sectionRelativeRepoPath": "introducing-orbit-your-fleet-agent-manager.md", + "meta": { + "category": "announcements", + "authorFullName": "Mo Zhu", + "authorGitHubUsername": "zhumo", + "publishedOn": "2022-08-18", + "articleTitle": "Introducing Orbit, your Fleet agent manager", + "articleImageUrl": "/images/articles/fleet-4.17.0-1-1600x900@2x.jpg" + } + }, + { + "url": "/engineering/linux-vulnerability-detection-with-oval-and-fleet", + "title": "Linux vulnerability detection with oval and Fleet", + "lastModifiedAt": 1726839805150, + "htmlId": "articles--linux-vulnerability---0d4c8fd5ac", + "sectionRelativeRepoPath": "linux-vulnerability-detection-with-oval-and-fleet.md", + "meta": { + "category": "engineering", + "authorGitHubUsername": "juan-fdz-hawa", + "authorFullName": "Juan Fernandes", + "publishedOn": "2022-07-29", + "articleTitle": "Linux vulnerability detection with OVAL and Fleet", + "articleImageUrl": "/images/articles/linux-vulnerability-detection-with-oval-and-fleet-1600x900@2x.jpg" + } + }, + { + "url": "/guides/locate-assets-with-osquery", + "title": "Locate assets with osquery", + "lastModifiedAt": 1726839805150, + "htmlId": "articles--locate-assets-with-o--764d2b5f55", + "sectionRelativeRepoPath": "locate-assets-with-osquery.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2021-05-11", + "articleTitle": "Locate device assets in the event of an emergency.", + "articleImageUrl": "/images/articles/locate-assets-with-osquery-cover-700x393@2x.jpeg" + } + }, + { + "url": "/guides/log-destinations", + "title": "Log destinations", + "lastModifiedAt": 1726839805152, + "htmlId": "articles--log-destinations--9bb62f5aa2", + "sectionRelativeRepoPath": "log-destinations.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "rachaelshaw", + "authorFullName": "Rachael Shaw", + "publishedOn": "2023-11-02", + "articleTitle": "Log destinations", + "description": "Learn about supported log destinations in Fleet, including Amazon Kinesis, AWS Lambda Snowflake, Splunk, and more." + } + }, + { + "url": "/securing/lossless-yubikeys-with-yubitrak-and-airtag", + "title": "Lossless yubikeys with yubitrak and airtag", + "lastModifiedAt": 1726839805153, + "htmlId": "articles--lossless-yubikeys-wi--b260bfc20a", + "sectionRelativeRepoPath": "lossless-yubiKeys-with-yubitrak-and-airtag.md", + "meta": { + "category": "security", + "authorGitHubUsername": "GuillaumeRoss", + "authorFullName": "Guillaume Ross", + "publishedOn": "2022-06-16", + "articleTitle": "Lossless YubiKeys with Yubitrak and AirTag", + "articleImageUrl": "/images/articles/lossless-yubikeys-with-yubitrak-and-airtag-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/macos-mdm-setup", + "title": "Macos mdm setup", + "lastModifiedAt": 1726839805154, + "htmlId": "articles--macos-mdm-setup--66538706f5", + "sectionRelativeRepoPath": "macos-mdm-setup.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "zhumo", + "authorFullName": "Mo Zhu", + "publishedOn": "2024-07-02", + "articleTitle": "macOS MDM setup", + "description": "Learn how to turn on MDM features in Fleet." + } + }, + { + "url": "/guides/macos-setup-experience", + "title": "Macos setup experience", + "lastModifiedAt": 1726839805155, + "htmlId": "articles--macos-setup-experien--cca7e9e073", + "sectionRelativeRepoPath": "macos-setup-experience.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-07-03", + "articleTitle": "macOS setup experience", + "description": "Customize your macOS setup experience with Fleet Premium by managing user authentication, Setup Assistant panes, and installing bootstrap packages." + } + }, + { + "url": "/guides/managing-labels-in-fleet", + "title": "Managing labels in Fleet", + "lastModifiedAt": 1726839805156, + "htmlId": "articles--managing-labels-in-f--b2e5aed976", + "sectionRelativeRepoPath": "managing-labels-in-fleet.md", + "meta": { + "articleTitle": "Managing labels in Fleet", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "category": "guides", + "publishedOn": "2024-07-18", + "articleImageUrl": "/images/articles/managing-labels-in-fleet-1600x900@2x.png", + "description": "This guide will walk you through managing labels using the Fleet web UI." + } + }, + { + "url": "/securing/mapping-fleet-and-osquery-results-to-the-mitre-attck-framework-via-splunk", + "title": "Mapping Fleet and osquery results to the mitre attck framework via splunk", + "lastModifiedAt": 1726839805157, + "htmlId": "articles--mapping-fleet-and-os--7ee9249dc4", + "sectionRelativeRepoPath": "mapping-fleet-and-osquery-results-to-the-mitre-attck-framework-via-splunk.md", + "meta": { + "category": "security", + "authorFullName": "Dave Herder", + "authorGitHubUsername": "dherder", + "publishedOn": "2023-01-30", + "articleTitle": "Mapping Fleet and osquery results to the MITRE ATT&CK® framework via Splunk", + "articleImageUrl": "/images/articles/mapping-fleet-and-osquery-results-to-the-mitre-attck-framework-via-splunk-1600x900@2x.png" + } + }, + { + "url": "/guides/mdm-commands", + "title": "Mdm commands", + "lastModifiedAt": 1726839805158, + "htmlId": "articles--mdm-commands--8de440c455", + "sectionRelativeRepoPath": "mdm-commands.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-06-12", + "articleTitle": "MDM commands", + "description": "Learn how to run custom MDM commands on hosts using Fleet." + } + }, + { + "url": "/guides/mdm-migration", + "title": "Mdm migration", + "lastModifiedAt": 1726839805159, + "htmlId": "articles--mdm-migration--a500f61869", + "sectionRelativeRepoPath": "mdm-migration.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "zhumo", + "authorFullName": "Mo Zhu", + "publishedOn": "2024-08-14", + "articleTitle": "MDM migration", + "description": "Instructions for migrating hosts away from an old MDM solution to Fleet." + } + }, + { + "url": "/announcements/nvd-api-2.0", + "title": "Nvd API 2.0", + "lastModifiedAt": 1726839805160, + "htmlId": "articles--nvd-api-20--a754d441c3", + "sectionRelativeRepoPath": "nvd-api-2.0.md", + "meta": { + "category": "announcements", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-11-28", + "articleTitle": "NVD API 2.0: An important update for Fleet users", + "articleImageUrl": "/images/articles/nvd-api-2.0-1600x900@2x.jpg" + } + }, + { + "url": "/securing/optimizing-government-cybersecurity-strategies", + "title": "Optimizing government cybersecurity strategies", + "lastModifiedAt": 1726839805161, + "htmlId": "articles--optimizing-governmen--78189d23a6", + "sectionRelativeRepoPath": "optimizing-government-cybersecurity-strategies.md", + "meta": { + "category": "security", + "authorFullName": "Keith Barnes", + "authorGitHubUsername": "KAB703", + "publishedOn": "2023-11-14", + "articleTitle": "Optimizing government cybersecurity strategies with Fleet.", + "articleImageUrl": "/images/articles/optimizing-government-cybersecurity-strategies-1600x900@2x.png" + } + }, + { + "url": "/releases/osquery-5.11.0", + "title": "Osquery 5.11.0", + "lastModifiedAt": 1726839805162, + "htmlId": "articles--osquery-5110--5af6435495", + "sectionRelativeRepoPath": "osquery-5.11.0.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2024-02-16", + "articleTitle": "osquery 5.11.0 | VSCode, Apple silicon, and more", + "articleImageUrl": "/images/articles/osquery-5.11.0-cover-1600x900@2x.png" + } + }, + { + "url": "/guides/osquery-a-tool-to-easily-ask-questions-about-operating-systems", + "title": "Osquery a tool to easily ask questions about operating systems", + "lastModifiedAt": 1726839805163, + "htmlId": "articles--osquery-a-tool-to-ea--424e2ed801", + "sectionRelativeRepoPath": "osquery-a-tool-to-easily-ask-questions-about-operating-systems.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "dominuskelvin", + "authorFullName": "Kelvin Omereshone", + "publishedOn": "2022-04-04", + "articleTitle": "Osquery: a tool to easily ask questions about operating systems", + "articleImageUrl": "/images/articles/osquery-a-tool-to-easily-ask-questions-about-operating-systems-cover-1600x900@2x.jpg" + } + }, + { + "url": "/securing/osquery-as-a-threat-hunting-platform", + "title": "Osquery as a threat hunting platform", + "lastModifiedAt": 1726839805164, + "htmlId": "articles--osquery-as-a-threat---d96a59f1dd", + "sectionRelativeRepoPath": "osquery-as-a-threat-hunting-platform.md", + "meta": { + "category": "security", + "authorFullName": "Chris McGillicuddy", + "authorGitHubUsername": "chris-mcgillicuddy", + "publishedOn": "2022-09-16", + "articleTitle": "Osquery… as a threat hunting platform?", + "articleImageUrl": "/images/articles/osquery-for-threat-hunting-1600x900@2x.jpg" + } + }, + { + "url": "/guides/osquery-consider-joining-against-the-users-table", + "title": "Osquery consider joining against the users table", + "lastModifiedAt": 1726839805165, + "htmlId": "articles--osquery-consider-joi--b99ae264e4", + "sectionRelativeRepoPath": "osquery-consider-joining-against-the-users-table.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2021-05-06", + "articleTitle": "Osquery: Consider joining against the users table", + "articleImageUrl": "/images/articles/osquery-consider-joining-against-the-users-table-cover-700x437@2x.jpeg" + } + }, + { + "url": "/releases/osquery-5.8.1", + "title": "Osquery 5.8.1", + "lastModifiedAt": 1726839805166, + "htmlId": "articles--osquery-581--5d3dced550", + "sectionRelativeRepoPath": "osquery-5.8.1.md", + "meta": { + "category": "releases", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "publishedOn": "2023-03-14", + "articleTitle": "osquery 5.8.1 | Process auditing, stats, and additional tables", + "articleImageUrl": "/images/articles/osquery-5.8.1-cover-1600x900@2x.png" + } + }, + { + "url": "/guides/osquery-evented-tables-overview", + "title": "Osquery evented tables overview", + "lastModifiedAt": 1726839805168, + "htmlId": "articles--osquery-evented-tabl--b9b1176562", + "sectionRelativeRepoPath": "osquery-evented-tables-overview.md", + "meta": { + "articleTitle": "How to use osquery evented tables", + "authorFullName": "Mo Zhu", + "authorGitHubUsername": "zhumo", + "category": "guides", + "publishedOn": "2022-09-21" + } + }, + { + "url": "/securing/osquery-vulnerability-management-at-scale", + "title": "Osquery vulnerability management at scale", + "lastModifiedAt": 1726839805169, + "htmlId": "articles--osquery-vulnerabilit--cac605ad18", + "sectionRelativeRepoPath": "osquery-vulnerability-management-at-scale.md", + "meta": { + "category": "security", + "authorFullName": "Chris McGillicuddy", + "authorGitHubUsername": "chris-mcgillicuddy", + "publishedOn": "2022-10-05", + "articleTitle": "Vulnerability management at scale: a presentation from osquery Co-creator Zach Wasserman", + "articleImageUrl": "/images/articles/vulnerability-management-at-scale-with-osquery_800x450@2x.jpg" + } + }, + { + "url": "/guides/osquery-watchdog", + "title": "Osquery watchdog", + "lastModifiedAt": 1726839805170, + "htmlId": "articles--osquery-watchdog--6a195970e0", + "sectionRelativeRepoPath": "osquery-watchdog.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "juan-fdz-hawa", + "authorFullName": "Juan Fernandes", + "publishedOn": "2023-07-28", + "articleTitle": "Osquery watchdog", + "description": "Learn about how osquery process manages child processes and managed extensions in Fleet." + } + }, + { + "url": "/announcements/psu-macadmins-conference-2023", + "title": "Psu macadmins conference 2023", + "lastModifiedAt": 1726839805171, + "htmlId": "articles--psu-macadmins-confer--175629dfbd", + "sectionRelativeRepoPath": "psu-macadmins-conference-2023.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "spokanemac", + "authorFullName": "JD Strong", + "publishedOn": "2023-07-13", + "articleTitle": "Mac admins summer camp ⛺ at PSU MacAdmins Conference 2023", + "articleImageUrl": "/images/articles/psu-macadmins-conference-2023@2x.png", + "description": "A look ahead to PSU MacAdmin Conference July 18-21, 2023" + } + }, + { + "url": "/guides/puppet-module", + "title": "Puppet module", + "lastModifiedAt": 1726839805172, + "htmlId": "articles--puppet-module--c01ecdf2b6", + "sectionRelativeRepoPath": "puppet-module.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-05-24", + "articleTitle": "Puppet module", + "description": "Learn how to use Fleet's Puppet module to automatically assign custom configuration profiles on your macOS hosts." + } + }, + { + "url": "/guides/queries", + "title": "Queries", + "lastModifiedAt": 1726839805173, + "htmlId": "articles--queries--ce5c1e3c99", + "sectionRelativeRepoPath": "queries.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-08-09", + "articleTitle": "Queries", + "description": "Learn how to create, run, and schedule queries, as well as update agent options in the Fleet user interface." + } + }, + { + "url": "/guides/querying-process-file-events-table-on-centos-7", + "title": "Querying process file events table on centos 7", + "lastModifiedAt": 1726839805174, + "htmlId": "articles--querying-process-fil--5587f39199", + "sectionRelativeRepoPath": "querying-process-file-events-table-on-centos-7.md", + "meta": { + "articleTitle": "Querying process_file_events on CentOS 7", + "description": "Learn how to configure and query the process_file_events table on CentOS 7 with Fleet.", + "category": "guides", + "authorGitHubUsername": "lucasmrod", + "authorFullName": "Lucas Rodriguez", + "publishedOn": "2023-07-17" + } + }, + { + "url": "/guides/role-based-access", + "title": "Role based access", + "lastModifiedAt": 1726839805177, + "htmlId": "articles--role-based-access--92a94667b2", + "sectionRelativeRepoPath": "role-based-access.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-08-10", + "articleTitle": "Role-based access", + "description": "Learn about the different roles and permissions in Fleet." + } + }, + { + "url": "/engineering/saving-over-100x-on-egress-switching-from-aws-to-hetzner", + "title": "Saving over 100x on egress switching from aws to hetzner", + "lastModifiedAt": 1726839805179, + "htmlId": "articles--saving-over-100x-on---a46f112fc0", + "sectionRelativeRepoPath": "saving-over-100x-on-egress-switching-from-aws-to-hetzner.md", + "meta": { + "category": "engineering", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-01-25", + "articleTitle": "Saving over 100x on egress switching from AWS to Hetzner", + "articleImageUrl": "/images/articles/saving-over-100x-on-egress-switching-from-aws-to-hetzner-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/scripts", + "title": "Scripts", + "lastModifiedAt": 1726839805179, + "htmlId": "articles--scripts--3a91ba655e", + "sectionRelativeRepoPath": "scripts.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-06-04", + "articleTitle": "Scripts", + "description": "Learn how to execute a custom script on macOS, Windows, and Linux hosts in Fleet." + } + }, + { + "url": "/guides/seamless-mdm-migration", + "title": "Seamless mdm migration", + "lastModifiedAt": 1726839805182, + "htmlId": "articles--seamless-mdm-migrati--f0abcf2f23", + "sectionRelativeRepoPath": "seamless-mdm-migration.md", + "meta": { + "category": "guides", + "authorFullName": "Zach Wasserman", + "authorGitHubUsername": "zwass", + "publishedOn": "2024-08-08", + "articleTitle": "Seamless MDM migrations to Fleet", + "articleImageUrl": "/images/articles/seamless-mdm-migration-1600x900@2x.png", + "description": "This guide provides a process for seamlessly migrating macOS devices from an existing MDM solution to Fleet." + } + }, + { + "url": "/announcements/seattle-bellevue-cyber-security-summit-march-8-2023", + "title": "Seattle bellevue cyber security summit march 8 2023", + "lastModifiedAt": 1726839805183, + "htmlId": "articles--seattle-bellevue-cyb--3b5ca28169", + "sectionRelativeRepoPath": "seattle-bellevue-cyber-security-summit-march-8-2023.md", + "meta": { + "category": "announcements", + "authorGitHubUsername": "spokanemac", + "authorFullName": "JD Strong", + "publishedOn": "2023-03-02", + "articleTitle": "Join Fleet at Cyber Security Summit Seattle/Bellevue", + "articleImageUrl": "/images/articles/seattle-bellevue-cyber-security-summit-social-post-1200x628@2x.png" + } + }, + { + "url": "/securing/security-testing-at-fleet-fleet-pentest", + "title": "Security testing at Fleet Fleet pentest", + "lastModifiedAt": 1726839805184, + "htmlId": "articles--security-testing-at---106e7f1999", + "sectionRelativeRepoPath": "security-testing-at-fleet-fleet-pentest.md", + "meta": { + "category": "security", + "authorGitHubUsername": "GuillaumeRoss", + "authorFullName": "Guillaume Ross", + "publishedOn": "2022-05-10", + "articleTitle": "Penetration testing of Fleet (April 2022)", + "articleImageUrl": "/images/articles/security-testing-at-fleet-fleet-pentest-cover-1600x900@2x.jpg" + } + }, + { + "url": "/securing/security-testing-at-fleet-orbit-auto-updater-audit", + "title": "Security testing at Fleet orbit auto updater audit", + "lastModifiedAt": 1726839805185, + "htmlId": "articles--security-testing-at---f487015e45", + "sectionRelativeRepoPath": "security-testing-at-fleet-orbit-auto-updater-audit.md", + "meta": { + "category": "security", + "authorGitHubUsername": "GuillaumeRoss", + "authorFullName": "Guillaume Ross", + "publishedOn": "2022-03-30", + "articleTitle": "Security testing at Fleet/Orbit auto-updater audit", + "articleImageUrl": "/images/articles/security-testing-at-fleet-orbit-auto-updater-audit-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/software-self-service", + "title": "Software self service", + "lastModifiedAt": 1726839805186, + "htmlId": "articles--software-self-servic--9047e7f63d", + "sectionRelativeRepoPath": "software-self-service.md", + "meta": { + "articleTitle": "Software self-service", + "authorFullName": "Jahziel Villasana-Espinoza", + "authorGitHubUsername": "jahzielv", + "category": "guides", + "publishedOn": "2024-08-06", + "articleImageUrl": "/images/articles/software-self-service-1600x900@2x.png", + "description": "This guide will walk you through adding apps to Fleet for user self-service." + } + }, + { + "url": "/guides/standard-query-library", + "title": "Standard query library", + "lastModifiedAt": 1726839805187, + "htmlId": "articles--standard-query-libra--dccfaa84b4", + "sectionRelativeRepoPath": "standard-query-library.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-04-04", + "articleTitle": "Standard query library", + "description": "Learn how to use and contribute to Fleet's standard query library." + } + }, + { + "url": "/report/state-of-device-management", + "title": "State of device management", + "lastModifiedAt": 1726839805187, + "htmlId": "articles--state-of-device-mana--f6254cc69c", + "sectionRelativeRepoPath": "state-of-device-management.md", + "meta": { + "category": "report", + "authorFullName": "Mike McNeil", + "authorGitHubUsername": "mikermcneil", + "publishedOn": "2022-07-07", + "articleTitle": "State of Device Management report 2022", + "articleImageUrl": "/images/articles/state-of-device-management-report-1600x900@2x.png" + } + }, + { + "url": "/securing/stay-on-course-with-your-security-compliance-goals", + "title": "Stay on course with your security compliance goals", + "lastModifiedAt": 1726839805188, + "htmlId": "articles--stay-on-course-with---a487f310dc", + "sectionRelativeRepoPath": "stay-on-course-with-your-security-compliance-goals.md", + "meta": { + "category": "security", + "authorFullName": "Chris McGillicuddy", + "authorGitHubUsername": "chris-mcgillicuddy", + "publishedOn": "2022-07-18", + "articleTitle": "Stay on course with your security compliance goals", + "articleImageUrl": "/images/articles/security-compliance-goals-cover-800x450@2x.jpg" + } + }, + { + "url": "/guides/sysadmin-diaries-device-enrollment", + "title": "Sysadmin diaries device enrollment", + "lastModifiedAt": 1726839805189, + "htmlId": "articles--sysadmin-diaries-dev--abfda23f04", + "sectionRelativeRepoPath": "sysadmin-diaries-device-enrollment.md", + "meta": { + "articleTitle": "Sysadmin diaries: device enrollment", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "category": "guides", + "publishedOn": "2024-05-03", + "articleImageUrl": "/images/articles/sysadmin-diaries-1600x900@2x.png", + "description": "In this sysadmin diary, we explore a the differences in device enrollment." + } + }, + { + "url": "/guides/sysadmin-diaries-exporting-policies", + "title": "Sysadmin diaries exporting policies", + "lastModifiedAt": 1726839805190, + "htmlId": "articles--sysadmin-diaries-exp--a101d98c97", + "sectionRelativeRepoPath": "sysadmin-diaries-exporting-policies.md", + "meta": { + "articleTitle": "Sysadmin diaries: exporting policies", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "category": "guides", + "publishedOn": "2024-06-28", + "articleImageUrl": "/images/articles/sysadmin-diaries-1600x900@2x.png", + "description": "In this sysadmin diary, we explore extracting existing policies to enable gitops." + } + }, + { + "url": "/guides/sysadmin-diaries-lost-device", + "title": "Sysadmin diaries lost device", + "lastModifiedAt": 1726839805191, + "htmlId": "articles--sysadmin-diaries-los--3bcb909203", + "sectionRelativeRepoPath": "sysadmin-diaries-lost-device.md", + "meta": { + "articleTitle": "Sysadmin diaries: lost device", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "category": "guides", + "publishedOn": "2024-07-09", + "articleImageUrl": "/images/articles/sysadmin-diaries-1600x900@2x.png", + "description": "In this sysadmin diary, we explore what actions can be taken with Fleet when a device is lost." + } + }, + { + "url": "/guides/sysadmin-diaries-passcode-profiles", + "title": "Sysadmin diaries passcode profiles", + "lastModifiedAt": 1726839805192, + "htmlId": "articles--sysadmin-diaries-pas--883471875d", + "sectionRelativeRepoPath": "sysadmin-diaries-passcode-profiles.md", + "meta": { + "articleTitle": "Sysadmin diaries: passcode profiles", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "category": "guides", + "publishedOn": "2024-04-01", + "articleImageUrl": "/images/articles/sysadmin-diaries-1600x900@2x.png", + "description": "In this sysadmin diary, we explore a missapplied passcode policy." + } + }, + { + "url": "/guides/sysadmin-diaries-restoring-fleetd", + "title": "Sysadmin diaries restoring fleetd", + "lastModifiedAt": 1726839805193, + "htmlId": "articles--sysadmin-diaries-res--96c547e138", + "sectionRelativeRepoPath": "sysadmin-diaries-restoring-fleetd.md", + "meta": { + "articleTitle": "Sysadmin diaries: restoring fleetd", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "category": "guides", + "publishedOn": "2024-06-14", + "articleImageUrl": "/images/articles/sysadmin-diaries-1600x900@2x.png", + "description": "In this sysadmin diary, we explore restoring fleetd deleted by a surly employee." + } + }, + { + "url": "/securing/tales-from-fleet-security-github-configuration-and-openssf-scorecards", + "title": "Tales from Fleet security github configuration and openssf scorecards", + "lastModifiedAt": 1726839805194, + "htmlId": "articles--tales-from-fleet-sec--035c3d6474", + "sectionRelativeRepoPath": "tales-from-fleet-security-github-configuration-and-openssf-scorecards.md", + "meta": { + "category": "security", + "authorFullName": "Guillaume Ross", + "authorGitHubUsername": "GuillaumeRoss", + "publishedOn": "2022-04-15", + "articleTitle": "Tales from Fleet security: GitHub configuration and OpenSSF Scorecards", + "articleImageUrl": "/images/articles/tales-from-fleet-security-github-configuration-and-openssf-scorecards-cover-1600x900@2x.jpg" + } + }, + { + "url": "/securing/tales-from-fleet-security-google-groups-scams", + "title": "Tales from Fleet security google groups scams", + "lastModifiedAt": 1726839805195, + "htmlId": "articles--tales-from-fleet-sec--841598a71f", + "sectionRelativeRepoPath": "tales-from-fleet-security-google-groups-scams.md", + "meta": { + "category": "security", + "authorFullName": "Guillaume Ross", + "authorGitHubUsername": "GuillaumeRoss", + "publishedOn": "2022-08-05", + "articleTitle": "Tales from Fleet security: scams targeting Google Groups", + "articleImageUrl": "/images/articles/tales-from-fleet-security-google-groups-scams-cover-1600x900@2x.jpg" + } + }, + { + "url": "/securing/tales-from-fleet-security-securing-1password", + "title": "Tales from Fleet security securing 1password", + "lastModifiedAt": 1726839805196, + "htmlId": "articles--tales-from-fleet-sec--d172f39898", + "sectionRelativeRepoPath": "tales-from-fleet-security-securing-1password.md", + "meta": { + "category": "security", + "authorFullName": "Guillaume Ross", + "authorGitHubUsername": "GuillaumeRoss", + "publishedOn": "2022-05-06", + "articleTitle": "Tales from Fleet security: securing 1Password", + "articleImageUrl": "/images/articles/tales-from-fleet-security-securing-1password-cover-1600x900@2x.jpg" + } + }, + { + "url": "/securing/tales-from-fleet-security-securing-bank-accounts-from-business-email-compromise", + "title": "Tales from Fleet security securing bank accounts from business email compromise", + "lastModifiedAt": 1726839805198, + "htmlId": "articles--tales-from-fleet-sec--f60a0becab", + "sectionRelativeRepoPath": "tales-from-fleet-security-securing-bank-accounts-from-business-email-compromise.md", + "meta": { + "category": "security", + "authorFullName": "Guillaume Ross", + "authorGitHubUsername": "GuillaumeRoss", + "publishedOn": "2022-07-15", + "articleTitle": "Tales from Fleet security: securing bank accounts from business email compromise", + "articleImageUrl": "/images/articles/securing-bank-accounts-from-business-email-compromise-1600x900@2x.jpg" + } + }, + { + "url": "/securing/tales-from-fleet-security-securing-google-workspace", + "title": "Tales from Fleet security securing google workspace", + "lastModifiedAt": 1726839805199, + "htmlId": "articles--tales-from-fleet-sec--72efc9f80f", + "sectionRelativeRepoPath": "tales-from-fleet-security-securing-google-workspace.md", + "meta": { + "category": "security", + "authorFullName": "Guillaume Ross", + "authorGitHubUsername": "GuillaumeRoss", + "publishedOn": "2022-03-25", + "articleTitle": "Tales from Fleet security: securing Google Workspace", + "articleImageUrl": "/images/articles/tales-from-fleet-security-securing-google-workspace-cover-1600x900@2x.jpg" + } + }, + { + "url": "/securing/tales-from-fleet-security-securing-the-startup", + "title": "Tales from Fleet security securing the startup", + "lastModifiedAt": 1726839805200, + "htmlId": "articles--tales-from-fleet-sec--a25132f487", + "sectionRelativeRepoPath": "tales-from-fleet-security-securing-the-startup.md", + "meta": { + "category": "security", + "authorFullName": "Guillaume Ross", + "authorGitHubUsername": "GuillaumeRoss", + "publishedOn": "2022-03-17", + "articleTitle": "Tales from Fleet security: securing the startup", + "articleImageUrl": "/images/articles/tales-from-fleet-security-securing-the-startup-cover-1600x900@2x.jpg" + } + }, + { + "url": "/securing/tales-from-fleet-security-soc2", + "title": "Tales from Fleet security soc2", + "lastModifiedAt": 1726839805202, + "htmlId": "articles--tales-from-fleet-sec--f537169e1e", + "sectionRelativeRepoPath": "tales-from-fleet-security-soc2.md", + "meta": { + "category": "security", + "authorGitHubUsername": "GuillaumeRoss", + "authorFullName": "Guillaume Ross", + "publishedOn": "2022-06-24", + "articleTitle": "Tales from Fleet security: how we achieved our SOC 2 type 1 rapidly", + "articleImageUrl": "/images/articles/tales-from-fleet-soc2-type1-report-cover-1600x900@2x.jpg" + } + }, + { + "url": "/securing/tales-from-fleet-security-speeding-up-macos-updates-with-nudge", + "title": "Tales from Fleet security speeding up macos updates with nudge", + "lastModifiedAt": 1726839805203, + "htmlId": "articles--tales-from-fleet-sec--41bc496d3c", + "sectionRelativeRepoPath": "tales-from-fleet-security-speeding-up-macos-updates-with-nudge.md", + "meta": { + "category": "security", + "authorFullName": "Guillaume Ross", + "authorGitHubUsername": "GuillaumeRoss", + "publishedOn": "2022-07-05", + "articleTitle": "Tales from Fleet security: speeding up macOS updates with Nudge", + "articleImageUrl": "/images/articles/tales-from-fleet-nudge-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/teams", + "title": "Teams", + "lastModifiedAt": 1726839805204, + "htmlId": "articles--teams--a6aba53335", + "sectionRelativeRepoPath": "teams.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-07-11", + "articleTitle": "Teams", + "description": "Learn how to group hosts in Fleet to apply specific queries, policies, and agent options using teams." + } + }, + { + "url": "/announcements/the-device-security-tightrope-balancing-cost-and-protection-in-k-12-schools", + "title": "The device security tightrope balancing cost and protection in k 12 schools", + "lastModifiedAt": 1726839805205, + "htmlId": "articles--the-device-security---cba806f3e1", + "sectionRelativeRepoPath": "the-device-security-tightrope-balancing-cost-and-protection-in-K-12-schools.md", + "meta": { + "category": "announcements", + "authorFullName": "Keith Barnes", + "authorGitHubUsername": "KAB703", + "publishedOn": "2024-03-01", + "articleTitle": "The device security tightrope: balancing cost and protection in K-12 schools", + "articleImageUrl": "/images/articles/the-device-security-tightrope-balancing-cost-and-protection-in-K-12-schools-1600x900@2x.png" + } + }, + { + "url": "/podcasts/the-future-of-device-management-ep1", + "title": "The future of device management ep1", + "lastModifiedAt": 1726839805207, + "htmlId": "articles--the-future-of-device--e424a67517", + "sectionRelativeRepoPath": "the-future-of-device-management-ep1.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-06-06", + "articleTitle": "Future of device management episode 1", + "articleImageUrl": "/images/articles/future-of-device-management-ep1-cover-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/the-future-of-device-management-ep2", + "title": "The future of device management ep2", + "lastModifiedAt": 1726839805208, + "htmlId": "articles--the-future-of-device--0b4ec299db", + "sectionRelativeRepoPath": "the-future-of-device-management-ep2.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-06-30", + "articleTitle": "Future of device management episode 2", + "articleImageUrl": "/images/articles/future-of-device-management-ep2-cover-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/the-future-of-device-management-ep3", + "title": "The future of device management ep3", + "lastModifiedAt": 1726839805209, + "htmlId": "articles--the-future-of-device--d7b8d1fbfe", + "sectionRelativeRepoPath": "the-future-of-device-management-ep3.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-07-21", + "articleTitle": "Future of device management episode 3", + "articleImageUrl": "/images/articles/future-of-device-management-ep3-cover-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/the-future-of-device-management-ep4", + "title": "The future of device management ep4", + "lastModifiedAt": 1726839805210, + "htmlId": "articles--the-future-of-device--bd6c88c590", + "sectionRelativeRepoPath": "the-future-of-device-management-ep4.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-08-12", + "articleTitle": "Future of device management episode 4", + "articleImageUrl": "/images/articles/future-of-device-management-ep4-cover-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/the-future-of-device-management-ep5", + "title": "The future of device management ep5", + "lastModifiedAt": 1726839805210, + "htmlId": "articles--the-future-of-device--c5ce4719fa", + "sectionRelativeRepoPath": "the-future-of-device-management-ep5.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-09-01", + "articleTitle": "Future of device management episode 5", + "articleImageUrl": "/images/articles/future-of-device-management-ep5-cover-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/the-future-of-device-management-ep6", + "title": "The future of device management ep6", + "lastModifiedAt": 1726839805211, + "htmlId": "articles--the-future-of-device--141153d341", + "sectionRelativeRepoPath": "the-future-of-device-management-ep6.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-09-23", + "articleTitle": "Future of device management episode 6", + "articleImageUrl": "/images/articles/future-of-device-management-ep6-cover-1600x900@2x.jpg" + } + }, + { + "url": "/podcasts/the-future-of-device-management-ep7", + "title": "The future of device management ep7", + "lastModifiedAt": 1726839805212, + "htmlId": "articles--the-future-of-device--52a1db0bde", + "sectionRelativeRepoPath": "the-future-of-device-management-ep7.md", + "meta": { + "category": "podcasts", + "authorGitHubUsername": "zwass", + "authorFullName": "Zach Wasserman", + "publishedOn": "2022-11-03", + "articleTitle": "Future of device management episode 7", + "articleImageUrl": "/images/articles/future-of-device-management-ep7-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/understanding-the-intricacies-of-fleet-policies", + "title": "Understanding the intricacies of Fleet policies", + "lastModifiedAt": 1726839805213, + "htmlId": "articles--understanding-the-in--edae4ca064", + "sectionRelativeRepoPath": "understanding-the-intricacies-of-fleet-policies.md", + "meta": { + "articleTitle": "Understanding the intricacies of Fleet policies", + "authorFullName": "Victor Lyuboslavsky", + "authorGitHubUsername": "getvictor", + "category": "guides", + "publishedOn": "2023-12-29", + "description": "Learn how Fleet policies work behind the scenes." + } + }, + { + "url": "/guides/using-elasticsearch-and-kibana-to-visualize-osquery-performance", + "title": "Using elasticsearch and kibana to visualize osquery performance", + "lastModifiedAt": 1726839805215, + "htmlId": "articles--using-elasticsearch---55019ee35a", + "sectionRelativeRepoPath": "using-elasticsearch-and-kibana-to-visualize-osquery-performance.md", + "meta": { + "category": "guides", + "authorFullName": "Zach Wasserman", + "authorGitHubUsername": "zwass", + "publishedOn": "2021-05-26", + "articleTitle": "Using Elasticsearch and Kibana to visualize osquery performance", + "articleImageUrl": "/images/articles/using-elasticsearch-and-kibana-to-visualize-osquery-performance-cover-700x393@2x.jpeg" + } + }, + { + "url": "/guides/using-fleet-and-okta-workflows-to-generate-a-daily-os-report", + "title": "Using Fleet and okta workflows to generate a daily os report", + "lastModifiedAt": 1726839805218, + "htmlId": "articles--using-fleet-and-okta--a4676a8577", + "sectionRelativeRepoPath": "using-fleet-and-okta-workflows-to-generate-a-daily-os-report.md", + "meta": { + "articleTitle": "Using Fleet and Okta Workflows to generate a daily OS report", + "authorFullName": "Harrison Ravazzolo", + "authorGitHubUsername": "harrisonravazzolo", + "category": "guides", + "publishedOn": "2023-05-09", + "articleImageUrl": "/images/articles/using-fleet-and-okta-workflows-to-generate-a-daily-os-report@2x.jpg", + "description": "Learn how to use Fleet to query device OS information through the Fleet REST API and automate daily Slack notifications using Okta Workflows." + } + }, + { + "url": "/guides/using-fleet-and-tines-together", + "title": "Using Fleet and tines together", + "lastModifiedAt": 1726839805219, + "htmlId": "articles--using-fleet-and-tine--3606f85672", + "sectionRelativeRepoPath": "using-fleet-and-tines-together.md", + "meta": { + "category": "guides", + "authorFullName": "Dave Herder", + "authorGitHubUsername": "dherder", + "publishedOn": "2023-03-08", + "articleTitle": "Using Fleet and Tines together", + "articleImageUrl": "/images/articles/using-fleet-and-tines-together-1600x900@2x.png" + } + }, + { + "url": "/guides/using-github-actions-to-apply-configuration-profiles-with-fleet", + "title": "Using github actions to apply configuration profiles with Fleet", + "lastModifiedAt": 1726839805220, + "htmlId": "articles--using-github-actions--d966ed0177", + "sectionRelativeRepoPath": "using-github-actions-to-apply-configuration-profiles-with-fleet.md", + "meta": { + "articleTitle": "Using GitHub Actions to apply configuration profiles with Fleet", + "authorFullName": "JD Strong", + "authorGitHubUsername": "spokanemac", + "category": "guides", + "publishedOn": "2023-05-31", + "articleImageUrl": "/images/articles/using-github-actions-to-apply-configuration-profiles-with-fleet@2x.jpg", + "description": "A guide on using GitHub Actions with Fleet for efficient and automated application of the latest configuration profiles for a GitOps workflow." + } + }, + { + "url": "/securing/vulnerability-management-the-advantages-of-fleet-to-support-government-agencies", + "title": "Vulnerability management the advantages of Fleet to support government agencies", + "lastModifiedAt": 1726839805221, + "htmlId": "articles--vulnerability-manage--fae19ad566", + "sectionRelativeRepoPath": "vulnerability-management-the-advantages-of-fleet-to-support-government-agencies.md", + "meta": { + "category": "security", + "authorFullName": "Keith Barnes", + "authorGitHubUsername": "KAB703", + "publishedOn": "2023-12-26", + "articleTitle": "Vulnerability management: advantages of Fleet to support government agencies", + "articleImageUrl": "/images/articles/vulnerability-management-advantages-of-fleet-to-support-government-agencies-1600x900@2x.png" + } + }, + { + "url": "/guides/vulnerability-processing", + "title": "Vulnerability processing", + "lastModifiedAt": 1726839805222, + "htmlId": "articles--vulnerability-proces--244a2b70ee", + "sectionRelativeRepoPath": "vulnerability-processing.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "noahtalerman", + "authorFullName": "Noah Talerman", + "publishedOn": "2024-07-12", + "articleTitle": "Vulnerability processing", + "description": "Find out how Fleet detects vulnerabilities and what software it covers." + } + }, + { + "url": "/guides/what-api-endpoints-to-expose-to-the-public-internet", + "title": "What API endpoints to expose to the public internet", + "lastModifiedAt": 1726839805223, + "htmlId": "articles--what-api-endpoints-t--cd0552d444", + "sectionRelativeRepoPath": "what-api-endpoints-to-expose-to-the-public-internet.md", + "meta": { + "category": "guides", + "authorGitHubUsername": "mike-j-thomas", + "authorFullName": "Mike Thomas", + "publishedOn": "2023-11-13", + "articleTitle": "Which API endpoints to expose to the public internet?" + } + }, + { + "url": "/securing/what-are-fleet-policies", + "title": "What are Fleet policies", + "lastModifiedAt": 1726839805224, + "htmlId": "articles--what-are-fleet-polic--d8ca2da611", + "sectionRelativeRepoPath": "what-are-fleet-policies.md", + "meta": { + "category": "security", + "authorGitHubUsername": "Drew-P-drawers", + "authorFullName": "Andrew Baker", + "publishedOn": "2022-05-20", + "articleTitle": "What are Fleet policies?", + "articleImageUrl": "/images/articles/what-are-fleet-policies-cover-1600x900@2x.jpg" + } + }, + { + "url": "/guides/windows-mdm-setup", + "title": "Windows mdm setup", + "lastModifiedAt": 1726839805226, + "htmlId": "articles--windows-mdm-setup--ebf4ebf0ba", + "sectionRelativeRepoPath": "windows-mdm-setup.md", + "meta": { + "articleTitle": "Windows MDM setup", + "authorFullName": "Noah Talerman", + "authorGitHubUsername": "noahtalerman", + "category": "guides", + "publishedOn": "2023-10-23", + "articleImageUrl": "/images/articles/windows-mdm-fleet-1600x900@2x.png", + "description": "Configuring Windows MDM in Fleet." + } + }, + { + "url": "/guides/zero-trust-attestation-with-fleet", + "title": "Zero trust attestation with Fleet", + "lastModifiedAt": 1726839805227, + "htmlId": "articles--zero-trust-attestati--b892a54252", + "sectionRelativeRepoPath": "zero-trust-attestation-with-fleet.md", + "meta": { + "articleTitle": "How to use Fleet for zero trust attestation", + "authorFullName": "Mo Zhu", + "authorGitHubUsername": "zhumo", + "category": "guides", + "publishedOn": "2022-10-14", + "articleImageUrl": "/images/articles/fleet-for-zero-trust-attestation-800x450@2x.jpg" + } + }, + { + "url": "/securing/work-may-be-watching-but-it-might-not-be-as-bad-as-you-think", + "title": "Work may be watching but it might not be as bad as you think", + "lastModifiedAt": 1726839805227, + "htmlId": "articles--work-may-be-watching--420e065d2f", + "sectionRelativeRepoPath": "work-may-be-watching-but-it-might-not-be-as-bad-as-you-think.md", + "meta": { + "category": "security", + "authorFullName": "Mike Thomas", + "authorGitHubUsername": "mike-j-thomas", + "publishedOn": "2021-10-22", + "articleTitle": "Work may be watching, but it might not be as bad as you think.", + "articleImageUrl": "/images/articles/work-may-be-watching-but-it-might-not-be-as-bad-as-you-think-cover-1600x900@2x.jpg" + } + }, + { + "url": "/handbook/company/open-positions/software-engineer", + "title": "🚀 Software Engineer", + "lastModifiedAt": 1726839805228, + "htmlId": "handbook--software-engineer--be50029cfb", + "sectionRelativeRepoPath": "company/open-positions.yml", + "meta": { + "maintainedBy": "LukeHeath" + } + }, + { + "url": "/handbook/company/open-positions/account-executive", + "title": "🐋 Account Executive", + "lastModifiedAt": 1726839805228, + "htmlId": "handbook--account-executive--d5def7dc8f", + "sectionRelativeRepoPath": "company/open-positions.yml", + "meta": { + "maintainedBy": "alexmitchelliii" + } + }, + { + "url": "/tables/account_policy_data", + "title": "account_policy_data", + "htmlId": "table--accountpolicydata--31df68b22b", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "account_policy_data", + "creation_time", + "failed_login_count", + "failed_login_timestamp", + "password_last_set_time", + "uid" + ], + "sectionRelativeRepoPath": "account_policy_data", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/account_policy_data.yml" + }, + { + "url": "/tables/ad_config", + "title": "ad_config", + "htmlId": "table--adconfig--39d2211d09", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "ad_config", + "domain", + "name", + "option", + "value" + ], + "sectionRelativeRepoPath": "ad_config", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/ad_config.yml" + }, + { + "url": "/tables/alf", + "title": "alf", + "htmlId": "table--alf--4c28031b0f", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "alf", + "allow_signed_enabled", + "firewall_unload", + "global_state", + "logging_enabled", + "logging_option", + "stealth_enabled", + "version" + ], + "sectionRelativeRepoPath": "alf", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/alf.yml" + }, + { + "url": "/tables/alf_exceptions", + "title": "alf_exceptions", + "htmlId": "table--alfexceptions--1fbd2a6157", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "alf_exceptions", + "path", + "state" + ], + "sectionRelativeRepoPath": "alf_exceptions", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/alf_exceptions.yml" + }, + { + "url": "/tables/alf_explicit_auths", + "title": "alf_explicit_auths", + "htmlId": "table--alfexplicitauths--4b47436520", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "alf_explicit_auths", + "process" + ], + "sectionRelativeRepoPath": "alf_explicit_auths", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/alf_explicit_auths.yml" + }, + { + "url": "/tables/apfs_physical_stores", + "title": "apfs_physical_stores", + "htmlId": "table--apfsphysicalstores--30af4e1d13", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "apfs_physical_stores", + "container_capacity_ceiling", + "container_capacity_free", + "container_designated_physical_store", + "container_fusion", + "container_reference", + "container_uuid", + "identifier", + "size", + "uuid" + ], + "sectionRelativeRepoPath": "apfs_physical_stores", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/apfs_physical_stores.yml" + }, + { + "url": "/tables/apfs_volumes", + "title": "apfs_volumes", + "htmlId": "table--apfsvolumes--d8e8cc281d", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "apfs_volumes", + "capacity_in_use", + "capacity_quota", + "capacity_reserve", + "container_capacity_ceiling", + "container_capacity_free", + "container_designated_physical_store", + "container_fusion", + "container_reference", + "container_uuid", + "crypto_migration_on", + "device_identifier", + "encryption", + "filevault", + "locked", + "name", + "role", + "uuid" + ], + "sectionRelativeRepoPath": "apfs_volumes", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/apfs_volumes.yml" + }, + { + "url": "/tables/app_icons", + "title": "app_icons", + "htmlId": "table--appicons--93bed0002f", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "app_icons", + "hash", + "icon", + "path" + ], + "sectionRelativeRepoPath": "app_icons", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/app_icons.yml" + }, + { + "url": "/tables/app_schemes", + "title": "app_schemes", + "htmlId": "table--appschemes--e75c685f8d", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "app_schemes", + "enabled", + "external", + "handler", + "protected", + "scheme" + ], + "sectionRelativeRepoPath": "app_schemes", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/app_schemes.yml" + }, + { + "url": "/tables/apparmor_events", + "title": "apparmor_events", + "htmlId": "table--apparmorevents--1b9b1af186", + "evented": true, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "apparmor_events", + "apparmor", + "capability", + "capname", + "comm", + "denied_mask", + "eid", + "error", + "fsuid", + "info", + "label", + "message", + "name", + "namespace", + "operation", + "ouid", + "parent", + "pid", + "profile", + "requested_mask", + "time", + "type", + "uptime" + ], + "sectionRelativeRepoPath": "apparmor_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fapparmor_events.yml&value=name%3A%20apparmor_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/apparmor_profiles", + "title": "apparmor_profiles", + "htmlId": "table--apparmorprofiles--49f0f69437", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "apparmor_profiles", + "attach", + "mode", + "name", + "path", + "sha1" + ], + "sectionRelativeRepoPath": "apparmor_profiles", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fapparmor_profiles.yml&value=name%3A%20apparmor_profiles%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/appcompat_shims", + "title": "appcompat_shims", + "htmlId": "table--appcompatshims--33b5da402f", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "appcompat_shims", + "description", + "executable", + "install_time", + "path", + "sdb_id", + "type" + ], + "sectionRelativeRepoPath": "appcompat_shims", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fappcompat_shims.yml&value=name%3A%20appcompat_shims%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/apps", + "title": "apps", + "htmlId": "table--apps--ccdee150a9", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "apps", + "applescript_enabled", + "bundle_executable", + "bundle_identifier", + "bundle_name", + "bundle_package_type", + "bundle_short_version", + "bundle_version", + "category", + "compiler", + "copyright", + "development_region", + "display_name", + "element", + "environment", + "info_string", + "last_opened_time", + "minimum_system_version", + "name", + "path" + ], + "sectionRelativeRepoPath": "apps", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/apps.yml" + }, + { + "url": "/tables/apt_sources", + "title": "apt_sources", + "htmlId": "table--aptsources--a209051a90", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "apt_sources", + "architectures", + "base_uri", + "components", + "maintainer", + "name", + "pid_with_namespace", + "release", + "source", + "version" + ], + "sectionRelativeRepoPath": "apt_sources", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/apt_sources.yml" + }, + { + "url": "/tables/arp_cache", + "title": "arp_cache", + "htmlId": "table--arpcache--83f95510b6", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "arp_cache", + "address", + "interface", + "mac", + "permanent" + ], + "sectionRelativeRepoPath": "arp_cache", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/arp_cache.yml" + }, + { + "url": "/tables/asl", + "title": "asl", + "htmlId": "table--asl--d2accdbfe3", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "asl", + "extra", + "facility", + "gid", + "host", + "level", + "message", + "pid", + "ref_pid", + "ref_proc", + "sender", + "time", + "time_nano_sec", + "uid" + ], + "sectionRelativeRepoPath": "asl", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/asl.yml" + }, + { + "url": "/tables/augeas", + "title": "augeas", + "htmlId": "table--augeas--b316cda7a7", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "augeas", + "label", + "node", + "path", + "value" + ], + "sectionRelativeRepoPath": "augeas", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/augeas.yml" + }, + { + "url": "/tables/authdb", + "title": "authdb", + "htmlId": "table--authdb--a304d751e5", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "authdb", + "json_result", + "right_name" + ], + "sectionRelativeRepoPath": "authdb", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/authdb.yml" + }, + { + "url": "/tables/authenticode", + "title": "authenticode", + "htmlId": "table--authenticode--0de9da48eb", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "authenticode", + "issuer_name", + "original_program_name", + "path", + "result", + "serial_number", + "subject_name" + ], + "sectionRelativeRepoPath": "authenticode", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fauthenticode.yml&value=name%3A%20authenticode%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/authorization_mechanisms", + "title": "authorization_mechanisms", + "htmlId": "table--authorizationmechanisms--d2490cb436", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "authorization_mechanisms", + "entry", + "label", + "mechanism", + "plugin", + "privileged" + ], + "sectionRelativeRepoPath": "authorization_mechanisms", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/authorization_mechanisms.yml" + }, + { + "url": "/tables/authorizations", + "title": "authorizations", + "htmlId": "table--authorizations--7fb6b733e8", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "authorizations", + "allow_root", + "authenticate_user", + "class", + "comment", + "created", + "label", + "modified", + "session_owner", + "shared", + "timeout", + "tries", + "version" + ], + "sectionRelativeRepoPath": "authorizations", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/authorizations.yml" + }, + { + "url": "/tables/authorized_keys", + "title": "authorized_keys", + "htmlId": "table--authorizedkeys--5108700dee", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "authorized_keys", + "algorithm", + "comment", + "key", + "key_file", + "options", + "pid_with_namespace", + "uid" + ], + "sectionRelativeRepoPath": "authorized_keys", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/authorized_keys.yml" + }, + { + "url": "/tables/autoexec", + "title": "autoexec", + "htmlId": "table--autoexec--ab98111b94", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "autoexec", + "name", + "path", + "source" + ], + "sectionRelativeRepoPath": "autoexec", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fautoexec.yml&value=name%3A%20autoexec%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/azure_instance_metadata", + "title": "azure_instance_metadata", + "htmlId": "table--azureinstancemetadata--01df1dde23", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "azure_instance_metadata", + "location", + "name", + "offer", + "os_type", + "placement_group_id", + "platform_fault_domain", + "platform_update_domain", + "publisher", + "resource_group_name", + "sku", + "subscription_id", + "version", + "vm_id", + "vm_scale_set_name", + "vm_size", + "zone" + ], + "sectionRelativeRepoPath": "azure_instance_metadata", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/azure_instance_metadata.yml" + }, + { + "url": "/tables/azure_instance_tags", + "title": "azure_instance_tags", + "htmlId": "table--azureinstancetags--166e2b6f18", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "azure_instance_tags", + "key", + "value", + "vm_id" + ], + "sectionRelativeRepoPath": "azure_instance_tags", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/azure_instance_tags.yml" + }, + { + "url": "/tables/background_activities_moderator", + "title": "background_activities_moderator", + "htmlId": "table--backgroundactivitiesmoderator--12072ab407", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "background_activities_moderator", + "last_execution_time", + "path", + "sid" + ], + "sectionRelativeRepoPath": "background_activities_moderator", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fbackground_activities_moderator.yml&value=name%3A%20background_activities_moderator%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/battery", + "title": "battery", + "htmlId": "table--battery--e54a7e368b", + "evented": false, + "platforms": [ + "darwin", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "battery", + "amperage", + "charged", + "charging", + "chemistry", + "condition", + "current_capacity", + "cycle_count", + "designed_capacity", + "health", + "manufacture_date", + "manufacturer", + "max_capacity", + "minutes_to_full_charge", + "minutes_until_empty", + "model", + "percent_remaining", + "serial_number", + "state", + "voltage" + ], + "sectionRelativeRepoPath": "battery", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/battery.yml" + }, + { + "url": "/tables/bitlocker_info", + "title": "bitlocker_info", + "htmlId": "table--bitlockerinfo--277b4f7713", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "bitlocker_info", + "conversion_status", + "device_id", + "drive_letter", + "encryption_method", + "lock_status", + "percentage_encrypted", + "persistent_volume_id", + "protection_status", + "version" + ], + "sectionRelativeRepoPath": "bitlocker_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/bitlocker_info.yml" + }, + { + "url": "/tables/block_devices", + "title": "block_devices", + "htmlId": "table--blockdevices--3db1d23d7b", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "block_devices", + "block_size", + "label", + "model", + "name", + "parent", + "size", + "type", + "uuid", + "vendor" + ], + "sectionRelativeRepoPath": "block_devices", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/block_devices.yml" + }, + { + "url": "/tables/bpf_process_events", + "title": "bpf_process_events", + "htmlId": "table--bpfprocessevents--f98d50f0c4", + "evented": true, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "bpf_process_events", + "cid", + "cmdline", + "cwd", + "duration", + "eid", + "exit_code", + "gid", + "json_cmdline", + "ntime", + "parent", + "path", + "pid", + "probe_error", + "syscall", + "tid", + "time", + "uid" + ], + "sectionRelativeRepoPath": "bpf_process_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fbpf_process_events.yml&value=name%3A%20bpf_process_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/bpf_socket_events", + "title": "bpf_socket_events", + "htmlId": "table--bpfsocketevents--2bbe58be1b", + "evented": true, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "bpf_socket_events", + "cid", + "duration", + "eid", + "exit_code", + "family", + "fd", + "gid", + "local_address", + "local_port", + "ntime", + "parent", + "path", + "pid", + "probe_error", + "protocol", + "remote_address", + "remote_port", + "syscall", + "tid", + "time", + "type", + "uid" + ], + "sectionRelativeRepoPath": "bpf_socket_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fbpf_socket_events.yml&value=name%3A%20bpf_socket_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/carbon_black_info", + "title": "carbon_black_info", + "htmlId": "table--carbonblackinfo--1a7333701d", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "carbon_black_info", + "binary_queue", + "collect_cross_processes", + "collect_data_file_writes", + "collect_emet_events", + "collect_file_mods", + "collect_module_info", + "collect_module_loads", + "collect_net_conns", + "collect_process_user_context", + "collect_processes", + "collect_reg_mods", + "collect_sensor_operations", + "collect_store_files", + "config_name", + "event_queue", + "log_file_disk_quota_mb", + "log_file_disk_quota_percentage", + "protection_disabled", + "sensor_backend_server", + "sensor_id", + "sensor_ip_addr" + ], + "sectionRelativeRepoPath": "carbon_black_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/carbon_black_info.yml" + }, + { + "url": "/tables/carves", + "title": "carves", + "htmlId": "table--carves--faab2a865e", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "carves", + "carve", + "carve_guid", + "path", + "request_id", + "sha256", + "size", + "status", + "time" + ], + "sectionRelativeRepoPath": "carves", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fcarves.yml&value=name%3A%20carves%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/certificates", + "title": "certificates", + "htmlId": "table--certificates--e853dcf612", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "certificates", + "authority_key_id", + "ca", + "common_name", + "issuer", + "issuer2", + "key_algorithm", + "key_strength", + "key_usage", + "not_valid_after", + "not_valid_before", + "path", + "self_signed", + "serial", + "sha1", + "sid", + "signing_algorithm", + "store", + "store_id", + "store_location", + "subject", + "subject2", + "subject_key_id", + "username" + ], + "sectionRelativeRepoPath": "certificates", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/certificates.yml" + }, + { + "url": "/tables/chassis_info", + "title": "chassis_info", + "htmlId": "table--chassisinfo--b4f2a373fd", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "chassis_info", + "audible_alarm", + "breach_description", + "chassis_types", + "description", + "lock", + "manufacturer", + "model", + "security_breach", + "serial", + "sku", + "smbios_tag", + "status", + "visible_alarm" + ], + "sectionRelativeRepoPath": "chassis_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fchassis_info.yml&value=name%3A%20chassis_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/chocolatey_packages", + "title": "chocolatey_packages", + "htmlId": "table--chocolateypackages--a948b45942", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "chocolatey_packages", + "author", + "license", + "name", + "path", + "summary", + "version" + ], + "sectionRelativeRepoPath": "chocolatey_packages", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fchocolatey_packages.yml&value=name%3A%20chocolatey_packages%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/chrome_extension_content_scripts", + "title": "chrome_extension_content_scripts", + "htmlId": "table--chromeextensioncontentscripts--90dfc8f7b0", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "chrome_extension_content_scripts", + "browser_type", + "identifier", + "match", + "path", + "profile_path", + "referenced", + "script", + "uid", + "version" + ], + "sectionRelativeRepoPath": "chrome_extension_content_scripts", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/chrome_extension_content_scripts.yml" + }, + { + "url": "/tables/chrome_extensions", + "title": "chrome_extensions", + "htmlId": "table--chromeextensions--0b832601b4", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux", + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "chrome_extensions", + "author", + "browser_type", + "current_locale", + "default_locale", + "description", + "from_webstore", + "identifier", + "install_time", + "install_timestamp", + "key", + "manifest_hash", + "manifest_json", + "name", + "optional_permissions", + "optional_permissions_json", + "path", + "permissions", + "permissions_json", + "persistent", + "profile", + "profile_path", + "referenced", + "referenced_identifier", + "state", + "uid", + "update_url", + "version" + ], + "sectionRelativeRepoPath": "chrome_extensions", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/chrome_extensions.yml" + }, + { + "url": "/tables/cis_audit", + "title": "cis_audit", + "htmlId": "table--cisaudit--021dcf9746", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "cis_audit", + "item", + "value" + ], + "sectionRelativeRepoPath": "cis_audit", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/cis_audit.yml" + }, + { + "url": "/tables/connected_displays", + "title": "connected_displays", + "htmlId": "table--connecteddisplays--f57653bc5b", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "connected_displays", + "ambient_brightness_enabled", + "connection_type", + "display_id", + "display_type", + "main", + "manufactured_week", + "manufactured_year", + "mirror", + "name", + "online", + "pixels", + "product_id", + "resolution", + "rotation", + "serial_number", + "vendor_id" + ], + "sectionRelativeRepoPath": "connected_displays", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fconnected_displays.yml&value=name%3A%20connected_displays%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/connectivity", + "title": "connectivity", + "htmlId": "table--connectivity--9bd961f435", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "connectivity", + "disconnected", + "ipv4_internet", + "ipv4_local_network", + "ipv4_no_traffic", + "ipv4_subnet", + "ipv6_internet", + "ipv6_local_network", + "ipv6_no_traffic", + "ipv6_subnet" + ], + "sectionRelativeRepoPath": "connectivity", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fconnectivity.yml&value=name%3A%20connectivity%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/corestorage_logical_volume_families", + "title": "corestorage_logical_volume_families", + "htmlId": "table--corestoragelogicalvolumefamilies--c844b6943f", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "corestorage_logical_volume_families", + "EncryptionStatus", + "EncryptionType", + "HasVisibleUsers", + "HasVolumeKey", + "IsAcceptingNewUsers", + "IsFullySecure", + "MayHaveEncryptedEvents", + "RequiresPasswordUnlock", + "UUID", + "vg_FreeSpace", + "vg_FusionDrive", + "vg_Name", + "vg_Sequence", + "vg_Size", + "vg_Sparse", + "vg_Status", + "vg_UUID", + "vg_Version" + ], + "sectionRelativeRepoPath": "corestorage_logical_volume_families", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/corestorage_logical_volume_families.yml" + }, + { + "url": "/tables/corestorage_logical_volumes", + "title": "corestorage_logical_volumes", + "htmlId": "table--corestoragelogicalvolumes--b32c10c6c2", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "corestorage_logical_volumes", + "ContentHint", + "ConversionState", + "ConverstionProgressPercent", + "DesignatedPhysicalVolume", + "DesignatedPhysicalVolumeIdentifier", + "Identifier", + "Name", + "Sequence", + "Size", + "Status", + "UUID", + "Version", + "VolumeName", + "lvf_EncryptionStatus", + "lvf_EncryptionType", + "lvf_HasVisibleUsers", + "lvf_HasVolumeKey", + "lvf_IsAcceptingNewUsers", + "lvf_IsFullySecure", + "lvf_MayHaveEncryptedEvents", + "lvf_RequiresPasswordUnlock", + "lvf_UUID", + "vg_FreeSpace", + "vg_FusionDrive", + "vg_Name", + "vg_Sequence", + "vg_Size", + "vg_Sparse", + "vg_Status", + "vg_UUID", + "vg_Version" + ], + "sectionRelativeRepoPath": "corestorage_logical_volumes", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/corestorage_logical_volumes.yml" + }, + { + "url": "/tables/cpu_info", + "title": "cpu_info", + "htmlId": "table--cpuinfo--aa3c0cfb0c", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "cpu_info", + "address_width", + "availability", + "cpu_status", + "current_clock_speed", + "device_id", + "load_percentage", + "logical_processors", + "manufacturer", + "max_clock_speed", + "model", + "number_of_cores", + "number_of_efficiency_cores", + "number_of_performance_cores", + "processor_type", + "socket_designation" + ], + "sectionRelativeRepoPath": "cpu_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/cpu_info.yml" + }, + { + "url": "/tables/cpu_time", + "title": "cpu_time", + "htmlId": "table--cputime--8f68637ee3", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "cpu_time", + "core", + "guest", + "guest_nice", + "idle", + "iowait", + "irq", + "nice", + "softirq", + "steal", + "system", + "user" + ], + "sectionRelativeRepoPath": "cpu_time", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/cpu_time.yml" + }, + { + "url": "/tables/cpuid", + "title": "cpuid", + "htmlId": "table--cpuid--68704a46e7", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "cpuid", + "feature", + "input_eax", + "output_bit", + "output_register", + "value" + ], + "sectionRelativeRepoPath": "cpuid", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/cpuid.yml" + }, + { + "url": "/tables/crashes", + "title": "crashes", + "htmlId": "table--crashes--6bccea7c2f", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "crashes", + "crash_path", + "crashed_thread", + "datetime", + "exception_codes", + "exception_notes", + "exception_type", + "identifier", + "parent", + "path", + "pid", + "registers", + "responsible", + "stack_trace", + "type", + "uid", + "version" + ], + "sectionRelativeRepoPath": "crashes", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/crashes.yml" + }, + { + "url": "/tables/crontab", + "title": "crontab", + "htmlId": "table--crontab--a8fe1b5316", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "crontab", + "command", + "day_of_month", + "day_of_week", + "event", + "hour", + "minute", + "month", + "path", + "pid_with_namespace" + ], + "sectionRelativeRepoPath": "crontab", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/crontab.yml" + }, + { + "url": "/tables/cryptoinfo", + "title": "cryptoinfo", + "htmlId": "table--cryptoinfo--5e90627c08", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "cryptoinfo", + "fullkey", + "key", + "parent", + "passphrase", + "path", + "query", + "value" + ], + "sectionRelativeRepoPath": "cryptoinfo", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/cryptoinfo.yml" + }, + { + "url": "/tables/cryptsetup_status", + "title": "cryptsetup_status", + "htmlId": "table--cryptsetupstatus--3aa1264a26", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "cryptsetup_status", + "fullkey", + "key", + "name", + "parent", + "query", + "value" + ], + "sectionRelativeRepoPath": "cryptsetup_status", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/cryptsetup_status.yml" + }, + { + "url": "/tables/csrutil_info", + "title": "csrutil_info", + "htmlId": "table--csrutilinfo--959d823b8e", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "csrutil_info", + "ssv_enabled" + ], + "sectionRelativeRepoPath": "csrutil_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/csrutil_info.yml" + }, + { + "url": "/tables/cups_destinations", + "title": "cups_destinations", + "htmlId": "table--cupsdestinations--8ccb3721f2", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "cups_destinations", + "name", + "option_name", + "option_value" + ], + "sectionRelativeRepoPath": "cups_destinations", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/cups_destinations.yml" + }, + { + "url": "/tables/cups_jobs", + "title": "cups_jobs", + "htmlId": "table--cupsjobs--3268465efb", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "cups_jobs", + "completed_time", + "creation_time", + "destination", + "format", + "processing_time", + "size", + "title", + "user" + ], + "sectionRelativeRepoPath": "cups_jobs", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/cups_jobs.yml" + }, + { + "url": "/tables/curl", + "title": "curl", + "htmlId": "table--curl--2ab03fa14d", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "curl", + "bytes", + "method", + "response_code", + "result", + "round_trip_time", + "url", + "user_agent" + ], + "sectionRelativeRepoPath": "curl", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/curl.yml" + }, + { + "url": "/tables/curl_certificate", + "title": "curl_certificate", + "htmlId": "table--curlcertificate--6d52c798b0", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "curl_certificate", + "authority_key_identifier", + "basic_constraint", + "common_name", + "dump_certificate", + "extended_key_usage", + "has_expired", + "hostname", + "info_access", + "issuer_alternative_names", + "issuer_common_name", + "issuer_organization", + "issuer_organization_unit", + "key_usage", + "name_constraints", + "organization", + "organization_unit", + "pem", + "policies", + "policy_constraints", + "policy_mappings", + "serial_number", + "sha1_fingerprint", + "sha256_fingerprint", + "signature", + "signature_algorithm", + "subject_alternative_names", + "subject_info_access", + "subject_key_identifier", + "timeout", + "valid_from", + "valid_to", + "version" + ], + "sectionRelativeRepoPath": "curl_certificate", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/curl_certificate.yml" + }, + { + "url": "/tables/deb_packages", + "title": "deb_packages", + "htmlId": "table--debpackages--f9f4ca0355", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "deb_packages", + "admindir", + "arch", + "maintainer", + "mount_namespace_id", + "name", + "pid_with_namespace", + "priority", + "revision", + "section", + "size", + "source", + "status", + "version" + ], + "sectionRelativeRepoPath": "deb_packages", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/deb_packages.yml" + }, + { + "url": "/tables/default_environment", + "title": "default_environment", + "htmlId": "table--defaultenvironment--ccbaea6671", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "default_environment", + "expand", + "value", + "variable" + ], + "sectionRelativeRepoPath": "default_environment", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdefault_environment.yml&value=name%3A%20default_environment%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/device_file", + "title": "device_file", + "htmlId": "table--devicefile--e5267d9f3e", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "device_file", + "atime", + "block_size", + "ctime", + "device", + "filename", + "gid", + "hard_links", + "inode", + "mode", + "mtime", + "partition", + "path", + "size", + "type", + "uid" + ], + "sectionRelativeRepoPath": "device_file", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdevice_file.yml&value=name%3A%20device_file%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/device_firmware", + "title": "device_firmware", + "htmlId": "table--devicefirmware--ab4ba7dd63", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "device_firmware", + "device", + "type", + "version" + ], + "sectionRelativeRepoPath": "device_firmware", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/device_firmware.yml" + }, + { + "url": "/tables/device_hash", + "title": "device_hash", + "htmlId": "table--devicehash--c839a630b0", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "device_hash", + "device", + "inode", + "md5", + "partition", + "sha1", + "sha256" + ], + "sectionRelativeRepoPath": "device_hash", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdevice_hash.yml&value=name%3A%20device_hash%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/device_partitions", + "title": "device_partitions", + "htmlId": "table--devicepartitions--3489019e85", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "device_partitions", + "blocks", + "blocks_size", + "device", + "flags", + "inodes", + "label", + "offset", + "partition", + "type" + ], + "sectionRelativeRepoPath": "device_partitions", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdevice_partitions.yml&value=name%3A%20device_partitions%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/disk_encryption", + "title": "disk_encryption", + "htmlId": "table--diskencryption--26d5b55253", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "disk_encryption", + "encrypted", + "encryption_status", + "filevault_status", + "name", + "type", + "uid", + "user_uuid", + "uuid" + ], + "sectionRelativeRepoPath": "disk_encryption", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/disk_encryption.yml" + }, + { + "url": "/tables/disk_events", + "title": "disk_events", + "htmlId": "table--diskevents--737534006f", + "evented": true, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "disk_events", + "action", + "checksum", + "content", + "device", + "eid", + "ejectable", + "filesystem", + "media_name", + "mountable", + "name", + "path", + "size", + "time", + "uuid", + "vendor", + "writable" + ], + "sectionRelativeRepoPath": "disk_events", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/disk_events.yml" + }, + { + "url": "/tables/disk_info", + "title": "disk_info", + "htmlId": "table--diskinfo--e7393d4e29", + "evented": false, + "platforms": [ + "windows", + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "disk_info", + "description", + "disk_index", + "disk_size", + "hardware_model", + "id", + "manufacturer", + "name", + "partitions", + "pnp_device_id", + "serial", + "type" + ], + "sectionRelativeRepoPath": "disk_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/disk_info.yml" + }, + { + "url": "/tables/dns_cache", + "title": "dns_cache", + "htmlId": "table--dnscache--dc0e67fdcf", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "dns_cache", + "flags", + "name", + "type" + ], + "sectionRelativeRepoPath": "dns_cache", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/dns_cache.yml" + }, + { + "url": "/tables/dns_resolvers", + "title": "dns_resolvers", + "htmlId": "table--dnsresolvers--2c8fb31e5d", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "dns_resolvers", + "address", + "id", + "netmask", + "options", + "pid_with_namespace", + "type" + ], + "sectionRelativeRepoPath": "dns_resolvers", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/dns_resolvers.yml" + }, + { + "url": "/tables/docker_container_envs", + "title": "docker_container_envs", + "htmlId": "table--dockercontainerenvs--3f92fabef8", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_container_envs", + "id", + "key", + "value" + ], + "sectionRelativeRepoPath": "docker_container_envs", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/docker_container_envs.yml" + }, + { + "url": "/tables/docker_container_fs_changes", + "title": "docker_container_fs_changes", + "htmlId": "table--dockercontainerfschanges--e8a13529f8", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_container_fs_changes", + "change_type", + "id", + "path" + ], + "sectionRelativeRepoPath": "docker_container_fs_changes", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_container_fs_changes.yml&value=name%3A%20docker_container_fs_changes%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_container_labels", + "title": "docker_container_labels", + "htmlId": "table--dockercontainerlabels--525f815a85", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_container_labels", + "id", + "key", + "value" + ], + "sectionRelativeRepoPath": "docker_container_labels", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/docker_container_labels.yml" + }, + { + "url": "/tables/docker_container_mounts", + "title": "docker_container_mounts", + "htmlId": "table--dockercontainermounts--feffa9b278", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_container_mounts", + "destination", + "driver", + "id", + "mode", + "name", + "propagation", + "rw", + "source", + "type" + ], + "sectionRelativeRepoPath": "docker_container_mounts", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/docker_container_mounts.yml" + }, + { + "url": "/tables/docker_container_networks", + "title": "docker_container_networks", + "htmlId": "table--dockercontainernetworks--7482838a3b", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_container_networks", + "endpoint_id", + "gateway", + "id", + "ip_address", + "ip_prefix_len", + "ipv6_address", + "ipv6_gateway", + "ipv6_prefix_len", + "mac_address", + "name", + "network_id" + ], + "sectionRelativeRepoPath": "docker_container_networks", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/docker_container_networks.yml" + }, + { + "url": "/tables/docker_container_ports", + "title": "docker_container_ports", + "htmlId": "table--dockercontainerports--8fa613bed0", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_container_ports", + "host_ip", + "host_port", + "id", + "port", + "type" + ], + "sectionRelativeRepoPath": "docker_container_ports", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/docker_container_ports.yml" + }, + { + "url": "/tables/docker_container_processes", + "title": "docker_container_processes", + "htmlId": "table--dockercontainerprocesses--3790b40e9b", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_container_processes", + "cmdline", + "cpu", + "egid", + "euid", + "gid", + "id", + "mem", + "name", + "nice", + "parent", + "pgroup", + "pid", + "resident_size", + "sgid", + "start_time", + "state", + "suid", + "threads", + "time", + "total_size", + "uid", + "user", + "wired_size" + ], + "sectionRelativeRepoPath": "docker_container_processes", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_container_processes.yml&value=name%3A%20docker_container_processes%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_container_stats", + "title": "docker_container_stats", + "htmlId": "table--dockercontainerstats--55f8d1f434", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_container_stats", + "cpu_kernelmode_usage", + "cpu_total_usage", + "cpu_usermode_usage", + "disk_read", + "disk_write", + "id", + "interval", + "memory_cached", + "memory_limit", + "memory_max_usage", + "memory_usage", + "name", + "network_rx_bytes", + "network_tx_bytes", + "num_procs", + "online_cpus", + "pids", + "pre_cpu_kernelmode_usage", + "pre_cpu_total_usage", + "pre_cpu_usermode_usage", + "pre_online_cpus", + "pre_system_cpu_usage", + "preread", + "read", + "system_cpu_usage" + ], + "sectionRelativeRepoPath": "docker_container_stats", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_container_stats.yml&value=name%3A%20docker_container_stats%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_containers", + "title": "docker_containers", + "htmlId": "table--dockercontainers--e586f60cb7", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_containers", + "cgroup_namespace", + "command", + "config_entrypoint", + "created", + "env_variables", + "finished_at", + "id", + "image", + "image_id", + "ipc_namespace", + "mnt_namespace", + "name", + "net_namespace", + "path", + "pid", + "pid_namespace", + "privileged", + "readonly_rootfs", + "security_options", + "started_at", + "state", + "status", + "user_namespace", + "uts_namespace" + ], + "sectionRelativeRepoPath": "docker_containers", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/docker_containers.yml" + }, + { + "url": "/tables/docker_image_history", + "title": "docker_image_history", + "htmlId": "table--dockerimagehistory--77b04426fe", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_image_history", + "comment", + "created", + "created_by", + "id", + "size", + "tags" + ], + "sectionRelativeRepoPath": "docker_image_history", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_image_history.yml&value=name%3A%20docker_image_history%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_image_labels", + "title": "docker_image_labels", + "htmlId": "table--dockerimagelabels--14e0871386", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_image_labels", + "id", + "key", + "value" + ], + "sectionRelativeRepoPath": "docker_image_labels", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_image_labels.yml&value=name%3A%20docker_image_labels%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_image_layers", + "title": "docker_image_layers", + "htmlId": "table--dockerimagelayers--91693c4e4c", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_image_layers", + "id", + "layer_id", + "layer_order" + ], + "sectionRelativeRepoPath": "docker_image_layers", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_image_layers.yml&value=name%3A%20docker_image_layers%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_images", + "title": "docker_images", + "htmlId": "table--dockerimages--6819d40071", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_images", + "created", + "id", + "size_bytes", + "tags" + ], + "sectionRelativeRepoPath": "docker_images", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/docker_images.yml" + }, + { + "url": "/tables/docker_info", + "title": "docker_info", + "htmlId": "table--dockerinfo--2f30b285cd", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_info", + "architecture", + "bridge_nf_ip6tables", + "bridge_nf_iptables", + "cgroup_driver", + "containers", + "containers_paused", + "containers_running", + "containers_stopped", + "cpu_cfs_period", + "cpu_cfs_quota", + "cpu_set", + "cpu_shares", + "cpus", + "http_proxy", + "https_proxy", + "id", + "images", + "ipv4_forwarding", + "kernel_memory", + "kernel_version", + "logging_driver", + "memory", + "memory_limit", + "name", + "no_proxy", + "oom_kill_disable", + "os", + "os_type", + "root_dir", + "server_version", + "storage_driver", + "swap_limit" + ], + "sectionRelativeRepoPath": "docker_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_info.yml&value=name%3A%20docker_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_network_labels", + "title": "docker_network_labels", + "htmlId": "table--dockernetworklabels--1f827dc474", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_network_labels", + "id", + "key", + "value" + ], + "sectionRelativeRepoPath": "docker_network_labels", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_network_labels.yml&value=name%3A%20docker_network_labels%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_networks", + "title": "docker_networks", + "htmlId": "table--dockernetworks--2ae40ea518", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_networks", + "created", + "driver", + "enable_ipv6", + "gateway", + "id", + "name", + "subnet" + ], + "sectionRelativeRepoPath": "docker_networks", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_networks.yml&value=name%3A%20docker_networks%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_version", + "title": "docker_version", + "htmlId": "table--dockerversion--d5c8b11df6", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_version", + "api_version", + "arch", + "build_time", + "git_commit", + "go_version", + "kernel_version", + "min_api_version", + "os", + "version" + ], + "sectionRelativeRepoPath": "docker_version", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_version.yml&value=name%3A%20docker_version%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_volume_labels", + "title": "docker_volume_labels", + "htmlId": "table--dockervolumelabels--45adc74ba3", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_volume_labels", + "key", + "name", + "value" + ], + "sectionRelativeRepoPath": "docker_volume_labels", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdocker_volume_labels.yml&value=name%3A%20docker_volume_labels%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/docker_volumes", + "title": "docker_volumes", + "htmlId": "table--dockervolumes--cee95f6b90", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "docker_volumes", + "driver", + "mount_point", + "name", + "type" + ], + "sectionRelativeRepoPath": "docker_volumes", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/docker_volumes.yml" + }, + { + "url": "/tables/drivers", + "title": "drivers", + "htmlId": "table--drivers--58290d489f", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "drivers", + "class", + "date", + "description", + "device_id", + "device_name", + "driver_key", + "image", + "inf", + "manufacturer", + "provider", + "service", + "service_key", + "signed", + "version" + ], + "sectionRelativeRepoPath": "drivers", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fdrivers.yml&value=name%3A%20drivers%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/dscl", + "title": "dscl", + "htmlId": "table--dscl--54e7060384", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "dscl", + "command", + "key", + "path", + "value" + ], + "sectionRelativeRepoPath": "dscl", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/dscl.yml" + }, + { + "url": "/tables/ec2_instance_metadata", + "title": "ec2_instance_metadata", + "htmlId": "table--ec2instancemetadata--8b1828d8f6", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "ec2_instance_metadata", + "account_id", + "ami_id", + "architecture", + "availability_zone", + "iam_arn", + "instance_id", + "instance_type", + "local_hostname", + "local_ipv4", + "mac", + "region", + "reservation_id", + "security_groups", + "ssh_public_key" + ], + "sectionRelativeRepoPath": "ec2_instance_metadata", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fec2_instance_metadata.yml&value=name%3A%20ec2_instance_metadata%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/ec2_instance_tags", + "title": "ec2_instance_tags", + "htmlId": "table--ec2instancetags--450384158f", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "ec2_instance_tags", + "instance_id", + "key", + "value" + ], + "sectionRelativeRepoPath": "ec2_instance_tags", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fec2_instance_tags.yml&value=name%3A%20ec2_instance_tags%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/es_process_events", + "title": "es_process_events", + "htmlId": "table--esprocessevents--d79d694750", + "evented": true, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "es_process_events", + "cdhash", + "child_pid", + "cmdline", + "cmdline_count", + "codesigning_flags", + "cwd", + "egid", + "eid", + "env", + "env_count", + "euid", + "event_type", + "exit_code", + "gid", + "global_seq_num", + "original_parent", + "parent", + "path", + "pid", + "platform_binary", + "seq_num", + "signing_id", + "team_id", + "time", + "uid", + "username", + "version" + ], + "sectionRelativeRepoPath": "es_process_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fes_process_events.yml&value=name%3A%20es_process_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/es_process_file_events", + "title": "es_process_file_events", + "htmlId": "table--esprocessfileevents--e28968a0e8", + "evented": true, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "es_process_file_events", + "dest_filename", + "eid", + "event_type", + "filename", + "global_seq_num", + "parent", + "path", + "pid", + "seq_num", + "time", + "version" + ], + "sectionRelativeRepoPath": "es_process_file_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fes_process_file_events.yml&value=name%3A%20es_process_file_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/etc_hosts", + "title": "etc_hosts", + "htmlId": "table--etchosts--a56205b3f9", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "etc_hosts", + "address", + "hostnames", + "pid_with_namespace" + ], + "sectionRelativeRepoPath": "etc_hosts", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/etc_hosts.yml" + }, + { + "url": "/tables/etc_protocols", + "title": "etc_protocols", + "htmlId": "table--etcprotocols--b5ffb257d1", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "etc_protocols", + "alias", + "comment", + "name", + "number" + ], + "sectionRelativeRepoPath": "etc_protocols", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fetc_protocols.yml&value=name%3A%20etc_protocols%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/etc_services", + "title": "etc_services", + "htmlId": "table--etcservices--454572c18c", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "etc_services", + "aliases", + "comment", + "name", + "port", + "protocol" + ], + "sectionRelativeRepoPath": "etc_services", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/etc_services.yml" + }, + { + "url": "/tables/event_taps", + "title": "event_taps", + "htmlId": "table--eventtaps--b2afde9ecc", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "event_taps", + "enabled", + "event_tap_id", + "event_tapped", + "process_being_tapped", + "tapping_process" + ], + "sectionRelativeRepoPath": "event_taps", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/event_taps.yml" + }, + { + "url": "/tables/extended_attributes", + "title": "extended_attributes", + "htmlId": "table--extendedattributes--9dea030217", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "extended_attributes", + "base64", + "directory", + "key", + "path", + "value" + ], + "sectionRelativeRepoPath": "extended_attributes", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fextended_attributes.yml&value=name%3A%20extended_attributes%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/falcon_kernel_check", + "title": "falcon_kernel_check", + "htmlId": "table--falconkernelcheck--5479232641", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "falcon_kernel_check", + "kernel", + "sensor_version", + "supported" + ], + "sectionRelativeRepoPath": "falcon_kernel_check", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/falcon_kernel_check.yml" + }, + { + "url": "/tables/falconctl_options", + "title": "falconctl_options", + "htmlId": "table--falconctloptions--7106491b65", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "falconctl_options", + "options" + ], + "sectionRelativeRepoPath": "falconctl_options", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/falconctl_options.yml" + }, + { + "url": "/tables/fan_speed_sensors", + "title": "fan_speed_sensors", + "htmlId": "table--fanspeedsensors--32417c8bf6", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "fan_speed_sensors", + "actual", + "fan", + "max", + "min", + "name", + "target" + ], + "sectionRelativeRepoPath": "fan_speed_sensors", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Ffan_speed_sensors.yml&value=name%3A%20fan_speed_sensors%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/file", + "title": "file", + "htmlId": "table--file--5f21761417", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "file", + "atime", + "attributes", + "block_size", + "bsd_flags", + "btime", + "ctime", + "device", + "directory", + "file_id", + "file_version", + "filename", + "gid", + "hard_links", + "inode", + "mode", + "mount_namespace_id", + "mtime", + "original_filename", + "path", + "pid_with_namespace", + "product_version", + "shortcut_comment", + "shortcut_run", + "shortcut_start_in", + "shortcut_target_location", + "shortcut_target_path", + "shortcut_target_type", + "size", + "symlink", + "type", + "uid", + "volume_serial" + ], + "sectionRelativeRepoPath": "file", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/file.yml" + }, + { + "url": "/tables/file_events", + "title": "file_events", + "htmlId": "table--fileevents--7d5b0a2d3e", + "evented": true, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "file_events", + "action", + "atime", + "category", + "ctime", + "eid", + "gid", + "hashed", + "inode", + "md5", + "mode", + "mtime", + "sha1", + "sha256", + "size", + "target_path", + "time", + "transaction_id", + "uid" + ], + "sectionRelativeRepoPath": "file_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Ffile_events.yml&value=name%3A%20file_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/file_lines", + "title": "file_lines", + "htmlId": "table--filelines--66f7e5497f", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "file_lines", + "line", + "path" + ], + "sectionRelativeRepoPath": "file_lines", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/file_lines.yml" + }, + { + "url": "/tables/filevault_prk", + "title": "filevault_prk", + "htmlId": "table--filevaultprk--4327326014", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "filevault_prk", + "base64_encrypted" + ], + "sectionRelativeRepoPath": "filevault_prk", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/filevault_prk.yml" + }, + { + "url": "/tables/filevault_status", + "title": "filevault_status", + "htmlId": "table--filevaultstatus--808666eddb", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "filevault_status", + "status" + ], + "sectionRelativeRepoPath": "filevault_status", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/filevault_status.yml" + }, + { + "url": "/tables/filevault_users", + "title": "filevault_users", + "htmlId": "table--filevaultusers--283a958213", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "filevault_users", + "username", + "uuid" + ], + "sectionRelativeRepoPath": "filevault_users", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/filevault_users.yml" + }, + { + "url": "/tables/find_cmd", + "title": "find_cmd", + "htmlId": "table--findcmd--6d09c7cd5f", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "find_cmd", + "directory", + "path", + "perm", + "type" + ], + "sectionRelativeRepoPath": "find_cmd", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/find_cmd.yml" + }, + { + "url": "/tables/firefox_addons", + "title": "firefox_addons", + "htmlId": "table--firefoxaddons--9eabc39fea", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "firefox_addons", + "active", + "autoupdate", + "creator", + "description", + "disabled", + "identifier", + "location", + "name", + "path", + "source_url", + "type", + "uid", + "version", + "visible" + ], + "sectionRelativeRepoPath": "firefox_addons", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/firefox_addons.yml" + }, + { + "url": "/tables/firefox_preferences", + "title": "firefox_preferences", + "htmlId": "table--firefoxpreferences--2366a56fa1", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "firefox_preferences", + "fullkey", + "key", + "parent", + "path", + "query", + "value" + ], + "sectionRelativeRepoPath": "firefox_preferences", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/firefox_preferences.yml" + }, + { + "url": "/tables/firmware_eficheck_integrity_check", + "title": "firmware_eficheck_integrity_check", + "htmlId": "table--firmwareeficheckintegritycheck--88da320790", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "firmware_eficheck_integrity_check", + "chip", + "output" + ], + "sectionRelativeRepoPath": "firmware_eficheck_integrity_check", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/firmware_eficheck_integrity_check.yml" + }, + { + "url": "/tables/firmwarepasswd", + "title": "firmwarepasswd", + "htmlId": "table--firmwarepasswd--34c47d2dc2", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "firmwarepasswd", + "mode", + "option_roms_allowed", + "password_enabled" + ], + "sectionRelativeRepoPath": "firmwarepasswd", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/firmwarepasswd.yml" + }, + { + "url": "/tables/fleetd_logs", + "title": "fleetd_logs", + "htmlId": "table--fleetdlogs--04f95fb2e5", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "fleetd_logs", + "error", + "level", + "message", + "payload", + "time" + ], + "sectionRelativeRepoPath": "fleetd_logs", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/fleetd_logs.yml" + }, + { + "url": "/tables/gatekeeper", + "title": "gatekeeper", + "htmlId": "table--gatekeeper--c48826d081", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "gatekeeper", + "assessments_enabled", + "dev_id_enabled", + "opaque_version", + "version" + ], + "sectionRelativeRepoPath": "gatekeeper", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/gatekeeper.yml" + }, + { + "url": "/tables/gatekeeper_approved_apps", + "title": "gatekeeper_approved_apps", + "htmlId": "table--gatekeeperapprovedapps--ccb2041adc", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "gatekeeper_approved_apps", + "ctime", + "mtime", + "path", + "requirement" + ], + "sectionRelativeRepoPath": "gatekeeper_approved_apps", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fgatekeeper_approved_apps.yml&value=name%3A%20gatekeeper_approved_apps%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/geolocation", + "title": "geolocation", + "htmlId": "table--geolocation--0338bc3ba9", + "evented": false, + "platforms": [ + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "geolocation", + "city", + "country", + "ip", + "region" + ], + "sectionRelativeRepoPath": "geolocation", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/geolocation.yml" + }, + { + "url": "/tables/google_chrome_profiles", + "title": "google_chrome_profiles", + "htmlId": "table--googlechromeprofiles--bc22157648", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "google_chrome_profiles", + "email", + "ephemeral", + "name", + "username" + ], + "sectionRelativeRepoPath": "google_chrome_profiles", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/google_chrome_profiles.yml" + }, + { + "url": "/tables/groups", + "title": "groups", + "htmlId": "table--groups--05fec1d6ce", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "groups", + "comment", + "gid", + "gid_signed", + "group_sid", + "groupname", + "is_hidden", + "pid_with_namespace" + ], + "sectionRelativeRepoPath": "groups", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/groups.yml" + }, + { + "url": "/tables/hardware_events", + "title": "hardware_events", + "htmlId": "table--hardwareevents--f7cce3883a", + "evented": true, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "hardware_events", + "action", + "driver", + "eid", + "model", + "model_id", + "path", + "revision", + "serial", + "time", + "type", + "vendor", + "vendor_id" + ], + "sectionRelativeRepoPath": "hardware_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fhardware_events.yml&value=name%3A%20hardware_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/hash", + "title": "hash", + "htmlId": "table--hash--c08ce91512", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "hash", + "directory", + "md5", + "mount_namespace_id", + "path", + "pid_with_namespace", + "sha1", + "sha256" + ], + "sectionRelativeRepoPath": "hash", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/hash.yml" + }, + { + "url": "/tables/homebrew_packages", + "title": "homebrew_packages", + "htmlId": "table--homebrewpackages--9c26173ba7", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "homebrew_packages", + "name", + "path", + "prefix", + "type", + "version" + ], + "sectionRelativeRepoPath": "homebrew_packages", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/homebrew_packages.yml" + }, + { + "url": "/tables/hvci_status", + "title": "hvci_status", + "htmlId": "table--hvcistatus--46a3ee08e5", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "hvci_status", + "code_integrity_policy_enforcement_status", + "instance_identifier", + "umci_policy_status", + "vbs_status", + "version" + ], + "sectionRelativeRepoPath": "hvci_status", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fhvci_status.yml&value=name%3A%20hvci_status%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/ibridge_info", + "title": "ibridge_info", + "htmlId": "table--ibridgeinfo--38f5f5d7eb", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "ibridge_info", + "boot_uuid", + "coprocessor_version", + "firmware_version", + "unique_chip_id" + ], + "sectionRelativeRepoPath": "ibridge_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fibridge_info.yml&value=name%3A%20ibridge_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/icloud_private_relay", + "title": "icloud_private_relay", + "htmlId": "table--icloudprivaterelay--7cbb9c575c", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "icloud_private_relay", + "status" + ], + "sectionRelativeRepoPath": "icloud_private_relay", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/icloud_private_relay.yml" + }, + { + "url": "/tables/ie_extensions", + "title": "ie_extensions", + "htmlId": "table--ieextensions--412b814817", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "ie_extensions", + "name", + "path", + "registry_path", + "version" + ], + "sectionRelativeRepoPath": "ie_extensions", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/ie_extensions.yml" + }, + { + "url": "/tables/intel_me_info", + "title": "intel_me_info", + "htmlId": "table--intelmeinfo--fd5eb9626f", + "evented": false, + "platforms": [ + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "intel_me_info", + "version" + ], + "sectionRelativeRepoPath": "intel_me_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fintel_me_info.yml&value=name%3A%20intel_me_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/interface_addresses", + "title": "interface_addresses", + "htmlId": "table--interfaceaddresses--4163068693", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "interface_addresses", + "address", + "broadcast", + "friendly_name", + "interface", + "mask", + "point_to_point", + "type" + ], + "sectionRelativeRepoPath": "interface_addresses", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/interface_addresses.yml" + }, + { + "url": "/tables/interface_details", + "title": "interface_details", + "htmlId": "table--interfacedetails--c8234f77ad", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "interface_details", + "collisions", + "connection_id", + "connection_status", + "description", + "dhcp_enabled", + "dhcp_lease_expires", + "dhcp_lease_obtained", + "dhcp_server", + "dns_domain", + "dns_domain_suffix_search_order", + "dns_host_name", + "dns_server_search_order", + "enabled", + "flags", + "friendly_name", + "ibytes", + "idrops", + "ierrors", + "interface", + "ipackets", + "last_change", + "link_speed", + "mac", + "manufacturer", + "metric", + "mtu", + "obytes", + "odrops", + "oerrors", + "opackets", + "pci_slot", + "physical_adapter", + "service", + "speed", + "type" + ], + "sectionRelativeRepoPath": "interface_details", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/interface_details.yml" + }, + { + "url": "/tables/interface_ipv6", + "title": "interface_ipv6", + "htmlId": "table--interfaceipv6--48a78776ae", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "interface_ipv6", + "forwarding_enabled", + "hop_limit", + "interface", + "redirect_accept", + "rtadv_accept" + ], + "sectionRelativeRepoPath": "interface_ipv6", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/interface_ipv6.yml" + }, + { + "url": "/tables/iokit_devicetree", + "title": "iokit_devicetree", + "htmlId": "table--iokitdevicetree--475d23de81", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "iokit_devicetree", + "busy_state", + "class", + "depth", + "device_path", + "id", + "name", + "parent", + "retain_count", + "service" + ], + "sectionRelativeRepoPath": "iokit_devicetree", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/iokit_devicetree.yml" + }, + { + "url": "/tables/iokit_registry", + "title": "iokit_registry", + "htmlId": "table--iokitregistry--213523c85d", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "iokit_registry", + "busy_state", + "class", + "depth", + "id", + "name", + "parent", + "retain_count" + ], + "sectionRelativeRepoPath": "iokit_registry", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/iokit_registry.yml" + }, + { + "url": "/tables/ioreg", + "title": "ioreg", + "htmlId": "table--ioreg--64934c5b2c", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "ioreg", + "c", + "d", + "fullkey", + "k", + "key", + "n", + "p", + "parent", + "query", + "r", + "value" + ], + "sectionRelativeRepoPath": "ioreg", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/ioreg.yml" + }, + { + "url": "/tables/iptables", + "title": "iptables", + "htmlId": "table--iptables--73fe23ccfd", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "iptables", + "bytes", + "chain", + "dst_ip", + "dst_mask", + "dst_port", + "filter_name", + "iniface", + "iniface_mask", + "match", + "outiface", + "outiface_mask", + "packets", + "policy", + "protocol", + "src_ip", + "src_mask", + "src_port", + "target" + ], + "sectionRelativeRepoPath": "iptables", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/iptables.yml" + }, + { + "url": "/tables/kernel_extensions", + "title": "kernel_extensions", + "htmlId": "table--kernelextensions--015ed33cfc", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "kernel_extensions", + "idx", + "linked_against", + "name", + "path", + "refs", + "size", + "version" + ], + "sectionRelativeRepoPath": "kernel_extensions", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/kernel_extensions.yml" + }, + { + "url": "/tables/kernel_info", + "title": "kernel_info", + "htmlId": "table--kernelinfo--e02ab4d886", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "kernel_info", + "arguments", + "device", + "path", + "version" + ], + "sectionRelativeRepoPath": "kernel_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/kernel_info.yml" + }, + { + "url": "/tables/kernel_keys", + "title": "kernel_keys", + "htmlId": "table--kernelkeys--c3a84244c8", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "kernel_keys", + "description", + "flags", + "gid", + "permissions", + "serial_number", + "timeout", + "type", + "uid", + "usage" + ], + "sectionRelativeRepoPath": "kernel_keys", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fkernel_keys.yml&value=name%3A%20kernel_keys%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/kernel_modules", + "title": "kernel_modules", + "htmlId": "table--kernelmodules--c9051ad100", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "kernel_modules", + "address", + "name", + "size", + "status", + "used_by" + ], + "sectionRelativeRepoPath": "kernel_modules", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fkernel_modules.yml&value=name%3A%20kernel_modules%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/kernel_panics", + "title": "kernel_panics", + "htmlId": "table--kernelpanics--c6cb2cce6e", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "kernel_panics", + "dependencies", + "frame_backtrace", + "kernel_version", + "last_loaded", + "last_unloaded", + "module_backtrace", + "name", + "os_version", + "path", + "registers", + "system_model", + "time", + "uptime" + ], + "sectionRelativeRepoPath": "kernel_panics", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/kernel_panics.yml" + }, + { + "url": "/tables/keychain_acls", + "title": "keychain_acls", + "htmlId": "table--keychainacls--e46564a1f0", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "keychain_acls", + "authorizations", + "description", + "keychain_path", + "label", + "path" + ], + "sectionRelativeRepoPath": "keychain_acls", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/keychain_acls.yml" + }, + { + "url": "/tables/keychain_items", + "title": "keychain_items", + "htmlId": "table--keychainitems--ceb19aa966", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "keychain_items", + "account", + "comment", + "created", + "description", + "label", + "modified", + "path", + "pk_hash", + "type" + ], + "sectionRelativeRepoPath": "keychain_items", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/keychain_items.yml" + }, + { + "url": "/tables/known_hosts", + "title": "known_hosts", + "htmlId": "table--knownhosts--2c508bc3c8", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "known_hosts", + "key", + "key_file", + "uid" + ], + "sectionRelativeRepoPath": "known_hosts", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/known_hosts.yml" + }, + { + "url": "/tables/kva_speculative_info", + "title": "kva_speculative_info", + "htmlId": "table--kvaspeculativeinfo--aa9ff39cc2", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "kva_speculative_info", + "bp_microcode_disabled", + "bp_mitigations", + "bp_system_pol_disabled", + "cpu_pred_cmd_supported", + "cpu_spec_ctrl_supported", + "ibrs_support_enabled", + "kva_shadow_enabled", + "kva_shadow_inv_pcid", + "kva_shadow_pcid", + "kva_shadow_user_global", + "stibp_support_enabled" + ], + "sectionRelativeRepoPath": "kva_speculative_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fkva_speculative_info.yml&value=name%3A%20kva_speculative_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/last", + "title": "last", + "htmlId": "table--last--81b773b51e", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "last", + "host", + "pid", + "time", + "tty", + "type", + "type_name", + "username" + ], + "sectionRelativeRepoPath": "last", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/last.yml" + }, + { + "url": "/tables/launchd", + "title": "launchd", + "htmlId": "table--launchd--e309e31831", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "launchd", + "disabled", + "groupname", + "inetd_compatibility", + "keep_alive", + "label", + "name", + "on_demand", + "path", + "process_type", + "program", + "program_arguments", + "queue_directories", + "root_directory", + "run_at_load", + "start_interval", + "start_on_mount", + "stderr_path", + "stdout_path", + "username", + "watch_paths", + "working_directory" + ], + "sectionRelativeRepoPath": "launchd", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/launchd.yml" + }, + { + "url": "/tables/launchd_overrides", + "title": "launchd_overrides", + "htmlId": "table--launchdoverrides--89410cb367", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "launchd_overrides", + "key", + "label", + "path", + "uid", + "value" + ], + "sectionRelativeRepoPath": "launchd_overrides", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flaunchd_overrides.yml&value=name%3A%20launchd_overrides%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/listening_ports", + "title": "listening_ports", + "htmlId": "table--listeningports--de6bf76ec3", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "listening_ports", + "address", + "family", + "fd", + "net_namespace", + "path", + "pid", + "port", + "protocol", + "socket" + ], + "sectionRelativeRepoPath": "listening_ports", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/listening_ports.yml" + }, + { + "url": "/tables/load_average", + "title": "load_average", + "htmlId": "table--loadaverage--f5f080e140", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "load_average", + "average", + "period" + ], + "sectionRelativeRepoPath": "load_average", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/load_average.yml" + }, + { + "url": "/tables/location_services", + "title": "location_services", + "htmlId": "table--locationservices--f22473f4be", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "location_services", + "enabled" + ], + "sectionRelativeRepoPath": "location_services", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/location_services.yml" + }, + { + "url": "/tables/logged_in_users", + "title": "logged_in_users", + "htmlId": "table--loggedinusers--bd140b0e93", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "logged_in_users", + "host", + "pid", + "registry_hive", + "sid", + "time", + "tty", + "type", + "user" + ], + "sectionRelativeRepoPath": "logged_in_users", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/logged_in_users.yml" + }, + { + "url": "/tables/logical_drives", + "title": "logical_drives", + "htmlId": "table--logicaldrives--e69b777f6c", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "logical_drives", + "boot_partition", + "description", + "device_id", + "file_system", + "free_space", + "size", + "type" + ], + "sectionRelativeRepoPath": "logical_drives", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flogical_drives.yml&value=name%3A%20logical_drives%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/logon_sessions", + "title": "logon_sessions", + "htmlId": "table--logonsessions--54d10b59e8", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "logon_sessions", + "authentication_package", + "dns_domain_name", + "home_directory", + "home_directory_drive", + "logon_domain", + "logon_id", + "logon_script", + "logon_server", + "logon_sid", + "logon_time", + "logon_type", + "profile_path", + "session_id", + "upn", + "user" + ], + "sectionRelativeRepoPath": "logon_sessions", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flogon_sessions.yml&value=name%3A%20logon_sessions%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/lxd_certificates", + "title": "lxd_certificates", + "htmlId": "table--lxdcertificates--06e045fa14", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "lxd_certificates", + "certificate", + "fingerprint", + "name", + "type" + ], + "sectionRelativeRepoPath": "lxd_certificates", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flxd_certificates.yml&value=name%3A%20lxd_certificates%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/lxd_cluster", + "title": "lxd_cluster", + "htmlId": "table--lxdcluster--a8491b6203", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "lxd_cluster", + "enabled", + "member_config_description", + "member_config_entity", + "member_config_key", + "member_config_name", + "member_config_value", + "server_name" + ], + "sectionRelativeRepoPath": "lxd_cluster", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flxd_cluster.yml&value=name%3A%20lxd_cluster%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/lxd_cluster_members", + "title": "lxd_cluster_members", + "htmlId": "table--lxdclustermembers--7d6e6837d2", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "lxd_cluster_members", + "database", + "message", + "server_name", + "status", + "url" + ], + "sectionRelativeRepoPath": "lxd_cluster_members", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flxd_cluster_members.yml&value=name%3A%20lxd_cluster_members%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/lxd_images", + "title": "lxd_images", + "htmlId": "table--lxdimages--55db6fdd97", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "lxd_images", + "aliases", + "architecture", + "auto_update", + "cached", + "created_at", + "description", + "expires_at", + "filename", + "id", + "last_used_at", + "os", + "public", + "release", + "size", + "update_source_alias", + "update_source_certificate", + "update_source_protocol", + "update_source_server", + "uploaded_at" + ], + "sectionRelativeRepoPath": "lxd_images", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flxd_images.yml&value=name%3A%20lxd_images%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/lxd_instance_config", + "title": "lxd_instance_config", + "htmlId": "table--lxdinstanceconfig--54469816ca", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "lxd_instance_config", + "key", + "name", + "value" + ], + "sectionRelativeRepoPath": "lxd_instance_config", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flxd_instance_config.yml&value=name%3A%20lxd_instance_config%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/lxd_instance_devices", + "title": "lxd_instance_devices", + "htmlId": "table--lxdinstancedevices--f28caba867", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "lxd_instance_devices", + "device", + "device_type", + "key", + "name", + "value" + ], + "sectionRelativeRepoPath": "lxd_instance_devices", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flxd_instance_devices.yml&value=name%3A%20lxd_instance_devices%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/lxd_instances", + "title": "lxd_instances", + "htmlId": "table--lxdinstances--77d953ad3e", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "lxd_instances", + "architecture", + "base_image", + "created_at", + "description", + "ephemeral", + "name", + "os", + "pid", + "processes", + "stateful", + "status" + ], + "sectionRelativeRepoPath": "lxd_instances", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flxd_instances.yml&value=name%3A%20lxd_instances%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/lxd_networks", + "title": "lxd_networks", + "htmlId": "table--lxdnetworks--7dd5f10782", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "lxd_networks", + "bytes_received", + "bytes_sent", + "hwaddr", + "ipv4_address", + "ipv6_address", + "managed", + "mtu", + "name", + "packets_received", + "packets_sent", + "state", + "type", + "used_by" + ], + "sectionRelativeRepoPath": "lxd_networks", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flxd_networks.yml&value=name%3A%20lxd_networks%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/lxd_storage_pools", + "title": "lxd_storage_pools", + "htmlId": "table--lxdstoragepools--950b575e61", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "lxd_storage_pools", + "driver", + "inodes_total", + "inodes_used", + "name", + "size", + "source", + "space_total", + "space_used" + ], + "sectionRelativeRepoPath": "lxd_storage_pools", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Flxd_storage_pools.yml&value=name%3A%20lxd_storage_pools%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/macadmins_unified_log", + "title": "macadmins_unified_log", + "htmlId": "table--macadminsunifiedlog--e036df9e57", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "macadmins_unified_log", + "activity_identifier", + "boot_uuid", + "category", + "event_message", + "event_type", + "format_string", + "log_level", + "parent_activity_identifier", + "process_id", + "process_image_path", + "sender_image_path", + "sender_image_uuid", + "sender_program_counter", + "subsystem", + "thread_id", + "timestamp", + "trace_id" + ], + "sectionRelativeRepoPath": "macadmins_unified_log", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/macadmins_unified_log.yml" + }, + { + "url": "/tables/macos_profiles", + "title": "macos_profiles", + "htmlId": "table--macosprofiles--cae047dfff", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "macos_profiles", + "description", + "display_name", + "identifier", + "install_date", + "organization", + "type", + "uuid", + "verification_state" + ], + "sectionRelativeRepoPath": "macos_profiles", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/macos_profiles.yml" + }, + { + "url": "/tables/macos_rsr", + "title": "macos_rsr", + "htmlId": "table--macosrsr--9c9ef590fd", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "macos_rsr", + "full_macos_version", + "macos_version", + "rsr_supported", + "rsr_version" + ], + "sectionRelativeRepoPath": "macos_rsr", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/macos_rsr.yml" + }, + { + "url": "/tables/magic", + "title": "magic", + "htmlId": "table--magic--2b54571c80", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "magic", + "data", + "magic_db_files", + "mime_encoding", + "mime_type", + "path" + ], + "sectionRelativeRepoPath": "magic", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmagic.yml&value=name%3A%20magic%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/managed_policies", + "title": "managed_policies", + "htmlId": "table--managedpolicies--494a329dfb", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "managed_policies", + "domain", + "manual", + "name", + "username", + "uuid", + "value" + ], + "sectionRelativeRepoPath": "managed_policies", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/managed_policies.yml" + }, + { + "url": "/tables/md_devices", + "title": "md_devices", + "htmlId": "table--mddevices--cc18ebf22a", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "md_devices", + "active_disks", + "bitmap_chunk_size", + "bitmap_external_file", + "bitmap_on_mem", + "check_array_finish", + "check_array_progress", + "check_array_speed", + "chunk_size", + "device_name", + "failed_disks", + "nr_raid_disks", + "other", + "raid_disks", + "raid_level", + "recovery_finish", + "recovery_progress", + "recovery_speed", + "reshape_finish", + "reshape_progress", + "reshape_speed", + "resync_finish", + "resync_progress", + "resync_speed", + "size", + "spare_disks", + "status", + "superblock_state", + "superblock_update_time", + "superblock_version", + "unused_devices", + "working_disks" + ], + "sectionRelativeRepoPath": "md_devices", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmd_devices.yml&value=name%3A%20md_devices%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/md_drives", + "title": "md_drives", + "htmlId": "table--mddrives--f529358f7d", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "md_drives", + "drive_name", + "md_device_name", + "slot", + "state" + ], + "sectionRelativeRepoPath": "md_drives", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmd_drives.yml&value=name%3A%20md_drives%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/md_personalities", + "title": "md_personalities", + "htmlId": "table--mdpersonalities--6234b42367", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "md_personalities", + "name" + ], + "sectionRelativeRepoPath": "md_personalities", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmd_personalities.yml&value=name%3A%20md_personalities%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/mdfind", + "title": "mdfind", + "htmlId": "table--mdfind--2061531fab", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "mdfind", + "path", + "query" + ], + "sectionRelativeRepoPath": "mdfind", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmdfind.yml&value=name%3A%20mdfind%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/mdls", + "title": "mdls", + "htmlId": "table--mdls--8826cff54e", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "mdls", + "key", + "path", + "value", + "valuetype" + ], + "sectionRelativeRepoPath": "mdls", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/mdls.yml" + }, + { + "url": "/tables/mdm", + "title": "mdm", + "htmlId": "table--mdm--4e74952c0b", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "mdm", + "access_rights", + "checkin_url", + "dep_capable", + "enrolled", + "has_scep_payload", + "identity_certificate_uuid", + "install_date", + "installed_from_dep", + "payload_identifier", + "server_url", + "sign_message", + "topic", + "user_approved" + ], + "sectionRelativeRepoPath": "mdm", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/mdm.yml" + }, + { + "url": "/tables/mdm_bridge", + "title": "mdm_bridge", + "htmlId": "table--mdmbridge--6dff726888", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "mdm_bridge", + "enrolled_user", + "enrollment_status", + "mdm_command_input", + "mdm_command_output", + "raw_mdm_command_output" + ], + "sectionRelativeRepoPath": "mdm_bridge", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/mdm_bridge.yml" + }, + { + "url": "/tables/memory_array_mapped_addresses", + "title": "memory_array_mapped_addresses", + "htmlId": "table--memoryarraymappedaddresses--6f656395f7", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "memory_array_mapped_addresses", + "ending_address", + "handle", + "memory_array_handle", + "partition_width", + "starting_address" + ], + "sectionRelativeRepoPath": "memory_array_mapped_addresses", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmemory_array_mapped_addresses.yml&value=name%3A%20memory_array_mapped_addresses%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/memory_arrays", + "title": "memory_arrays", + "htmlId": "table--memoryarrays--abd1487b4b", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "memory_arrays", + "handle", + "location", + "max_capacity", + "memory_error_correction", + "memory_error_info_handle", + "number_memory_devices", + "use" + ], + "sectionRelativeRepoPath": "memory_arrays", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmemory_arrays.yml&value=name%3A%20memory_arrays%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/memory_device_mapped_addresses", + "title": "memory_device_mapped_addresses", + "htmlId": "table--memorydevicemappedaddresses--21aa4bee51", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "memory_device_mapped_addresses", + "ending_address", + "handle", + "interleave_data_depth", + "interleave_position", + "memory_array_mapped_address_handle", + "memory_device_handle", + "partition_row_position", + "starting_address" + ], + "sectionRelativeRepoPath": "memory_device_mapped_addresses", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmemory_device_mapped_addresses.yml&value=name%3A%20memory_device_mapped_addresses%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/memory_devices", + "title": "memory_devices", + "htmlId": "table--memorydevices--8e8226757f", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "memory_devices", + "array_handle", + "asset_tag", + "bank_locator", + "configured_clock_speed", + "configured_voltage", + "data_width", + "device_locator", + "form_factor", + "handle", + "manufacturer", + "max_speed", + "max_voltage", + "memory_type", + "memory_type_details", + "min_voltage", + "part_number", + "serial_number", + "set", + "size", + "total_width" + ], + "sectionRelativeRepoPath": "memory_devices", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmemory_devices.yml&value=name%3A%20memory_devices%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/memory_error_info", + "title": "memory_error_info", + "htmlId": "table--memoryerrorinfo--0e04980533", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "memory_error_info", + "device_error_address", + "error_granularity", + "error_operation", + "error_resolution", + "error_type", + "handle", + "memory_array_error_address", + "vendor_syndrome" + ], + "sectionRelativeRepoPath": "memory_error_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmemory_error_info.yml&value=name%3A%20memory_error_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/memory_info", + "title": "memory_info", + "htmlId": "table--memoryinfo--84feac1e17", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "memory_info", + "active", + "buffers", + "cached", + "inactive", + "memory_available", + "memory_free", + "memory_total", + "swap_cached", + "swap_free", + "swap_total" + ], + "sectionRelativeRepoPath": "memory_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmemory_info.yml&value=name%3A%20memory_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/memory_map", + "title": "memory_map", + "htmlId": "table--memorymap--dbdfd30e2f", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "memory_map", + "end", + "name", + "start" + ], + "sectionRelativeRepoPath": "memory_map", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmemory_map.yml&value=name%3A%20memory_map%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/mounts", + "title": "mounts", + "htmlId": "table--mounts--9bd193b227", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "mounts", + "blocks", + "blocks_available", + "blocks_free", + "blocks_size", + "device", + "device_alias", + "flags", + "inodes", + "inodes_free", + "path", + "type" + ], + "sectionRelativeRepoPath": "mounts", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/mounts.yml" + }, + { + "url": "/tables/msr", + "title": "msr", + "htmlId": "table--msr--ff9484332b", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "msr", + "feature_control", + "perf_ctl", + "perf_status", + "platform_info", + "processor_number", + "rapl_energy_status", + "rapl_power_limit", + "rapl_power_units", + "turbo_disabled", + "turbo_ratio_limit" + ], + "sectionRelativeRepoPath": "msr", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fmsr.yml&value=name%3A%20msr%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/munki_info", + "title": "munki_info", + "htmlId": "table--munkiinfo--2e4b112369", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "munki_info", + "console_user", + "end_time", + "errors", + "manifest_name", + "problem_installs", + "start_time", + "success", + "version", + "warnings" + ], + "sectionRelativeRepoPath": "munki_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/munki_info.yml" + }, + { + "url": "/tables/munki_installs", + "title": "munki_installs", + "htmlId": "table--munkiinstalls--b403c42531", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "munki_installs", + "end_time", + "installed", + "installed_version", + "name" + ], + "sectionRelativeRepoPath": "munki_installs", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/munki_installs.yml" + }, + { + "url": "/tables/network_interfaces", + "title": "network_interfaces", + "htmlId": "table--networkinterfaces--ea6f795816", + "evented": false, + "platforms": [ + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "network_interfaces", + "ipv4", + "ipv6", + "mac" + ], + "sectionRelativeRepoPath": "network_interfaces", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/network_interfaces.yml" + }, + { + "url": "/tables/nfs_shares", + "title": "nfs_shares", + "htmlId": "table--nfsshares--b4f614d51e", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "nfs_shares", + "options", + "readonly", + "share" + ], + "sectionRelativeRepoPath": "nfs_shares", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/nfs_shares.yml" + }, + { + "url": "/tables/npm_packages", + "title": "npm_packages", + "htmlId": "table--npmpackages--b2a26bbba0", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "npm_packages", + "author", + "description", + "directory", + "homepage", + "license", + "mount_namespace_id", + "name", + "path", + "pid_with_namespace", + "version" + ], + "sectionRelativeRepoPath": "npm_packages", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/npm_packages.yml" + }, + { + "url": "/tables/ntdomains", + "title": "ntdomains", + "htmlId": "table--ntdomains--57ef982364", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "ntdomains", + "client_site_name", + "dc_site_name", + "dns_forest_name", + "domain_controller_address", + "domain_controller_name", + "domain_name", + "name", + "status" + ], + "sectionRelativeRepoPath": "ntdomains", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/ntdomains.yml" + }, + { + "url": "/tables/ntfs_acl_permissions", + "title": "ntfs_acl_permissions", + "htmlId": "table--ntfsaclpermissions--2d66c6c45e", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "ntfs_acl_permissions", + "access", + "inherited_from", + "path", + "principal", + "type" + ], + "sectionRelativeRepoPath": "ntfs_acl_permissions", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fntfs_acl_permissions.yml&value=name%3A%20ntfs_acl_permissions%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/ntfs_journal_events", + "title": "ntfs_journal_events", + "htmlId": "table--ntfsjournalevents--2369d84275", + "evented": true, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "ntfs_journal_events", + "action", + "category", + "drive_letter", + "eid", + "file_attributes", + "node_ref_number", + "old_path", + "parent_ref_number", + "partial", + "path", + "record_timestamp", + "record_usn", + "time" + ], + "sectionRelativeRepoPath": "ntfs_journal_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fntfs_journal_events.yml&value=name%3A%20ntfs_journal_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/nvram", + "title": "nvram", + "htmlId": "table--nvram--450a99f968", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "nvram", + "name", + "type", + "value" + ], + "sectionRelativeRepoPath": "nvram", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/nvram.yml" + }, + { + "url": "/tables/nvram_info", + "title": "nvram_info", + "htmlId": "table--nvraminfo--a99cb280af", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "nvram_info", + "amfi_enabled" + ], + "sectionRelativeRepoPath": "nvram_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/nvram_info.yml" + }, + { + "url": "/tables/oem_strings", + "title": "oem_strings", + "htmlId": "table--oemstrings--89f170ddda", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "oem_strings", + "handle", + "number", + "value" + ], + "sectionRelativeRepoPath": "oem_strings", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Foem_strings.yml&value=name%3A%20oem_strings%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/office_mru", + "title": "office_mru", + "htmlId": "table--officemru--11e1929c70", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "office_mru", + "application", + "last_opened_time", + "path", + "sid", + "version" + ], + "sectionRelativeRepoPath": "office_mru", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Foffice_mru.yml&value=name%3A%20office_mru%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/orbit_info", + "title": "orbit_info", + "htmlId": "table--orbitinfo--98fca7c408", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "orbit_info", + "desktop_channel", + "desktop_version", + "device_auth_token", + "enrolled", + "last_recorded_error", + "orbit_channel", + "osqueryd_channel", + "scripts_enabled", + "uptime", + "version" + ], + "sectionRelativeRepoPath": "orbit_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/orbit_info.yml" + }, + { + "url": "/tables/os_version", + "title": "os_version", + "htmlId": "table--osversion--95451301c8", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows", + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "os_version", + "arch", + "build", + "codename", + "extra", + "install_date", + "major", + "minor", + "mount_namespace_id", + "name", + "patch", + "pid_with_namespace", + "platform", + "platform_like", + "revision", + "version" + ], + "sectionRelativeRepoPath": "os_version", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/os_version.yml" + }, + { + "url": "/tables/osquery_events", + "title": "osquery_events", + "htmlId": "table--osqueryevents--3bff81a1b8", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "osquery_events", + "active", + "events", + "name", + "publisher", + "refreshes", + "subscriptions", + "type" + ], + "sectionRelativeRepoPath": "osquery_events", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/osquery_events.yml" + }, + { + "url": "/tables/osquery_extensions", + "title": "osquery_extensions", + "htmlId": "table--osqueryextensions--56dea82216", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "osquery_extensions", + "name", + "path", + "sdk_version", + "type", + "uuid", + "version" + ], + "sectionRelativeRepoPath": "osquery_extensions", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/osquery_extensions.yml" + }, + { + "url": "/tables/osquery_flags", + "title": "osquery_flags", + "htmlId": "table--osqueryflags--27972ebab6", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "osquery_flags", + "default_value", + "description", + "name", + "shell_only", + "type", + "value" + ], + "sectionRelativeRepoPath": "osquery_flags", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/osquery_flags.yml" + }, + { + "url": "/tables/osquery_info", + "title": "osquery_info", + "htmlId": "table--osqueryinfo--99ebd3222b", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux", + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "osquery_info", + "build_distro", + "build_platform", + "config_hash", + "config_valid", + "extensions", + "instance_id", + "pid", + "platform_mask", + "start_time", + "uuid", + "version", + "watcher" + ], + "sectionRelativeRepoPath": "osquery_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/osquery_info.yml" + }, + { + "url": "/tables/osquery_packs", + "title": "osquery_packs", + "htmlId": "table--osquerypacks--c2f0293ed5", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "osquery_packs", + "active", + "discovery_cache_hits", + "discovery_executions", + "name", + "platform", + "shard", + "version" + ], + "sectionRelativeRepoPath": "osquery_packs", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/osquery_packs.yml" + }, + { + "url": "/tables/osquery_registry", + "title": "osquery_registry", + "htmlId": "table--osqueryregistry--723b93f998", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "osquery_registry", + "active", + "internal", + "name", + "owner_uuid", + "registry" + ], + "sectionRelativeRepoPath": "osquery_registry", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/osquery_registry.yml" + }, + { + "url": "/tables/osquery_schedule", + "title": "osquery_schedule", + "htmlId": "table--osqueryschedule--81eadaf536", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "osquery_schedule", + "average_memory", + "denylisted", + "executions", + "interval", + "last_executed", + "last_memory", + "last_system_time", + "last_user_time", + "last_wall_time_ms", + "name", + "output_size", + "query", + "system_time", + "user_time", + "wall_time", + "wall_time_ms" + ], + "sectionRelativeRepoPath": "osquery_schedule", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/osquery_schedule.yml" + }, + { + "url": "/tables/package_bom", + "title": "package_bom", + "htmlId": "table--packagebom--8182ed768f", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "package_bom", + "filepath", + "gid", + "mode", + "modified_time", + "path", + "size", + "uid" + ], + "sectionRelativeRepoPath": "package_bom", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/package_bom.yml" + }, + { + "url": "/tables/package_install_history", + "title": "package_install_history", + "htmlId": "table--packageinstallhistory--988f999553", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "package_install_history", + "content_type", + "name", + "package_id", + "source", + "time", + "version" + ], + "sectionRelativeRepoPath": "package_install_history", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/package_install_history.yml" + }, + { + "url": "/tables/package_receipts", + "title": "package_receipts", + "htmlId": "table--packagereceipts--4d830b5b2d", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "package_receipts", + "install_time", + "installer_name", + "location", + "package_filename", + "package_id", + "path", + "version" + ], + "sectionRelativeRepoPath": "package_receipts", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/package_receipts.yml" + }, + { + "url": "/tables/parse_ini", + "title": "parse_ini", + "htmlId": "table--parseini--4de2377a57", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "parse_ini", + "fullkey", + "key", + "parent", + "path", + "value" + ], + "sectionRelativeRepoPath": "parse_ini", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/parse_ini.yml" + }, + { + "url": "/tables/parse_json", + "title": "parse_json", + "htmlId": "table--parsejson--c3c9947479", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "parse_json", + "fullkey", + "key", + "parent", + "path", + "value" + ], + "sectionRelativeRepoPath": "parse_json", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/parse_json.yml" + }, + { + "url": "/tables/parse_jsonl", + "title": "parse_jsonl", + "htmlId": "table--parsejsonl--b71d789467", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "parse_jsonl", + "fullkey", + "key", + "parent", + "path", + "value" + ], + "sectionRelativeRepoPath": "parse_jsonl", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/parse_jsonl.yml" + }, + { + "url": "/tables/parse_xml", + "title": "parse_xml", + "htmlId": "table--parsexml--15ed589727", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "parse_xml", + "fullkey", + "key", + "parent", + "path", + "value" + ], + "sectionRelativeRepoPath": "parse_xml", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/parse_xml.yml" + }, + { + "url": "/tables/password_policy", + "title": "password_policy", + "htmlId": "table--passwordpolicy--9a2e1051b8", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "password_policy", + "policy_content", + "policy_description", + "policy_identifier", + "uid" + ], + "sectionRelativeRepoPath": "password_policy", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/password_policy.yml" + }, + { + "url": "/tables/patches", + "title": "patches", + "htmlId": "table--patches--b3f61813f5", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "patches", + "caption", + "csname", + "description", + "fix_comments", + "hotfix_id", + "install_date", + "installed_by", + "installed_on" + ], + "sectionRelativeRepoPath": "patches", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/patches.yml" + }, + { + "url": "/tables/pci_devices", + "title": "pci_devices", + "htmlId": "table--pcidevices--b00adf6d59", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "pci_devices", + "driver", + "model", + "model_id", + "pci_class", + "pci_class_id", + "pci_slot", + "pci_subclass", + "pci_subclass_id", + "subsystem_model", + "subsystem_model_id", + "subsystem_vendor", + "subsystem_vendor_id", + "vendor", + "vendor_id" + ], + "sectionRelativeRepoPath": "pci_devices", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/pci_devices.yml" + }, + { + "url": "/tables/physical_disk_performance", + "title": "physical_disk_performance", + "htmlId": "table--physicaldiskperformance--21ffb96328", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "physical_disk_performance", + "avg_disk_bytes_per_read", + "avg_disk_bytes_per_write", + "avg_disk_read_queue_length", + "avg_disk_sec_per_read", + "avg_disk_sec_per_write", + "avg_disk_write_queue_length", + "current_disk_queue_length", + "name", + "percent_disk_read_time", + "percent_disk_time", + "percent_disk_write_time", + "percent_idle_time" + ], + "sectionRelativeRepoPath": "physical_disk_performance", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fphysical_disk_performance.yml&value=name%3A%20physical_disk_performance%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/pipes", + "title": "pipes", + "htmlId": "table--pipes--6c348a0bda", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "pipes", + "flags", + "instances", + "max_instances", + "name", + "pid" + ], + "sectionRelativeRepoPath": "pipes", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/pipes.yml" + }, + { + "url": "/tables/platform_info", + "title": "platform_info", + "htmlId": "table--platforminfo--606b0b07f8", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "platform_info", + "address", + "date", + "extra", + "firmware_type", + "revision", + "size", + "vendor", + "version", + "volume_size" + ], + "sectionRelativeRepoPath": "platform_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/platform_info.yml" + }, + { + "url": "/tables/plist", + "title": "plist", + "htmlId": "table--plist--10bd270ccc", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "plist", + "key", + "path", + "subkey", + "value" + ], + "sectionRelativeRepoPath": "plist", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/plist.yml" + }, + { + "url": "/tables/pmset", + "title": "pmset", + "htmlId": "table--pmset--5f7c05dca3", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "pmset", + "getting", + "json_result" + ], + "sectionRelativeRepoPath": "pmset", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/pmset.yml" + }, + { + "url": "/tables/portage_keywords", + "title": "portage_keywords", + "htmlId": "table--portagekeywords--16048373f7", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "portage_keywords", + "keyword", + "mask", + "package", + "unmask", + "version" + ], + "sectionRelativeRepoPath": "portage_keywords", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fportage_keywords.yml&value=name%3A%20portage_keywords%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/portage_packages", + "title": "portage_packages", + "htmlId": "table--portagepackages--af336b6b49", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "portage_packages", + "build_time", + "eapi", + "package", + "repository", + "size", + "slot", + "version", + "world" + ], + "sectionRelativeRepoPath": "portage_packages", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fportage_packages.yml&value=name%3A%20portage_packages%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/portage_use", + "title": "portage_use", + "htmlId": "table--portageuse--61384aa618", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "portage_use", + "package", + "use", + "version" + ], + "sectionRelativeRepoPath": "portage_use", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fportage_use.yml&value=name%3A%20portage_use%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/power_sensors", + "title": "power_sensors", + "htmlId": "table--powersensors--27bd8387f6", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "power_sensors", + "category", + "key", + "name", + "value" + ], + "sectionRelativeRepoPath": "power_sensors", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/power_sensors.yml" + }, + { + "url": "/tables/powershell_events", + "title": "powershell_events", + "htmlId": "table--powershellevents--728605e870", + "evented": true, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "powershell_events", + "cosine_similarity", + "datetime", + "script_block_count", + "script_block_id", + "script_name", + "script_path", + "script_text", + "time" + ], + "sectionRelativeRepoPath": "powershell_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fpowershell_events.yml&value=name%3A%20powershell_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/preferences", + "title": "preferences", + "htmlId": "table--preferences--96fcf226b3", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "preferences", + "domain", + "forced", + "host", + "key", + "subkey", + "username", + "value" + ], + "sectionRelativeRepoPath": "preferences", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/preferences.yml" + }, + { + "url": "/tables/prefetch", + "title": "prefetch", + "htmlId": "table--prefetch--8592ee7112", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "prefetch", + "accessed_directories", + "accessed_directories_count", + "accessed_files", + "accessed_files_count", + "filename", + "hash", + "last_run_time", + "other_run_times", + "path", + "run_count", + "size", + "volume_creation", + "volume_serial" + ], + "sectionRelativeRepoPath": "prefetch", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fprefetch.yml&value=name%3A%20prefetch%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/privacy_preferences", + "title": "privacy_preferences", + "htmlId": "table--privacypreferences--927ea3e9b3", + "evented": false, + "platforms": [ + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "privacy_preferences", + "ad_measurement_enabled", + "autofill_address_enabled", + "autofill_credit_card_enabled", + "autofill_enabled", + "do_not_track_enabled", + "fledge_enabled", + "hyperlink_auditing_enabled", + "network_prediction_enabled", + "privacy_sandbox_enabled", + "protected_content_enabled", + "referrers_enabled", + "safe_browsing_enabled", + "safe_browsing_extended_reporting_enabled", + "save_passwords_enabled", + "search_suggest_enabled", + "spelling_service_enabled", + "third_party_cookies_allowed", + "topics_enabled", + "translation_service_enabled", + "web_rtc_ip_handling_policy" + ], + "sectionRelativeRepoPath": "privacy_preferences", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/privacy_preferences.yml" + }, + { + "url": "/tables/process_envs", + "title": "process_envs", + "htmlId": "table--processenvs--586b20fc53", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "process_envs", + "key", + "pid", + "value" + ], + "sectionRelativeRepoPath": "process_envs", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/process_envs.yml" + }, + { + "url": "/tables/process_etw_events", + "title": "process_etw_events", + "htmlId": "table--processetwevents--61143eacfc", + "evented": true, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "process_etw_events", + "cmdline", + "datetime", + "eid", + "exit_code", + "flags", + "header_pid", + "mandatory_label", + "parent_process_sequence_number", + "path", + "pid", + "ppid", + "process_sequence_number", + "session_id", + "time", + "time_windows", + "token_elevation_status", + "token_elevation_type", + "type", + "username" + ], + "sectionRelativeRepoPath": "process_etw_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fprocess_etw_events.yml&value=name%3A%20process_etw_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/process_events", + "title": "process_events", + "htmlId": "table--processevents--6ae8ba2267", + "evented": true, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "process_events", + "atime", + "auid", + "btime", + "cmdline", + "cmdline_size", + "ctime", + "cwd", + "egid", + "eid", + "env", + "env_count", + "env_size", + "euid", + "fsgid", + "fsuid", + "gid", + "mode", + "mtime", + "overflows", + "owner_gid", + "owner_uid", + "parent", + "path", + "pid", + "sgid", + "status", + "suid", + "syscall", + "time", + "uid", + "uptime" + ], + "sectionRelativeRepoPath": "process_events", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/process_events.yml" + }, + { + "url": "/tables/process_file_events", + "title": "process_file_events", + "htmlId": "table--processfileevents--67c363ae55", + "evented": true, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "process_file_events", + "auid", + "cwd", + "dest_path", + "egid", + "eid", + "euid", + "executable", + "fsgid", + "fsuid", + "gid", + "operation", + "partial", + "path", + "pid", + "ppid", + "sgid", + "suid", + "time", + "uid", + "uptime" + ], + "sectionRelativeRepoPath": "process_file_events", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/process_file_events.yml" + }, + { + "url": "/tables/process_memory_map", + "title": "process_memory_map", + "htmlId": "table--processmemorymap--6bf8d10644", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "process_memory_map", + "device", + "end", + "inode", + "offset", + "path", + "permissions", + "pid", + "pseudo", + "start" + ], + "sectionRelativeRepoPath": "process_memory_map", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/process_memory_map.yml" + }, + { + "url": "/tables/process_namespaces", + "title": "process_namespaces", + "htmlId": "table--processnamespaces--d1156621d4", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "process_namespaces", + "cgroup_namespace", + "ipc_namespace", + "mnt_namespace", + "net_namespace", + "pid", + "pid_namespace", + "user_namespace", + "uts_namespace" + ], + "sectionRelativeRepoPath": "process_namespaces", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fprocess_namespaces.yml&value=name%3A%20process_namespaces%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/process_open_files", + "title": "process_open_files", + "htmlId": "table--processopenfiles--43c8c6bba0", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "process_open_files", + "fd", + "path", + "pid" + ], + "sectionRelativeRepoPath": "process_open_files", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/process_open_files.yml" + }, + { + "url": "/tables/process_open_pipes", + "title": "process_open_pipes", + "htmlId": "table--processopenpipes--0f49c83994", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "process_open_pipes", + "fd", + "inode", + "mode", + "partner_fd", + "partner_mode", + "partner_pid", + "pid", + "type" + ], + "sectionRelativeRepoPath": "process_open_pipes", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fprocess_open_pipes.yml&value=name%3A%20process_open_pipes%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/process_open_sockets", + "title": "process_open_sockets", + "htmlId": "table--processopensockets--9dc2c99a67", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "process_open_sockets", + "family", + "fd", + "local_address", + "local_port", + "net_namespace", + "path", + "pid", + "protocol", + "remote_address", + "remote_port", + "socket", + "state" + ], + "sectionRelativeRepoPath": "process_open_sockets", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/process_open_sockets.yml" + }, + { + "url": "/tables/processes", + "title": "processes", + "htmlId": "table--processes--3a54ed4992", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "processes", + "cgroup_path", + "cmdline", + "cpu_subtype", + "cpu_type", + "cwd", + "disk_bytes_read", + "disk_bytes_written", + "egid", + "elapsed_time", + "elevated_token", + "euid", + "gid", + "handle_count", + "name", + "nice", + "on_disk", + "parent", + "path", + "percent_processor_time", + "pgroup", + "pid", + "protection_type", + "resident_size", + "root", + "secure_process", + "sgid", + "start_time", + "state", + "suid", + "system_time", + "threads", + "total_size", + "translated", + "uid", + "upid", + "uppid", + "user_time", + "virtual_process", + "wired_size" + ], + "sectionRelativeRepoPath": "processes", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/processes.yml" + }, + { + "url": "/tables/programs", + "title": "programs", + "htmlId": "table--programs--f7f76d14a9", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "programs", + "identifying_number", + "install_date", + "install_location", + "install_source", + "language", + "name", + "publisher", + "uninstall_string", + "version" + ], + "sectionRelativeRepoPath": "programs", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/programs.yml" + }, + { + "url": "/tables/prometheus_metrics", + "title": "prometheus_metrics", + "htmlId": "table--prometheusmetrics--f6ce409d91", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "prometheus_metrics", + "metric_name", + "metric_value", + "target_name", + "timestamp_ms" + ], + "sectionRelativeRepoPath": "prometheus_metrics", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fprometheus_metrics.yml&value=name%3A%20prometheus_metrics%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/puppet_info", + "title": "puppet_info", + "htmlId": "table--puppetinfo--ce553a89eb", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "puppet_info", + "cached_catalog_status", + "catalog_uuid", + "code_id", + "configuration_version", + "corrective_change", + "environment", + "host", + "kind", + "master_used", + "noop", + "noop_pending", + "puppet_version", + "report_format", + "status", + "time", + "transaction_completed", + "transaction_uuid" + ], + "sectionRelativeRepoPath": "puppet_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/puppet_info.yml" + }, + { + "url": "/tables/puppet_logs", + "title": "puppet_logs", + "htmlId": "table--puppetlogs--c81bf10f91", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "puppet_logs", + "file", + "level", + "line", + "message", + "source", + "time" + ], + "sectionRelativeRepoPath": "puppet_logs", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/puppet_logs.yml" + }, + { + "url": "/tables/puppet_state", + "title": "puppet_state", + "htmlId": "table--puppetstate--802f52e922", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "puppet_state", + "change_count", + "changed", + "corrective_change", + "evaluation_time", + "failed", + "file", + "line", + "out_of_sync", + "out_of_sync_count", + "resource", + "resource_type", + "skipped", + "title" + ], + "sectionRelativeRepoPath": "puppet_state", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/puppet_state.yml" + }, + { + "url": "/tables/pwd_policy", + "title": "pwd_policy", + "htmlId": "table--pwdpolicy--b862a98afa", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "pwd_policy", + "days_to_expiration", + "expires_every_n_days", + "history_depth", + "max_failed_attempts", + "min_mixed_case_characters" + ], + "sectionRelativeRepoPath": "pwd_policy", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/pwd_policy.yml" + }, + { + "url": "/tables/python_packages", + "title": "python_packages", + "htmlId": "table--pythonpackages--31ae8c2370", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "python_packages", + "author", + "directory", + "license", + "name", + "path", + "pid_with_namespace", + "summary", + "version" + ], + "sectionRelativeRepoPath": "python_packages", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/python_packages.yml" + }, + { + "url": "/tables/quicklook_cache", + "title": "quicklook_cache", + "htmlId": "table--quicklookcache--19ae561620", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "quicklook_cache", + "cache_path", + "fs_id", + "hit_count", + "icon_mode", + "inode", + "label", + "last_hit_date", + "mtime", + "path", + "rowid", + "size", + "volume_id" + ], + "sectionRelativeRepoPath": "quicklook_cache", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fquicklook_cache.yml&value=name%3A%20quicklook_cache%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/registry", + "title": "registry", + "htmlId": "table--registry--415b2b1c89", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "registry", + "data", + "key", + "mtime", + "name", + "path", + "type" + ], + "sectionRelativeRepoPath": "registry", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/registry.yml" + }, + { + "url": "/tables/routes", + "title": "routes", + "htmlId": "table--routes--ed00beba43", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "routes", + "destination", + "flags", + "gateway", + "hopcount", + "interface", + "metric", + "mtu", + "netmask", + "source", + "type" + ], + "sectionRelativeRepoPath": "routes", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/routes.yml" + }, + { + "url": "/tables/rpm_package_files", + "title": "rpm_package_files", + "htmlId": "table--rpmpackagefiles--96e530c921", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "rpm_package_files", + "groupname", + "mode", + "package", + "path", + "sha256", + "size", + "username" + ], + "sectionRelativeRepoPath": "rpm_package_files", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Frpm_package_files.yml&value=name%3A%20rpm_package_files%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/rpm_packages", + "title": "rpm_packages", + "htmlId": "table--rpmpackages--e4da8f9f41", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "rpm_packages", + "arch", + "epoch", + "install_time", + "mount_namespace_id", + "name", + "package_group", + "pid_with_namespace", + "release", + "sha1", + "size", + "source", + "vendor", + "version" + ], + "sectionRelativeRepoPath": "rpm_packages", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/rpm_packages.yml" + }, + { + "url": "/tables/running_apps", + "title": "running_apps", + "htmlId": "table--runningapps--c9443711d8", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "running_apps", + "bundle_identifier", + "is_active", + "pid" + ], + "sectionRelativeRepoPath": "running_apps", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/running_apps.yml" + }, + { + "url": "/tables/safari_extensions", + "title": "safari_extensions", + "htmlId": "table--safariextensions--75748b2d43", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "safari_extensions", + "author", + "bundle_version", + "copyright", + "description", + "developer_id", + "extension_type", + "identifier", + "name", + "path", + "sdk", + "uid", + "update_url", + "version" + ], + "sectionRelativeRepoPath": "safari_extensions", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/safari_extensions.yml" + }, + { + "url": "/tables/sandboxes", + "title": "sandboxes", + "htmlId": "table--sandboxes--c68d00ef55", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "sandboxes", + "build_id", + "bundle_path", + "enabled", + "label", + "path", + "user" + ], + "sectionRelativeRepoPath": "sandboxes", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fsandboxes.yml&value=name%3A%20sandboxes%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/scheduled_tasks", + "title": "scheduled_tasks", + "htmlId": "table--scheduledtasks--a69b6b604d", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "scheduled_tasks", + "action", + "enabled", + "hidden", + "last_run_code", + "last_run_message", + "last_run_time", + "name", + "next_run_time", + "path", + "state" + ], + "sectionRelativeRepoPath": "scheduled_tasks", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/scheduled_tasks.yml" + }, + { + "url": "/tables/screenlock", + "title": "screenlock", + "htmlId": "table--screenlock--91a400ed71", + "evented": false, + "platforms": [ + "darwin", + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "screenlock", + "enabled", + "grace_period" + ], + "sectionRelativeRepoPath": "screenlock", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/screenlock.yml" + }, + { + "url": "/tables/seccomp_events", + "title": "seccomp_events", + "htmlId": "table--seccompevents--5cf6060bd9", + "evented": true, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "seccomp_events", + "arch", + "auid", + "code", + "comm", + "compat", + "exe", + "gid", + "ip", + "pid", + "ses", + "sig", + "syscall", + "time", + "uid", + "uptime" + ], + "sectionRelativeRepoPath": "seccomp_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fseccomp_events.yml&value=name%3A%20seccomp_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/secureboot", + "title": "secureboot", + "htmlId": "table--secureboot--299ca9c718", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "secureboot", + "description", + "kernel_extensions", + "mdm_operations", + "secure_boot", + "secure_mode", + "setup_mode" + ], + "sectionRelativeRepoPath": "secureboot", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/secureboot.yml" + }, + { + "url": "/tables/security_profile_info", + "title": "security_profile_info", + "htmlId": "table--securityprofileinfo--17121d5fa6", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "security_profile_info", + "audit_account_logon", + "audit_account_manage", + "audit_ds_access", + "audit_logon_events", + "audit_object_access", + "audit_policy_change", + "audit_privilege_use", + "audit_process_tracking", + "audit_system_events", + "clear_text_password", + "enable_admin_account", + "enable_guest_account", + "force_logoff_when_expire", + "lockout_bad_count", + "logon_to_change_password", + "lsa_anonymous_name_lookup", + "maximum_password_age", + "minimum_password_age", + "minimum_password_length", + "new_administrator_name", + "new_guest_name", + "password_complexity", + "password_history_size" + ], + "sectionRelativeRepoPath": "security_profile_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fsecurity_profile_info.yml&value=name%3A%20security_profile_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/selinux_events", + "title": "selinux_events", + "htmlId": "table--selinuxevents--cfc47c5cc9", + "evented": true, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "selinux_events", + "eid", + "message", + "time", + "type", + "uptime" + ], + "sectionRelativeRepoPath": "selinux_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fselinux_events.yml&value=name%3A%20selinux_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/selinux_settings", + "title": "selinux_settings", + "htmlId": "table--selinuxsettings--392476076c", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "selinux_settings", + "key", + "scope", + "value" + ], + "sectionRelativeRepoPath": "selinux_settings", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fselinux_settings.yml&value=name%3A%20selinux_settings%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/services", + "title": "services", + "htmlId": "table--services--a7e374154f", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "services", + "description", + "display_name", + "module_path", + "name", + "path", + "pid", + "service_exit_code", + "service_type", + "start_type", + "status", + "user_account", + "win32_exit_code" + ], + "sectionRelativeRepoPath": "services", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fservices.yml&value=name%3A%20services%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/shadow", + "title": "shadow", + "htmlId": "table--shadow--2a5e749131", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "shadow", + "expire", + "flag", + "hash_alg", + "inactive", + "last_change", + "max", + "min", + "password_status", + "username", + "warning" + ], + "sectionRelativeRepoPath": "shadow", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fshadow.yml&value=name%3A%20shadow%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/shared_folders", + "title": "shared_folders", + "htmlId": "table--sharedfolders--edd6c29f21", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "shared_folders", + "name", + "path" + ], + "sectionRelativeRepoPath": "shared_folders", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/shared_folders.yml" + }, + { + "url": "/tables/shared_memory", + "title": "shared_memory", + "htmlId": "table--sharedmemory--4632a169c9", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "shared_memory", + "atime", + "attached", + "creator_pid", + "creator_uid", + "ctime", + "dtime", + "locked", + "owner_uid", + "permissions", + "pid", + "shmid", + "size", + "status" + ], + "sectionRelativeRepoPath": "shared_memory", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fshared_memory.yml&value=name%3A%20shared_memory%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/shared_resources", + "title": "shared_resources", + "htmlId": "table--sharedresources--1eedd340fb", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "shared_resources", + "allow_maximum", + "description", + "install_date", + "maximum_allowed", + "name", + "path", + "status", + "type", + "type_name" + ], + "sectionRelativeRepoPath": "shared_resources", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/shared_resources.yml" + }, + { + "url": "/tables/sharing_preferences", + "title": "sharing_preferences", + "htmlId": "table--sharingpreferences--435a39048e", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "sharing_preferences", + "bluetooth_sharing", + "content_caching", + "disc_sharing", + "file_sharing", + "internet_sharing", + "printer_sharing", + "remote_apple_events", + "remote_login", + "remote_management", + "screen_sharing" + ], + "sectionRelativeRepoPath": "sharing_preferences", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/sharing_preferences.yml" + }, + { + "url": "/tables/shell_history", + "title": "shell_history", + "htmlId": "table--shellhistory--487890df4c", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "shell_history", + "command", + "history_file", + "time", + "uid" + ], + "sectionRelativeRepoPath": "shell_history", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/shell_history.yml" + }, + { + "url": "/tables/shellbags", + "title": "shellbags", + "htmlId": "table--shellbags--ea58c94fcb", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "shellbags", + "accessed_time", + "created_time", + "mft_entry", + "mft_sequence", + "modified_time", + "path", + "sid", + "source" + ], + "sectionRelativeRepoPath": "shellbags", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fshellbags.yml&value=name%3A%20shellbags%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/shimcache", + "title": "shimcache", + "htmlId": "table--shimcache--78c1808f2a", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "shimcache", + "entry", + "execution_flag", + "modified_time", + "path" + ], + "sectionRelativeRepoPath": "shimcache", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/shimcache.yml" + }, + { + "url": "/tables/signature", + "title": "signature", + "htmlId": "table--signature--651b5e1a16", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "signature", + "arch", + "authority", + "cdhash", + "hash_resources", + "identifier", + "path", + "signed", + "team_identifier" + ], + "sectionRelativeRepoPath": "signature", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/signature.yml" + }, + { + "url": "/tables/sip_config", + "title": "sip_config", + "htmlId": "table--sipconfig--72a4d07300", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "sip_config", + "config_flag", + "enabled", + "enabled_nvram" + ], + "sectionRelativeRepoPath": "sip_config", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/sip_config.yml" + }, + { + "url": "/tables/smbios_tables", + "title": "smbios_tables", + "htmlId": "table--smbiostables--14a3086ac5", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "smbios_tables", + "description", + "handle", + "header_size", + "md5", + "number", + "size", + "type" + ], + "sectionRelativeRepoPath": "smbios_tables", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/smbios_tables.yml" + }, + { + "url": "/tables/smc_keys", + "title": "smc_keys", + "htmlId": "table--smckeys--65a180be47", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "smc_keys", + "hidden", + "key", + "size", + "type", + "value" + ], + "sectionRelativeRepoPath": "smc_keys", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/smc_keys.yml" + }, + { + "url": "/tables/sntp_request", + "title": "sntp_request", + "htmlId": "table--sntprequest--31b3965f95", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "sntp_request", + "clock_offset_ms", + "server", + "timestamp_ms" + ], + "sectionRelativeRepoPath": "sntp_request", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/sntp_request.yml" + }, + { + "url": "/tables/socket_events", + "title": "socket_events", + "htmlId": "table--socketevents--45972f7f3b", + "evented": true, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "socket_events", + "action", + "auid", + "eid", + "family", + "fd", + "local_address", + "local_port", + "path", + "pid", + "protocol", + "remote_address", + "remote_port", + "socket", + "status", + "success", + "time", + "uptime" + ], + "sectionRelativeRepoPath": "socket_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fsocket_events.yml&value=name%3A%20socket_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/sofa_security_release_info", + "title": "sofa_security_release_info", + "htmlId": "table--sofasecurityreleaseinfo--b23bdf9329", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "sofa_security_release_info", + "days_since_previous_release", + "os_version", + "product_version", + "release_date", + "security_info", + "unique_cves_count", + "update_name" + ], + "sectionRelativeRepoPath": "sofa_security_release_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/sofa_security_release_info.yml" + }, + { + "url": "/tables/sofa_unpatched_cves", + "title": "sofa_unpatched_cves", + "htmlId": "table--sofaunpatchedcves--680ab849b7", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "sofa_unpatched_cves", + "actively_exploited", + "cve", + "os_version", + "patched_version" + ], + "sectionRelativeRepoPath": "sofa_unpatched_cves", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/sofa_unpatched_cves.yml" + }, + { + "url": "/tables/software_update", + "title": "software_update", + "htmlId": "table--softwareupdate--6cb5e63ee6", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "software_update", + "software_update_required" + ], + "sectionRelativeRepoPath": "software_update", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/software_update.yml" + }, + { + "url": "/tables/ssh_configs", + "title": "ssh_configs", + "htmlId": "table--sshconfigs--084b9832a4", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "ssh_configs", + "block", + "option", + "ssh_config_file", + "uid" + ], + "sectionRelativeRepoPath": "ssh_configs", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/ssh_configs.yml" + }, + { + "url": "/tables/startup_items", + "title": "startup_items", + "htmlId": "table--startupitems--f212a6ad4e", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "startup_items", + "args", + "name", + "path", + "source", + "status", + "type", + "username" + ], + "sectionRelativeRepoPath": "startup_items", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/startup_items.yml" + }, + { + "url": "/tables/sudo_info", + "title": "sudo_info", + "htmlId": "table--sudoinfo--91f0750d0d", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "sudo_info", + "json_result" + ], + "sectionRelativeRepoPath": "sudo_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/sudo_info.yml" + }, + { + "url": "/tables/sudoers", + "title": "sudoers", + "htmlId": "table--sudoers--53cbb8caa7", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "sudoers", + "header", + "rule_details", + "source" + ], + "sectionRelativeRepoPath": "sudoers", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/sudoers.yml" + }, + { + "url": "/tables/suid_bin", + "title": "suid_bin", + "htmlId": "table--suidbin--12efbe4810", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "suid_bin", + "groupname", + "path", + "permissions", + "pid_with_namespace", + "username" + ], + "sectionRelativeRepoPath": "suid_bin", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/suid_bin.yml" + }, + { + "url": "/tables/syslog_events", + "title": "syslog_events", + "htmlId": "table--syslogevents--cc5c3d702f", + "evented": true, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "syslog_events", + "datetime", + "eid", + "facility", + "host", + "message", + "severity", + "tag", + "time" + ], + "sectionRelativeRepoPath": "syslog_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fsyslog_events.yml&value=name%3A%20syslog_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/system_controls", + "title": "system_controls", + "htmlId": "table--systemcontrols--bc070f5bb2", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "system_controls", + "config_value", + "current_value", + "field_name", + "name", + "oid", + "subsystem", + "type" + ], + "sectionRelativeRepoPath": "system_controls", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/system_controls.yml" + }, + { + "url": "/tables/system_extensions", + "title": "system_extensions", + "htmlId": "table--systemextensions--59019bbb28", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "system_extensions", + "UUID", + "bundle_path", + "category", + "identifier", + "mdm_managed", + "path", + "state", + "team", + "version" + ], + "sectionRelativeRepoPath": "system_extensions", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/system_extensions.yml" + }, + { + "url": "/tables/system_info", + "title": "system_info", + "htmlId": "table--systeminfo--4f963da54a", + "evented": false, + "platforms": [ + "windows", + "darwin", + "linux", + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "system_info", + "board_model", + "board_serial", + "board_vendor", + "board_version", + "computer_name", + "cpu_brand", + "cpu_logical_cores", + "cpu_microcode", + "cpu_physical_cores", + "cpu_sockets", + "cpu_subtype", + "cpu_type", + "hardware_model", + "hardware_serial", + "hardware_vendor", + "hardware_version", + "hostname", + "local_hostname", + "physical_memory", + "uuid" + ], + "sectionRelativeRepoPath": "system_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/system_info.yml" + }, + { + "url": "/tables/system_state", + "title": "system_state", + "htmlId": "table--systemstate--d1ce3bbb0e", + "evented": false, + "platforms": [ + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "system_state", + "idle_state" + ], + "sectionRelativeRepoPath": "system_state", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/system_state.yml" + }, + { + "url": "/tables/systemd_units", + "title": "systemd_units", + "htmlId": "table--systemdunits--cc47585fcb", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "systemd_units", + "active_state", + "description", + "following", + "fragment_path", + "id", + "job_id", + "job_path", + "job_type", + "load_state", + "object_path", + "source_path", + "sub_state", + "unit_file_state", + "user" + ], + "sectionRelativeRepoPath": "systemd_units", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fsystemd_units.yml&value=name%3A%20systemd_units%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/tcc_access", + "title": "tcc_access", + "htmlId": "table--tccaccess--103e029af3", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "tcc_access", + "auth_reason", + "auth_value", + "client", + "client_type", + "indirect_object_identifier", + "indirect_object_identifier_type", + "last_modified", + "policy_id", + "service", + "source", + "uid" + ], + "sectionRelativeRepoPath": "tcc_access", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/tcc_access.yml" + }, + { + "url": "/tables/temperature_sensors", + "title": "temperature_sensors", + "htmlId": "table--temperaturesensors--952195065c", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "temperature_sensors", + "celsius", + "fahrenheit", + "key", + "name" + ], + "sectionRelativeRepoPath": "temperature_sensors", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/temperature_sensors.yml" + }, + { + "url": "/tables/time", + "title": "time", + "htmlId": "table--time--740a172c2f", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "time", + "datetime", + "day", + "hour", + "iso_8601", + "local_timezone", + "minutes", + "month", + "seconds", + "timestamp", + "timezone", + "unix_time", + "weekday", + "win_timestamp", + "year" + ], + "sectionRelativeRepoPath": "time", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/time.yml" + }, + { + "url": "/tables/time_machine_backups", + "title": "time_machine_backups", + "htmlId": "table--timemachinebackups--6a1cb2e696", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "time_machine_backups", + "backup_date", + "destination_id" + ], + "sectionRelativeRepoPath": "time_machine_backups", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/time_machine_backups.yml" + }, + { + "url": "/tables/time_machine_destinations", + "title": "time_machine_destinations", + "htmlId": "table--timemachinedestinations--8c33b4e082", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "time_machine_destinations", + "alias", + "bytes_available", + "bytes_used", + "consistency_scan_date", + "destination_id", + "encryption", + "root_volume_uuid" + ], + "sectionRelativeRepoPath": "time_machine_destinations", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/time_machine_destinations.yml" + }, + { + "url": "/tables/tpm_info", + "title": "tpm_info", + "htmlId": "table--tpminfo--086cc37696", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "tpm_info", + "activated", + "enabled", + "manufacturer_id", + "manufacturer_name", + "manufacturer_version", + "owned", + "physical_presence_version", + "product_name", + "spec_version" + ], + "sectionRelativeRepoPath": "tpm_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Ftpm_info.yml&value=name%3A%20tpm_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/ulimit_info", + "title": "ulimit_info", + "htmlId": "table--ulimitinfo--9cff90dafb", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "ulimit_info", + "hard_limit", + "soft_limit", + "type" + ], + "sectionRelativeRepoPath": "ulimit_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/ulimit_info.yml" + }, + { + "url": "/tables/unified_log", + "title": "unified_log", + "htmlId": "table--unifiedlog--d971aaf7c9", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "unified_log", + "activity", + "category", + "level", + "max_rows", + "message", + "pid", + "predicate", + "process", + "sender", + "storage", + "subsystem", + "tid", + "timestamp" + ], + "sectionRelativeRepoPath": "unified_log", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Funified_log.yml&value=name%3A%20unified_log%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/uptime", + "title": "uptime", + "htmlId": "table--uptime--542f2cc52b", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "uptime", + "days", + "hours", + "minutes", + "seconds", + "total_seconds" + ], + "sectionRelativeRepoPath": "uptime", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/uptime.yml" + }, + { + "url": "/tables/usb_devices", + "title": "usb_devices", + "htmlId": "table--usbdevices--12892f9cf7", + "evented": false, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "usb_devices", + "class", + "model", + "model_id", + "protocol", + "removable", + "serial", + "subclass", + "usb_address", + "usb_port", + "vendor", + "vendor_id", + "version" + ], + "sectionRelativeRepoPath": "usb_devices", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/usb_devices.yml" + }, + { + "url": "/tables/user_events", + "title": "user_events", + "htmlId": "table--userevents--8aaee70de1", + "evented": true, + "platforms": [ + "darwin", + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "user_events", + "address", + "auid", + "eid", + "message", + "path", + "pid", + "terminal", + "time", + "type", + "uid", + "uptime" + ], + "sectionRelativeRepoPath": "user_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fuser_events.yml&value=name%3A%20user_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/user_groups", + "title": "user_groups", + "htmlId": "table--usergroups--03e0b1a5e7", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "user_groups", + "gid", + "uid" + ], + "sectionRelativeRepoPath": "user_groups", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fuser_groups.yml&value=name%3A%20user_groups%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/user_interaction_events", + "title": "user_interaction_events", + "htmlId": "table--userinteractionevents--ed2ac5b181", + "evented": true, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "user_interaction_events", + "time" + ], + "sectionRelativeRepoPath": "user_interaction_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fuser_interaction_events.yml&value=name%3A%20user_interaction_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/user_login_settings", + "title": "user_login_settings", + "htmlId": "table--userloginsettings--1abbdf6e57", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "user_login_settings", + "password_hint_enabled" + ], + "sectionRelativeRepoPath": "user_login_settings", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/user_login_settings.yml" + }, + { + "url": "/tables/user_ssh_keys", + "title": "user_ssh_keys", + "htmlId": "table--usersshkeys--1ba0f20456", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "user_ssh_keys", + "encrypted", + "key_type", + "path", + "pid_with_namespace", + "uid" + ], + "sectionRelativeRepoPath": "user_ssh_keys", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/user_ssh_keys.yml" + }, + { + "url": "/tables/userassist", + "title": "userassist", + "htmlId": "table--userassist--4e3bbdb293", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "userassist", + "count", + "last_execution_time", + "path", + "sid" + ], + "sectionRelativeRepoPath": "userassist", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/userassist.yml" + }, + { + "url": "/tables/users", + "title": "users", + "htmlId": "table--users--023e2862dc", + "evented": false, + "platforms": [ + "darwin", + "windows", + "linux", + "chrome" + ], + "keywordsForSyntaxHighlighting": [ + "users", + "description", + "directory", + "email", + "gid", + "gid_signed", + "is_hidden", + "pid_with_namespace", + "shell", + "type", + "uid", + "uid_signed", + "username", + "uuid" + ], + "sectionRelativeRepoPath": "users", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/users.yml" + }, + { + "url": "/tables/video_info", + "title": "video_info", + "htmlId": "table--videoinfo--bcca78a3df", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "video_info", + "color_depth", + "driver", + "driver_date", + "driver_version", + "manufacturer", + "model", + "series", + "video_mode" + ], + "sectionRelativeRepoPath": "video_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fvideo_info.yml&value=name%3A%20video_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/virtual_memory_info", + "title": "virtual_memory_info", + "htmlId": "table--virtualmemoryinfo--4c4e71449e", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "virtual_memory_info", + "active", + "anonymous", + "compressed", + "compressor", + "copy", + "decompressed", + "faults", + "file_backed", + "free", + "inactive", + "page_ins", + "page_outs", + "purgeable", + "purged", + "reactivated", + "speculative", + "swap_ins", + "swap_outs", + "throttled", + "uncompressed", + "wired", + "zero_fill" + ], + "sectionRelativeRepoPath": "virtual_memory_info", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/virtual_memory_info.yml" + }, + { + "url": "/tables/vscode_extensions", + "title": "vscode_extensions", + "htmlId": "table--vscodeextensions--3122f67e21", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "vscode_extensions", + "installed_at", + "name", + "path", + "prerelease", + "publisher", + "publisher_id", + "uid", + "uuid", + "version" + ], + "sectionRelativeRepoPath": "vscode_extensions", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/vscode_extensions.yml" + }, + { + "url": "/tables/wifi_networks", + "title": "wifi_networks", + "htmlId": "table--wifinetworks--196d0fe380", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "wifi_networks", + "add_reason", + "added_at", + "auto_join", + "auto_login", + "captive_login_date", + "captive_portal", + "disabled", + "last_connected", + "network_name", + "passpoint", + "personal_hotspot", + "possibly_hidden", + "roaming", + "roaming_profile", + "security_type", + "ssid", + "temporarily_disabled", + "was_captive_network" + ], + "sectionRelativeRepoPath": "wifi_networks", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/wifi_networks.yml" + }, + { + "url": "/tables/wifi_status", + "title": "wifi_status", + "htmlId": "table--wifistatus--7d5af734ae", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "wifi_status", + "bssid", + "channel", + "channel_band", + "channel_width", + "country_code", + "interface", + "mode", + "network_name", + "noise", + "rssi", + "security_type", + "ssid", + "transmit_rate" + ], + "sectionRelativeRepoPath": "wifi_status", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/wifi_status.yml" + }, + { + "url": "/tables/wifi_survey", + "title": "wifi_survey", + "htmlId": "table--wifisurvey--86f4a22532", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "wifi_survey", + "bssid", + "channel", + "channel_band", + "channel_width", + "country_code", + "interface", + "network_name", + "noise", + "rssi", + "ssid" + ], + "sectionRelativeRepoPath": "wifi_survey", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/wifi_survey.yml" + }, + { + "url": "/tables/winbaseobj", + "title": "winbaseobj", + "htmlId": "table--winbaseobj--0e0dd909ed", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "winbaseobj", + "object_name", + "object_type", + "session_id" + ], + "sectionRelativeRepoPath": "winbaseobj", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwinbaseobj.yml&value=name%3A%20winbaseobj%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/windows_crashes", + "title": "windows_crashes", + "htmlId": "table--windowscrashes--3bcda23e6b", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_crashes", + "build_number", + "command_line", + "crash_path", + "current_directory", + "datetime", + "exception_address", + "exception_code", + "exception_message", + "machine_name", + "major_version", + "minor_version", + "module", + "path", + "pid", + "process_uptime", + "registers", + "stack_trace", + "tid", + "type", + "username", + "version" + ], + "sectionRelativeRepoPath": "windows_crashes", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwindows_crashes.yml&value=name%3A%20windows_crashes%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/windows_eventlog", + "title": "windows_eventlog", + "htmlId": "table--windowseventlog--c368bc9838", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_eventlog", + "channel", + "computer_name", + "data", + "datetime", + "eventid", + "keywords", + "level", + "pid", + "provider_guid", + "provider_name", + "task", + "tid", + "time_range", + "timestamp", + "xpath" + ], + "sectionRelativeRepoPath": "windows_eventlog", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/windows_eventlog.yml" + }, + { + "url": "/tables/windows_events", + "title": "windows_events", + "htmlId": "table--windowsevents--b4aae30966", + "evented": true, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_events", + "computer_name", + "data", + "datetime", + "eid", + "eventid", + "keywords", + "level", + "provider_guid", + "provider_name", + "source", + "task", + "time" + ], + "sectionRelativeRepoPath": "windows_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwindows_events.yml&value=name%3A%20windows_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/windows_firewall_rules", + "title": "windows_firewall_rules", + "htmlId": "table--windowsfirewallrules--54886746d8", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_firewall_rules", + "action", + "app_name", + "direction", + "enabled", + "grouping", + "icmp_types_codes", + "local_addresses", + "local_ports", + "name", + "profile_domain", + "profile_private", + "profile_public", + "protocol", + "remote_addresses", + "remote_ports", + "service_name" + ], + "sectionRelativeRepoPath": "windows_firewall_rules", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/windows_firewall_rules.yml" + }, + { + "url": "/tables/windows_optional_features", + "title": "windows_optional_features", + "htmlId": "table--windowsoptionalfeatures--7fc389462f", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_optional_features", + "caption", + "name", + "state", + "statename" + ], + "sectionRelativeRepoPath": "windows_optional_features", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/windows_optional_features.yml" + }, + { + "url": "/tables/windows_search", + "title": "windows_search", + "htmlId": "table--windowssearch--3bc557a530", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_search", + "additional_properties", + "date_created", + "date_modified", + "max_results", + "name", + "owner", + "path", + "properties", + "query", + "size", + "sort", + "type" + ], + "sectionRelativeRepoPath": "windows_search", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwindows_search.yml&value=name%3A%20windows_search%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/windows_security_center", + "title": "windows_security_center", + "htmlId": "table--windowssecuritycenter--8c6fbc78cd", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_security_center", + "antispyware", + "antivirus", + "autoupdate", + "firewall", + "internet_settings", + "user_account_control", + "windows_security_center_service" + ], + "sectionRelativeRepoPath": "windows_security_center", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwindows_security_center.yml&value=name%3A%20windows_security_center%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/windows_security_products", + "title": "windows_security_products", + "htmlId": "table--windowssecurityproducts--f74ebb0ecc", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_security_products", + "name", + "remediation_path", + "signatures_up_to_date", + "state", + "state_timestamp", + "type" + ], + "sectionRelativeRepoPath": "windows_security_products", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwindows_security_products.yml&value=name%3A%20windows_security_products%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/windows_update_history", + "title": "windows_update_history", + "htmlId": "table--windowsupdatehistory--ef7bb6c2c1", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_update_history", + "client_app_id", + "date", + "description", + "hresult", + "operation", + "result_code", + "server_selection", + "service_id", + "support_url", + "title", + "update_id", + "update_revision" + ], + "sectionRelativeRepoPath": "windows_update_history", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwindows_update_history.yml&value=name%3A%20windows_update_history%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/windows_updates", + "title": "windows_updates", + "htmlId": "table--windowsupdates--aa61957cff", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "windows_updates", + "fullkey", + "is_default", + "key", + "locale", + "parent", + "query", + "value" + ], + "sectionRelativeRepoPath": "windows_updates", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/windows_updates.yml" + }, + { + "url": "/tables/wmi_bios_info", + "title": "wmi_bios_info", + "htmlId": "table--wmibiosinfo--e665577f28", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "wmi_bios_info", + "name", + "value" + ], + "sectionRelativeRepoPath": "wmi_bios_info", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwmi_bios_info.yml&value=name%3A%20wmi_bios_info%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/wmi_cli_event_consumers", + "title": "wmi_cli_event_consumers", + "htmlId": "table--wmiclieventconsumers--d43fbe70e9", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "wmi_cli_event_consumers", + "class", + "command_line_template", + "executable_path", + "name", + "relative_path" + ], + "sectionRelativeRepoPath": "wmi_cli_event_consumers", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwmi_cli_event_consumers.yml&value=name%3A%20wmi_cli_event_consumers%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/wmi_event_filters", + "title": "wmi_event_filters", + "htmlId": "table--wmieventfilters--04ba1150eb", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "wmi_event_filters", + "class", + "name", + "query", + "query_language", + "relative_path" + ], + "sectionRelativeRepoPath": "wmi_event_filters", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwmi_event_filters.yml&value=name%3A%20wmi_event_filters%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/wmi_filter_consumer_binding", + "title": "wmi_filter_consumer_binding", + "htmlId": "table--wmifilterconsumerbinding--c53468b489", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "wmi_filter_consumer_binding", + "class", + "consumer", + "filter", + "relative_path" + ], + "sectionRelativeRepoPath": "wmi_filter_consumer_binding", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwmi_filter_consumer_binding.yml&value=name%3A%20wmi_filter_consumer_binding%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/wmi_script_event_consumers", + "title": "wmi_script_event_consumers", + "htmlId": "table--wmiscripteventconsumers--9275e5f795", + "evented": false, + "platforms": [ + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "wmi_script_event_consumers", + "class", + "name", + "relative_path", + "script_file_name", + "script_text", + "scripting_engine" + ], + "sectionRelativeRepoPath": "wmi_script_event_consumers", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fwmi_script_event_consumers.yml&value=name%3A%20wmi_script_event_consumers%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/xprotect_entries", + "title": "xprotect_entries", + "htmlId": "table--xprotectentries--82da15dfc5", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "xprotect_entries", + "filename", + "filetype", + "identity", + "launch_type", + "name", + "optional", + "uses_pattern" + ], + "sectionRelativeRepoPath": "xprotect_entries", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/xprotect_entries.yml" + }, + { + "url": "/tables/xprotect_meta", + "title": "xprotect_meta", + "htmlId": "table--xprotectmeta--d9c759b143", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "xprotect_meta", + "developer_id", + "identifier", + "min_version", + "type" + ], + "sectionRelativeRepoPath": "xprotect_meta", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/xprotect_meta.yml" + }, + { + "url": "/tables/xprotect_reports", + "title": "xprotect_reports", + "htmlId": "table--xprotectreports--ed058eba3f", + "evented": false, + "platforms": [ + "darwin" + ], + "keywordsForSyntaxHighlighting": [ + "xprotect_reports", + "name", + "time", + "user_action" + ], + "sectionRelativeRepoPath": "xprotect_reports", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/xprotect_reports.yml" + }, + { + "url": "/tables/yara", + "title": "yara", + "htmlId": "table--yara--f7412a4474", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "yara", + "count", + "matches", + "path", + "pid_with_namespace", + "sig_group", + "sigfile", + "sigrule", + "sigurl", + "strings", + "tags" + ], + "sectionRelativeRepoPath": "yara", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/yara.yml" + }, + { + "url": "/tables/yara_events", + "title": "yara_events", + "htmlId": "table--yaraevents--a3df07297e", + "evented": true, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "yara_events", + "action", + "category", + "count", + "eid", + "matches", + "strings", + "tags", + "target_path", + "time", + "transaction_id" + ], + "sectionRelativeRepoPath": "yara_events", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fyara_events.yml&value=name%3A%20yara_events%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/ycloud_instance_metadata", + "title": "ycloud_instance_metadata", + "htmlId": "table--ycloudinstancemetadata--91cc1e1945", + "evented": false, + "platforms": [ + "darwin", + "linux", + "windows" + ], + "keywordsForSyntaxHighlighting": [ + "ycloud_instance_metadata", + "cloud_id", + "description", + "folder_id", + "hostname", + "instance_id", + "metadata_endpoint", + "name", + "serial_port_enabled", + "ssh_public_key", + "zone" + ], + "sectionRelativeRepoPath": "ycloud_instance_metadata", + "githubUrl": "https://github.com/fleetdm/fleet/new/main/schema?filename=tables%2Fycloud_instance_metadata.yml&value=name%3A%20ycloud_instance_metadata%0Adescription%3A%20%7C-%20%23%20(required)%20string%20-%20The%20description%20for%20this%20table.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%23%20Add%20description%20here%0Aexamples%3A%20%7C-%20%23%20(optional)%20string%20-%20An%20example%20query%20for%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown%0A%09%23%20Add%20examples%20here%0Anotes%3A%20%7C-%20%23%20(optional)%20string%20-%20Notes%20about%20this%20table.%20Note%3A%20This%20field%20supports%20Markdown.%0A%09%23%20Add%20notes%20here%0Acolumns%3A%20%23%20(required)%0A%09-%20name%3A%20%23%20(required)%20string%20-%20The%20name%20of%20the%20column%0A%09%20%20description%3A%20%23%20(required)%20string%20-%20The%20column's%20description.%20Note%3A%20this%20field%20supports%20Markdown%0A%09%20%20type%3A%20%23%20(required)%20string%20-%20the%20column's%20data%20type%0A%09%20%20required%3A%20%23%20(required)%20boolean%20-%20whether%20or%20not%20this%20column%20is%20required%20to%20query%20this%20table." + }, + { + "url": "/tables/yum_sources", + "title": "yum_sources", + "htmlId": "table--yumsources--866cfa7193", + "evented": false, + "platforms": [ + "linux" + ], + "keywordsForSyntaxHighlighting": [ + "yum_sources", + "baseurl", + "enabled", + "gpgcheck", + "gpgkey", + "mirrorlist", + "name", + "pid_with_namespace" + ], + "sectionRelativeRepoPath": "yum_sources", + "githubUrl": "https://github.com/fleetdm/fleet/blob/main/schema/tables/yum_sources.yml" + } + ], + "rituals": { + "handbook/demand/demand.rituals.yml": [ + { + "task": "Refresh event calendar", + "startedOn": "2023-12-31", + "frequency": "Quarterly", + "description": "https://fleetdm.com/handbook/demand#refresh-event-calendar", + "moreInfoUrl": "https://fleetdm.com/handbook/demand#refresh-event-calendar", + "dri": "Drew-P-drawers" + }, + { + "task": "Prioritize for next sprint", + "startedOn": "2023-09-04", + "frequency": "Triweekly", + "description": "Using your departmental kanban board, prioritize and finalize next sprint's goals for your team by draging the appropriate issues to the top of the 'Not yet' column.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/why-this-way#why-make-work-visible", + "dri": "mikermcneil", + "autoIssue": { + "labels": [ + "#g-demand" + ], + "repo": "confidential" + } + }, + { + "task": "Settle event strategy", + "startedOn": "2024-01-02", + "frequency": "Quarterly (first Tuesday)", + "description": "https://fleetdm.com/handbook/demand#settle-event-strategy", + "moreInfoUrl": "https://fleetdm.com/handbook/demand#settle-event-strategy", + "dri": "Drew-P-drawers" + }, + { + "task": "🫧 Pipeline sync", + "startedOn": "2024-08-29", + "frequency": "Weekly", + "description": "Allign with CRO and AEs on pipeline processes and incoming leads", + "moreInfoUrl": "", + "dri": "Drew-P-drawers" + }, + { + "task": "Optimize ads", + "startedOn": "2024-02-26", + "frequency": "Weekly", + "description": "Remove all but the top 5 perfoming ads in each evergreen campaign. Make sure ABM campaigns are using top performing evergreen ads.", + "moreInfoUrl": "https://fleetdm.com/handbook/demand#optimize-ads-through-experimentation", + "dri": "Drew-P-drawers" + }, + { + "task": "Process pending swag requests from the website", + "startedOn": "2023-09-20", + "frequency": "Weekly", + "description": "Complete draft orders.", + "moreInfoUrl": "https://fleetdm.com/handbook/demand#process-pending-swag-requests-from-the-website", + "dri": "Drew-P-drawers" + }, + { + "task": "Engage with the community", + "startedOn": "2023-09-20", + "frequency": "Daily", + "description": "Find relevant conversations with the community and contribute", + "moreInfoUrl": "https://fleetdm.com/handbook/demand#engage-with-the-community", + "dri": "Drew-P-drawers" + }, + { + "task": "Publish ☁️🌈 Sprint demos", + "startedOn": "2023-11-03", + "frequency": "Triweekly", + "description": "Every release cycle, upload the ☁️🌈 Sprint demos video to YouTube", + "moreInfoUrl": "https://fleetdm.com/handbook/demand#upload-to-youtube", + "dri": "Drew-P-drawers" + }, + { + "task": "Measure intent signals", + "startedOn": "2024-08-09", + "frequency": "Daily", + "description": "Measure intent signals and update SalesForce", + "moreInfoUrl": "https://fleetdm.com/handbook/demand#measure-intent-signals", + "dri": "Drew-P-drawers" + }, + { + "task": "Research accounts", + "startedOn": "2024-08-09", + "frequency": "Daily", + "description": "Research SalesForce accounts and begin ABM ads", + "moreInfoUrl": "https://fleetdm.com/handbook/demand#warm-up-actions", + "dri": "Drew-P-drawers" + } + ], + "handbook/customer-success/customer-success.rituals.yml": [ + { + "task": "Prioritize for next sprint", + "startedOn": "2023-09-04", + "frequency": "Triweekly", + "description": "Using your departmental kanban board, prioritize and finalize next sprint's goals for your team by draging the appropriate issues to the top of the 'Not yet' column.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/why-this-way#why-make-work-visible", + "dri": "zayhanlon", + "autoIssue": { + "labels": [ + "#g-customer-success" + ], + "repo": "confidential" + } + }, + { + "task": "Process new requests", + "startedOn": "2023-09-04", + "frequency": "Daily", + "description": "Prioritize all new requests including issues and PRs within one business day.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/communications#process-new-requests", + "dri": "zayhanlon" + }, + { + "task": "Overnight customer feedback", + "startedOn": "2024-02-08", + "frequency": "Daily", + "description": "Respond to messages and alerts", + "moreInfoUrl": "https://fleetdm.com/handbook/customer-success#respond-to-messages-and-alerts", + "dri": "ksatter" + }, + { + "task": "Monitor customer Slack channels ", + "startedOn": "2024-02-08", + "frequency": "Daily", + "description": "Continuously monitor Slack for customer feedback, feature requests, reported bugs, etc., and respond in less than an hour.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/communications#customer-support-service-level-agreements-slas", + "dri": "ksatter" + }, + { + "task": "Follow-up on unresolved customer questions and concerns", + "startedOn": "2024-02-08", + "frequency": "Daily", + "description": "Follow-up with and tag appropriate personnel on customer issues and bugs in progress and items that remain unresolved.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/communications#customer-support-service-level-agreements-slas", + "dri": "ksatter" + }, + { + "task": "Prepare for customer voice", + "startedOn": "2024-02-23", + "frequency": "Weekly", + "description": "Prepare and review the health and latest updates from Fleet's key customers and active proof of concepts (POCs).", + "moreInfoUrl": "", + "dri": "patagonia121" + }, + { + "task": "Prepare customer requests for feature fest", + "startedOn": "2024-02-12", + "frequency": "Triweekly", + "description": "Check-in before the 🗣️ Product Feature Requests meeting to make sure that all information necessary has been gathered before presenting customer requests and feedback to the Product team.", + "moreInfoUrl": "", + "dri": "nonpunctual" + }, + { + "task": "Present customer requests at feature fest", + "startedOn": "2024-02-15", + "frequency": "Triweekly", + "description": "Present and advocate for requests and ideas brought to Fleet's attention by customers that are interesting from a product perspective.", + "moreInfoUrl": "", + "dri": "nonpunctual" + }, + { + "task": "Communicate release notes to stakeholders", + "startedOn": "2024-02-21", + "frequency": "Triweekly", + "description": "Update customers on new features and resolved bugs in an upcoming release.", + "moreInfoUrl": "", + "dri": "patagonia121" + }, + { + "task": "Upgrade Managed Cloud", + "startedOn": "2024-02-08", + "frequency": "Weekly", + "description": "Upgrade each Managed Cloud instance to the latest version of Fleet", + "moreInfoUrl": "https://github.com/fleetdm/fleet/releases", + "dri": "rfairburn" + } + ], + "handbook/digital-experience/digital-experience.rituals.yml": [ + { + "task": "Complete Digital Experience KPIs", + "startedOn": "2024-08-30", + "frequency": "Weekly", + "description": "Complete Digital Experience KPIs for this week", + "moreInfoUrl": "https://docs.google.com/spreadsheets/d/1Hso0LxqwrRVINCyW_n436bNHmoqhoLhC8bcbvLPOs9A/edit?gid=0#gid=0&range=DB1", + "dri": "SFriendLee", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "fleet" + } + }, + { + "task": "Prep 1:1s for OKR planning", + "startedOn": "2024-09-09", + "frequency": "Monthly", + "description": "Add ”DISCUSS: Mike: Expectations of OKR planning“ to each e-group member's 1:1 document", + "moreInfoUrl": "https://docs.google.com/spreadsheets/d/1Hso0LxqwrRVINCyW_n436bNHmoqhoLhC8bcbvLPOs9A/edit", + "dri": "SFriendLee", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "fleet" + } + }, + { + "task": "Check browser compatibility for fleetdm.com", + "startedOn": "2024-03-06", + "frequency": "Monthly", + "description": "Use Browserstack to manually QA pages on fleetdm.com in each of the earliest supported browser versions", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#check-browser-compatibility-for-fleetdm-com", + "dri": "eashaw", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "fleet" + } + }, + { + "task": "Regenerate messaging framework", + "startedOn": "2024-07-15", + "frequency": "Quarterly", + "description": "Run through the entire website in `?utm_content=clear` mode and build a fresh outline of the headings to make sure they all still make sense.", + "moreInfoUrl": "", + "dri": "mike-j-thomas" + }, + { + "task": "Check brand fronts are up to date", + "startedOn": "2024-08-01", + "frequency": "Quarterly", + "description": "Check all brand fronts for consistancy and update as needed with the current product pitch and graphics.", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#update-a-company-brand-front", + "dri": "mike-j-thomas" + }, + { + "task": "Check production dependencies of fleetdm.com", + "startedOn": "2023-11-10", + "frequency": "Weekly", + "description": "Check for vulnerabilities on the production dependencies of fleetdm.com.", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#check-production-dependencies-of-fleetdm-com", + "dri": "eashaw", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "fleet" + } + }, + { + "task": "Check osquery Slack invitation", + "startedOn": "2023-11-10", + "frequency": "Monthly", + "description": "Check the osquery Slack invitation that is linked to from Fleet and the Fleet website to make sure it is valid.", + "moreInfoUrl": "https://fleetdm.com/slack", + "dri": "eashaw", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "fleet" + } + }, + { + "task": "Prepare for CEO office minutes", + "startedOn": "2023-12-18", + "frequency": "Daily", + "description": "Prepare the CEO office minutes calendar event and meeting agenda", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#prepare-for-ceo-office-minutes", + "dri": "SFriendLee" + }, + { + "task": "Prioritize for next sprint", + "startedOn": "2023-08-09", + "frequency": "Triweekly", + "description": "Using your departmental kanban board, prioritize and finalize next sprint's goals for your team by draging the appropriate issues to the top of the 'Not yet' column.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/why-this-way#why-make-work-visible", + "dri": "sampfluger88", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "confidential" + } + }, + { + "task": "Process the CEO's inbox", + "startedOn": "2023-07-29", + "frequency": "Daily ⏰", + "description": "Process the CEO's inbox", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#process-the-ceos-email", + "dri": "SFriendLee" + }, + { + "task": "Process all \"New requests\" on the #g-digital-experience kanban board", + "startedOn": "2023-07-29", + "frequency": "Daily ⏰", + "description": "Process and prioritize all new issues and PRs", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#process-new-requests-from-the-g-ceo-kanban-board", + "dri": "sampfluger88" + }, + { + "task": "Process the CEO's calendar", + "startedOn": "2023-07-29", + "frequency": "Daily ⏰", + "description": "Process the CEO's calendar", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#process-the-ceos-calendar", + "dri": "SFriendLee" + }, + { + "task": "Send weekly update", + "startedOn": "2023-09-15", + "frequency": "Weekly", + "description": "Send weekly update", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#send-the-weekly-update", + "dri": "SFriendLee", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "confidential" + } + }, + { + "task": "Process and backup E-group agenda", + "startedOn": "2023-09-20", + "frequency": "Weekly", + "description": "Process and backup E-group agenda", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#process-and-backup-sid-agenda", + "dri": "SFriendLee", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "confidential" + } + }, + { + "task": "Process and backup Sid agenda", + "startedOn": "2023-09-25", + "frequency": "Monthly", + "description": "Process and backup Sid agenda", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#process-and-backup-e-group-agenda", + "dri": "SFriendLee", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "confidential" + } + }, + { + "task": "Share recording of all hands meeting", + "startedOn": "2023-07-01", + "frequency": "Monthly", + "description": "Sharing the all hands recording", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#share-recording-of-all-hands-meeting", + "dri": "SFriendLee", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "confidential" + } + }, + { + "task": "Prepare all hands deck", + "startedOn": "2023-07-01", + "frequency": "Monthly", + "description": "Preparing the all hands deck", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#preparing-for-the-all-hands", + "dri": "sampfluger88", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "confidential" + } + }, + { + "task": "Prepare board deck", + "startedOn": "2023-09-25", + "frequency": "Quarterly", + "description": "Prepare slide deck for the next board meeting", + "dri": "sampfluger88" + }, + { + "task": "Process CEO GitHub review requests, mentions, and outstanding PRs", + "startedOn": "2023-07-29", + "frequency": "Daily", + "description": "Filter all action items from CEO's GitHub notifications", + "dri": "SFriendLee" + }, + { + "task": "Check LinkedIn for unread messages", + "startedOn": "2023-09-25", + "frequency": "Daily", + "description": "Prevent connections from slipping through the cracks", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#check-linkedin-for-unread-messages", + "dri": "SFriendLee" + }, + { + "task": "Downgrade unused license seats", + "startedOn": "2024-03-31", + "frequency": "Quarterly", + "description": "Downgrade unused or questionable license seats on the first Wednesday of every quarter", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#downgrade-an-unused-license-seat", + "dri": "sampfluger88" + }, + { + "task": "Communicate Fleet's potential energy to stakeholders", + "startedOn": "2024-05-01", + "frequency": "Monthly", + "description": "Via hand or automation, send a monthly update email to all investors that hold 4% equity or greater in Fleet who have opted in to receive emails on the company's progress.", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#communicate-fleets-potential-energy-to-stakeholders", + "dri": "sampfluger88", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "confidential" + } + }, + { + "task": "Vanta check", + "startedOn": "2024-04-01", + "frequency": "Monthly", + "description": "Look for any new actions in Vanta due in the upcoming months and create issues to ensure they're done on time.", + "moreInfoUrl": null, + "dri": "sampfluger88", + "autoIssue": { + "labels": [ + "#g-digital-experience" + ], + "repo": "confidential" + } + }, + { + "task": "Recognize and benchmark workiversaries", + "startedOn": "2024-07-15", + "frequency": "Bimonthly", + "description": "Identify workiversaries coming up in the next two months and follow the steps to ensure they're recognized and benchmarked", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#recognize-employee-workiversaries", + "dri": "sampfluger88" + }, + { + "task": "Quarterly grants", + "startedOn": "2024-02-01", + "frequency": "Quarterly", + "description": "Create the equity grants GitHub issue and walk through the steps.", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#grant-equity", + "dri": "hollidayn" + }, + { + "task": "Change password of \"Integrations admin\" Salesforce account", + "startedOn": "2024-09-10", + "frequency": "Quarterly", + "description": "Log into the \"Integrations admin\" account in Salesforce and change the password to prevent a password change being required by Salesforce.", + "moreInfoUrl": "https://fleetdm.com/handbook/digital-experience#change-the-integrations-admin-salesforce-account-password", + "dri": "eashaw" + } + ], + "handbook/finance/finance.rituals.yml": [ + { + "task": "Communicate the status of customer financial actions", + "startedOn": "2024-02-12", + "frequency": "Weekly", + "description": "At the start of every week, check the Salesforce reports for past due invoices, non-invoiced opportunities, and past due renewals. Report findings to in the `#g-sales` channel.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#communicate-the-status-of-customer-financial-actions", + "dri": "ireedy", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "AP invoice monitoring", + "startedOn": "2024-04-01", + "frequency": "Weekly", + "description": "Look for new accounts payable invoices and make sure that Fleet's suppliers are paid.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#process-a-new-vendor-invoice", + "dri": "ireedy", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Complete Finance KPI inputs", + "startedOn": "2024-02-16", + "frequency": "Weekly", + "description": "Create the weekly team KPI issue, complete the finance update.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#update-weekly-kpis", + "dri": "ireedy", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Key review prep", + "startedOn": "2024-02-14", + "frequency": "Triweekly", + "description": "Prepare for this sprint's Key review meeting.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/leadership#key-reviews", + "dri": "jostableford", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Prioritize for next sprint", + "startedOn": "2023-08-09", + "frequency": "Triweekly", + "description": "Using your departmental kanban board, prioritize and finalize next sprint's goals for your team by draging the appropriate issues to the top of the 'Not yet' column.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/why-this-way#why-make-work-visible", + "dri": "jostableford", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Reconcile monthly recurring expenses", + "startedOn": "2024-02-28", + "frequency": "Monthly", + "description": "Each month, update the inputs in “The numbers” spreadsheet to reflect the actuals for recurring non-personnel spend, and identify any unexpected increase or decrease in spend.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#reconcile-monthly-recurring-expenses", + "dri": "jostableford", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Monthly accounting", + "startedOn": "2024-02-28", + "frequency": "Monthly", + "description": "Create the monthly close GitHub issue and walk through the steps. This process includes fulfilling the monthly reporting requirement for SVB.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#process-monthly-accounting", + "dri": "ireedy", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Run regular payroll", + "startedOn": "2024-02-24", + "frequency": "Monthly", + "description": "Verify auto-populated payroll for all full time employees is accurate, and approve for processing.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#run-payroll", + "dri": "jostableford", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Monthly mail review", + "startedOn": "2024-04-15", + "frequency": "Monthly", + "description": "Review and clear mail incurring storage fees", + "moreInfoUrl": null, + "dri": "ireedy", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Run US contractor payroll", + "startedOn": "2024-02-28", + "frequency": "Monthly", + "description": "Manually process US contractor payroll by verifying and syncing time contractor worked, then processing payment.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#run-us-contractor-payroll", + "dri": "jostableford", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Run US commission payroll", + "startedOn": "2024-01-31", + "frequency": "Monthly", + "description": "Verify closed-won deal amounts, use commission calculators to determine commissions owed, and process payroll.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#run-us-commission-payroll", + "dri": "jostableford", + "autoIssue": { + "labels": [ + "#g-finance" + ], + "repo": "confidential" + } + }, + { + "task": "Run bonus payroll", + "startedOn": "2024-01-31", + "frequency": "Quarterly", + "description": "Verify completion of any objective or outcome based bonus plans, and process payroll.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#run-us-commission-payroll", + "dri": "jostableford" + }, + { + "task": "Review state filings for the previous quarter", + "startedOn": "2024-07-19", + "frequency": "Quarterly", + "description": "Verify that state filings have been successfully submitted for the previous quarter", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#review-state-employment-tax-filings-for-the-previous-quarter", + "dri": "ireedy" + }, + { + "task": "Investor reporting", + "startedOn": "2024-03-31", + "frequency": "Quarterly", + "description": "Provide updated metrics for CRV in Chronograph.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#report-quarterly-numbers-in-chronograph", + "dri": "ireedy" + }, + { + "task": "Quartlery finance check", + "startedOn": "2024-03-31", + "frequency": "Quarterly", + "description": "Every quarter, we check Quickbooks Online (QBO) for discrepancies and follow up with accounting providers for any quirks found.", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#check-finances-for-quirks", + "dri": "jostableford" + }, + { + "task": "Deliver annual report for venture line", + "startedOn": "2024-12-01", + "frequency": "Annually", + "description": "Within 60 days of the new year, provide financial statements to SVB, along with board-approved projections for the new year", + "moreInfoUrl": "https://fleetdm.com/handbook/finance#deliver-annual-report-for-venture-line", + "dri": "jostableford" + }, + { + "task": "Tax preparation", + "startedOn": "2024-02-01", + "frequency": "Annually", + "description": "Provide information to tax team with Deloitte and assist with filing and paying state and federal returns", + "moreInfoUrl": null, + "dri": "jostableford" + } + ], + "handbook/engineering/engineering.rituals.yml": [ + { + "task": "Pull request review", + "startedOn": "2023-08-09", + "frequency": "Daily", + "description": "Engineers go through pull requests for which their review has been requested.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/why-this-way#why-make-work-visible", + "dri": "lukeheath" + }, + { + "task": "Engineering group discussions", + "startedOn": "2023-08-09", + "frequency": "Daily", + "description": "Engineers go through pull requests for which their review has been requested.", + "moreInfoUrl": null, + "dri": "lukeheath" + }, + { + "task": "Oncall handoff", + "startedOn": "2023-08-09", + "frequency": "Weekly", + "description": "Hand off the oncall engineering responsibilities to the next oncall engineer.", + "moreInfoUrl": null, + "dri": "lukeheath" + }, + { + "task": "Vulnerability alerts (fleetdm.com)", + "startedOn": "2023-08-09", + "frequency": "Weekly", + "description": "Review and remediate or dismiss vulnerability alerts for the fleetdm.com codebase on GitHub.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/security", + "dri": "eashaw" + }, + { + "task": "Vulnerability alerts (frontend)", + "startedOn": "2023-08-09", + "frequency": "Weekly", + "description": "Review and remediate or dismiss vulnerability alerts for the Fleet frontend codebase (and related JS) on GitHub.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/security", + "dri": "lukeheath" + }, + { + "task": "Vulnerability alerts (backend)", + "startedOn": "2023-08-09", + "frequency": "Weekly", + "description": "Review and remediate or dismiss vulnerability alerts for the Fleet backend codebase (and all Go code) on GitHub.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/security", + "dri": "lukeheath" + }, + { + "task": "Release candidate ritual", + "startedOn": "2023-08-09", + "frequency": "Triweekly", + "description": "Go through the process of creating a release candidate.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/blob/main/tools/release/README.md#minor-release-typically-end-of-sprint", + "dri": "lukeheath" + }, + { + "task": "Release ritual", + "startedOn": "2023-08-09", + "frequency": "Triweekly", + "description": "Go through the process of releasing the next iteration of Fleet.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Releasing-Fleet.md", + "dri": "lukeheath" + }, + { + "task": "Create patch release branch", + "startedOn": "2023-08-09", + "frequency": "Every patch release", + "description": "Go through the process of creating a patch release branch, cherry picking commits, and pushing the branch to github.com/fleetdm/fleet.", + "moreInfoUrl": "https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Releasing-Fleet.md#patch-releases", + "dri": "lukeheath" + }, + { + "task": "Bug review", + "startedOn": "2023-08-09", + "frequency": "Weekly", + "description": "Review bugs that are in QA's inbox.", + "moreInfoUrl": "https://www.fleetdm.com/handbook/company/product-groups#inbox", + "dri": "xpkoala" + }, + { + "task": "QA report", + "startedOn": "2023-08-09", + "frequency": "Triweekly", + "description": "Every release cycle, on the Monday of release week, update the DRI for the release ritual on status of testing.", + "moreInfoUrl": null, + "dri": "xpkoala" + }, + { + "task": "Release QA", + "startedOn": "2023-08-09", + "frequency": "Triweekly", + "description": "Every release cycle, by end of day Friday of release week, move all issues to the ”✅ Ready for release” column on the #g-mdm and #g-endpoint-ops sprint boards.", + "moreInfoUrl": null, + "dri": "xpkoala" + }, + { + "task": "Check ongoing events", + "startedOn": "2024-02-09", + "frequency": "Daily", + "description": "Check event issues and complete steps.", + "moreInfoUrl": "https://fleetdm.com/handbook/engineering#book-an-event", + "dri": "spokanemac" + } + ], + "handbook/sales/sales.rituals.yml": [ + { + "task": "Close leads contacted ≥7 days ago", + "startedOn": "2024-07-05", + "frequency": "Daily", + "description": "Close all of your leads in the 'Attempted to contact' stage and which have been there for 7 or more days. If follow-up is appropriate, and won't be bothersome, it can be done after closing the lead. (A new lead can always be opened for the contact later.)", + "moreInfoUrl": "", + "dri": "Every AE" + }, + { + "task": "Prioritize for next sprint", + "startedOn": "2023-09-04", + "frequency": "Triweekly", + "description": "Using your departmental kanban board, prioritize and finalize next sprint's goals for your team by draging the appropriate issues to the top of the 'Not yet' column.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/why-this-way#why-make-work-visible", + "dri": "alexmitchelliii", + "autoIssue": { + "labels": [ + "#g-sales" + ], + "repo": "confidential" + } + }, + { + "task": "g-sales standup", + "startedOn": "2023-09-04", + "frequency": "Daily", + "description": "Review progress on priorities for Sprint. Discuss previous day accomplishments, goals for today and any blockers.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/why-this-way#why-make-work-visible", + "dri": "alexmitchelliii" + }, + { + "task": "Opportunity pipeline review", + "startedOn": "2023-09-04", + "frequency": "Weekly", + "description": "Review status of sales opportunities and discuss next steps.", + "moreInfoUrl": "https://fleetdm.com/handbook/customers#review-rep-activity", + "dri": "alexmitchelliii", + "autoIssue": { + "labels": [ + "#g-sales" + ], + "repo": "confidential" + } + }, + { + "task": "Review rep activity", + "startedOn": "2023-09-18", + "frequency": "Monthly", + "description": "https://fleetdm.com/handbook/customers#review-rep-activity", + "moreInfoUrl": "https://fleetdm.com/handbook/customers#review-rep-activity", + "dri": "alexmitchelliii" + } + ], + "handbook/product-design/product-design.rituals.yml": [ + { + "task": "Design sprint review", + "startedOn": "2024-03-07", + "frequency": "Triweekly", + "description": "Clear out the drafting board of all issues that are not estimated but leave the items we want to take in the next sprint on the drafting board. Record the number of dropped stories for KPIs (all user stories that did not meet the 3 week drafting timeline).", + "moreInfoUrl": null, + "dri": "noahtalerman" + }, + { + "task": "🎁 Feature fest", + "startedOn": "2024-03-07", + "frequency": "Triweekly", + "description": "We make a decision regarding which customer and community feature requests can be committed to in the next six weeks.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/product-groups#feature-fest", + "dri": "noahtalerman" + }, + { + "task": "Design sprint kickoff", + "startedOn": "2024-03-07", + "frequency": "Triweekly", + "description": "Add stories prioritized during Feature fest to Drafting board, assign stories to product designers, and align on priorities.", + "moreInfoUrl": null, + "dri": "noahtalerman" + }, + { + "task": "Sprint kickoff review", + "startedOn": "2024-03-07", + "frequency": "Triweekly", + "description": "Identify stories that did not make it into this sprint and remove them from the board. Notify relevant requesters/stakeholders. Ensure bugs have been effectively prioritized across teams. Recommend highlights for next release notes. Record the number of drops for KPI reporting. Consider product group staffing. Are we scheduling what we prioritized? Did we finish what we scheduled in the sprint? (Look at org chart.)", + "moreInfoUrl": null, + "dri": "noahtalerman" + }, + { + "task": "🦢🗣 Design review", + "startedOn": "2024-03-07", + "frequency": "Daily", + "description": "On Mondays, contributors present wireframes in 'Feedback' mode and anyone can give feedback. 'Final review' mode during all other days and only Head of Product Design + CTO + Product Designers give feedback.", + "moreInfoUrl": "https://fleetdm.com/handbook/company/product-groups#design-reviews", + "dri": "noahtalerman" + }, + { + "task": "🦢🔄 Product design sync", + "startedOn": "2023-07-11", + "frequency": "Weekly", + "description": "Weekly time to chat about product design work (design reviews, conventions & best practices, using Figma, etc.)", + "moreInfoUrl": "https://docs.google.com/document/d/1GDEcXuTUjHI2CD9Jqega_GyF9DL6-PBmcyJpj55Lmos/edit", + "dri": "noahtalerman" + }, + { + "task": "🦢🗣 Product office hours", + "startedOn": "2023-07-11", + "frequency": "Weekly", + "description": "Head of Product Design + any other contributors who would like to attend. 30 minutes reserved to talk about any product.", + "moreInfoUrl": "https://docs.google.com/document/d/1Znyp2a9qcM9JdYHrzLudvcPwEdhnCg7RiKi22s8yGWw/edit", + "dri": "noahtalerman" + }, + { + "task": "Maintenance", + "startedOn": "2024-03-01", + "frequency": "Weekly", + "description": "Head of Product Design checks the latest versions of relevant platforms, updates the maintenance tracker, and notifies the #g-mdm and #g-endpoint-ops Slack channel.", + "moreInfoUrl": null, + "dri": "noahtalerman" + }, + { + "task": "Product confirm and celebrate", + "startedOn": "2024-02-27", + "frequency": "Weekly", + "description": "Review user stories we shipped but haven't closed/ Confirm all the loose ends are tied up: docs, internal and external comms, guides, pricing page, transparency page, user permissions.", + "moreInfoUrl": null, + "dri": "noahtalerman" + }, + { + "task": "Pre-sprint prioritization", + "startedOn": "2024-02-27", + "frequency": "Triweekly", + "description": "Discuss what stories weren't completed in the previous sprint. Record the number of stories in KPIs. Align on priorities for upcoming sprint.", + "dri": "noahtalerman" + } + ] + }, + "testimonials": [ + { + "quote": "Yes Sir. Great tools for the everyday open-source geeks 💯", + "quoteAuthorName": "Alvaro Gutierrez", + "quoteAuthorProfileImageFilename": "testimonial-authour-alvaro-gutierrez-100x100@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/aantoniogutierrez/", + "quoteAuthorJobTitle": "Technology Evangelist", + "productCategories": [ + "Endpoint operations" + ] + }, + { + "quote": "Fleet / osquery are some of my favorite open source detection tooling.", + "quoteAuthorName": "Joe Pistone", + "quoteAuthorProfileImageFilename": "testimonial-author-joe-pistone-100x100@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/josephpistone/", + "quoteAuthorJobTitle": "Manager, Security Operations", + "productCategories": [ + "Endpoint operations" + ] + }, + { + "quote": "I had to answer some really complex questions for a compliance audit, and I was able to do it in about 15 minutes by munging some data together via a few queries into a csv. It took me longer to remember how to use `xsv` than to actually put together the report. If you aren't using osquery in your environment, you should be.", + "quoteAuthorName": "Charles Zaffery", + "quoteAuthorProfileImageFilename": "testimonial-author-charles-zaffery-48x48@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/charleszaffery/", + "quoteAuthorJobTitle": "Principle Computer Janitor", + "productCategories": [ + "Vulnerability management" + ] + }, + { + "quote": "The visibility down into the assets covered by the agent is phenomenal. Fleet has become the central source for a lot of things.", + "quoteAuthorName": "Andre Shields", + "quoteAuthorProfileImageFilename": "testimonial-author-andre-shields-48x48@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/andre-shields/", + "quoteAuthorJobTitle": "Staff Cybersecurity Engineer, Vulnerability Management", + "youtubeVideoUrl": "https://www.youtube.com/watch?v=siXy9aanOu4", + "productCategories": [ + "Endpoint operations", + "Vulnerability management" + ], + "videoIdForEmbed": "siXy9aanOu4" + }, + { + "quote": "I love the steady and consistent delivery of features that help teams work how they want to work, not how your product dictates they work.", + "quoteImageFilename": "social-proof-logo-atlassian-192x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/danielgrzelak/", + "quoteAuthorName": "Dan Grzelak", + "quoteAuthorProfileImageFilename": "testimonial-author-daniel-grzelak-48x48@2x.png", + "quoteAuthorJobTitle": "Security Chief of Staff", + "productCategories": [ + "Endpoint operations", + "Vulnerability management", + "Device management" + ], + "imageHeight": 32 + }, + { + "quote": "We can build it exactly the way we want it. Which is just not possible on other platforms.", + "quoteAuthorName": "Austin Anderson", + "quoteAuthorProfileImageFilename": "testimonial-author-austin-anderson-48x48@2x.png", + "quoteAuthorJobTitle": "Cybersecurity team senior manager", + "quoteLinkUrl": "https://www.linkedin.com/in/austin-anderson-73172185/", + "youtubeVideoUrl": "https://www.youtube.com/watch?v=G5Ry_vQPaYc", + "productCategories": [ + "Endpoint operations", + "Vulnerability management" + ], + "videoIdForEmbed": "G5Ry_vQPaYc" + }, + { + "quote": "Exciting. This is a team that listens to feedback.", + "quoteImageFilename": "social-proof-logo-uber-71x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/eriknicolasgomez/", + "quoteAuthorName": "Erik Gomez", + "quoteAuthorProfileImageFilename": "testimonial-author-erik-gomez-48x48@2x.png", + "quoteAuthorJobTitle": "Staff Client Platform Engineer", + "productCategories": [ + "Endpoint operations", + "Device management" + ], + "imageHeight": 32 + }, + { + "quote": "Context is king for device data, and Fleet provides a way to surface that information to our other teams and partners.", + "quoteAuthorName": "Nick Fohs", + "quoteAuthorProfileImageFilename": "testimonial-author-nick-fohs-24x24@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/nickfohs/", + "quoteAuthorJobTitle": "Systems and infrastructure manager", + "youtubeVideoUrl": "https://www.youtube.com/watch?v=fs5ULAR4e4A", + "productCategories": [ + "Endpoint operations", + "Device management", + "Vulnerability management" + ], + "videoIdForEmbed": "fs5ULAR4e4A" + }, + { + "quote": "Keeping up with the latest issues in endpoint security is a never-ending task, because engineers have to regularly ensure every laptop and server is still sufficiently patched and securely configured. The problem is, software vendors release new versions all the time, and no matter how much you lock it down, end users find ways to change things.", + "quoteImageFilename": "social-proof-logo-lyft-47x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/nwaisman/", + "quoteAuthorName": "Nico Waisman", + "quoteAuthorProfileImageFilename": "testimonial-author-nico-waisman-48x48@2x.png", + "quoteAuthorJobTitle": "CISO of Lyft", + "productCategories": [ + "Endpoint operations", + "Vulnerability management" + ], + "imageHeight": 32 + }, + { + "quote": "Having the freedom to take full advantage of the product is one of the reasons why I always support open-source products with a commercially-backed company, like Fleet.", + "quoteImageFilename": "social-proof-logo-lyft-47x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/posts/nwaisman_movingtofleet-activity-7156319785981509632-bk_W", + "quoteAuthorName": "Nico Waisman", + "quoteAuthorProfileImageFilename": "testimonial-author-nico-waisman-48x48@2x.png", + "quoteAuthorJobTitle": "CISO of Lyft", + "productCategories": [ + "Device management" + ], + "imageHeight": 32 + }, + { + "quote": "Fleet has been highly effective for our needs. We appreciate your team for always being so open to hearing our feedback.", + "quoteAuthorName": "Kenny Botelho", + "quoteAuthorProfileImageFilename": "testimonial-author-kenny-botelho-48x48@2x.png", + "quoteAuthorJobTitle": "Client Platform IT Engineer / Leader", + "quoteLinkUrl": "https://www.linkedin.com/in/kennybotelho/", + "productCategories": [ + "Endpoint operations", + "Device management" + ] + }, + { + "quote": "Mad props to how easy making a deploy pkg of the agent was. I wish everyone made stuff that easy.", + "quoteImageFilename": "social-proof-logo-stripe-67x32@2x.png", + "quoteAuthorName": "Wes Whetstone", + "quoteAuthorProfileImageFilename": "testimonial-author-wes-whetstone-48x48@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/jckwhet/", + "quoteAuthorJobTitle": "Staff CPE at Stripe", + "productCategories": [ + "Endpoint operations", + "Device management" + ], + "imageHeight": 32 + }, + { + "quote": "Fleet’s come a long way - to now being the top open-source osquery manager.", + "quoteImageFilename": "social-proof-logo-atlassian-192x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/bshak/", + "quoteAuthorName": "Brendan Shaklovitz", + "quoteAuthorProfileImageFilename": "testimonial-author-brendan-shaklovitz-48x48@2x.png", + "quoteAuthorJobTitle": "Senior SRE", + "productCategories": [ + "Endpoint operations" + ], + "imageHeight": 32 + }, + { + "quote": "It’s great to see the new release of Fleet containing some really cool new features that make osquery much more usable in practical environments. I’m really impressed with the work that Zach Wasserman and the crew are doing at Fleet.", + "quoteImageFilename": "social-proof-logo-osquery-124x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/marpaia/", + "quoteAuthorName": "Mike Arpaia", + "quoteAuthorProfileImageFilename": "testimonial-author-mike-arpaia-48x48@2x.png", + "quoteAuthorJobTitle": "Creator of osquery", + "productCategories": [ + "Endpoint operations" + ], + "imageHeight": 32 + }, + { + "quote": "Osquery is one of the best tools out there and Fleet makes it even better. Highly recommend it if you want to monitor, detect and investigate threats on a scale and also for infra/sys admin. I have used it on 15k servers and it’s really scalable.", + "quoteImageFilename": "social-proof-logo-salesforce-48x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/anelshaer/", + "quoteAuthorName": "Ahmed Elshaer", + "quoteAuthorProfileImageFilename": "testimonial-author-ahmed-elshaer-48x48@2x.png", + "quoteAuthorJobTitle": "DFIR, Blue Teaming, SecOps", + "productCategories": [ + "Endpoint operations" + ], + "imageHeight": 32 + }, + { + "quote": "With the power of osquery, you need a scalable & resilient platform to manage your workloads. Fleet is the \"just right\" open-source, enterprise grade solution.", + "quoteImageFilename": "social-proof-logo-comcast-91x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/abubakar-yousafzai-b7213659/", + "quoteAuthorName": "Abubakar Yousafzai", + "quoteAuthorProfileImageFilename": "testimonial-author-abubakar-yousafzai-48x48@2x.png", + "quoteAuthorJobTitle": "Security Software Development & Engineering", + "productCategories": [ + "Endpoint operations" + ], + "imageHeight": 32 + }, + { + "quote": "One of the best teams out there to go work for and help shape security platforms.", + "quoteImageFilename": "social-proof-logo-deloitte-130x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/neondhruv/", + "quoteAuthorName": "Dhruv Majumdar", + "quoteAuthorProfileImageFilename": "testimonial-author-dhruv-majumdar-48x48@2x.png", + "quoteAuthorJobTitle": "Director Of Cyber Risk & Advisory", + "productCategories": [ + "Vulnerability management", + "Endpoint operations" + ], + "imageHeight": 32 + }, + { + "quote": "Fleet has such a huge amount of use cases. My goal was to get telemetry on endpoints, but then our IR team, our TBM team, and multiple other folks in security started heavily utilizing the system in ways I didn’t expect. It spread so naturally, even our corporate and infrastructure teams want to run it.", + "quoteAuthorName": "Charles Zaffery", + "quoteLinkUrl": "https://www.linkedin.com/in/charleszaffery/", + "quoteAuthorJobTitle": "Principle computer janitor", + "quoteAuthorProfileImageFilename": "testimonial-author-charles-zaffery-48x48@2x.png", + "youtubeVideoUrl": "https://www.youtube.com/watch?v=nRbZJflWqCo", + "productCategories": [ + "Endpoint operations" + ], + "videoIdForEmbed": "nRbZJflWqCo" + }, + { + "quote": "I don't want one bad actor to brick my fleet, I want them to make a pull request first.", + "quoteAuthorName": "Matt Carr", + "quoteAuthorJobTitle": "CPE manager", + "quoteAuthorProfileImageFilename": "testimonial-author-matt-carr-48x48@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/mathewcarr/", + "productCategories": [ + "Device management" + ] + }, + { + "quote": "I wanted an easy way to control osquery configurations, and I wanted to stream data as fast as possible into Snowflake. No other solution jumped out to solve those things except for Fleet.", + "quoteAuthorName": "Tom Larkin", + "quoteAuthorJobTitle": "IT Engineering Manager", + "quoteAuthorProfileImageFilename": "testimonial-author-tom-larkin-48x48@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/thlarkin/", + "youtubeVideoUrl": "https://www.youtube.com/watch?v=nkjg_hNe86Q", + "productCategories": [ + "Endpoint operations" + ], + "videoIdForEmbed": "nkjg_hNe86Q" + }, + { + "quote": "Something I really appreciate about working with you guys is that it doesn't feel like I'm talking to a vendor. It actually feels like I'm talking to my team, and I really appreciate it.", + "quoteImageFilename": "social-proof-logo-deloitte-130x32@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/cmajumdar/", + "quoteAuthorName": "Chandra Majumdar", + "quoteAuthorProfileImageFilename": "testimonial-author-chandra-majumdar-48x48@2x.png", + "quoteAuthorJobTitle": "Partner - Cyber and Strategic Risk", + "productCategories": [ + "Vulnerability management", + "Endpoint operations" + ], + "imageHeight": 32 + }, + { + "quote": "This is not just production osquery, but actually a way bigger opportunity than even something like Airwatch or Jamf.", + "quoteImageFilename": "logo-flock-safety-907x132@2x.png", + "quoteLinkUrl": "https://www.linkedin.com/in/mrerictan/", + "quoteAuthorName": "Eric Tan", + "quoteAuthorProfileImageFilename": "testimonial-author-eric-tan-99x99@2x.png", + "quoteAuthorJobTitle": "CIO & Chief Security Officer at Flock Safety", + "productCategories": [ + "Device management", + "Endpoint operations" + ], + "imageHeight": 132 + } + ], + "openPositions": [ + { + "jobTitle": "🚀 Software Engineer", + "url": "/handbook/company/open-positions/software-engineer" + }, + { + "jobTitle": "🐋 Account Executive", + "url": "/handbook/company/open-positions/account-executive" + } + ], + "compiledPagePartialsAppPath": "views/partials/built-from-markdown" } } From a17ab39ab6d39fecf510194f61f1cf0caae465ba Mon Sep 17 00:00:00 2001 From: Rebecca Cowart Date: Fri, 20 Sep 2024 15:57:13 -0400 Subject: [PATCH 32/81] Update button name in deploy-fleet.md (#22271) Render changed their "Apply" button to read "Deploy Blueprint" --- docs/Deploy/deploy-fleet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Deploy/deploy-fleet.md b/docs/Deploy/deploy-fleet.md index ee5299bfc378..5f1355b80b35 100644 --- a/docs/Deploy/deploy-fleet.md +++ b/docs/Deploy/deploy-fleet.md @@ -47,7 +47,7 @@ Render is a cloud hosting service that makes it easy to get up and running fast, 2. Give the Blueprint a unique name like `yourcompany-fleet`. -3. Click "**Apply.**" Render will provision your services, which should take less than five minutes. +3. Click "**Deploy Blueprint.**" Render will provision your services, which should take less than five minutes. 4. Click the "**Dashboard**" tab in Render when provisioning is complete to see your new services. From fc8b1d67f51fa317cd5c298075555999806f9f96 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Fri, 20 Sep 2024 16:00:01 -0400 Subject: [PATCH 33/81] Remove placeholder text (#22274) --------- Co-authored-by: RachelElysia --- .../AppleOSTargetForm/AppleOSTargetForm.tsx | 14 -------------- .../WindowsTargetForm/WindowsTargetForm.tsx | 2 -- 2 files changed, 16 deletions(-) diff --git a/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx b/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx index d3c35e3f604b..755b59d093a0 100644 --- a/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx +++ b/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx @@ -166,18 +166,6 @@ const AppleOSTargetForm = ({ setDeadline(val); }; - const getMinimumVersionPlaceholder = (platform: ApplePlatform) => { - switch (platform) { - case "darwin": - return "13.0.1"; - case "ios": - case "ipados": - return "17.5.1"; - default: - return ""; - } - }; - const getMinimumVersionTooltip = () => { return ( <> @@ -210,7 +198,6 @@ const AppleOSTargetForm = ({ label="Minimum version" tooltip={getMinimumVersionTooltip()} helpText="Version number only (e.g., “13.0.1” not “Ventura 13” or “13.0.1 (22A400)”)" - placeholder={getMinimumVersionPlaceholder(applePlatform)} value={minOsVersion} error={minOsVersionError} onChange={handleMinVersionChange} @@ -219,7 +206,6 @@ const AppleOSTargetForm = ({ label="Deadline" tooltip={getDeadlineTooltip(applePlatform)} helpText="YYYY-MM-DD format only (e.g., “2024-07-01”)." - placeholder="2024-07-01" value={deadline} error={deadlineError} onChange={handleDeadlineChange} diff --git a/frontend/pages/ManageControlsPage/OSUpdates/components/WindowsTargetForm/WindowsTargetForm.tsx b/frontend/pages/ManageControlsPage/OSUpdates/components/WindowsTargetForm/WindowsTargetForm.tsx index ec7007a29e0b..7addf342e3a8 100644 --- a/frontend/pages/ManageControlsPage/OSUpdates/components/WindowsTargetForm/WindowsTargetForm.tsx +++ b/frontend/pages/ManageControlsPage/OSUpdates/components/WindowsTargetForm/WindowsTargetForm.tsx @@ -158,7 +158,6 @@ const WindowsTargetForm = ({ label="Deadline" tooltip="Number of days the end user has before updates are installed and the host is forced to restart." helpText="Number of days from 0 to 30." - placeholder="5" value={deadlineDays} error={deadlineDaysError} onChange={handleDeadlineDaysChange} @@ -167,7 +166,6 @@ const WindowsTargetForm = ({ label="Grace period" tooltip="Number of days after the deadline the end user has before the host is forced to restart (only if end user was offline when deadline passed)." helpText="Number of days from 0 to 7." - placeholder="2" value={gracePeriodDays} error={gracePeriodDaysError} onChange={handleGracePeriodDays} From d7594d1f1d156bbe7d4046f2e3afba670dc66583 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:19:43 -0700 Subject: [PATCH 34/81] Fleet UI: Disable install/uninstall actions if scripts are disabled (#22240) --- .../HostActionsDropdown/helpers.tsx | 59 +++++++------ .../HostDetailsPage/HostDetailsPage.tsx | 1 + .../details/cards/Software/HostSoftware.tsx | 4 + .../HostSoftwareTableConfig.tests.tsx | 83 +++++++++++++++++++ .../Software/HostSoftwareTableConfig.tsx | 49 +++++++---- 5 files changed, 156 insertions(+), 40 deletions(-) create mode 100644 frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx index 3665687d0353..5590846c9e49 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx +++ b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx @@ -282,6 +282,36 @@ const removeUnavailableOptions = ( return options; }; +// Available tooltips for disabled options +export const getDropdownOptionTooltipContent = ( + value: string | number, + isHostOnline?: boolean +) => { + const tooltipAction: Record = { + runScript: "run scripts on", + wipe: "wipe", + lock: "lock", + unlock: "unlock", + installSoftware: "install software on", // Host software dropdown option + uninstallSoftware: "uninstall software on", // Host software dropdown option + }; + if (tooltipAction[value]) { + return ( + <> + To {tooltipAction[value]} this host, deploy the +
+ fleetd agent with --enable-scripts and +
+ refetch host vitals + + ); + } + if (!isHostOnline && value === "query") { + return <>You can't query an offline host.; + } + return undefined; +}; + const modifyOptions = ( options: IDropdownOption[], { @@ -291,34 +321,13 @@ const modifyOptions = ( hostPlatform, }: IHostActionConfigOptions ) => { - // Available tooltips for disabled options - const getDropdownOptionTooltipContent = (value: string | number) => { - const tooltipAction: Record = { - runScript: "run scripts on", - wipe: "wipe", - lock: "lock", - unlock: "unlock", - }; - if (tooltipAction[value]) { - return ( - <> - To {tooltipAction[value]} this host, deploy the -
- fleetd agent with --enable-scripts and -
- refetch host vitals - - ); - } - if (!isHostOnline && value === "query") { - return <>You can't query an offline host.; - } - }; - const disableOptions = (optionsToDisable: IDropdownOption[]) => { optionsToDisable.forEach((option) => { option.disabled = true; - option.tooltipContent = getDropdownOptionTooltipContent(option.value); + option.tooltipContent = getDropdownOptionTooltipContent( + option.value, + isHostOnline + ); }); }; diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx index 5c627edb9a62..0c56d7c6ca4d 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx +++ b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx @@ -946,6 +946,7 @@ const HostDetailsPage = ({ platform={host.platform} softwareUpdatedAt={host.software_updated_at} hostCanWriteSoftware={!!host.orbit_version || isIosOrIpadosHost} + hostScriptsEnabled={host.scripts_enabled || false} isSoftwareEnabled={featuresConfig?.enable_software_inventory} router={router} queryParams={parseHostSoftwareQueryParams(location.query)} diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx index 818fbcd7d989..1853d0aeee34 100644 --- a/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx +++ b/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx @@ -44,6 +44,7 @@ interface IHostSoftwareProps { hostTeamId: number; onShowSoftwareDetails?: (software: IHostSoftware) => void; isSoftwareEnabled?: boolean; + hostScriptsEnabled?: boolean; isMyDevicePage?: boolean; } @@ -87,6 +88,7 @@ const HostSoftware = ({ platform, softwareUpdatedAt, hostCanWriteSoftware, + hostScriptsEnabled, router, queryParams, pathname, @@ -249,6 +251,7 @@ const HostSoftware = ({ router, softwareIdActionPending, userHasSWWritePermission, + hostScriptsEnabled, onSelectAction, teamId: hostTeamId, hostCanWriteSoftware, @@ -258,6 +261,7 @@ const HostSoftware = ({ router, softwareIdActionPending, userHasSWWritePermission, + hostScriptsEnabled, onSelectAction, hostTeamId, hostCanWriteSoftware, diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx new file mode 100644 index 000000000000..aa14172c86f8 --- /dev/null +++ b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx @@ -0,0 +1,83 @@ +import { + generateActions, + DEFAULT_ACTION_OPTIONS, + generateActionsProps, +} from "./HostSoftwareTableConfig"; + +describe("generateActions", () => { + const defaultProps: generateActionsProps = { + userHasSWWritePermission: true, + hostScriptsEnabled: true, + hostCanWriteSoftware: true, + softwareIdActionPending: null, + softwareId: 1, + status: null, + software_package: null, + app_store_app: null, + }; + + it("returns default actions when user has write permission and scripts are enabled", () => { + const actions = generateActions(defaultProps); + expect(actions).toEqual(DEFAULT_ACTION_OPTIONS); + }); + + it("removes install and uninstall actions when user has no write permission", () => { + const props = { ...defaultProps, userHasSWWritePermission: false }; + const actions = generateActions(props); + expect(actions.find((a) => a.value === "install")).toBeUndefined(); + expect(actions.find((a) => a.value === "uninstall")).toBeUndefined(); + }); + + it("disables install and uninstall actions when host scripts are disabled", () => { + const props = { ...defaultProps, hostScriptsEnabled: false }; + const actions = generateActions(props); + expect(actions.find((a) => a.value === "install")?.disabled).toBe(true); + expect(actions.find((a) => a.value === "uninstall")?.disabled).toBe(true); + }); + + it("disables install and uninstall actions when locally pending (waiting for API response)", () => { + const props = { + ...defaultProps, + softwareIdActionPending: 1, + softwareId: 1, + }; + const actions = generateActions(props); + expect(actions.find((a) => a.value === "install")?.disabled).toBe(true); + expect(actions.find((a) => a.value === "uninstall")?.disabled).toBe(true); + }); + + it("disables install and uninstall actions when pending install status", () => { + const props: generateActionsProps = { + ...defaultProps, + status: "pending_install", + }; + const actions = generateActions(props); + expect(actions.find((a) => a.value === "install")?.disabled).toBe(true); + expect(actions.find((a) => a.value === "uninstall")?.disabled).toBe(true); + }); + + it("disables install and uninstall actions when pending uninstall status", () => { + const props: generateActionsProps = { + ...defaultProps, + status: "pending_uninstall", + }; + const actions = generateActions(props); + expect(actions.find((a) => a.value === "install")?.disabled).toBe(true); + expect(actions.find((a) => a.value === "uninstall")?.disabled).toBe(true); + }); + + it("removes uninstall action for VPP apps", () => { + const props: generateActionsProps = { + ...defaultProps, + app_store_app: { + app_store_id: "1", + self_service: false, + icon_url: "", + version: "", + last_install: { command_uuid: "", installed_at: "" }, + }, + }; + const actions = generateActions(props); + expect(actions.find((a) => a.value === "uninstall")).toBeUndefined(); + }); +}); diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx index dd4aef833e74..53256f50bffb 100644 --- a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx +++ b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx @@ -29,8 +29,9 @@ import VersionCell from "pages/SoftwarePage/components/VersionCell"; import { getVulnerabilities } from "pages/SoftwarePage/SoftwareTitles/SoftwareTable/SoftwareTitlesTableConfig"; import InstallStatusCell from "./InstallStatusCell"; +import { getDropdownOptionTooltipContent } from "../../HostDetailsPage/HostActionsDropdown/helpers"; -const DEFAULT_ACTION_OPTIONS: IDropdownOption[] = [ +export const DEFAULT_ACTION_OPTIONS: IDropdownOption[] = [ { value: "showDetails", label: "Show details", disabled: false }, { value: "install", label: "Install", disabled: false }, { value: "uninstall", label: "Uninstall", disabled: false }, @@ -50,24 +51,25 @@ type IInstalledVersionsCellProps = CellProps< >; type IVulnerabilitiesCellProps = IInstalledVersionsCellProps; -const generateActions = ({ - userHasSWWritePermission, - // Commenting below in case there is a quick decision to use these conditions after all - // hostCanWriteSoftware, - // software_package, - softwareIdActionPending, - softwareId, - status, - app_store_app, -}: { +export interface generateActionsProps { userHasSWWritePermission: boolean; + hostScriptsEnabled: boolean; hostCanWriteSoftware: boolean; softwareIdActionPending: number | null; softwareId: number; status: SoftwareInstallStatus | null; software_package: IHostSoftwarePackage | null; app_store_app: IHostAppStoreApp | null; -}) => { +} + +export const generateActions = ({ + userHasSWWritePermission, + hostScriptsEnabled, + softwareIdActionPending, + softwareId, + status, + app_store_app, +}: generateActionsProps) => { // this gives us a clean slate of the default actions so we can modify // the options. const actions = cloneDeep(DEFAULT_ACTION_OPTIONS); @@ -88,15 +90,29 @@ const generateActions = ({ } if (!userHasSWWritePermission) { - actions.splice(indexInstallAction, 1); + // Reverse order to not change index of subsequent array element before removal actions.splice(indexUninstallAction, 1); + actions.splice(indexInstallAction, 1); } else { + // if host's scripts are disabled, disable install/uninstall with tooltip + if (!hostScriptsEnabled) { + actions[indexInstallAction].disabled = true; + actions[indexUninstallAction].disabled = true; + + actions[ + indexInstallAction + ].tooltipContent = getDropdownOptionTooltipContent("installSoftware"); + actions[ + indexUninstallAction + ].tooltipContent = getDropdownOptionTooltipContent("uninstallSoftware"); + } + // user has software write permission for host const pendingStatuses = ["pending_install", "pending_uninstall"]; + // if locally pending (waiting for API response) or pending install/uninstall, + // disable both install and uninstall if ( - // if locally pending (waiting for API response) or pending install/uninstall, disable both - // install and uninstall softwareId === softwareIdActionPending || pendingStatuses.includes(status || "") ) { @@ -114,6 +130,7 @@ const generateActions = ({ interface ISoftwareTableHeadersProps { userHasSWWritePermission: boolean; + hostScriptsEnabled?: boolean; hostCanWriteSoftware: boolean; softwareIdActionPending: number | null; router: InjectedRouter; @@ -125,6 +142,7 @@ interface ISoftwareTableHeadersProps { // more info here https://react-table.tanstack.com/docs/api/useTable#cell-properties export const generateSoftwareTableHeaders = ({ userHasSWWritePermission, + hostScriptsEnabled = false, hostCanWriteSoftware, softwareIdActionPending, router, @@ -217,6 +235,7 @@ export const generateSoftwareTableHeaders = ({ placeholder="Actions" options={generateActions({ userHasSWWritePermission, + hostScriptsEnabled, hostCanWriteSoftware, softwareIdActionPending, softwareId, From ff62f9820f149a1f43c928d2efd1e0a088008256 Mon Sep 17 00:00:00 2001 From: Rachael Shaw Date: Fri, 20 Sep 2024 18:03:50 -0500 Subject: [PATCH 35/81] Update rest-api.md --- docs/REST API/rest-api.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/REST API/rest-api.md b/docs/REST API/rest-api.md index c160aac679ff..ab1e8d36cd53 100644 --- a/docs/REST API/rest-api.md +++ b/docs/REST API/rest-api.md @@ -1695,6 +1695,7 @@ _Available in Fleet Premium._ | ipados_updates | object | See [`mdm.ipados_updates`](#mdm-ipados-updates). | | windows_updates | object | See [`mdm.window_updates`](#mdm-windows-updates). | | macos_migration | object | See [`mdm.macos_migration`](#mdm-macos-migration). | +| windows_migration | object | See [`mdm.windows_migration`](#mdm-windows-migration). | | macos_setup | object | See [`mdm.macos_setup`](#mdm-macos-setup). | | macos_settings | object | See [`mdm.macos_settings`](#mdm-macos-settings). | | windows_settings | object | See [`mdm.windows_settings`](#mdm-windows-settings). | @@ -1765,6 +1766,16 @@ _Available in Fleet Premium._ | mode | string | The end user migration workflow mode for devices migrating from your old MDM solution. Options are `"voluntary"` or `"forced"`. | | webhook_url | string | The webhook url configured to receive requests to unenroll devices migrating from your old MDM solution. | +##### mdm.windows_migration + +_Available in Fleet Premium._ + +`mdm.windows_migration` is an object with the following structure: + +| Name | Type | Description | +| --------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| enable | boolean | Whether to enable automatic migration via fleetd for devices migrating from your old MDM solution. | +
##### mdm.macos_setup From b26c592143587db3c6bf1364e9ef3d8c2e2faad9 Mon Sep 17 00:00:00 2001 From: Rachael Shaw Date: Sun, 22 Sep 2024 15:18:01 -0500 Subject: [PATCH 36/81] Handbook: Update drafting steps (#22286) - Update where to make reference doc PRs (use reference doc release branch) - Point toward story issue template re: what to link to in issues (since it's always evolving) --- handbook/product-design/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/handbook/product-design/README.md b/handbook/product-design/README.md index 3a269485f8b6..6034f6296fab 100644 --- a/handbook/product-design/README.md +++ b/handbook/product-design/README.md @@ -36,9 +36,9 @@ At Fleet, like [GitLab](https://about.gitlab.com/handbook/product-development-fl - **Ready.** Use this page to communicate designs reviews and development. - **Scratchpad.** Use this page for work in progress and design that might be useful in the future. -- If the story requires API or YAML file changes, open a draft PR with the proposed design. +- If the story requires API or YAML file changes, open a pull request to the reference docs release branch (e.g. `docs-v4.58.0`) with the proposed design. Mark the PR ready for review as soon as it's ready for feedback from the [API design DRI](https://fleetdm.com/handbook/company/communications#directly-responsible-individuals-dris). -- Add links to the Figma file's cover page and draft PRs in the user story. +- Add links to the user story as specified in the [issue template](https://github.com/fleetdm/fleet/issues/new?template=story.md). - Draft changes to the Fleet product that solve the problem specified in the story. Constantly place yourself in the shoes of a user while drafting changes. Place these drafts in the appropriate Figma file in Fleet product project. From 2d90b7f35b511d652c9ea938ef99d96c084f3d66 Mon Sep 17 00:00:00 2001 From: Rachael Shaw Date: Sun, 22 Sep 2024 15:18:23 -0500 Subject: [PATCH 37/81] Update product-design.rituals.yml (#22285) Create the reference docs release branch as part of product design sprint kickoff (This will help make sure everyone's on the same page re: which branch to make API design PRs to) --- handbook/product-design/product-design.rituals.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handbook/product-design/product-design.rituals.yml b/handbook/product-design/product-design.rituals.yml index d9225ce778ff..b32f5406fe06 100644 --- a/handbook/product-design/product-design.rituals.yml +++ b/handbook/product-design/product-design.rituals.yml @@ -16,7 +16,7 @@ task: "Design sprint kickoff" # 2024-03-06 TODO: Link to responsibility or corresponding "how to" info e.g. https://fleetdm.com/handbook/company/product-groups#making-changes startedOn: "2024-03-07" frequency: "Triweekly" - description: "Add stories prioritized during Feature fest to Drafting board, assign stories to product designers, and align on priorities." + description: "Add stories prioritized during Feature fest to Drafting board, assign stories to product designers, create upcoming reference docs release branch, and align on priorities." moreInfoUrl: dri: "noahtalerman" - From 85a8cb9b6b1287507dca824fbc529268830adc3e Mon Sep 17 00:00:00 2001 From: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> Date: Sun, 22 Sep 2024 15:23:51 -0500 Subject: [PATCH 38/81] Clarify empty space formatting (#22294) --- handbook/company/communications.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/handbook/company/communications.md b/handbook/company/communications.md index 271c2e3f19ae..c83524ee6693 100644 --- a/handbook/company/communications.md +++ b/handbook/company/communications.md @@ -1359,10 +1359,10 @@ Each heading needs two lines of empty space separating it from the previous sect ``` ...previous content. - - + + ### New heading - + Related content... ``` From 6d9eb8d73efc526bf137467e1c3bbb97661386e7 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Sun, 22 Sep 2024 23:01:27 -0400 Subject: [PATCH 39/81] Clean up Product Design responsibilities (#22282) Product Design doesn't have these responsibilities anymore - Bugs go straight to the release board - I think @spokanemac ranks features after the "Sprint-kickoff review" and is DRI for the release article - We use [experimental features](https://fleetdm.com/handbook/company/product-groups#experimental-features) instead of "beta" features --- handbook/product-design/README.md | 59 ------------------------------- 1 file changed, 59 deletions(-) diff --git a/handbook/product-design/README.md b/handbook/product-design/README.md index 6034f6296fab..2044bde60c80 100644 --- a/handbook/product-design/README.md +++ b/handbook/product-design/README.md @@ -97,28 +97,6 @@ What happens during expedited drafting? 5. UI changes [are approved](https://fleetdm.com/handbook/company/development-groups#drafting-process), and the UI changes are brought back into the sprint or are estimated. -### Correctly prioritize a bug - -Bugs are always prioritized. (Fleet takes quality and stability [very seriously](https://fleetdm.com/handbook/company/why-this-way#why-spend-so-much-energy-responding-to-every-potential-production-incident).) Bugs should be prioritized in the following order: -1. Quality: product does what it's supposed to (what is documented). -2. Common-sense user criticality: If no one can load any page, that's obviously important. -3. Age of bugs: Long-open bugs are open wounds bleeding quality out of the product. They must be closed quickly. -4. Customer criticality: How important it is to a customer use case. - - -If a bug is unreleased or [critical](https://fleetdm.com/handbook/engineering#critical-bugs), it is addressed in the current sprint. Otherwise, it may be prioritized and estimated for the next sprint. If a bug [requires drafting](https://fleetdm.com/handbook/engineering#in-product-drafting-as-needed) to determine the expected functionality, the bug should undergo [expedited drafting](#expedited-drafting). - -If a bug is not addressed within six weeks, it is [sent to the product team for triage](https://fleetdm.com/handbook/engineering#in-engineering). Each sprint, the Head of Product Design reviews these bugs. Bugs are categorized as follows: -- **Schedule**: the bug should be prioritized in the next sprint if there's engineering capacity for it. -- **De-prioritized**: the issue will be closed and the necessary subsequent steps will be initiated. This might include updating documentation and informing the community. - -The Head of Product Design meets with the Director of Product Development to discuss and finalize the outcomes for the churned bugs. - -After aligning with the Director of Product Development on the outcomes, The Head of Product Design will clean up churned bugs. Below are the steps for each category: -- **Schedule**: Remove the `:product` label, move the bug ticket to the 'Sprint backlog' column on the bug board, and assign it to the appropriate group's Engineering Manager so that it can be prioritized into the sprint backlog. -- **De-prioritized**: The Head of Product Design should close the issue and, as the DRI, ensure all follow-up actions are finalized. - - ### Write a user story Product Managers [write user stories](https://fleetdm.com/handbook/company/product-groups#writing-a-good-user-story) in the [drafting board](https://app.zenhub.com/workspaces/-product-backlog-coming-soon-6192dd66ea2562000faea25c/board). The drafting board is shared by every [product group](https://fleetdm.com/handbook/company/development-groups). @@ -133,26 +111,6 @@ If an issue's title or user story summary (_"as a…I want to…so that"_) does Engineering Managers estimate user stories. They are responsible for delivering planned work in the current sprint (0-3 weeks) while quickly getting user stories estimated for the next sprint (3-6 weeks). Only work that is slated to be released into the hands of users within ≤six weeks will be estimated. Estimation is run by each group's Engineering Manager and occurs on the [drafting board](https://app.zenhub.com/workspaces/-product-backlog-coming-soon-6192dd66ea2562000faea25c/board). -### Rank features before release - -These measures exist to keep all contributors (including other departments besides engineering and product) up to date with improvements and changes to the Fleet product. This helps folks plan and communicate with customers and users more effectively. - -After the kickoff of a product sprint, the demand and product teams decide which improvements are most important to highlight in this release, whether that's through social media "drumbeat" tweets, collaboration with partners, or emphasized [content blocks](https://about.gitlab.com/handbook/marketing/blog/release-posts/#3rd-to-10th) within the release blog post. - -When an improvement gets scheduled for release, the Head of Product sets its "echelon" to determine the emphasis the company will place on it. This leveling is based on the improvement's desirability and timeliness, and will affect demand effort for the feature. - -- **Echelon 1: A major product feature announcement.** The most important release types, these require a specific and custom demand package. Usually including an individual blog post, a demo video and potentially a press release or official product demand launch. There is a maximum of one _echelon 1_ product announcement per release sprint. -- **Echelon 2: A highlighted feature in the release notes.** This product feature will be highlighted at the top of the Sprint Release blog post. Depending on the feature specifics this will include: a 1-2 paragraph write-up of the feature, a demo video (if applicable) and a link to the docs. Ideally there would be no more than three _echelon 2_ features in a release post, otherwise the top features will be crowded. -- **Echelon 3: A notable feature to mention in the [changelog](https://github.com/fleetdm/fleet/blob/main/CHANGELOG.md)**. Most product improvements fit into this echelon. This includes 1-2 sentences in the changelog and [release blog post](https://fleetdm.com/releases). - - -### Create release issue - -Before each release, the Head of Product [creates a "Release" issue](https://github.com/fleetdm/confidential/issues/new/choose), which includes a list of all improvements included in the upcoming release. Each improvement links to the relevant bug or user story issue on GitHub so it is easy to read the related discussion and history. - -The product team is responsible for providing the demand team with the necessary information for writing the release blog post. Every three weeks after the sprint is kicked off, the product team meets with the relevant demand team members to go over the features for that sprint and recommend items to highlight as _echelon 2_ features and provide relevant context for other features to help demand decide which features to highlight. - - ### Consider a feature eligible to be flagged At Fleet, features are placed behind feature flags if the changes could affect Fleet's availability of existing functionalities. The following highlights should be considered when deciding if we should leverage feature flags: @@ -167,20 +125,6 @@ At Fleet, features are placed behind feature flags if the changes could affect F > Fleet's feature flag guidelines is borrowed from GitLab's ["When to use feature flags" section](https://about.gitlab.com/handbook/product-development-flow/feature-flag-lifecycle/#when-to-use-feature-flags) of their handbook. Check out [GitLab's "Feature flags only when needed" video](https://www.youtube.com/watch?v=DQaGqyolOd8) for an explanation of the costs of introducing feature flags. -### Consider promoting a feature as "beta" - -At Fleet, features are advertised as "beta" if there are concerns that the feature may not work as intended in certain Fleet -deployments. For example, these concerns could be related to the feature's performance in Fleet -deployments with hundreds of thousands of hosts. - -The following highlights should be considered when deciding if we promote a feature as "beta:" - -- The feature will not be advertised as "beta" permanently. This means that the Directly - Responsible Individual (DRI) who decides a feature is advertised as "beta" is also responsible for creating an issue that - explains why the feature is advertised as "beta" and tracking the feature's progress towards advertising the feature as "stable." -- The feature will be advertised as "beta" in the documentation on fleetdm.com/docs, release notes, release blog posts, and Twitter. - - ### View Fleet usage statistics In order to understand the usage of the Fleet product, we [collect statistics](https://fleetdm.com/docs/using-fleet/usage-statistics) from installations where this functionality is enabled. @@ -276,9 +220,6 @@ Please see [handbook/product#create-release-issue](https://fleetdm.com/handbook/ ##### Feature flags Please see [handbook/product#consider-a-feature-eligible-to-be-flagged](https://fleetdm.com/handbook/product#consider-a-feature-eligible-to-be-flagged) -##### Beta features -Please see [handbook/product#consider-promoting-a-feature-as-beta](https://fleetdm.com/handbook/product#consider-promoting-a-feature-as-beta) - ##### Feature fest Please see [handbook/product-groups#feature-fest](https://fleetdm.com/handbook/product-groups#feature-fest) From b5fcaa73dcf46f738ccea124188a4eb413f34d53 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Sun, 22 Sep 2024 23:01:53 -0400 Subject: [PATCH 40/81] Update story template (#22280) - Reminder to use the reference docs branch instead of `main` (also no more draft PRs) --- .github/ISSUE_TEMPLATE/story.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/story.md b/.github/ISSUE_TEMPLATE/story.md index 052d25c7d6d6..bc76e169c1e4 100644 --- a/.github/ISSUE_TEMPLATE/story.md +++ b/.github/ISSUE_TEMPLATE/story.md @@ -32,15 +32,15 @@ What else should contributors [keep in mind](https://fleetdm.com/handbook/compan ## Changes ### Product -- [ ] Reference documentation changes: TODO - [ ] UI changes: TODO - [ ] CLI (fleetctl) usage changes: TODO -- [ ] YAML changes: TODO -- [ ] REST API changes: TODO +- [ ] YAML changes: TODO +- [ ] REST API changes: TODO - [ ] Fleet's agent (fleetd) changes: TODO - [ ] Activity changes: TODO -- [ ] Permissions changes: TODO -- [ ] Changes to paid features or tiers: TODO +- [ ] Permissions changes: TODO +- [ ] Changes to paid features or tiers: TODO +- [ ] Other reference documentation changes: TODO - [ ] Once shipped, requester has been notified ### Engineering From 66a9fb21111674e89bcb0e1a5f8d08613107c34a Mon Sep 17 00:00:00 2001 From: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> Date: Mon, 23 Sep 2024 00:23:02 -0500 Subject: [PATCH 41/81] Update hiring steps (#22296) --- handbook/company/leadership.md | 48 ++++------------------------------ 1 file changed, 5 insertions(+), 43 deletions(-) diff --git a/handbook/company/leadership.md b/handbook/company/leadership.md index 05097bf552f6..d89b81639f1a 100644 --- a/handbook/company/leadership.md +++ b/handbook/company/leadership.md @@ -360,54 +360,16 @@ After receiving the interview packet, the Head of Digital Experience uses the fo 4. **Send offer:** 🐈‍⬛ CEO reviews and sends the offer to the candidate: - _Grant the candidate "edit" access_ to their "exit scenarios" spreadsheet. - _Send_ the email. +5. **Process the offer response** The Head of Digital Experience will process the offer response by either creating a new ["Teammate pre-onboarding" issue](https://github.com/fleetdm/confidential/issues/new?assignees=&labels=%23g-digital-experience&projects=&template=pre-onboarding.md&title=Pre-onboarding%3A+______________________) and following the steps if the offer is accepted or notifying the stakeholders that the offer was not accepted and we should continue the search. -#### Steps after an offer is accepted -Once the new team member replies and accepts their offer in writing, 🌐 Head of Digital Experience follows these steps: -1. **Verify, track, and reply:** Reply to the candidate: - - _Verify the candidate replied with their physical address… or else keep asking._ If they did not reply with their physical address, then we are not done. No offer is "accepted" until we've received a physical address. - - _Review and update the team database_ to be sure everything is accurate, **one last time**. Remember to read the column headers and precisely follow the instructions about how to format the data: - - The new team member's role in ["🧑‍🚀 Fleeties"](https://docs.google.com/spreadsheets/d/1OSLn-ZCbGSjPusHPiR5dwQhheH1K8-xqyZdsOe9y7qc/edit#gid=0) now includes: - - **Start date** _(The new fleetie's first day, YYYY-MM-DD)_ - - **Location** _(Derive this from the physical address)_ - - **GitHub username** _(Username of 2FA-enabled GitHub account)_ - - **@fleetdm.com email** _(Set this to whatever email you think this person should have)_ - - The new team member's row in ["🥧 Equity plan"](https://docs.google.com/spreadsheets/d/1_GJlqnWWIQBiZFOoyl9YbTr72bg5qdSSp4O3kuKm1Jc/edit#gid=0) now includes: - - **OTE** _("On-target earnings", i.e. anticipated total annual cash compensation)_ - - **Equity** _(Stock options)_ - - **"Notes"** _(Track base salary here, as well as a very short explanation of commission or bonus structure.)_ - - **Physical address** _(The full street address of the location where work will typically be performed.)_ - - **Personal email** _(Use the personal email they're replying from, e.g. `@gmail.com`)_ - - **"Offer accepted?"** _(Set this to `TRUE`)_ - - _[Create a "Hiring" issue](https://github.com/fleetdm/confidential/issues/new/choose)_ for the new team member. (This issue will keep track of the hiring tasks for the new team member.) - - _Send a reply_ welcoming the team member to Fleet and letting them know to expect a separate email with next steps for getting the team member's laptop, Yubikeys, and agreement going ASAP so they can start on time. For example: +#### After an offer is accepted - ``` - \o/ It's official! - - Be on the lookout for an email in a separate thread with next steps for quickly signing the paperwork and getting your company laptop and hardware 2FA keys (Yubikeys), which we recommend setting up ASAP. - - Thanks, and welcome to the team! - - Cheers, - Sam - ``` - -2. **Ask hiring manager to send rejections:** Post to the `hiring-xxxxx-yyyy` Slack channel to let folks know the offer was accepted, and at-mention the _hiring manager_ using the following template: - -``` -@HIRING_MANAGER, :astronaut: TEAM_MEMBER_NAME has accepted the offer :fleet: and this position is now filled :white_check_mark:. Please inform any other interviewees who are still in the running and let them know that we chose a different person. :thankyou-ty: -``` - -3. **Close Slack channel:** Then archive the channel. +The Head of Digital Experience will then follow the steps in the ["Teammate pre-onboarding"](https://github.com/fleetdm/confidential/issues/new?assignees=&labels=%23g-digital-experience&projects=&template=pre-onboarding.md&title=Pre-onboarding%3A+______________________) issue, which includes reaching out to the new team member within 1 business day from a separate email thread to get additional information as needed, prepare their agreement, add them to the company's payroll system, and get their new laptop and hardware security keys ordered so that everything is ready for them to start on their first day. - >_**Note:** Send rejection emails quickly, within 1 business day. It only gets harder if you wait._ -4. **Remove open position:** Ensure the hiring manager removes the newly-filled position from the fleetdm.com website by [making a pull request](https://fleetdm.com/handbook/company/communications#making-a-pull-request) to delete it from the [open-positions.yml](https://github.com/fleetdm/fleet/blob/main/handbook/company/open-positions.yml) file. -5. **Create 30-60-90 day plan:** 🧑‍🚀 Hiring manager creates a 30-60-90 day plan outlining key role objectives. The plan is reviewed weekly in 1:1 meetings during the first three months of employment, ensuring continuous support and alignment with company goals. To create the 30-60-90 day plan, hiring manager will: - - Create a copy of the [30-60-90 day plan template](https://docs.google.com/document/d/1EztmPBuMFXbVoy4ZToXcxasNO38ooOh8Gh5hPXFvJhI/copy) and rename the copied file using the naming convention `[start date] - 30-60-90 day plan - [teammate full name]` and move it to the [30-60-90 day plan folder](https://drive.google.com/drive/u/0/folders/1QWiAbgBFuuofT_3M8oIoBsbEBmubQAj7) in Google Drive. - - Follow the prompts in the template to fill out the 30-60-90 day plan for the new teammate before they start. +## Create a 30-60-90 day plan -Now what happens? 🌐 Head of Digital Experience will then follow the steps in the "Hiring" issue, which includes reaching out to the new team member within 1 business day from a separate email thread to get additional information as needed, prepare their agreement, add them to the company's payroll system, and get their new laptop and hardware security keys ordered so that everything is ready for them to start on their first day. +The hiring manager creates a 30-60-90 day plan outlining key role objectives to be reviewed in 1:1 meetings during the first three months of employment. To create the 30-60-90 day plan, use the prompts in the "Vision" section of the new teammates [1:1 meeting doc (TEMPLATE)](https://docs.google.com/document/d/1IkGQJ4PPU0MyW35Xo8BuvoUPKpStsmcw_nHWt71W2yE/edit#heading=h.uzxntzlyyaou) to ensure continuous support and alignment with company goals. ## CEO shadow program From 2ce2b806015b86cb7555aba1e618e9ea98cb2044 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 06:56:37 -0300 Subject: [PATCH 42/81] Update versions of fleetd components in Fleet's TUF [automated] (#22289) Automated change from [GitHub action](https://github.com/fleetdm/fleet/actions/workflows/fleetd-tuf.yml). Co-authored-by: lucasmrod --- orbit/TUF.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/orbit/TUF.md b/orbit/TUF.md index 727e5f34b60d..64cd1cb9f2b3 100644 --- a/orbit/TUF.md +++ b/orbit/TUF.md @@ -18,8 +18,8 @@ Following are the currently deployed versions of fleetd components on the `stabl | Component\OS | macOS | Linux | Windows | Linux (arm64) | |--------------|--------|--------|---------|---------------| -| orbit | 1.32.0 | 1.32.0 | 1.32.0 | 1.32.0 | -| desktop | 1.32.0 | 1.32.0 | 1.32.0 | 1.32.0 | +| orbit | 1.33.0 | 1.33.0 | 1.33.0 | 1.33.0 | +| desktop | 1.33.0 | 1.33.0 | 1.33.0 | 1.33.0 | | osqueryd | 5.13.1 | 5.13.1 | 5.13.1 | 5.13.1 | | nudge | - | - | - | - | | swiftDialog | - | - | - | - | From cbf563fb9b0a34353639784640d63fb4e27bba2d Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Mon, 23 Sep 2024 04:58:13 -0500 Subject: [PATCH 43/81] Use sync.Map for stubbed key-value store to avoid data races in GitOps test (#22292) This override only happens in testing, so this isn't release-blocking, but this is the quickest way to clean up a test that will otherwise be flaky due to data races, at the cost of performance (vs. setting up a more complex solution with mutexes). # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Added/updated tests - [x] Manual QA for all new/changed functionality (via manually running test using the KV store) --- cmd/fleetctl/gitops_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/fleetctl/gitops_test.go b/cmd/fleetctl/gitops_test.go index b93496155999..1a054482f618 100644 --- a/cmd/fleetctl/gitops_test.go +++ b/cmd/fleetctl/gitops_test.go @@ -10,6 +10,7 @@ import ( "path/filepath" "slices" "strings" + "sync" "testing" "time" @@ -2919,24 +2920,23 @@ software: } type memKeyValueStore struct { - m map[string]string + m sync.Map } func newMemKeyValueStore() *memKeyValueStore { - return &memKeyValueStore{ - m: make(map[string]string), - } + return &memKeyValueStore{} } func (m *memKeyValueStore) Set(ctx context.Context, key string, value string, expireTime time.Duration) error { - m.m[key] = value + m.m.Store(key, value) return nil } func (m *memKeyValueStore) Get(ctx context.Context, key string) (*string, error) { - v, ok := m.m[key] + v, ok := m.m.Load(key) if !ok { return nil, nil } - return &v, nil + vAsString := v.(string) + return &vAsString, nil } From e861ae7319a5ee3d065d215ce923925f7bd09137 Mon Sep 17 00:00:00 2001 From: Lucas Manuel Rodriguez Date: Mon, 23 Sep 2024 06:59:04 -0300 Subject: [PATCH 44/81] Release fleetd 1.33.0 (#22283) --- .github/workflows/generate-desktop-targets.yml | 7 +------ .github/workflows/goreleaser-orbit.yaml | 5 ----- orbit/CHANGELOG.md | 6 ++++++ orbit/changes/20320-uninstall-after-failed-post-install | 1 - orbit/changes/update-go1.23.1 | 2 -- 5 files changed, 7 insertions(+), 14 deletions(-) delete mode 100644 orbit/changes/20320-uninstall-after-failed-post-install delete mode 100644 orbit/changes/update-go1.23.1 diff --git a/.github/workflows/generate-desktop-targets.yml b/.github/workflows/generate-desktop-targets.yml index d7324c9bf0ba..93e5a30fcec3 100644 --- a/.github/workflows/generate-desktop-targets.yml +++ b/.github/workflows/generate-desktop-targets.yml @@ -13,18 +13,13 @@ on: - '.github/workflows/generate-desktop-targets.yml' workflow_dispatch: -# This allows a subsequently queued workflow run to interrupt previous runs -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id}} - cancel-in-progress: true - defaults: run: # fail-fast using bash -eo pipefail. See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference shell: bash env: - FLEET_DESKTOP_VERSION: 1.32.0 + FLEET_DESKTOP_VERSION: 1.33.0 permissions: contents: read diff --git a/.github/workflows/goreleaser-orbit.yaml b/.github/workflows/goreleaser-orbit.yaml index 54e16752b335..e196901ead56 100644 --- a/.github/workflows/goreleaser-orbit.yaml +++ b/.github/workflows/goreleaser-orbit.yaml @@ -5,11 +5,6 @@ on: tags: - "orbit-*" # For testing, use a pre-release tag like 'orbit-1.24.0-1' -# This allows a subsequently queued workflow run to interrupt previous runs -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id}} - cancel-in-progress: true - defaults: run: # fail-fast using bash -eo pipefail. See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference diff --git a/orbit/CHANGELOG.md b/orbit/CHANGELOG.md index 1d11365182eb..fa9efe36efeb 100644 --- a/orbit/CHANGELOG.md +++ b/orbit/CHANGELOG.md @@ -1,3 +1,9 @@ +## Orbit 1.33.0 (Sep 20, 2024) + +* Added support to run the configured uninstall script when installer's post-install script fails. + +* Updated Go to go1.23.1 + ## Orbit 1.32.0 (Aug 29, 2024) * Bumped macadmins extension to use SOFA feed sofafeed.macadmins.io diff --git a/orbit/changes/20320-uninstall-after-failed-post-install b/orbit/changes/20320-uninstall-after-failed-post-install deleted file mode 100644 index 5dd4d969729e..000000000000 --- a/orbit/changes/20320-uninstall-after-failed-post-install +++ /dev/null @@ -1 +0,0 @@ -During software install flow, if installer's post-install script fails, run the uninstall script to attempt to roll back. diff --git a/orbit/changes/update-go1.23.1 b/orbit/changes/update-go1.23.1 deleted file mode 100644 index d9a689e4e905..000000000000 --- a/orbit/changes/update-go1.23.1 +++ /dev/null @@ -1,2 +0,0 @@ -* Updated Go to go1.23.1 - From f83260a8f2374d8a7d6477894d88f0facede6fb7 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Mon, 23 Sep 2024 09:35:34 -0700 Subject: [PATCH 45/81] Fleet UI: Host details > about info uses less columns at small widths (#22257) --- changes/20683-less-columns-smaller-width | 1 + .../details/HostDetailsPage/_styles.scss | 5 -- frontend/pages/hosts/details/_styles.scss | 35 ------------- .../pages/hosts/details/cards/About/About.tsx | 4 +- .../hosts/details/cards/About/_styles.scss | 50 +++++++++++++++++++ 5 files changed, 53 insertions(+), 42 deletions(-) create mode 100644 changes/20683-less-columns-smaller-width diff --git a/changes/20683-less-columns-smaller-width b/changes/20683-less-columns-smaller-width new file mode 100644 index 000000000000..c2e03aedde0c --- /dev/null +++ b/changes/20683-less-columns-smaller-width @@ -0,0 +1 @@ +- UI cleanup: Host details about section condenses information into fewer columns at smaller widths diff --git a/frontend/pages/hosts/details/HostDetailsPage/_styles.scss b/frontend/pages/hosts/details/HostDetailsPage/_styles.scss index 3809916a6b4a..25f6e705f60d 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/_styles.scss +++ b/frontend/pages/hosts/details/HostDetailsPage/_styles.scss @@ -63,11 +63,6 @@ flex-direction: row; } } - &__block { - display: flex; - flex-direction: column; - margin-right: $pad-xxlarge; - } &__data { margin-bottom: $pad-medium; diff --git a/frontend/pages/hosts/details/_styles.scss b/frontend/pages/hosts/details/_styles.scss index e3f17951b7fc..f2ef26fe9d9a 100644 --- a/frontend/pages/hosts/details/_styles.scss +++ b/frontend/pages/hosts/details/_styles.scss @@ -21,41 +21,6 @@ margin: 0 0 $pad-medium 0; } - .info-grid { - display: grid; - grid-auto-flow: column; - grid-template-columns: repeat( - 3, - max-content - ); // Prevents overflow off screen - grid-template-rows: repeat(4, 1fr); - column-gap: $pad-xxlarge; - row-gap: $pad-medium; - - @media (min-width: $break-md) { - grid-template-columns: repeat(4, max-content); - grid-template-rows: repeat(3, 1fr); - } - - &__block { - font-size: $x-small; - display: flex; - flex-direction: column; - white-space: nowrap; - } - - &__data { - .device-mapping { - &__source { - color: $ui-fleet-black-75; - } - &__more { - color: $ui-fleet-black-50; - } - } - } - } - .list { list-style: none; padding: 0; diff --git a/frontend/pages/hosts/details/cards/About/About.tsx b/frontend/pages/hosts/details/cards/About/About.tsx index 94d1bdf36f66..f1667f890059 100644 --- a/frontend/pages/hosts/details/cards/About/About.tsx +++ b/frontend/pages/hosts/details/cards/About/About.tsx @@ -189,11 +189,11 @@ const About = ({

About

-
+
Date: Mon, 23 Sep 2024 13:37:58 -0300 Subject: [PATCH 46/81] Update versions of fleetd components in Fleet's TUF [automated] (#22305) Automated change from [GitHub action](https://github.com/fleetdm/fleet/actions/workflows/fleetd-tuf.yml). Co-authored-by: lucasmrod --- orbit/TUF.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/orbit/TUF.md b/orbit/TUF.md index 64cd1cb9f2b3..c022aa4a6527 100644 --- a/orbit/TUF.md +++ b/orbit/TUF.md @@ -7,8 +7,8 @@ Following are the currently deployed versions of fleetd components on the `stabl | Component\OS | macOS | Linux | Windows | Linux (arm64) | |--------------|--------------|--------|---------|---------------| -| orbit | 1.32.0 | 1.32.0 | 1.32.0 | 1.32.0 | -| desktop | 1.32.0 | 1.32.0 | 1.32.0 | 1.32.0 | +| orbit | 1.33.0 | 1.33.0 | 1.33.0 | 1.33.0 | +| desktop | 1.33.0 | 1.33.0 | 1.33.0 | 1.33.0 | | osqueryd | 5.13.1 | 5.13.1 | 5.13.1 | 5.13.1 | | nudge | 1.1.10.81462 | - | - | - | | swiftDialog | 2.1.0 | - | - | - | From 631dc6075da062a47869b99048c1c454484f3dbe Mon Sep 17 00:00:00 2001 From: Robert Fairburn <8029478+rfairburn@users.noreply.github.com> Date: Mon, 23 Sep 2024 13:28:23 -0500 Subject: [PATCH 47/81] add s3 installers to loadtest (#22306) --- infrastructure/loadtesting/terraform/ecs.tf | 18 ++++---- infrastructure/loadtesting/terraform/rds.tf | 8 ++-- infrastructure/loadtesting/terraform/s3.tf | 46 +++++++++++++++++++++ 3 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 infrastructure/loadtesting/terraform/s3.tf diff --git a/infrastructure/loadtesting/terraform/ecs.tf b/infrastructure/loadtesting/terraform/ecs.tf index cce392657a78..2327c2787b78 100644 --- a/infrastructure/loadtesting/terraform/ecs.tf +++ b/infrastructure/loadtesting/terraform/ecs.tf @@ -203,7 +203,11 @@ resource "aws_ecs_task_definition" "backend" { { name = "FLEET_OSQUERY_ASYNC_HOST_REDIS_SCAN_KEYS_COUNT" value = "10000" - } + }, + { + name = "FLEET_S3_SOFTWARE_INSTALLERS_BUCKET" + value = aws_s3_bucket.software_installers.bucket + }, ], local.additional_env_vars) } ]) @@ -329,18 +333,18 @@ resource "aws_appautoscaling_policy" "ecs_policy_cpu" { resource "random_password" "fleet_server_private_key" { length = 32 special = true -} - -resource "aws_secretsmanager_secret" "fleet_server_private_key" { +} + +resource "aws_secretsmanager_secret" "fleet_server_private_key" { name = "${terraform.workspace}-fleet-server-private-key" recovery_window_in_days = "0" lifecycle { create_before_destroy = true } -} - +} + resource "aws_secretsmanager_secret_version" "fleet_server_private_key" { secret_id = aws_secretsmanager_secret.fleet_server_private_key.id secret_string = random_password.fleet_server_private_key.result -} +} diff --git a/infrastructure/loadtesting/terraform/rds.tf b/infrastructure/loadtesting/terraform/rds.tf index 87dea8134898..b70d4de1cfca 100644 --- a/infrastructure/loadtesting/terraform/rds.tf +++ b/infrastructure/loadtesting/terraform/rds.tf @@ -26,10 +26,10 @@ module "aurora_mysql" { #tfsec:ignore:aws-rds-enable-performance-insights-encryp source = "terraform-aws-modules/rds-aurora/aws" version = "7.7.1" - name = "${local.name}-mysql" - engine = "aurora-mysql" - engine_version = "8.0.mysql_aurora.3.05.2" - instance_class = var.db_instance_type + name = "${local.name}-mysql" + engine = "aurora-mysql" + engine_version = "8.0.mysql_aurora.3.05.2" + instance_class = var.db_instance_type instances = { one = {} diff --git a/infrastructure/loadtesting/terraform/s3.tf b/infrastructure/loadtesting/terraform/s3.tf new file mode 100644 index 000000000000..ca15b37dba49 --- /dev/null +++ b/infrastructure/loadtesting/terraform/s3.tf @@ -0,0 +1,46 @@ +data "aws_iam_policy_document" "software_installers" { + statement { + actions = [ + "s3:GetObject*", + "s3:PutObject*", + "s3:ListBucket*", + "s3:ListMultipartUploadParts*", + "s3:DeleteObject", + "s3:CreateMultipartUpload", + "s3:AbortMultipartUpload", + "s3:ListMultipartUploadParts", + "s3:GetBucketLocation" + ] + resources = [aws_s3_bucket.software_installers.arn, "${aws_s3_bucket.software_installers.arn}/*"] + } +} + +resource "aws_iam_policy" "software_installers" { + policy = data.aws_iam_policy_document.software_installers.json +} + +resource "aws_iam_role_policy_attachment" "software_installers" { + policy_arn = aws_iam_policy.software_installers.arn + role = aws_iam_role.main.name +} + +resource "aws_s3_bucket" "software_installers" { #tfsec:ignore:aws-s3-encryption-customer-key:exp:2022-07-01 #tfsec:ignore:aws-s3-enable-versioning #tfsec:ignore:aws-s3-enable-bucket-logging:exp:2022-06-15 + bucket_prefix = terraform.workspace +} + +resource "aws_s3_bucket_server_side_encryption_configuration" "software_installers" { + bucket = aws_s3_bucket.software_installers.bucket + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "aws:kms" + } + } +} + +resource "aws_s3_bucket_public_access_block" "software_installers" { + bucket = aws_s3_bucket.software_installers.id + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} From 31633148ed842b519a58bcc353381e89f689775f Mon Sep 17 00:00:00 2001 From: Luke Heath Date: Mon, 23 Sep 2024 15:14:34 -0500 Subject: [PATCH 48/81] Fixed self-service checkbox appearing when iOS or iPadOS app is selected. (#22287) --- changes/21796-fix-vpp-self-service-checkbox | 1 + .../components/AppStoreVpp/AppStoreVpp.tsx | 40 +++++++++++++------ .../components/AppStoreVpp/helpers.tsx | 8 ++-- 3 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 changes/21796-fix-vpp-self-service-checkbox diff --git a/changes/21796-fix-vpp-self-service-checkbox b/changes/21796-fix-vpp-self-service-checkbox new file mode 100644 index 000000000000..6ec7e46db9c1 --- /dev/null +++ b/changes/21796-fix-vpp-self-service-checkbox @@ -0,0 +1 @@ +- Fixed self-service checkbox appearing when iOS or iPadOS app is selected. diff --git a/frontend/pages/SoftwarePage/components/AppStoreVpp/AppStoreVpp.tsx b/frontend/pages/SoftwarePage/components/AppStoreVpp/AppStoreVpp.tsx index ffde9220a271..12664495fe0e 100644 --- a/frontend/pages/SoftwarePage/components/AppStoreVpp/AppStoreVpp.tsx +++ b/frontend/pages/SoftwarePage/components/AppStoreVpp/AppStoreVpp.tsx @@ -177,6 +177,9 @@ const AppStoreVpp = ({ const onSelectApp = (app: IVppApp) => { setIsSubmitDisabled(false); setSelectedApp(app); + if (app.platform === "ios" || app.platform === "ipados") { + setIsSelfService(false); + } }; const onAddSoftware = async () => { @@ -209,6 +212,27 @@ const AppStoreVpp = ({ onExit(); }; + const renderSelfServiceContent = (platform: string) => { + if (platform !== "ios" && platform !== "ipados") { + return ( + setIsSelfService(newVal)} + className={`${baseClass}__self-service-checkbox`} + tooltipContent={ + <> + End users can install from Fleet Desktop {">"}{" "} + Self-service. + + } + > + Self-service + + ); + } + return null; + }; + const renderContent = () => { if (isLoadingVppInfo || isLoadingVppApps) { return ; @@ -238,19 +262,9 @@ const AppStoreVpp = ({ apps, head to{" "}
- setIsSelfService(newVal)} - className={`${baseClass}__self-service-checkbox`} - tooltipContent={ - <> - End users can install from Fleet Desktop {">"}{" "} - Self-service. - - } - > - Self-service - + {renderSelfServiceContent( + (selectedApp && selectedApp.platform) || "" + )}
); } diff --git a/frontend/pages/SoftwarePage/components/AppStoreVpp/helpers.tsx b/frontend/pages/SoftwarePage/components/AppStoreVpp/helpers.tsx index 76c131769fa1..8d8c5a171d89 100644 --- a/frontend/pages/SoftwarePage/components/AppStoreVpp/helpers.tsx +++ b/frontend/pages/SoftwarePage/components/AppStoreVpp/helpers.tsx @@ -35,13 +35,15 @@ const generateAlreadyAvailableMessage = (msg: string) => { // eslint-disable-next-line import/prefer-default-export export const getErrorMessage = (e: unknown) => { - const reason = getErrorReason(e); - + let reason = getErrorReason(e); // software is already available for install if (reason.toLowerCase().includes("already")) { return generateAlreadyAvailableMessage(reason); } - return DEFAULT_ERROR_MESSAGE; + if (reason && !reason.endsWith(".")) { + reason += "."; + } + return reason || DEFAULT_ERROR_MESSAGE; }; export const getUniqueAppId = (app: IVppApp) => From dd583f051beffe21c850d88569c5b774784c15e7 Mon Sep 17 00:00:00 2001 From: Luke Heath Date: Mon, 23 Sep 2024 15:43:55 -0500 Subject: [PATCH 49/81] Update docs codeowners temporarily (#22320) --- CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 5f1c7e9bca1e..153161e7ee82 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -66,8 +66,8 @@ go.mod @fleetdm/go # # (see website/config/custom.js for DRIs of other paths not listed here) ############################################################################################## -/docs @rachaelshaw -/docs/REST\ API/rest-api.md @rachaelshaw # « REST API reference documentation +/docs @rachaelshaw @lukeheath +/docs/REST\ API/rest-api.md @rachaelshaw @lukeheath # « REST API reference documentation /docs/Contributing/API-for-contributors.md @lukeheath # « Advanced / contributors-only API reference documentation /schema @eashaw # « Data tables (osquery/fleetd schema) documentation /docs/Deploy/_kubernetes/ @dherder # « Kubernetes best practice From adf19c4527f74c6471ea6236d015ecc26a2ff865 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:56:59 -0400 Subject: [PATCH 50/81] Reference docs for v4.57.0 (#22319) Co-authored-by: Rachael Shaw Co-authored-by: mostlikelee Co-authored-by: Tim Lee Co-authored-by: Marko Lisica Co-authored-by: Ian Littman Co-authored-by: Luke Heath --- docs/Configuration/yaml-files.md | 76 ++++++- docs/Contributing/API-for-contributors.md | 119 ++++++++++- docs/REST API/rest-api.md | 240 ++++++++++++++++++++-- website/config/routes.js | 1 + 4 files changed, 413 insertions(+), 23 deletions(-) diff --git a/docs/Configuration/yaml-files.md b/docs/Configuration/yaml-files.md index f66c79f1e751..7599fd259f9a 100644 --- a/docs/Configuration/yaml-files.md +++ b/docs/Configuration/yaml-files.md @@ -6,14 +6,16 @@ To learn how to set up a GitOps workflow see the [Fleet GitOps repo](https://git ## File structure -- `default.yml`- File where you define the queries, policies, controls, and agent options for all hosts. If you're using Fleet Premium, this file updates queries and policies that run on all hosts ("All teams"). Controls and agent options are defined for hosts on "No team." -- `teams/` - Folder where you define your teams in Fleet. These `teams/team-name.yml` files define the controls, queries, policies, and agent options for hosts assigned to the specified team. Teams are available in Fleet Premium. +- `default.yml` - File where you define the queries, policies and agent options for all hosts. If you're using Fleet Premium, this file updates queries and policies that run on all hosts ("All teams"). +- `teams/no-team.yml` - File where you define the policies, controls, and software for hosts on "No team". Available in Fleet Premium. +- `teams/` - Folder where you define your teams in Fleet. These `teams/team-name.yml` files define the controls, queries, policies, software, and agent options for hosts assigned to the specified team. Available in Fleet Premium. - `lib/` - Folder where you define policies, queries, configuration profiles, scripts, and agent options. These files can be referenced in top level keys in the `default.yml` file and the files in the `teams/` folder. - `.github/workflows/workflow.yml` - The GitHub workflow file where you can add [environment variables](https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow). -The following files are responsible for running the GitHub action. Most users don't need to edit these files. +The following files are responsible for running the GitHub action or GitLab CI/CD. Most users don't need to edit these files. - `gitops.sh` - The bash script that applies the latest configuration to Fleet. This script is used in the GitHub action file. - `.github/gitops-action/action.yml` - The GitHub action that runs `gitops.sh`. This action is used in the GitHub workflow file. It can also be used in other workflows. +- `.gitlab-ci.yml` - The GitLab CI/CD file that applies the latest configuration to Fleet. ## Configuration options @@ -24,8 +26,7 @@ name: # Only teams/team-name.yml. To edit a team's name, change `name` but don't policies: queries: agent_options: -controls: -software: +controls: # Can be defined in teams/no-team.yml too. org_settings: # Only default.yml team_settings: # Only teams/team-name.yml ``` @@ -40,6 +41,8 @@ team_settings: # Only teams/team-name.yml ### policies Polcies can be specified inline in your `default.yml` file or `teams/team-name.yml` files. They can also be specified in separate files in your `lib/` folder. +Policies defined in `default.yml` run on **all** hosts. +Policies defined in `teams/no-team.yml` run on hosts that belong to "No team". #### Options @@ -81,9 +84,16 @@ policies: platform: darwin critical: false calendar_event_enabled: false +- name: Firefox on Linux installed and up to date + platform: linux + description: "This policy checks that Firefox is installed and up to date." + resolution: "Install Firefox version 129.0.2 or higher." + query: "SELECT 1 FROM deb_packages WHERE name = 'firefox' AND version_compare(version, '129.0.2') >= 0;" + install_software: + package_path: "../lib/linux-firefox.deb.package.yml" ``` -`default.yml` or `teams/team-name.yml` +`default.yml`, `teams/team-name.yml`, or `teams/no-team.yml` ```yaml policies: @@ -210,6 +220,8 @@ queries: The `controls` section allows you to configure scripts and device management (MDM) features in Fleet. +Controls for hosts that are in "No team" can be defined in `default.yml` or in `teams/no-team.yml` (but not in both files). + - `scripts` is a list of paths to macOS, Windows, or Linux scripts. - `windows_enabled_and_configured` specifies whether or not to turn on Windows MDM features (default: `false`). Can only be configured for all teams (`default.yml`). - `enable_disk_encryption` specifies whether or not to enforce disk encryption on macOS and Windows hosts (default: `false`). @@ -304,11 +316,15 @@ Can only be configure for all teams (`default.yml`). > **Experimental feature**. This feature is undergoing rapid improvement, which may result in breaking changes to the API or configuration surface. It is not recommended for use in automated workflows. The `software` section allows you to configure packages and Apple App Store apps that you want to install on your hosts. +Software for hosts that belong to "No team" have to be defined in `teams/no-team.yml`. +Software can also be specified in separate files in your `lib/` folder. - `packages` is a list of software packages (.pkg, .msi, .exe, or .deb) and software specific options. - `app_store_apps` is a list of Apple App Store apps. -##### Example +#### Example + +##### Inline ```yaml software: @@ -326,7 +342,7 @@ software: - app_store_id: '1091189122' ``` -#### packages +##### packages - `url` specifies the URL at which the software is located. Fleet will download the software and upload it to S3 (default: `""`). - `install_script.path` specifies the command Fleet will run on hosts to install software. The [default script](https://github.com/fleetdm/fleet/tree/main/pkg/file/scripts) is dependent on the software type (i.e. .pkg). @@ -334,12 +350,41 @@ software: - `post_install_script.path` is the script Fleet will run on hosts after intalling software (default: `""`). - `self_service` specifies whether or not end users can install from **Fleet Desktop > Self-service**. -#### app_store_apps +##### app_store_apps - `app_store_id` is the ID of the Apple App Store app. You can find this at the end of the app's App Store URL. For example, "Bear - Markdown Notes" URL is "https://apps.apple.com/us/app/bear-markdown-notes/id1016366447" and the `app_store_id` is `1016366447`. > Make sure to include only the ID itself, and not the `id` prefix shown in the URL. The ID must be wrapped in quotes as shown in the example so that it is processed as a string. +##### Separate file + +`lib/software-name.package.yml`: + +```yaml +url: https://dl.tailscale.com/stable/tailscale-setup-1.72.0.exe +install_script: + path: ../lib/software/tailscale-install-script.ps1 +self_service: true +``` + +`lib/software/tailscale-install-script.ps1` + +```yaml +$exeFilePath = "${env:INSTALLER_PATH}" +$installProcess = Start-Process $exeFilePath ` + -ArgumentList "/quiet /norestart" ` + -PassThru -Verb RunAs -Wait +``` + +`default.yml`, `teams/team-name.yml`, or `teams/no-team.yml` + +```yaml +software: + packages: + - path: ../lib/software-name.package.yml +# path is relative to default.yml or teams/team-name.yml +``` + ### org_settings and team_settings #### features @@ -640,6 +685,19 @@ Once the IdP settings are configured, you can use the [`controls.macos_setup.ena Can only be configured for all teams (`org_settings`). +##### end_user_authentication + +The `end_user_authentication` section lets you define the identity provider (IdP) settings used for end user authentication during Automated Device Enrollment (ADE). Learn more about end user authentication in Fleet [here](https://fleetdm.com/guides/macos-setup-experience#end-user-authentication-and-eula). + +Once the IdP settings are configured, you can use the [`controls.macos_setup.enable_end_user_authentication`](#macos_setup) key to control the end user experience during ADE. + +- `idp_name` is the human-friendly name for the identity provider that will provide single sign-on authentication (default: `""`). +- `entity_id` is the entity ID: a Uniform Resource Identifier (URI) that you use to identify Fleet when configuring the identity provider. It must exactly match the Entity ID field used in identity provider configuration (default: `""`). +- `metadata` is the metadata (in XML format) provided by the identity provider. (default: `""`) +- `metadata_url` is the URL that references the identity provider metadata. Only one of `metadata` or `metadata_url` is required (default: `""`). + +Can only be configured for all teams (`org_settings`). + diff --git a/docs/Contributing/API-for-contributors.md b/docs/Contributing/API-for-contributors.md index ec39149199a1..2e8efe70ca49 100644 --- a/docs/Contributing/API-for-contributors.md +++ b/docs/Contributing/API-for-contributors.md @@ -543,11 +543,13 @@ The MDM endpoints exist to support the related command-line interface sub-comman - [Batch-apply MDM custom settings](#batch-apply-mdm-custom-settings) - [Initiate SSO during DEP enrollment](#initiate-sso-during-dep-enrollment) - [Complete SSO during DEP enrollment](#complete-sso-during-dep-enrollment) +- [Over the air enrollment](#over-the-air-enrollment) - [Preassign profiles to devices](#preassign-profiles-to-devices) - [Match preassigned profiles](#match-preassigned-profiles) - [Get FileVault statistics](#get-filevault-statistics) - [Upload VPP content token](#upload-vpp-content-token) - [Disable VPP](#disable-vpp) +- [Get an over the air (OTA) enrollment profile](#get-an-over-the-air-ota-enrollment-profile) ### Generate Apple Business Manager public key (ADE) @@ -1029,6 +1031,34 @@ If the credentials are valid, the server redirects the client to the Fleet UI. T - `profile_token` is a token that can be used to download an enrollment profile (.mobileconfig). - `eula_token` (optional) if an EULA was uploaded, this contains a token that can be used to view the EULA document. +### Over the air enrollment + +This endpoint handles over the air (OTA) MDM enrollments + +`POST /api/v1/fleet/ota_enrollment` + +#### Parameters + +| Name | Type | In | Description | +| ------------------- | ------ | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| enroll_secret | string | url | **Required** Assigns the host to a team with a matching enroll secret | +| XML device response | XML | body | **Required**. The XML response from the device. Fields are documented [here](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/ConfigurationProfileExamples/ConfigurationProfileExamples.html#//apple_ref/doc/uid/TP40009505-CH4-SW7) | + +> Note: enroll secrets can contain special characters. Ensure any special characters are [properly escaped](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding). + +#### Example + +`POST /api/v1/fleet/ota_enrollment?enroll_secret=0Z6IuKpKU4y7xl%2BZcrp2gPcMi1kKNs3p` + +##### Default response + +`Status: 200` + +Per [the spec](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009505-CH1-SW1), the response is different depending on the signature of the XML device response: + +- If the body is signed with a certificate that can be validated by our root SCEP certificate, it returns an enrollment profile. +- Otherwise, it returns a SCEP payload. + ### Preassign profiles to devices _Available in Fleet Premium_ @@ -1453,12 +1483,14 @@ NOTE: when updating a policy, team and platform will be ignored. "name": "new policy", "description": "This will be a new policy because a policy with the name 'new policy' doesn't exist in Fleet.", "query": "SELECT * FROM osquery_info", + "team": "No team", "resolution": "some resolution steps here", "critical": false }, { "name": "Is FileVault enabled on macOS devices?", "query": "SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT “” AND filevault_status = ‘on’ LIMIT 1;", + "team": "Workstations", "description": "Checks to make sure that the FileVault feature is enabled on macOS devices.", "resolution": "Choose Apple menu > System Preferences, then click Security & Privacy. Click the FileVault tab. Click the Lock icon, then enter an administrator name and password. Click Turn On FileVault.", "platform": "darwin", @@ -3320,7 +3352,24 @@ If both `team_id` and `team_name` parameters are included, this endpoint will re ##### Default response -`Status: 204` +`Status: 200` + +```json +{ + "packages": [ + { + "team_id": 3, + "software_title_id": 6690, + "url": "https://dl.tailscale.com/stable/tailscale-setup-1.72.0.exe" + }, + { + "team_id": 3, + "software_title_id": 10412, + "url": "https://ftp.mozilla.org/pub/firefox/releases/129.0.2/win64/en-US/Firefox%20Setup%20129.0.2.msi" + } + ] +} +``` ### Run live script @@ -3420,3 +3469,71 @@ Content-Disposition: attachment Content-Length: Body: ``` + +### Get an over the air (OTA) enrollment profile + +`GET /api/v1/fleet/enrollment_profiles/ota` + +The returned value is a signed `.mobileconfig` OTA profile. + +#### Parameters + +| Name | Type | In | Description | +|-------------------|---------|-------|----------------------------------------------------------------------------------| +| enroll_secret | string | query | **Required**. The enroll secret of the team this host will be assigned to. | + +#### Example + +`GET /api/v1/fleet/enrollment_profiles/ota?enroll_secret=foobar` + +##### Default response + +`Status: 200` + +**Note** To confirm success, it is important for clients to match content length with the response +header (this is done automatically by most clients, including the browser) rather than relying +solely on the response status code returned by this endpoint. + +##### Example response headers + +```http + Content-Length: 542 + Content-Type: application/x-apple-aspen-config; charset=urf-8 + Content-Disposition: attachment;filename="fleet-mdm-enrollment-profile.mobileconfig" + X-Content-Type-Options: nosniff +``` + +###### Example response body + +```xml + + + + + PayloadContent + + URL + https://foo.example.com/api/fleet/ota_enrollment?enroll_secret=foobar + DeviceAttributes + + UDID + VERSION + PRODUCT + SERIAL + + + PayloadOrganization + Acme Inc. + PayloadDisplayName + Acme Inc. enrollment + PayloadVersion + 1 + PayloadUUID + fdb376e5-b5bb-4d8c-829e-e90865f990c9 + PayloadIdentifier + com.fleetdm.fleet.mdm.apple.ota + PayloadType + Profile Service + + +``` diff --git a/docs/REST API/rest-api.md b/docs/REST API/rest-api.md index c160aac679ff..d7b8b8f172da 100644 --- a/docs/REST API/rest-api.md +++ b/docs/REST API/rest-api.md @@ -484,6 +484,22 @@ for pagination. For a comprehensive list of activity types and detailed informat ```json { "activities": [ + { + "created_at": "2023-07-27T14:35:08Z", + "id": 25, + "actor_full_name": "Anna Chao", + "actor_id": 3, + "actor_gravatar": "", + "actor_email": "", + "type": "uninstalled_software", + "details": { + "host_id": 1, + "host_display_name": "Marko's MacBook Pro", + "software_title": "Adobe Acrobat.app", + "script_execution_id": "eeeddb94-52d3-4071-8b18-7322cd382abb", + "status": "failed" + } + }, { "created_at": "2021-07-30T13:41:07Z", "id": 24, @@ -4241,7 +4257,7 @@ Resends a configuration profile for the specified host. "last_install": { "install_uuid": "8bbb8ac2-b254-4387-8cba-4d8a0407368b", "installed_at": "2024-05-15T15:23:57Z" - }, + } }, "app_store_app": null "source": "apps", @@ -4262,10 +4278,16 @@ Resends a configuration profile for the specified host. "name": "FalconSensor-6.44.pkg" "self_service": false, "last_install": null + "last_install": null, + "last_uninstall": { + "script_execution_id": "ed579e73-0f41-46c8-aaf4-3c1e5880ed27", + "uninstalled_at": "2024-05-15T15:23:57Z" + } }, "app_store_app": null "source": "", "status": null, + "status": "pending_uninstall", "installed_versions": [], }, { @@ -4546,6 +4568,38 @@ To wipe a macOS, iOS, iPadOS, or Windows host, the host must have MDM turned on. ```json { "activities": [ + { + "created_at": "2023-07-27T14:35:08Z", + "actor_id": 1, + "actor_full_name": "Anna Chao", + "id": 4, + "actor_gravatar": "", + "actor_email": "", + "type": "uninstalled_software", + "details": { + "host_id": 1, + "host_display_name": "Marko’s MacBook Pro", + "software_title": "Adobe Acrobat.app", + "script_execution_id": "ecf22dba-07dc-40a9-b122-5480e948b756", + "status": "failed" + } + }, + { + "created_at": "2023-07-27T14:35:08Z", + "actor_id": 1, + "actor_full_name": "Anna Chao", + "id": 3, + "actor_gravatar": "", + "actor_email": "", + "type": "uninstalled_software", + "details": { + "host_id": 1, + "host_display_name": "Marko’s MacBook Pro", + "software_title": "Adobe Acrobat.app", + "script_execution_id": "ecf22dba-07dc-40a9-b122-5480e948b756", + "status": "uninstalled" + } + }, { "created_at": "2023-07-27T14:35:08Z", "id": 2, @@ -4610,6 +4664,23 @@ To wipe a macOS, iOS, iPadOS, or Windows host, the host must have MDM turned on. { "count": 3, "activities": [ + { + "created_at": "2023-07-27T14:35:08Z", + "actor_id": 1, + "actor_full_name": "Anna Chao", + "uuid": "cc081637-fdf9-4d44-929f-96dfaec00f67", + "actor_gravatar": "", + "actor_email": "", + "type": "uninstalled_software", + "fleet_initiated_activity": false, + "details": { + "host_id": 1, + "host_display_name": "Marko's MacBook Pro", + "software_title": "Adobe Acrobat.app", + "script_execution_id": "ecf22dba-07dc-40a9-b122-5480e948b756", + "status": "pending_uninstall", + } + }, { "created_at": "2023-07-27T14:35:08Z", "uuid": "d6cffa75-b5b5-41ef-9230-15073c8a88cf", @@ -6812,6 +6883,29 @@ Team policies work the same as policies, but at the team level. "failing_host_count": 0, "host_count_updated_at": "2023-12-20T15:23:57Z", "calendar_events_enabled": false + }, + { + "id": 3, + "name": "macOS - install/update Adobe Acrobat", + "query": "SELECT 1 FROM apps WHERE name = \"Adobe Acrobat.app\" AND bundle_short_version != \"24.002.21005\";", + "description": "Checks if the hard disk is encrypted on Windows devices", + "critical": false, + "author_id": 43, + "author_name": "Alice", + "author_email": "alice@example.com", + "team_id": 1, + "resolution": "Resolution steps", + "platform": "darwin", + "created_at": "2021-12-16T14:37:37Z", + "updated_at": "2021-12-16T16:39:00Z", + "passing_host_count": 2300, + "failing_host_count": 3, + "host_count_updated_at": "2023-12-20T15:23:57Z", + "calendar_events_enabled": false, + "install_software": { + "name": "Adobe Acrobat.app", + "software_title_id": 1234 + } } ], "inherited_policies": [ @@ -6993,6 +7087,7 @@ The semantics for creating a team policy are the same as for global policies, se | resolution | string | body | The resolution steps for the policy. | | platform | string | body | Comma-separated target platforms, currently supported values are "windows", "linux", "darwin". The default, an empty string means target all platforms. | | critical | boolean | body | _Available in Fleet Premium_. Mark policy as critical/high impact. | +| software_title_id | integer | body | _Available in Fleet Premium_. ID of software title to install if the policy fails. | Either `query` or `query_id` must be provided. @@ -7036,7 +7131,11 @@ Either `query` or `query_id` must be provided. "passing_host_count": 0, "failing_host_count": 0, "host_count_updated_at": null, - "calendar_events_enabled": false + "calendar_events_enabled": false, + "install_software": { + "name": "Adobe Acrobat.app", + "software_title_id": 1234 + } } } ``` @@ -7091,6 +7190,7 @@ Either `query` or `query_id` must be provided. | platform | string | body | Comma-separated target platforms, currently supported values are "windows", "linux", "darwin". The default, an empty string means target all platforms. | | critical | boolean | body | _Available in Fleet Premium_. Mark policy as critical/high impact. | | calendar_events_enabled | boolean | body | _Available in Fleet Premium_. Whether to trigger calendar events when policy is failing. | +| software_title_id | integer | body | _Available in Fleet Premium_. ID of software title to install if the policy fails. | #### Example @@ -7132,7 +7232,11 @@ Either `query` or `query_id` must be provided. "passing_host_count": 0, "failing_host_count": 0, "host_count_updated_at": null, - "calendar_events_enabled": true + "calendar_events_enabled": true, + "install_software": { + "name": "Adobe Acrobat.app", + "software_title_id": 1234 + } } } ``` @@ -8300,12 +8404,15 @@ Gets the result of a script that was executed. "host_timeout": false, "host_id": 1, "execution_id": "e797d6c6-3aae-11ee-be56-0242ac120002", - "runtime": 20 + "runtime": 20, + "created_at": "2024-09-11T20:30:24Z" } ``` > Note: `exit_code` can be `null` if Fleet hasn't heard back from the host yet. +> Note: `created_at` is the creation timestamp of the script execution request. + ### Add script Uploads a script, making it available to run on hosts assigned to the specified team (or no team). @@ -8539,6 +8646,7 @@ Deletes the session specified by ID. When the user associated with the session n - [Add package](#add-package) - [List App Store apps](#list-app-store-apps) - [Add App Store app](#add-app-store-app) +- [Add Fleet library app](#add-fleet-library-app) - [Install package or App Store app](#install-package-or-app-store-app) - [Get package install result](#get-package-install-result) - [Download package](#download-package) @@ -8854,14 +8962,17 @@ Returns information about the specified software. By default, `versions` are sor "installer_id": 23, "team_id": 3, "uploaded_at": "2024-04-01T14:22:58Z", - "install_script": "sudo installer -pkg /temp/FalconSensor-6.44.pkg -target /", + "install_script": "sudo installer -pkg '$INSTALLER_PATH' -target /", "pre_install_query": "SELECT 1 FROM macos_profiles WHERE uuid='c9f4f0d5-8426-4eb8-b61b-27c543c9d3db';", "post_install_script": "sudo /Applications/Falcon.app/Contents/Resources/falconctl license 0123456789ABCDEFGHIJKLMNOPQRSTUV-WX", + "uninstall_script": "/Library/CS/falconctl uninstall", "self_service": true, "status": { "installed": 3, - "pending": 1, - "failed": 2, + "pending_install": 1, + "failed_install": 0, + "pending_uninstall": 2, + "failed_uninstall": 1 } }, "app_store_app": null, @@ -9067,7 +9178,7 @@ Add a package (.pkg, .msi, .exe, .deb) to install on macOS, Windows, or Linux (U | ---- | ------- | ---- | -------------------------------------------- | | software | file | form | **Required**. Installer package file. Supported packages are PKG, MSI, EXE, and DEB. | | team_id | integer | form | **Required**. The team ID. Adds a software package to the specified team. | -| install_script | string | form | Command that Fleet runs to install software. If not specified Fleet runs [default install command](https://github.com/fleetdm/fleet/tree/f71a1f183cc6736205510580c8366153ea083a8d/pkg/file/scripts) for each package type. | +| install_script | string | form | Script that Fleet runs to install software. If not specified Fleet runs [default install script](https://github.com/fleetdm/fleet/tree/f71a1f183cc6736205510580c8366153ea083a8d/pkg/file/scripts) for each package type. | | pre_install_query | string | form | Query that is pre-install condition. If the query doesn't return any result, Fleet won't proceed to install. | | post_install_script | string | form | The contents of the script to run after install. If the specified script fails (exit code non-zero) software install will be marked as failed and rolled back. | | self_service | boolean | form | Self-service software is optional and can be installed by the end user. | @@ -9112,6 +9223,87 @@ Content-Type: application/octet-stream `Status: 200` +### Modify package + +_Available in Fleet Premium._ + +Update a package to install on macOS, Windows, or Linux (Ubuntu) hosts. + +`PATCH /api/v1/fleet/software/titles/:title_id/package` + +#### Parameters + +| Name | Type | In | Description | +| ---- | ------- | ---- | -------------------------------------------- | +| software | file | form | Installer package file. Supported packages are PKG, MSI, EXE, and DEB. | +| team_id | integer | form | **Required**. The team ID. Updates a software package in the specified team. | +| install_script | string | form | Command that Fleet runs to install software. If not specified Fleet runs the [default install command](https://github.com/fleetdm/fleet/tree/f71a1f183cc6736205510580c8366153ea083a8d/pkg/file/scripts) for each package type. | +| pre_install_query | string | form | Query that is pre-install condition. If the query doesn't return any result, the package will not be installed. | +| post_install_script | string | form | The contents of the script to run after install. If the specified script fails (exit code non-zero) software install will be marked as failed and rolled back. | +| self_service | boolean | form | Whether this is optional self-service software that can be installed by the end user. | + +> Changes to the installer package will reset installation counts. Changes to any field other than `self_service` will cancel pending installs for the old package. +#### Example + +`PATCH /api/v1/fleet/software/titles/1/package` + +##### Request header + +```http +Content-Length: 8500 +Content-Type: multipart/form-data; boundary=------------------------d8c247122f594ba0 +``` + +##### Request body + +```http +--------------------------d8c247122f594ba0 +Content-Disposition: form-data; name="team_id" +1 +--------------------------d8c247122f594ba0 +Content-Disposition: form-data; name="self_service" +true +--------------------------d8c247122f594ba0 +Content-Disposition: form-data; name="install_script" +sudo installer -pkg /temp/FalconSensor-6.44.pkg -target / +--------------------------d8c247122f594ba0 +Content-Disposition: form-data; name="pre_install_query" +SELECT 1 FROM macos_profiles WHERE uuid='c9f4f0d5-8426-4eb8-b61b-27c543c9d3db'; +--------------------------d8c247122f594ba0 +Content-Disposition: form-data; name="post_install_script" +sudo /Applications/Falcon.app/Contents/Resources/falconctl license 0123456789ABCDEFGHIJKLMNOPQRSTUV-WX +--------------------------d8c247122f594ba0 +Content-Disposition: form-data; name="software"; filename="FalconSensor-6.44.pkg" +Content-Type: application/octet-stream + +--------------------------d8c247122f594ba0 +``` + +##### Default response + +`Status: 200` + +```json +{ + "software_package": { + "name": "FalconSensor-6.44.pkg", + "version": "6.44", + "installer_id": 23, + "team_id": 3, + "uploaded_at": "2024-04-01T14:22:58Z", + "install_script": "sudo installer -pkg /temp/FalconSensor-6.44.pkg -target /", + "pre_install_query": "SELECT 1 FROM macos_profiles WHERE uuid='c9f4f0d5-8426-4eb8-b61b-27c543c9d3db';", + "post_install_script": "sudo /Applications/Falcon.app/Contents/Resources/falconctl license 0123456789ABCDEFGHIJKLMNOPQRSTUV-WX", + "self_service": true, + "status": { + "installed": 0, + "pending": 0, + "failed": 0 + } + } +} +``` + ### List App Store apps > **Experimental feature**. This feature is undergoing rapid improvement, which may result in breaking changes to the API or configuration surface. It is not recommended for use in automated workflows. @@ -9238,9 +9430,31 @@ _Available in Fleet Premium._ Install software (package or App Store app) on a macOS, iOS, iPadOS, Windows, or Linux (Ubuntu) host. Software title must have a `software_package` or `app_store_app` added to be installed. -> Note: Fleet's agent (fleetd) only installs software it has been asked to install, but technically has access to all installer executables. +`POST /api/v1/fleet/hosts/:id/software/:software_title_id/install` + +#### Parameters + +| Name | Type | In | Description | +| --------- | ---------- | ---- | -------------------------------------------- | +| id | integer | path | **Required**. The host's ID. | +| software_title_id | integer | path | **Required**. The software title's ID. | + +#### Example + +`POST /api/v1/fleet/hosts/123/software/3435/install` + +##### Default response + +`Status: 202` + +### Uninstall package + +> **Experimental feature**. This feature is undergoing rapid improvement, which may result in breaking changes to the API or configuration surface. It is not recommended for use in automated workflows. +_Available in Fleet Premium._ + +Uninstall software (package) on a macOS, Windows, or Linux (Ubuntu) host. Software title must have a `software_package` added to be uninstalled. -`POST /api/v1/fleet/hosts/:id/software/install/:software_title_id` +`POST /api/v1/fleet/hosts/:id/software/:software_title_id/uninstall` #### Parameters @@ -9251,7 +9465,7 @@ Install software (package or App Store app) on a macOS, iOS, iPadOS, Windows, or #### Example -`POST /api/v1/fleet/hosts/123/software/install/3435` +`POST /api/v1/fleet/hosts/123/software/3435/uninstall` ##### Default response @@ -9263,7 +9477,7 @@ Install software (package or App Store app) on a macOS, iOS, iPadOS, Windows, or _Available in Fleet Premium._ -`GET /api/v1/fleet/software/install/results/:install_uuid` +`GET /api/v1/fleet/software/install/:install_uuid/results` Get the results of a software package install. @@ -9275,7 +9489,7 @@ To get the results of an App Store app install, use the [List MDM commands](#lis #### Example -`GET /api/v1/fleet/software/install/results/b15ce221-e22e-4c6a-afe7-5b3400a017da` +`GET /api/v1/fleet/software/install/b15ce221-e22e-4c6a-afe7-5b3400a017da/results` ##### Default response diff --git a/website/config/routes.js b/website/config/routes.js index 8c9991200f3a..57d1c0608bd8 100644 --- a/website/config/routes.js +++ b/website/config/routes.js @@ -559,6 +559,7 @@ module.exports.routes = { 'GET /learn-more-about/host-identifiers': '/docs/rest-api/rest-api#get-host-by-identifier', 'GET /learn-more-about/uninstall-fleetd': '/docs/using-fleet/faq#how-can-i-uninstall-fleetd', 'GET /learn-more-about/vulnerability-processing': '/docs/using-fleet/vulnerability-processing', + 'GET /learn-more-about/dep-profile': 'https://developer.apple.com/documentation/devicemanagement/define_a_profile', 'GET /learn-more-about/apple-business-manager-tokens-api': '/docs/rest-api/rest-api#list-apple-business-manager-abm-tokens', 'GET /learn-more-about/apple-business-manager-teams-api': 'https://github.com/fleetdm/fleet/blob/main/docs/Contributing/API-for-contributors.md#update-abm-tokens-teams', 'GET /learn-more-about/apple-business-manager-gitops': '/docs/using-fleet/gitops#apple-business-manager', From 03c3c6ca373ed5836061edb8477ec35bdce1c5e3 Mon Sep 17 00:00:00 2001 From: Marko Lisica <83164494+marko-lisica@users.noreply.github.com> Date: Mon, 23 Sep 2024 23:09:48 +0200 Subject: [PATCH 51/81] Docs: OS updates page - unclear tooltip copy (#22272) Docs changes related to: #21976 --- articles/enforce-os-updates.md | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/articles/enforce-os-updates.md b/articles/enforce-os-updates.md index 3db4862a8768..de3fdbc83de3 100644 --- a/articles/enforce-os-updates.md +++ b/articles/enforce-os-updates.md @@ -2,7 +2,7 @@ _Available in Fleet Premium_ -In Fleet you can enforce OS updates on your macOS, Windows, iOS, and iPadOS hosts remotely using the Fleet UI, Fleet API, or [Fleet's GitOps workflow](https://github.com/fleetdm/fleet-gitops). +In Fleet, you can enforce OS updates on your macOS, Windows, iOS, and iPadOS hosts remotely using the Fleet UI, Fleet API, or [Fleet's GitOps workflow](https://github.com/fleetdm/fleet-gitops). Fleet UI: @@ -18,30 +18,22 @@ Fleet API: API documentation is [here](https://fleetdm.com/docs/rest-api/rest-ap ### macOS -When a minimum version is enforced, the end users see a native macOS notification (DDM) once per day. Users can choose to update ahead of the deadline or schedule it for that night. 24 hours before the deadline, the notification appears hourly and ignores Do Not Disturb. One hour before the deadline, the notification appears every 30 minutes, and then every 10 minutes. +When a minimum version is enforced, the end users see a native macOS notification (DDM) once per day. Users can choose to update ahead of the deadline or schedule it for that night. 24 hours before the deadline, the notification appears hourly and ignores Do Not Disturb. One hour before the deadline, the notification appears every 30 minutes and then every 10 minutes. If the host was turned off when the deadline passed, the update will be scheduled an hour after it’s turned on. -For macOS devices that use Automated Device Enrollment (ADE), if the device is below the specified -minimum version, it will be required to update to the very latest OS version during ADE before -device setup and enrollment can proceed. +For macOS devices that use Automated Device Enrollment (ADE), if the device is below the specified minimum version, it will be required to update to the latest [available version](#available-macos-ios-and-ipados-versions) during ADE before device setup and enrollment can proceed. -### macOS (below version 14.0) - -End users are encouraged to update macOS (via [Nudge](https://github.com/macadmins/nudge)). +### iOS and iPadOS -![Nudge window](https://raw.githubusercontent.com/fleetdm/fleet/main/docs/images/nudge-window.png) +End users will see a notification in their Notification Center after the deadline when a minimum version is enforced. They can’t use their iPhone or iPad until the OS update is installed. -| | > 1 day before deadline | < 1 day before deadline | Past deadline | -| ------------------------------------ | ----------------------- | ----------------------- | --------------------- | -| Nudge window frequency | Once a day at 8pm GMT | Once every 2 hours | Immediately on login | -| End user can defer | ✅ | ✅ | ❌ | -| Nudge window is dismissible | ✅ | ✅ | ❌ | +For iOS and iPadOS devices that use Automated Device Enrollment (ADE), if the device is below the specified +minimum version, it will be required to update to the latest [available version](#available-macos-ios-and-ipados-versions) during ADE before device setup and enrollment can proceed. -### iOS and iPadOS (version 17.0 and above) +### Available macOS, iOS, and iPadOS versions -For iOS and iPadOS devices that use Automated Device Enrollment (ADE), if the device is below the specified -minimum version, it will be required to update to the very latest OS version during ADE before device setup and enrollment can proceed. +The Apple Software Lookup Service (available at [https://gdmf.apple.com/v2/pmv](https://gdmf.apple.com/v2/pmv)) is the official resource for obtaining a list of publicly available updates, upgrades, and Rapid Security Responses. Make sure to use versions available in GDMF; otherwise, the update will not be scheduled. ### Windows @@ -55,9 +47,17 @@ If an end user was on vacation when the deadline passed, the end user is given a Fleet enforces OS updates for quality and feature updates. Read more about the types of Windows OS updates in the Microsoft documentation [here](https://learn.microsoft.com/en-us/windows/deployment/update/get-started-updates-channels-tools#types-of-updates). -### iOS and iPadOS +### macOS (below version 14.0) + +End users are encouraged to update macOS (via [Nudge](https://github.com/macadmins/nudge)). + +![Nudge window](https://raw.githubusercontent.com/fleetdm/fleet/main/docs/images/nudge-window.png) -When a minimum version is enforced, end users will see a notification in their Notification Center after the deadline. They can’t use their iPhone or iPad until the OS update is installed. +| | > 1 day before deadline | < 1 day before deadline | Past deadline | +| ------------------------------------ | ----------------------- | ----------------------- | --------------------- | +| Nudge window frequency | Once a day at 8pm GMT | Once every 2 hours | Immediately on login | +| End user can defer | ✅ | ✅ | ❌ | +| Nudge window is dismissible | ✅ | ✅ | ❌ | From 1fdd127f6c9039d0f50e78322853d3fc88e87464 Mon Sep 17 00:00:00 2001 From: Dave Herder <27025660+dherder@users.noreply.github.com> Date: Mon, 23 Sep 2024 14:17:39 -0700 Subject: [PATCH 52/81] Add macOS policies for patching in workstations-canary.yml (#22323) --- it-and-security/teams/workstations-canary.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/it-and-security/teams/workstations-canary.yml b/it-and-security/teams/workstations-canary.yml index 353f9c8500f3..1d7ea397107c 100644 --- a/it-and-security/teams/workstations-canary.yml +++ b/it-and-security/teams/workstations-canary.yml @@ -138,6 +138,20 @@ policies: resolution: We will perform system maintenance on your device. platform: darwin calendar_events_enabled: true + - name: macOS - Upgrade Firefox + query: SELECT 1 FROM apps WHERE name = 'Firefox.app' AND version_compare(bundle_short_version, '130.0.1') >= 0; + critical: false + description: The host may have an outdated or non-existent version of Firefox, potentially risking security vulnerabilities or compatibility issues. + resolution: During maintenance, the Firefox app could be updated to the correct version or installed if it's missing. + platform: darwin + calendar_events_enabled: false + - name: macOS - Upgrade Slack + query: SELECT 1 FROM apps WHERE name = 'Slack.app' AND version_compare(bundle_short_version, '4.40.126') >= 0; + critical: false + description: The host may be running an outdated version of Slack, which could pose security vulnerabilities or compatibility issues. + resolution: The host's Slack application will likely be updated to a version that is greater than or equal to '4.40.126'. + platform: darwin + calendar_events_enabled: false queries: - path: ../lib/collect-failed-login-attempts.queries.yml - path: ../lib/collect-fleetd-information.yml From dfc7289a6d19f9c5fbd3734b85ee65ff4c3fc5b2 Mon Sep 17 00:00:00 2001 From: Lucas Manuel Rodriguez Date: Mon, 23 Sep 2024 18:24:08 -0300 Subject: [PATCH 53/81] Add missing docs for batch apply VPP apps (#22265) #22069 --- docs/Contributing/API-for-contributors.md | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/Contributing/API-for-contributors.md b/docs/Contributing/API-for-contributors.md index 2e8efe70ca49..0b830dbc0719 100644 --- a/docs/Contributing/API-for-contributors.md +++ b/docs/Contributing/API-for-contributors.md @@ -3371,6 +3371,45 @@ If both `team_id` and `team_name` parameters are included, this endpoint will re } ``` +### Batch-apply VPP apps + +_Available in Fleet Premium._ + +`POST /api/latest/fleet/software/app_store_apps/batch` + +#### Parameters + +| Name | Type | In | Description | +| --------- | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| team_name | string | query | The name of the team to add the software package to. Ommitting this parameter will add software to 'No Team'. | +| dry_run | bool | query | If `true`, will validate the provided VPP apps and return any validation errors, but will not apply the changes. | +| app_store_apps | list | body | An array of objects. Each object contains `app_store_id` and `self_service`. | +| app_store_apps.app_store_id | string | body | ID of the App Store app. | +| app_store_apps.self_service | boolean | body | Whether the VPP app is "Self-service" or not. | + +#### Example + +`POST /api/latest/fleet/software/app_store_apps/batch` +```json +{ + "team_name": "Foobar", + "app_store_apps": { + { + "app_store_id": "597799333", + "self_service": false, + }, + { + "app_store_id": "497799835", + "self_service": true, + } + } +} +``` + +##### Default response + +`Status: 204` + ### Run live script Run a live script and get results back (5 minute timeout). Live scripts only runs on the host if it has no other scripts running. From 21b3c468c118c5afbfc2adc846f512e133d6582e Mon Sep 17 00:00:00 2001 From: Lucas Manuel Rodriguez Date: Mon, 23 Sep 2024 19:40:53 -0300 Subject: [PATCH 54/81] Add doc API changes for the now async software batch (#22259) API changes for #22069. --------- Co-authored-by: Marko Lisica <83164494+marko-lisica@users.noreply.github.com> Co-authored-by: Ian Littman Co-authored-by: Noah Talerman --- docs/Contributing/API-for-contributors.md | 65 ++++++++++++++++++----- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/docs/Contributing/API-for-contributors.md b/docs/Contributing/API-for-contributors.md index 0b830dbc0719..1d7c5eb17b75 100644 --- a/docs/Contributing/API-for-contributors.md +++ b/docs/Contributing/API-for-contributors.md @@ -3333,18 +3333,16 @@ _Available in Fleet Premium._ `POST /api/v1/fleet/software/batch` +This endpoint is asynchronous, meaning it will start a background process to download and apply the software and return a `request_uuid` in the JSON response that can be used to query the status of the batch-apply (using the `GET /api/v1/fleet/software/batch/{request_uuid}` endpoint defined below). + #### Parameters | Name | Type | In | Description | | --------- | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| team_id | number | query | The ID of the team to add the software package to. Only one team identifier (`team_id` or `team_name`) can be included in the request, omit this parameter if using `team_name`. Ommitting these parameters will add software to 'No Team'. | -| team_name | string | query | The name of the team to add the software package to. Only one team identifier (`team_id` or `team_name`) can be included in the request, omit this parameter if using `team_id`. Ommitting these parameters will add software to 'No Team'. | +| team_name | string | query | The name of the team to add the software package to. Ommitting these parameters will add software to 'No Team'. | | dry_run | bool | query | If `true`, will validate the provided software packages and return any validation errors, but will not apply the changes. | | software | object | body | The team's software that will be available for install. | | software.packages | list | body | An array of objects. Each object consists of:`url`- URL to the software package (PKG, MSI, EXE or DEB),`install_script` - command that Fleet runs to install software, `pre_install_query` - condition query that determines if the install will proceed, `post_install_script` - script that runs after software install, and `uninstall_script` - command that Fleet runs to uninstall software. | -| software.app_store_apps | list | body | An array objects. Each object consists of `app_store_id` - ID of the App Store app. | - -If both `team_id` and `team_name` parameters are included, this endpoint will respond with an error. If no `team_name` or `team_id` is provided, the scripts will be applied for **all hosts**. #### Example @@ -3353,24 +3351,67 @@ If both `team_id` and `team_name` parameters are included, this endpoint will re ##### Default response `Status: 200` +```json +{ + "request_uuid": "ec23c7b6-c336-4109-b89d-6afd859659b4", +} +``` +### Get status of software batch-apply request + +_Available in Fleet Premium._ + +`GET /api/v1/fleet/software/batch/{request_uuid}` + +This endpoint allows querying the status of a batch-apply software request (`POST /api/v1/fleet/software/batch`). +Returns `"status"` field that can be one of `"processing"`, `"complete"` or `"failed"`. +If `"status"` is `"completed"` then the `"packages"` field contains the applied packages. +If `"status"` is `"processing"` then the operation is ongoing and the request should be retried. +If `"status"` is `"failed"` then the `"message"` field contains the error message. + +#### Parameters + +| Name | Type | In | Description | +| ------------ | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request_uuid | string | query | The request_uuid returned by the `POST /api/v1/fleet/software/batch` endpoint. | +| team_name | string | query | The name of the team to add the software package to. Ommitting these parameters will add software to 'No Team'. | +| dry_run | bool | query | If `true`, will validate the provided software packages and return any validation errors, but will not apply the changes. | + +##### Default responses + +`Status: 200` ```json { + "status": "processing", + "message": "", + "packages": null +} +``` + +`Status: 200` +```json +{ + "status": "completed", + "message": "", "packages": [ { - "team_id": 3, - "software_title_id": 6690, - "url": "https://dl.tailscale.com/stable/tailscale-setup-1.72.0.exe" - }, - { - "team_id": 3, - "software_title_id": 10412, + "team_id": 1, + "title_id": 2751, "url": "https://ftp.mozilla.org/pub/firefox/releases/129.0.2/win64/en-US/Firefox%20Setup%20129.0.2.msi" } ] } ``` +`Status: 200` +```json +{ + "status": "failed", + "message": "validation failed: software.url Couldn't edit software. URL (\"https://foobar.does.not.exist.com\") returned \"Not Found\". Please make sure that URLs are reachable from your Fleet server.", + "packages": null +} +``` + ### Batch-apply VPP apps _Available in Fleet Premium._ From d83ed46373d967a17faae5648235b6f370ad0481 Mon Sep 17 00:00:00 2001 From: Dante Catalfamo <43040593+dantecatalfamo@users.noreply.github.com> Date: Mon, 23 Sep 2024 19:09:31 -0400 Subject: [PATCH 55/81] Add batch app store apps documentation (#21912) --- docs/Contributing/API-for-contributors.md | 255 +--------------------- docs/REST API/rest-api.md | 115 ++++++++++ 2 files changed, 116 insertions(+), 254 deletions(-) diff --git a/docs/Contributing/API-for-contributors.md b/docs/Contributing/API-for-contributors.md index 1d7c5eb17b75..2ba361b2c3a7 100644 --- a/docs/Contributing/API-for-contributors.md +++ b/docs/Contributing/API-for-contributors.md @@ -3325,133 +3325,7 @@ If both `team_id` and `team_name` parameters are included, this endpoint will re `Status: 204` -## Software - -### Batch-apply software - -_Available in Fleet Premium._ - -`POST /api/v1/fleet/software/batch` - -This endpoint is asynchronous, meaning it will start a background process to download and apply the software and return a `request_uuid` in the JSON response that can be used to query the status of the batch-apply (using the `GET /api/v1/fleet/software/batch/{request_uuid}` endpoint defined below). - -#### Parameters - -| Name | Type | In | Description | -| --------- | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| team_name | string | query | The name of the team to add the software package to. Ommitting these parameters will add software to 'No Team'. | -| dry_run | bool | query | If `true`, will validate the provided software packages and return any validation errors, but will not apply the changes. | -| software | object | body | The team's software that will be available for install. | -| software.packages | list | body | An array of objects. Each object consists of:`url`- URL to the software package (PKG, MSI, EXE or DEB),`install_script` - command that Fleet runs to install software, `pre_install_query` - condition query that determines if the install will proceed, `post_install_script` - script that runs after software install, and `uninstall_script` - command that Fleet runs to uninstall software. | - -#### Example - -`POST /api/v1/fleet/software/batch` - -##### Default response - -`Status: 200` -```json -{ - "request_uuid": "ec23c7b6-c336-4109-b89d-6afd859659b4", -} -``` - -### Get status of software batch-apply request - -_Available in Fleet Premium._ - -`GET /api/v1/fleet/software/batch/{request_uuid}` - -This endpoint allows querying the status of a batch-apply software request (`POST /api/v1/fleet/software/batch`). -Returns `"status"` field that can be one of `"processing"`, `"complete"` or `"failed"`. -If `"status"` is `"completed"` then the `"packages"` field contains the applied packages. -If `"status"` is `"processing"` then the operation is ongoing and the request should be retried. -If `"status"` is `"failed"` then the `"message"` field contains the error message. - -#### Parameters - -| Name | Type | In | Description | -| ------------ | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| request_uuid | string | query | The request_uuid returned by the `POST /api/v1/fleet/software/batch` endpoint. | -| team_name | string | query | The name of the team to add the software package to. Ommitting these parameters will add software to 'No Team'. | -| dry_run | bool | query | If `true`, will validate the provided software packages and return any validation errors, but will not apply the changes. | - -##### Default responses - -`Status: 200` -```json -{ - "status": "processing", - "message": "", - "packages": null -} -``` - -`Status: 200` -```json -{ - "status": "completed", - "message": "", - "packages": [ - { - "team_id": 1, - "title_id": 2751, - "url": "https://ftp.mozilla.org/pub/firefox/releases/129.0.2/win64/en-US/Firefox%20Setup%20129.0.2.msi" - } - ] -} -``` - -`Status: 200` -```json -{ - "status": "failed", - "message": "validation failed: software.url Couldn't edit software. URL (\"https://foobar.does.not.exist.com\") returned \"Not Found\". Please make sure that URLs are reachable from your Fleet server.", - "packages": null -} -``` - -### Batch-apply VPP apps - -_Available in Fleet Premium._ - -`POST /api/latest/fleet/software/app_store_apps/batch` - -#### Parameters - -| Name | Type | In | Description | -| --------- | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| team_name | string | query | The name of the team to add the software package to. Ommitting this parameter will add software to 'No Team'. | -| dry_run | bool | query | If `true`, will validate the provided VPP apps and return any validation errors, but will not apply the changes. | -| app_store_apps | list | body | An array of objects. Each object contains `app_store_id` and `self_service`. | -| app_store_apps.app_store_id | string | body | ID of the App Store app. | -| app_store_apps.self_service | boolean | body | Whether the VPP app is "Self-service" or not. | - -#### Example - -`POST /api/latest/fleet/software/app_store_apps/batch` -```json -{ - "team_name": "Foobar", - "app_store_apps": { - { - "app_store_id": "597799333", - "self_service": false, - }, - { - "app_store_id": "497799835", - "self_service": true, - } - } -} -``` - -##### Default response - -`Status: 204` - - ### Run live script +### Run live script Run a live script and get results back (5 minute timeout). Live scripts only runs on the host if it has no other scripts running. @@ -3490,130 +3364,3 @@ Run a live script and get results back (5 minute timeout). Live scripts only run "exit_code": 0 } ``` - -### Get token to download package - -_Available in Fleet Premium._ - -`POST /api/v1/fleet/software/titles/:software_title_id/package/token?alt=media` - -The returned token is a one-time use token that expires after 10 minutes. - -#### Parameters - -| Name | Type | In | Description | -|-------------------|---------|-------|------------------------------------------------------------------| -| software_title_id | integer | path | **Required**. The ID of the software title for software package. | -| team_id | integer | query | **Required**. The team ID containing the software package. | -| alt | integer | query | **Required**. Must be specified and set to "media". | - -#### Example - -`POST /api/v1/fleet/software/titles/123/package/token?alt=media&team_id=2` - -##### Default response - -`Status: 200` - -```json -{ - "token": "e905e33e-07fe-4f82-889c-4848ed7eecb7" -} -``` - -### Download package using a token - -_Available in Fleet Premium._ - -`GET /api/v1/fleet/software/titles/:software_title_id/package/token/:token?alt=media` - -#### Parameters - -| Name | Type | In | Description | -|-------------------|---------|------|--------------------------------------------------------------------------| -| software_title_id | integer | path | **Required**. The ID of the software title to download software package. | -| token | string | path | **Required**. The token to download the software package. | - -#### Example - -`GET /api/v1/fleet/software/titles/123/package/token/e905e33e-07fe-4f82-889c-4848ed7eecb7` - -##### Default response - -`Status: 200` - -```http -Status: 200 -Content-Type: application/octet-stream -Content-Disposition: attachment -Content-Length: -Body: -``` - -### Get an over the air (OTA) enrollment profile - -`GET /api/v1/fleet/enrollment_profiles/ota` - -The returned value is a signed `.mobileconfig` OTA profile. - -#### Parameters - -| Name | Type | In | Description | -|-------------------|---------|-------|----------------------------------------------------------------------------------| -| enroll_secret | string | query | **Required**. The enroll secret of the team this host will be assigned to. | - -#### Example - -`GET /api/v1/fleet/enrollment_profiles/ota?enroll_secret=foobar` - -##### Default response - -`Status: 200` - -**Note** To confirm success, it is important for clients to match content length with the response -header (this is done automatically by most clients, including the browser) rather than relying -solely on the response status code returned by this endpoint. - -##### Example response headers - -```http - Content-Length: 542 - Content-Type: application/x-apple-aspen-config; charset=urf-8 - Content-Disposition: attachment;filename="fleet-mdm-enrollment-profile.mobileconfig" - X-Content-Type-Options: nosniff -``` - -###### Example response body - -```xml - - - - - PayloadContent - - URL - https://foo.example.com/api/fleet/ota_enrollment?enroll_secret=foobar - DeviceAttributes - - UDID - VERSION - PRODUCT - SERIAL - - - PayloadOrganization - Acme Inc. - PayloadDisplayName - Acme Inc. enrollment - PayloadVersion - 1 - PayloadUUID - fdb376e5-b5bb-4d8c-829e-e90865f990c9 - PayloadIdentifier - com.fleetdm.fleet.mdm.apple.ota - PayloadType - Profile Service - - -``` diff --git a/docs/REST API/rest-api.md b/docs/REST API/rest-api.md index d7b8b8f172da..638728015b9d 100644 --- a/docs/REST API/rest-api.md +++ b/docs/REST API/rest-api.md @@ -8651,6 +8651,10 @@ Deletes the session specified by ID. When the user associated with the session n - [Get package install result](#get-package-install-result) - [Download package](#download-package) - [Delete package or App Store app](#delete-package-or-app-store-app) +- [Batch-apply software](#batch-apply-software) +- [Batch-apply app store apps](#batch-apply-app-store-apps) +- [Get token to download package](#get-token-to-download-package) +- [Download package using a token](#download-package-using-a-token) ### List software @@ -9535,6 +9539,117 @@ Deletes software that's available for install (package or App Store app). `Status: 204` +### Batch-apply software + +_Available in Fleet Premium._ + +`POST /api/v1/fleet/software/batch` + +#### Parameters + +| Name | Type | In | Description | +| --------- | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| team_id | number | query | The ID of the team to add the software package to. Only one team identifier (`team_id` or `team_name`) can be included in the request; omit this parameter if using `team_name`. Omitting these parameters will add software to "No Team". | +| team_name | string | query | The name of the team to add the software package to. Only one team identifier (`team_id` or `team_name`) can be included in the request; omit this parameter if using `team_id`. Omitting these parameters will add software to "No Team". | +| dry_run | bool | query | If `true`, will validate the provided software packages and return any validation errors, but will not apply the changes. | +| software | object | body | The team's software that will be available for install. | +| software.packages | list | body | An array of objects. Each object consists of:`url`- URL to the software package (PKG, MSI, EXE or DEB),`install_script` - command that Fleet runs to install software, `pre_install_query` - condition query that determines if the install will proceed, `post_install_script` - script that runs after software install, and `uninstall_script` - command that Fleet runs to uninstall software. | +| software.app_store_apps | list | body | An array objects. Each object consists of `app_store_id` - ID of the App Store app. | + +If both `team_id` and `team_name` parameters are included, this endpoint will respond with an error. If no `team_name` or `team_id` is provided, the scripts will be applied for **all hosts**. + +#### Example + +`POST /api/v1/fleet/software/batch` + +##### Default response + +`Status: 204` + +### Batch-apply app store apps + +_Available in Fleet Premium._ + +`POST /api/v1/fleet/software/app_store_apps/batch` + +#### Parameters + +| Name | Type | In | Description | +|-----------------|---------|-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| team_name | integer | query | **Required**. The name of the team to add the app to. | +| dry_run | bool | query | If `true`, will validate the provided apps and return any validation errors, but will not apply the changes. | +| apps_store_apps | list | body | The list of objects containing `app_store_id`: a string representation of the app's App ID, `self_service`: a bool indicating if the app's installation can be initiated by end users. | + +> Note that this endpoint replaces all apps associated with a team. + +#### Example + +`POST /api/v1/fleet/software/app_store_apps/batch` + +#### Default response + +`Status: 204` + +### Get token to download package + +_Available in Fleet Premium._ + +`POST /api/v1/fleet/software/titles/:software_title_id/package/token?alt=media` + +The returned token is a one-time use token that expires after 10 minutes. + +#### Parameters + +| Name | Type | In | Description | +|-------------------|---------|-------|------------------------------------------------------------------| +| software_title_id | integer | path | **Required**. The ID of the software title for software package. | +| team_id | integer | query | **Required**. The team ID containing the software package. | +| alt | integer | query | **Required**. Must be specified and set to "media". | + +#### Example + +`POST /api/v1/fleet/software/titles/123/package/token?alt=media&team_id=2` + +##### Default response + +`Status: 200` + +```json +{ + "token": "e905e33e-07fe-4f82-889c-4848ed7eecb7" +} +``` + +### Download package using a token + +_Available in Fleet Premium._ + +`GET /api/v1/fleet/software/titles/:software_title_id/package/token/:token?alt=media` + +#### Parameters + +| Name | Type | In | Description | +|-------------------|---------|------|--------------------------------------------------------------------------| +| software_title_id | integer | path | **Required**. The ID of the software title to download software package. | +| token | string | path | **Required**. The token to download the software package. | + +#### Example + +`GET /api/v1/fleet/software/titles/123/package/token/e905e33e-07fe-4f82-889c-4848ed7eecb7` + +##### Default response + +`Status: 200` + +```http +Status: 200 +Content-Type: application/octet-stream +Content-Disposition: attachment +Content-Length: +Body: +``` + + ## Vulnerabilities - [List vulnerabilities](#list-vulnerabilities) From 9c3ad8b533af05b106041521757298027b2ec471 Mon Sep 17 00:00:00 2001 From: JD Date: Mon, 23 Sep 2024 17:48:39 -0600 Subject: [PATCH 56/81] Article: Guide Enable Okta Verify on macOS (#22328) Article: Guide: Enable Okta Verify on macOS using configuration profile https://github.com/fleetdm/fleet/issues/22108 --- ...ify-on-macOS-with-configuration-profile.md | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 articles/enable-okta-verify-on-macOS-with-configuration-profile.md diff --git a/articles/enable-okta-verify-on-macOS-with-configuration-profile.md b/articles/enable-okta-verify-on-macOS-with-configuration-profile.md new file mode 100644 index 000000000000..19bd9c5c9ef4 --- /dev/null +++ b/articles/enable-okta-verify-on-macOS-with-configuration-profile.md @@ -0,0 +1,130 @@ +# Enable Okta Verify on macOS using configuration profile + +## Introduction + +This guide will show you how to install [Okta Verify](https://help.okta.com/en-us/content/topics/mobile/okta-verify-overview.htm) on your macOS hosts and set them as managed by issuing a SCEP certificate via a configuration profile [managed through Fleet](https://fleetdm.com/guides/custom-os-settings). + +By following these steps, you can automate the deployment of Okta Verify across your devices. This will allow you to enforce multifactor authentication policies, improve device security, and manage user access seamlessly. + +## Prerequisites + +* MDM enabled and configured + +## Step-by-Step Instructions + +### **Step 1: Install Okta Verify on your hosts** + +Okta Verify can be installed: + +* As a Volume Purchasing Program (VPP) application, follow [these steps to install VPP apps](https://fleetdm.com/guides/install-vpp-apps-on-macos-using-fleet). +* As a *.pkg *file download the [installer from Okta](https://help.okta.com/oie/en-us/content/topics/identity-engine/devices/ov-install-options-macos.htm) and [deploy the installer using Fleet](https://fleetdm.com/guides/deploy-security-agents). + +After installing Okta Verify on the host, the device will be registered in Okta. + +### **Step 2: Issue a SCEP certificate for management attestation** + +The next step to ensure Okta detects the device as managed is to issue a SCEP certificate. + +* Follow the instructions on the Okta documentation to [configure a certificate authority](https://help.okta.com/oie/en-us/content/topics/identity-engine/devices/configure-ca-main.htm) using a **static** SCEP challenge. +* In your text editor, copy and paste the following configuration profile and edit the relevant values: + * `[REPLACE_WITH_CHALLENGE] `with the SCEP challenge you generated in the previous step. + * `[REPLACE_WITH_URL]`with the URL to your SCEP server. + * Adjust the `CN `value according to your organization's needs. You can use any of the [profile variables](https://support.apple.com/en-my/guide/deployment/dep04666af94/1/web/1.0) to uniquely identify your device. In the example `%ComputerName%` `managementAttestation` `%HardwareUUID%,` the certificate Common Name (CN) will contain both the computer name and the hardware UUID. + +```xml + + + + + + PayloadVersion + 1 + PayloadType + Configuration + PayloadIdentifier + Ignored + PayloadUUID + Ignored + PayloadDisplayName + SCEP device attestation + PayloadContent + + + PayloadContent + + Key Type + RSA + Challenge + [REPLACE_WITH_CHALLENGE] + Key Usage + 1 + Keysize + 2048 + URL + [REPLACE_WITH_URL] + AllowAllAppsAccess + + KeyIsExtractable + + Subject + + + + O + Fleet + + + + + CN + %ComputerName% managementAttestation %HardwareUUID% + + + + + PayloadIdentifier + com.apple.security.scep.C2D94E67-4F1A-4A3C-8142-7523A8D35713 + PayloadType + com.apple.security.scep + PayloadUUID + 632289FA-C3E0-481A-A417-BF40012FB729 + PayloadVersion + 1 + + + + + +``` + +* Enforce the configuration profile on your hosts. You can follow [this guide on enforcing custom OS settings in Fleet](https://fleetdm.com/guides/custom-os-settings). +* You can optionally verify the issued certificate by opening Keychain Access on the device or by running a [live query](https://fleetdm.com/guides/get-current-telemetry-from-your-devices-with-live-queries): + +```sql +SELECT * FROM certificates where common_name like '%managementAttestation%'; +``` + +### **Step 3: Configure device management in Okta** + +With Okta Verify installed and an attestation certificate in place, all left is to configure Okta and the device for device management, useful links from the Okta documentation are: + +* [Managed devices](https://help.okta.com/oie/en-us/content/topics/identity-engine/devices/managed-main.htm) +* [Enable and configure Okta Verify](https://help.okta.com/en-us/content/topics/mobile/okta-verify-overview.htm) + +Make sure the device is properly set up in Okta and that the user has used Okta FastPass at least once to see it as managed on the Okta dashboard. + +## Conclusion + +This guide covered how to install Okta Verify on your macOS hosts, issue a SCEP certificate for management attestation, and configure device management in Okta. By automating this process through Fleet, you can enforce multi-factor authentication, improve device security, and ensure that devices accessing your organization’s resources are properly managed. + +For more detailed information on managing devices and using Okta Verify, explore the Okta documentation and Fleet’s guides to optimize your device management strategy further. + +See Fleet's [documentation](https://fleetdm.com/docs/using-fleet) and additional [guides](https://fleetdm.com/guides) for more details on advanced setups, software features, and vulnerability detection. + + + + + + + + From 6fce24c025f81a707fe4d71608471ff182a7ec65 Mon Sep 17 00:00:00 2001 From: JD Date: Mon, 23 Sep 2024 17:49:26 -0600 Subject: [PATCH 57/81] Article: Fleet 4.57.0 release (#22173) --- articles/fleet-4.57.0.md | 97 ++++++++++++++++++ .../articles/fleet-4.57.0-1600x900@2x.png | Bin 0 -> 52073 bytes 2 files changed, 97 insertions(+) create mode 100644 articles/fleet-4.57.0.md create mode 100644 website/assets/images/articles/fleet-4.57.0-1600x900@2x.png diff --git a/articles/fleet-4.57.0.md b/articles/fleet-4.57.0.md new file mode 100644 index 000000000000..4c9f959f9a44 --- /dev/null +++ b/articles/fleet-4.57.0.md @@ -0,0 +1,97 @@ +# Fleet 4.57.0 | Software improvements, policy automation, GitLab support. + +![Fleet 4.57.0](../website/assets/images/articles/fleet-4.57.0-1600x900@2x.png) + +Fleet 4.57.0 is live. Check out the full [changelog](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.57.0) or continue reading to get the highlights. +For upgrade instructions, see our [upgrade guide](https://fleetdm.com/docs/deploying/upgrading-fleet) in the Fleet docs. + +## Highlights +* Software improvements +* Policy automation: install software +* iPhone/iPad BYOD +* GitLab pipelines for GitOps + +### Software improvements + +Fleet allows admins to edit software items directly, offering greater control over software management across hosts. This feature allows IT teams to modify details such as software names or versions, ensuring the software inventory remains accurate and aligned with organizational needs. Additionally, Fleet has introduced the option to uninstall software from hosts, simplifying the removal of unwanted or outdated applications. + +For most cases, Fleet handles the uninstall process automatically, with the uninstall script conveniently located under “Advanced options.” However, Fleet stands out by allowing administrators to view and tweak the script if needed. This flexibility is beneficial when a host is in a unique state or the automatic uninstall process encounters issues. Fleet strives to provide full transparency into what’s under the hood, enabling IT teams to make necessary adjustments for specific scenarios. These updates enhance the efficiency of software management while maintaining flexibility, reflecting Fleet’s commitment to providing user-centric and adaptable solutions. + +### Policy automation: install software + +Admins can automatically trigger software installations when a policy fails, adding a proactive approach to maintaining compliance and security. This feature is handy when a device is found to have a vulnerable version of software installed. If a policy detects this vulnerability, Fleet can automatically install a secure, updated version of the software to remediate the issue and bring the host back into compliance. This automation helps IT teams address vulnerabilities quickly and efficiently, without manual intervention, ensuring that devices across the fleet remain secure and up-to-date. It highlights Fleet’s commitment to streamlining device management and enhancing security through automation. + +### iPhone/iPad BYOD + +Fleet now supports Bring Your Own Device (BYOD) enrollment for iPhone (iOS) and iPad (iPadOS) devices, providing organizations with a more flexible approach to managing employee-owned devices. This feature allows employees to enroll personal iPhones and iPads into Fleet’s Mobile Device Management (MDM) system, enabling IT teams to enforce security policies, manage configurations, and ensure compliance without needing complete control over the entire device. With BYOD enrollment, companies can balance security and privacy, seamlessly managing work-related configurations on personal devices while respecting the end user’s control over their personal data. This update enhances Fleet’s capabilities for managing various devices and supports organizations with modern, flexible workforce environments. + +### GitLab pipelines for GitOps + +Fleet now supports GitLab pipelines for its [GitOps integration](https://github.com/fleetdm/fleet-gitops), expanding the flexibility of how organizations manage their device configurations and policies through version control. With GitLab pipelines, IT teams can automate the deployment and management of Fleet configurations directly from their GitLab repositories, streamlining workflows and ensuring that changes are tracked, tested, and deployed consistently across their fleet. This integration enhances the automation and reliability of device management, enabling teams to adopt a more scalable and auditable approach to managing their Fleet environment. By supporting both GitLab and existing CI/CD tools, Fleet continues to empower organizations to implement modern, efficient workflows for managing configurations and policies. + +## Changes + +**NOTE:** Beginning with Fleet v4.55.0, Fleet no longer supports MySQL 5.7 because it has reached [end of life](https://mattermost.com/blog/mysql-5-7-reached-eol-upgrade-to-mysql-8-x-today/#:~:text=In%20October%202023%2C%20MySQL%205.7,to%20upgrade%20to%20MySQL%208.). The minimum version supported is MySQL 8.0.36. + +**Endpoint Operations** + +- Added support for configuring policy installers via GitOps. +- Added support for policies in "No team" that run on hosts that belong to "No team". +- Added reserved team names: "All teams" and "No team". +- Added support the software status filter for 'No teams' on the hosts page. +- Enable 'No teams' funcitonality for the policies page and associated workflows. +- Added reset install counts and cancel pending installs/uninstalls when GitOps installer updates change package contents. +- Added support for software installer packages, self-service flag, scripts, pre-install query, and self-service availability to be edited in-place rather than deleted and re-added. + +**Device Management (MDM)** + +- Added feature allowing automatic installation of software on hosts that fail policies. +- Added feature for end users to enroll BYOD devices into Fleet MDM. +- Added the ability to use Fleet to uninstall packages from hosts. +- Added an endpoint for getting an OTA MDM profile for enrolling iOS and iPadOS hosts. +- Added protocol support for OTA enrollment and automatic team assignment for hosts. +- Added validation of Setup Assistant profiles on profile upload. +- Added validation to prevent installing software on a host with a pending installation. +- Allowed custom SCEP CA certificates with any kind of extendedKeyUsage attributes. +- Modified `POST /api/latest/fleet/software/batch` endpoint to be asynchronous and added a new endpoint `GET /api/latest/fleet/software/batch/{request_uuid}` to retrieve the result of the batch upload. + +**Vulnerability Management** + +- Fixed a false negative vulnerability for git. +- Fixed false positive vulnerabilities for minio. +- Fixed an issue where virtual box for macOS wasn't matching against the NVD product name. +- Fixed Ubuntu python package false positive vulnerabilities by removing duplicate entries for ubuntu python packages installed by dpkg and renaming remaining pip installed packages to match OVAL definitions. + +**Bug fixes and improvements** + +- Updated Go to go1.23.1. +- Removed validation of APNS certificate from server startup. +- Removed invalid node keys from server logs. +- Improved the UX of turning off MDM on an offline host. +- Improved clarity of GitOps VPP app ID type errors. +- Improved gitops error message about enabling windows MDM. +- Improved messaging for VPP token constraint errors. +- Improved loading state for UI tables when no data is present yet. +- Improved permissions so that hosts can no longer access installers that aren't directly assigned to them. +- Improved verification of premium license before uploading VPP tokens. +- Added "0 items" description on empty software tables for UI consistency. +- Updated the macos target minimum version tooltip. +- Fixed logic to properly catch and log APNs errors. +- Fixed UI overflow issues with OS settings table data. +- Fixed regression for checking email used to get a signed CSR. +- Fixed bugs on enrollment profiles when the organization name contains invalid XML characters. +- Fixed an issue with cron profiles delivery failing if a Windows VM is enrolled twice. +- Fixed issue where Fleet server could start when an expired ABM certificate was provided as server config. +- Fixed self-service checkbox appearing when iOS or iPadOS app is selected. + + +## Ready to upgrade? + +Visit our [Upgrade guide](https://fleetdm.com/docs/deploying/upgrading-fleet) in the Fleet docs for instructions on updating to Fleet 4.57.0. + + + + + + + diff --git a/website/assets/images/articles/fleet-4.57.0-1600x900@2x.png b/website/assets/images/articles/fleet-4.57.0-1600x900@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ec48ddd12ae989659546fb0944c8160c01d040b0 GIT binary patch literal 52073 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 C3X5_8 literal 0 HcmV?d00001 From c06eb1387e865f1acb0a8b9566bfca020a99b917 Mon Sep 17 00:00:00 2001 From: JD Date: Mon, 23 Sep 2024 17:49:37 -0600 Subject: [PATCH 58/81] Article: Guide BYOD enroll iOS iPadOS (#22281) --- articles/enroll-byod-ios-ipados-hosts.md | 42 ++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 articles/enroll-byod-ios-ipados-hosts.md diff --git a/articles/enroll-byod-ios-ipados-hosts.md b/articles/enroll-byod-ios-ipados-hosts.md new file mode 100644 index 000000000000..31c070b2d5e7 --- /dev/null +++ b/articles/enroll-byod-ios-ipados-hosts.md @@ -0,0 +1,42 @@ +# Enroll BYOD iOS/iPadOS hosts + +This guide will walk you through the process of inviting BYOD (Bring Your Own Device) iPhones and iPads to enroll in Fleet. + +By enrolling BYOD iPhones and iPads in Fleet, IT admins can manage software installations, enforce settings, and ensure devices comply with company policies. By adding BYOD devices, you can monitor, enforce settings, and manage security on BYOD iPhones and iPads in real-time, providing enhanced control without compromising user autonomy. This helps secure access to organizational resources while maintaining control over device configurations. + +## Prerequisites + +* Fleet [v4.57.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.57.0). +* [MDM enabled and configured](https://fleetdm.com/guides/macos-mdm-setup) + +## Enrolling BYOD iPad/iOS devices in Fleet + +* **Step 1: Navigate to the manage hosts page** + * Click “Hosts” in the top navigation bar +* **Step 2: Choose the team** + * Select the desired [team](https://fleetdm.com/guides/teams) from the menu at the top of the screen +* **Step 3: Get a link to share with your end users** + * Click on “Add hosts.” + * In the modal, select the **iOS & iPadOS** tab. + * Copy the link to enroll hosts. +* **Step 4: Distribute the link** + * Share the link with your end users using an introductory email or message. + * The link provides instructions to guide users through downloading and installing Fleet’s enrollment profile. + +> Each team has a unique URL that includes the team's enrollment secret. This enrollment secret ensures that devices are assigned to the correct team during enrollment. When an incorrect enroll secret is provided, users can still download the enrollment profile, but the enrollment itself will fail (403 error). + +## Conclusion + +This guide covered how to invite and enroll BYOD iPhones and iPads into Fleet. This allows IT admins to manage software, enforce settings, and ensure compliance with organizational policies. Streamlining the enrollment process will enable you to secure access to company resources while maintaining control over end-user devices. + +For more information on device management and other features, explore Fleet’s documentation and guides to optimize your setup and keep your devices fully secure. + +See Fleet's [documentation](https://fleetdm.com/docs/using-fleet) and additional [guides](https://fleetdm.com/guides) for more details on advanced setups, software features, and vulnerability detection. + + + + + + + + From b9a5107fc40c4d974b2da0f16ddc623705289f3d Mon Sep 17 00:00:00 2001 From: JD Date: Mon, 23 Sep 2024 17:50:12 -0600 Subject: [PATCH 59/81] Article deploy software packages (#22245) Article: Guide update deploy software packages https://github.com/fleetdm/fleet/issues/21841 --------- Co-authored-by: Ian Littman --- articles/deploy-security-agents.md | 97 --------------- articles/deploy-software-packages.md | 177 +++++++++++++++++++++++++++ website/config/routes.js | 5 + 3 files changed, 182 insertions(+), 97 deletions(-) delete mode 100644 articles/deploy-security-agents.md create mode 100644 articles/deploy-software-packages.md diff --git a/articles/deploy-security-agents.md b/articles/deploy-security-agents.md deleted file mode 100644 index 20d6cd28abec..000000000000 --- a/articles/deploy-security-agents.md +++ /dev/null @@ -1,97 +0,0 @@ -# Deploy security agents - -![Deploy security agents](../website/assets/images/articles/deploy-security-agents-1600x900@2x.png) - -Fleet [v4.50.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.50.0) introduced the ability to upload and deploy security agents to your hosts. Beyond a [bootstrap package](https://fleetdm.com/docs/using-fleet/mdm-macos-setup-experience#bootstrap-package) at enrollment, deploying security agents allows you to specify and verify device configuration using a pre-enrollment osquery query and customization of the install and post-install scripts, allowing for key and license deployment and configuration. This guide will walk you through the steps to upload, configure, and install a security agent to hosts in your fleet. - -## Prerequisites - -* Fleet [v4.50.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.50.0). -* `fleetd` 1.25.0 deployed via MDM or built with the `--scripts-enabled` flag. -* An S3 bucket [configured](https://fleetdm.com/docs/configuration/fleet-server-configuration#s-3-software-installers-bucket) to store the installers. -* Increase any load balancer timeouts to at least 5 minutes for the following endpoints: - * [Add software](https://fleetdm.com/docs/rest-api/rest-api#add-software). - * [Batch-apply software](https://fleetdm.com/docs/rest-api/rest-api#add-software). - -## Step-by-step instructions - -### Access security agent installers - -To access and manage security agents in Fleet: - -* **Navigate to the Software page**: Click on the "Software" tab in the main navigation menu. -* **Select a team**: Click on the dropdown at the top left of the page. -* **Find your software**: using the filters on the top of the table, you can choose between: - * “Available for install” filters software that can be installed on your hosts. - * “Self-service” filters software that end users can install from Fleet Desktop. -* **Select security agent installer**: Click on a software package to view details and access additional actions for the agent installer. - -### Add a security agent to a team - -* **Navigate to the Software page**: Click on the "Software" tab in the main navigation menu. -* **Select a team**: Select a team or the "No team" team to add a security agent. - -> Security agents cannot be added to "All teams" - -* Click the “Add Software” button in the top right corner, and a modal will appear. -* Choose a file to upload. `.pkg`, `.msi`, `.exe`, or `.deb` files are supported. -* After selecting a file, a default install script will be pre-filled. If the security agent requires a custom installation process, this script can be edited. -* To allow users to install the software from Fleet Desktop, check the “Self-service” checkbox. -* To customize the conditions, click on “Advanced options”: - * **Pre-install condition**: A pre-install condition is a valid osquery SQL statement that will be evaluated on the host before installing the software. If provided, the installation will proceed only if the query returns any value. - * **Post-install script** A post-install script will run after the installation is complete, allowing you to configure the security agent right after installation. If this script returns a non-zero exit code, the installation will fail, and `fleetd` will attempt to uninstall the software. - -### Install a security agent on a host - -After an installer is added to a team, it can be installed on hosts via the UI. - -* **Navigate to the Hosts page**: Click on the "Hosts" tab in the main navigation menu. -* **Navigate to the Host details page**: Click the host you want to install the security agent. -* **Navigate to the Host software tab**: In the host details, search for the tab named “Software” -* **Find your security agent**: Use the search bar and filters to search for your security agent. -* **Install the security agent on the host**: In the leftmost row of the table, click on “Actions” > “Install.” -* **Track installation status**: by either - * Checking the “Install status” in the host software table. - * Navigate to the “Details” tab on the host details page and check the activity log. - -### Edit a security agent - -Security agent installers can’t be edited via the UI. To modify an installer, remove it from the UI and add a new one. - -### Remove a security agent from a team - -* **Navigate to the Software page**: Click on the "Software" tab in the main navigation menu. -* **Select a team**: Select a team or the "No team" team to add a security agent. -* **Find your software**: using the filters on the top of the table, you can choose between: - * “Available for install” filters software can be installed on your hosts. - * “Self-service” filters software that users can install from Fleet Desktop. -* **Select security agent installer**: Click on a software package to view details. -* **Remove security agent installer**: From the Actions menu, select "Delete." Click the "Delete" button on the modal. - -> Removing a security agent from a team will not uninstall the agent from the existing host(s). - -### Manage security agents with the REST API - -Fleet also provides a REST API for managing software programmatically. The API allows you to add, update, retrieve, list, and delete software. Detailed documentation on Fleet's [REST API is available](https://fleetdm.com/docs/rest-api/rest-api#software). - -### Manage security agents with GitOps - -Installers for security agents can be managed via `fleetctl` using [GitOps](https://fleetdm.com/docs/using-fleet/gitops). - -Please refer to the documentation specific to [managing software with GitOps](https://fleetdm.com/docs/using-fleet/gitops#software). For a real-world example, [see how we manage software at Fleet](https://github.com/fleetdm/fleet/tree/main/it-and-security/teams). - - -## Conclusion - -Deploying security agents with Fleet is straightforward and ensures your hosts are protected with the latest security measures. This guide has shown you how to access, add, and install security agents, as well as manage them using the REST API and `fleetctl`. Following these steps can effectively equip your fleet with the necessary security tools. - -See Fleet's [documentation](https://fleetdm.com/docs/using-fleet) and additional [guides](https://fleetdm.com/guides) for more details on advanced setups, software features, and vulnerability detection. - - - - - - - - - diff --git a/articles/deploy-software-packages.md b/articles/deploy-software-packages.md new file mode 100644 index 000000000000..92aa0901ccf1 --- /dev/null +++ b/articles/deploy-software-packages.md @@ -0,0 +1,177 @@ +# Deploy software packages + +![Deploy software](../website/assets/images/articles/deploy-security-agents-1600x900@2x.png) + +Fleet [v4.50.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.50.0) introduced the ability to upload and deploy software to your hosts. Fleet [v4.57.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.57.0) added the ability to include an uninstall script and edit software details. Beyond a [bootstrap package](https://fleetdm.com/docs/using-fleet/mdm-macos-setup-experience#bootstrap-package) at enrollment, deploying software allows you to specify and verify device configuration using a pre-install query and customization of the install, post-install, and uninstall scripts, allowing for key and license deployment and configuration. Admins can modify these options and settings after the initial upload. This guide will walk you through the steps to upload, configure, install, and uninstall a software package to hosts in your fleet. + +## Prerequisites + +* Fleet [v4.57.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.57.0). + +* `fleetd` 1.25.0 deployed via MDM or built with the `--scripts-enabled` flag. + +> `fleetd` prior to 1.33.0 will use a hard-coded uninstall script to clean up from a failed install. As of 1.33.0, the (default or customized) uninstall script will be used to clean up failed installs. + +* An S3 bucket [configured](https://fleetdm.com/docs/configuration/fleet-server-configuration#s-3-software-installers-bucket) to store the installers. + +* Increase any load balancer timeouts to at least 5 minutes for the [Add software](https://fleetdm.com/docs/rest-api/rest-api#add-software) endpoint. + +## Step-by-step instructions + +### Access software packages + +To access and manage software in Fleet: + +* **Navigate to the Software page**: Click on the "Software" tab in the main navigation menu. + +* **Select a team**: Click on the dropdown at the top left of the page. + +> Software packages are tied to a specific team. This allows you to, for example, test a newer release of an application within your IT team before rolling it out to the rest of your organization, or deploy the appropriate architecture-specific installer to both Intel and Apple Silicon Macs. + +* **Find your software**: using the filters on the top of the table, you can choose between: + + * “Available for install” filters software that can be installed on your hosts. + + * “Self-service” filters software that end users can install from Fleet Desktop. + +* **Select software package**: Click on a software package to view details and access additional actions for the software. + +### Add a software package to a team + +* **Navigate to the Software page**: Click on the "Software" tab in the main navigation menu. + +* **Select a team**: Select a team "No team" to add a software package. + +> Software cannot be added to "All teams." + +* Click the “Add Software” button in the top right corner, and a dialog will appear. + +* Choose a file to upload. `.pkg`, `.msi`, `.exe`, and `.deb` files are supported. + +> Software installer uploads will fail if Fleet is unable to extract information from the installer package such bundle ID and version number. + +* To allow users to install the software from Fleet Desktop, check the “Self-service” checkbox. + +* To customize installer behavior, click on “Advanced options.” + +> After the initial package upload, all options can be modified, including the self-service setting, pre-install query, scripts, and even the software package file. When replacing an installer package, the replacement package must be the same type and for the same software as the original package. + +#### Pre-install query + +A pre-install query is a valid osquery SQL statement that will be evaluated on the host before installing the software. If provided, the installation will proceed only if the query returns any value. + +#### Install script + +After selecting a file, a default install script will be pre-filled. If the software package requires a custom installation process (for example, if [an EXE-based Windows installer requires custom handling](https://fleetdm.com/learn-more-about/exe-install-scripts)), this script can be edited. When the script is run, the `$INSTALLER_PATH` environment variable will be set by `fleetd` to where the installer is being run. + +#### Post-install script + +A post-install script will run after the installation, allowing you to, for example, configure the security agent right after installation. If this script returns a non-zero exit code, the installation will fail, and `fleetd` will attempt to uninstall the software. + +#### Uninstall script + +An uninstall script will run when an admin chooses to uninstall the software from the host on the host details page, or if an install fails for hosts running `fleetd` 1.33.0 or later. Like the install script, a default uninstall script will be pre-filled after selecting a file. This script can be edited if the software package requires a custom uninstallation process. + +In addition to the `$INSTALLER_PATH` environment variable supported by install scripts, you can use `$PACKAGE_ID` in uninstall scripts as a placeholder for the package IDs (for .pkg files), package name (for Linux installers), product code (for MSIs), or software name (for EXE installers). The Fleet server will substitute `$PACKAGE_ID` on upload. + +### Install a software package on a host + +After a software package is added to a team, it can be installed on hosts via the UI. + +* **Navigate to the Hosts page**: Click on the "Hosts" tab in the main navigation menu. + +* **Navigate to the Host details page**: Click the host you want to install the software package. + +* **Navigate to the Host software tab**: In the host details, search for the tab named “Software.” + +* **Find your software package**: Use the dropdown to select software “Available for install” or use the search bar to search for your software package by name. + +* **Install the software package on the host**: In the rightmost column of the table, click on “Actions” > “Install.” Installation will happen automatically or when the host comes online. + +* **Track installation status**: by either + + * Checking the status column in the host software table. + + * Navigate to the “Details” tab on the host details page and check the activity log. + +### Edit a software package + +* **Navigate to the Software page**: Click on the "Software" tab in the main navigation menu. + +* **Select a team**: Select a team (or "No team") to switch to the team whose software you want to edit. + +* **Find your software**: using the filters on the top of the table, you can choose between: + + * “Available for install” filters software can be installed on your hosts. + + * “Self-service” filters software that users can install from Fleet Desktop. + +* **Select software package**: Click on a software package to view details. + +* **Edit software package**: From the Actions menu, select "Edit." + +> Editing the pre-install query, install script, post-install script, or uninstall script cancels all pending installations and uninstallations for that package, except for installs and uninstalls that are currently running on a host. If a new software package is uploaded, in addition to canceling pending installs and uninstalls, host counts (for installs and pending and failed installs and uninstalls) will be reset to zero, so counts reflect the currently uploaded version of the package. + +### Uninstall a software package on a host + +After a software package is installed on a host, it can be uninstalled on the host via the UI. + +* **Navigate to the Hosts page**: Click on the "Hosts" tab in the main navigation menu. + +* **Navigate to the Host details page**: Click the host you want to uninstall the software package. + +* **Navigate to the Host software tab**: In the host details, search for the tab named “Software.” + +* **Find your software package**: Use the dropdown to select software “Available for install” or use the search bar to search for your software package by name. + +* **Uninstall the software package from the host**: In the rightmost column of the table, click on “Actions” > “Uninstall.” Uninstallation will happen automatically or when the host comes online. + +* **Track uninstallation status**: by either + + * Checking the status column in the host software table. + + * Navigate to the “Details” tab on the host details page and check the activity log. + +### Remove a software package from a team + +* **Navigate to the Software page**: Click on the "Software" tab in the main navigation menu. + +* **Select a team**: Select a team (or "No team") to switch to the team whose software you want to remove. + +* **Find your software**: using the filters on the top of the table, you can choose between: + + * “Available for install” filters software can be installed on your hosts. + + * “Self-service” filters software that users can install from Fleet Desktop. + +* **Select software package**: Click on a software package to view details. + +* **Remove software package**: From the Actions menu, select "Delete." Click the "Delete" button on the dialog. + +> Removing a software package from a team will cancel pending installs for hosts that are not in the middle of installing the software but will not uninstall the software from hosts where it is already installed. + +### Manage software with the REST API + +Fleet also provides a REST API for managing software programmatically. The API allows you to add, update, retrieve, list, and delete software. Detailed documentation on Fleet's [REST API is available]([https://fleetdm.com/docs/rest-api/rest-api#software](https://fleetdm.com/docs/rest-api/rest-api#software)), including endpoints for installing and uninstalling packages. + +### Manage software with GitOps + +Software packages can be managed via `fleetctl` using [GitOps](https://fleetdm.com/docs/using-fleet/gitops). + +Please refer to the documentation for [managing software with GitOps](https://fleetdm.com/docs/using-fleet/gitops#software), for a real-world example, [see how we manage software at Fleet](https://github.com/fleetdm/fleet/tree/main/it-and-security/teams). + +> When managing software installers via GitOps, the Fleet server receiving GitOps requests (**not** the machine running fleetctl as part of the GitOps workflow) will download installers from the specified URLs directly. + +## Conclusion + +Managing software with Fleet is straightforward and ensures your hosts are equipped with the latest tools. This guide has outlined how to access, add, edit, and remove software packages from a team, install and uninstall from specific hosts, and use the REST API and `fleetctl` to manage software packages. By following these steps, you can effectively maintain software packages across your fleet. + +For more information on advanced setups and features, explore Fleet’s [documentation](https://fleetdm.com/docs/using-fleet) and additional [guides](https://fleetdm.com/guides). + + + + + + + + diff --git a/website/config/routes.js b/website/config/routes.js index 57d1c0608bd8..28fdbbf106ed 100644 --- a/website/config/routes.js +++ b/website/config/routes.js @@ -324,6 +324,7 @@ module.exports.routes = { 'GET /use-cases/get-and-stay-compliant-across-your-devices-with-fleet': '/securing/get-and-stay-compliant-across-your-devices-with-fleet', 'GET /use-cases/import-and-export-queries-and-packs-in-fleet': '/guides/import-and-export-queries-and-packs-in-fleet', 'GET /guides/import-and-export-queries-and-packs-in-fleet': '/guides/import-and-export-queries-in-fleet', + 'GET /guides/deploy-security-agents': '/guides/deploy-software-packages', 'GET /use-cases/locate-assets-with-osquery': '/guides/locate-assets-with-osquery', 'GET /use-cases/osquery-a-tool-to-easily-ask-questions-about-operating-systems': '/guides/osquery-a-tool-to-easily-ask-questions-about-operating-systems', 'GET /use-cases/osquery-consider-joining-against-the-users-table': '/guides/osquery-consider-joining-against-the-users-table', @@ -564,6 +565,10 @@ module.exports.routes = { 'GET /learn-more-about/apple-business-manager-teams-api': 'https://github.com/fleetdm/fleet/blob/main/docs/Contributing/API-for-contributors.md#update-abm-tokens-teams', 'GET /learn-more-about/apple-business-manager-gitops': '/docs/using-fleet/gitops#apple-business-manager', 'GET /learn-more-about/s3-bootstrap-package': '/docs/configuration/fleet-server-configuration#s-3-software-installers-bucket', + 'GET /learn-more-about/exe-install-scripts': '/guides/exe-install-scripts', + 'GET /learn-more-about/install-scripts': '/guides/deploy-software-packages#install-script', + 'GET /learn-more-about/uninstall-scripts': '/guides/deploy-software-packages#uninstall-script', + 'GET /learn-more-about/read-package-version': '/guides/deploy-software-packages##add-a-software-package-to-a-team', // Sitemap // ============================================================================================================= From c51c20a10b2221bba514736a0c8123575fdfb36f Mon Sep 17 00:00:00 2001 From: Luke Heath Date: Mon, 23 Sep 2024 19:02:23 -0500 Subject: [PATCH 60/81] Adding changes for Fleet v4.57.0 (#22109) (#22327) --- CHANGELOG.md | 53 +++++++++++++++++++ changes/17558-validation-errs | 2 - changes/18897-shoe-zeroes | 1 - changes/19442-ubuntu-python-packages | 1 - changes/19551-policy-software-automations | 1 - changes/19808-prof | 1 - changes/20320-uninstall-packages | 1 - changes/20404-edit-software | 1 - changes/20535-sw-table-loading | 1 - changes/20757-profiles-batch-activity | 1 - ...-cron-with-duplicate-host-uuid-windows-mdm | 1 - changes/20828-better-appid-error | 1 - changes/20846-vuln-virtual-box | 1 - changes/20868-turn-off-mdm | 1 - changes/20895-policy-software-install-gitops | 1 - changes/21019-ota-enrollment | 1 - changes/21264-fix-reserved-team-names | 2 - changes/21315-vpp-premium-license | 1 - ...-improve-windows-mdm-enabled-error-message | 1 - changes/21404-minio-false-positive | 1 - .../21412-remove-node-key-from-server-logs | 1 - .../21428-policy-automatic-install-software | 1 - ...21428-prevent-install-when-already-pending | 1 - changes/21462-host-vulnerability-filter | 1 - changes/21467-policies-for-no-team | 1 - changes/21468-no-teams-policies | 1 - changes/21557-ota-profile-endpoint | 1 - changes/21559-add-end-user-enrolment-page | 1 - changes/21612-edit-software-gitops | 1 - changes/21683-apns-cert-validation-on-start | 2 - changes/21779-git-false-negative | 1 - changes/21796-fix-vpp-self-service-checkbox | 1 - changes/21813-email-err | 2 - changes/21866-startup-expired-abm-cert | 2 - changes/21890-vpp-token-error | 1 - .../21976-update-macos-target-version-tooltip | 1 - changes/22069-gitops-async-software-batch | 1 - .../22136-software-status-no-teams-hosts-page | 1 - changes/22158-scep | 1 - .../7476-fix-ui-overflow-os-settings-table | 1 - changes/apns-errors | 1 - changes/hosts-can-access-any-software | 1 - changes/update-go1.23.1 | 1 - charts/fleet/Chart.yaml | 2 +- charts/fleet/values.yaml | 2 +- .../dogfood/terraform/aws/variables.tf | 2 +- .../dogfood/terraform/gcp/variables.tf | 2 +- terraform/addons/vuln-processing/variables.tf | 4 +- terraform/byo-vpc/byo-db/byo-ecs/variables.tf | 4 +- terraform/byo-vpc/byo-db/variables.tf | 4 +- terraform/byo-vpc/example/main.tf | 2 +- terraform/byo-vpc/variables.tf | 4 +- terraform/example/main.tf | 4 +- terraform/variables.tf | 4 +- tools/fleetctl-npm/package.json | 2 +- 55 files changed, 71 insertions(+), 65 deletions(-) delete mode 100644 changes/17558-validation-errs delete mode 100644 changes/18897-shoe-zeroes delete mode 100644 changes/19442-ubuntu-python-packages delete mode 100644 changes/19551-policy-software-automations delete mode 100644 changes/19808-prof delete mode 100644 changes/20320-uninstall-packages delete mode 100644 changes/20404-edit-software delete mode 100644 changes/20535-sw-table-loading delete mode 100644 changes/20757-profiles-batch-activity delete mode 100644 changes/20764-fix-cron-with-duplicate-host-uuid-windows-mdm delete mode 100644 changes/20828-better-appid-error delete mode 100644 changes/20846-vuln-virtual-box delete mode 100644 changes/20868-turn-off-mdm delete mode 100644 changes/20895-policy-software-install-gitops delete mode 100644 changes/21019-ota-enrollment delete mode 100644 changes/21264-fix-reserved-team-names delete mode 100644 changes/21315-vpp-premium-license delete mode 100644 changes/21402-improve-windows-mdm-enabled-error-message delete mode 100644 changes/21404-minio-false-positive delete mode 100644 changes/21412-remove-node-key-from-server-logs delete mode 100644 changes/21428-policy-automatic-install-software delete mode 100644 changes/21428-prevent-install-when-already-pending delete mode 100644 changes/21462-host-vulnerability-filter delete mode 100644 changes/21467-policies-for-no-team delete mode 100644 changes/21468-no-teams-policies delete mode 100644 changes/21557-ota-profile-endpoint delete mode 100644 changes/21559-add-end-user-enrolment-page delete mode 100644 changes/21612-edit-software-gitops delete mode 100644 changes/21683-apns-cert-validation-on-start delete mode 100644 changes/21779-git-false-negative delete mode 100644 changes/21796-fix-vpp-self-service-checkbox delete mode 100644 changes/21813-email-err delete mode 100644 changes/21866-startup-expired-abm-cert delete mode 100644 changes/21890-vpp-token-error delete mode 100644 changes/21976-update-macos-target-version-tooltip delete mode 100644 changes/22069-gitops-async-software-batch delete mode 100644 changes/22136-software-status-no-teams-hosts-page delete mode 100644 changes/22158-scep delete mode 100644 changes/7476-fix-ui-overflow-os-settings-table delete mode 100644 changes/apns-errors delete mode 100644 changes/hosts-can-access-any-software delete mode 100644 changes/update-go1.23.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e8745665715..f1f4dd2cee3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,56 @@ +## Fleet 4.57.0 (Sep 23, 2024) + +**Endpoint Operations** + +- Added support for configuring policy installers via GitOps. +- Added support for policies in "No team" that run on hosts that belong to "No team". +- Added reserved team names: "All teams" and "No team". +- Added support the software status filter for 'No teams' on the hosts page. +- Enable 'No teams' funcitonality for the policies page and associated workflows. +- Added reset install counts and cancel pending installs/uninstalls when GitOps installer updates change package contents. +- Added support for software installer packages, self-service flag, scripts, pre-install query, and self-service availability to be edited in-place rather than deleted and re-added. + +**Device Management (MDM)** + +- Added feature allowing automatic installation of software on hosts that fail policies. +- Added feature for end users to enroll BYOD devices into Fleet MDM. +- Added the ability to use Fleet to uninstall packages from hosts. +- Added an endpoint for getting an OTA MDM profile for enrolling iOS and iPadOS hosts. +- Added protocol support for OTA enrollment and automatic team assignment for hosts. +- Added validation of Setup Assistant profiles on profile upload. +- Added validation to prevent installing software on a host with a pending installation. +- Allowed custom SCEP CA certificates with any kind of extendedKeyUsage attributes. +- Modified `POST /api/latest/fleet/software/batch` endpoint to be asynchronous and added a new endpoint `GET /api/latest/fleet/software/batch/{request_uuid}` to retrieve the result of the batch upload. + +**Vulnerability Management** + +- Fixed a false negative vulnerability for git. +- Fixed false positive vulnerabilities for minio. +- Fixed an issue where virtual box for macOS wasn't matching against the NVD product name. +- Fixed Ubuntu python package false positive vulnerabilities by removing duplicate entries for ubuntu python packages installed by dpkg and renaming remaining pip installed packages to match OVAL definitions. + +**Bug fixes and improvements** + +- Updated Go to go1.23.1. +- Removed validation of APNS certificate from server startup. +- Removed invalid node keys from server logs. +- Improved the UX of turning off MDM on an offline host. +- Improved clarity of GitOps VPP app ID type errors. +- Improved gitops error message about enabling windows MDM. +- Improved messaging for VPP token constraint errors. +- Improved loading state for UI tables when no data is present yet. +- Improved permissions so that hosts can no longer access installers that aren't directly assigned to them. +- Improved verification of premium license before uploading VPP tokens. +- Added "0 items" description on empty software tables for UI consistency. +- Updated the macos target minimum version tooltip. +- Fixed logic to properly catch and log APNs errors. +- Fixed UI overflow issues with OS settings table data. +- Fixed regression for checking email used to get a signed CSR. +- Fixed bugs on enrollment profiles when the organization name contains invalid XML characters. +- Fixed an issue with cron profiles delivery failing if a Windows VM is enrolled twice. +- Fixed issue where Fleet server could start when an expired ABM certificate was provided as server config. +- Fixed self-service checkbox appearing when iOS or iPadOS app is selected. + ## Fleet 4.56.0 (Sep 7, 2024) ### Endpoint operations diff --git a/changes/17558-validation-errs b/changes/17558-validation-errs deleted file mode 100644 index 115c9bf14e03..000000000000 --- a/changes/17558-validation-errs +++ /dev/null @@ -1,2 +0,0 @@ -- Adds validation of Setup Assistant profiles on profile upload, giving users immediate feedback on -the validity of the profile. \ No newline at end of file diff --git a/changes/18897-shoe-zeroes b/changes/18897-shoe-zeroes deleted file mode 100644 index 7faddd522dd6..000000000000 --- a/changes/18897-shoe-zeroes +++ /dev/null @@ -1 +0,0 @@ -Added "0 items" description on empty software tables for UI consistency diff --git a/changes/19442-ubuntu-python-packages b/changes/19442-ubuntu-python-packages deleted file mode 100644 index 0be7e95616a1..000000000000 --- a/changes/19442-ubuntu-python-packages +++ /dev/null @@ -1 +0,0 @@ -- Addressing Ubuntu python package false positive vulnerabilities by removing duplicate entries for ubuntu python packages installed by dpkg and renaming remaining pip installed packages to match OVAL definitions. \ No newline at end of file diff --git a/changes/19551-policy-software-automations b/changes/19551-policy-software-automations deleted file mode 100644 index 4b88cb4c1fba..000000000000 --- a/changes/19551-policy-software-automations +++ /dev/null @@ -1 +0,0 @@ -* Implement features allowing automatic installation of software on hosts that fail policies. diff --git a/changes/19808-prof b/changes/19808-prof deleted file mode 100644 index 71d19f8c4bc3..000000000000 --- a/changes/19808-prof +++ /dev/null @@ -1 +0,0 @@ -* Fixed bugs on enrollment profiles when the organization name contains invalid XML characters. diff --git a/changes/20320-uninstall-packages b/changes/20320-uninstall-packages deleted file mode 100644 index 89ab8928419c..000000000000 --- a/changes/20320-uninstall-packages +++ /dev/null @@ -1 +0,0 @@ -* Implement the ability to use Fleet to uninstall packages from hosts. \ No newline at end of file diff --git a/changes/20404-edit-software b/changes/20404-edit-software deleted file mode 100644 index ec65b392b41a..000000000000 --- a/changes/20404-edit-software +++ /dev/null @@ -1 +0,0 @@ -* Software installer packages, self-service flag, scripts, pre-install query, and self-service availability can now be edited in-place rather than needing to be deleted and re-added. diff --git a/changes/20535-sw-table-loading b/changes/20535-sw-table-loading deleted file mode 100644 index d144ce782cce..000000000000 --- a/changes/20535-sw-table-loading +++ /dev/null @@ -1 +0,0 @@ -* Improve loading state for DataTables when no data is present yet \ No newline at end of file diff --git a/changes/20757-profiles-batch-activity b/changes/20757-profiles-batch-activity deleted file mode 100644 index 6b110b87c768..000000000000 --- a/changes/20757-profiles-batch-activity +++ /dev/null @@ -1 +0,0 @@ -API endpoint `/api/v1/fleet/mdm/profiles/batch` will now not log an activity for profile types that did not change in the database (Apple configuration profiles, Windows configuration profiles, or Apple declarations). diff --git a/changes/20764-fix-cron-with-duplicate-host-uuid-windows-mdm b/changes/20764-fix-cron-with-duplicate-host-uuid-windows-mdm deleted file mode 100644 index df19c08bc84b..000000000000 --- a/changes/20764-fix-cron-with-duplicate-host-uuid-windows-mdm +++ /dev/null @@ -1 +0,0 @@ -* Fixed an issue where cron profiles delivery fails if a Windows VM is enrolled twice with the same `host_uuid` / `mdm_device_id`. diff --git a/changes/20828-better-appid-error b/changes/20828-better-appid-error deleted file mode 100644 index 540c8fcbfa28..000000000000 --- a/changes/20828-better-appid-error +++ /dev/null @@ -1 +0,0 @@ -- Improve clarity of gitops VPP app ID type errors diff --git a/changes/20846-vuln-virtual-box b/changes/20846-vuln-virtual-box deleted file mode 100644 index 225dd0be2274..000000000000 --- a/changes/20846-vuln-virtual-box +++ /dev/null @@ -1 +0,0 @@ -- resolved an issue where virtual box for macOS wasn't matching against the vm_virtualbox NVD product name \ No newline at end of file diff --git a/changes/20868-turn-off-mdm b/changes/20868-turn-off-mdm deleted file mode 100644 index bfcd35d3150b..000000000000 --- a/changes/20868-turn-off-mdm +++ /dev/null @@ -1 +0,0 @@ -- Improves the UX of turning off MDM on an offline host (endpoint doesn't error anymore) \ No newline at end of file diff --git a/changes/20895-policy-software-install-gitops b/changes/20895-policy-software-install-gitops deleted file mode 100644 index 774f6a4bfe35..000000000000 --- a/changes/20895-policy-software-install-gitops +++ /dev/null @@ -1 +0,0 @@ -* Added support for configuring policy installers via GitOps. diff --git a/changes/21019-ota-enrollment b/changes/21019-ota-enrollment deleted file mode 100644 index b43db060a77f..000000000000 --- a/changes/21019-ota-enrollment +++ /dev/null @@ -1 +0,0 @@ -* Implement protocol support for OTA enrollment and automatic team assignment for hosts. diff --git a/changes/21264-fix-reserved-team-names b/changes/21264-fix-reserved-team-names deleted file mode 100644 index 6363b8186977..000000000000 --- a/changes/21264-fix-reserved-team-names +++ /dev/null @@ -1,2 +0,0 @@ -- Prevents teams with the name "All teams" or "No team" from being created (these are reserved team - names in Fleet). \ No newline at end of file diff --git a/changes/21315-vpp-premium-license b/changes/21315-vpp-premium-license deleted file mode 100644 index 2fd081703e47..000000000000 --- a/changes/21315-vpp-premium-license +++ /dev/null @@ -1 +0,0 @@ -- Verify user has premium license before uploading VPP tokens diff --git a/changes/21402-improve-windows-mdm-enabled-error-message b/changes/21402-improve-windows-mdm-enabled-error-message deleted file mode 100644 index 36dc6082f6e3..000000000000 --- a/changes/21402-improve-windows-mdm-enabled-error-message +++ /dev/null @@ -1 +0,0 @@ -- Improve gitops error message about enabling windows MDM diff --git a/changes/21404-minio-false-positive b/changes/21404-minio-false-positive deleted file mode 100644 index 57b4245e45d2..000000000000 --- a/changes/21404-minio-false-positive +++ /dev/null @@ -1 +0,0 @@ -- resolved issue where minio was reporting false positive vulnerabilities due to a mismatch in version strings \ No newline at end of file diff --git a/changes/21412-remove-node-key-from-server-logs b/changes/21412-remove-node-key-from-server-logs deleted file mode 100644 index c6555bd5bc99..000000000000 --- a/changes/21412-remove-node-key-from-server-logs +++ /dev/null @@ -1 +0,0 @@ -* Removed invalid node keys from server logs. diff --git a/changes/21428-policy-automatic-install-software b/changes/21428-policy-automatic-install-software deleted file mode 100644 index e61dc2a9eadc..000000000000 --- a/changes/21428-policy-automatic-install-software +++ /dev/null @@ -1 +0,0 @@ -* Added automatic installation of software packages using policy automations. diff --git a/changes/21428-prevent-install-when-already-pending b/changes/21428-prevent-install-when-already-pending deleted file mode 100644 index d01006d6f91d..000000000000 --- a/changes/21428-prevent-install-when-already-pending +++ /dev/null @@ -1 +0,0 @@ -* Added validation to `POST /api/_version_/fleet/hosts/{host_id}/software/install/{software_title_id}` to prevent installing on a host that already has a pending installation for that software title. diff --git a/changes/21462-host-vulnerability-filter b/changes/21462-host-vulnerability-filter deleted file mode 100644 index e55fb8c8363b..000000000000 --- a/changes/21462-host-vulnerability-filter +++ /dev/null @@ -1 +0,0 @@ -- fixed issue where the vulnerability filter was returning software not vulnerable for the currently selected host \ No newline at end of file diff --git a/changes/21467-policies-for-no-team b/changes/21467-policies-for-no-team deleted file mode 100644 index 4613cd39edaf..000000000000 --- a/changes/21467-policies-for-no-team +++ /dev/null @@ -1 +0,0 @@ -* Added support for policies in "No team" that run on hosts that belong to "No team". diff --git a/changes/21468-no-teams-policies b/changes/21468-no-teams-policies deleted file mode 100644 index d11adda1b8c8..000000000000 --- a/changes/21468-no-teams-policies +++ /dev/null @@ -1 +0,0 @@ -* Enable 'No teams' funcitonality for the policies page and associated workflows. \ No newline at end of file diff --git a/changes/21557-ota-profile-endpoint b/changes/21557-ota-profile-endpoint deleted file mode 100644 index 4acf2bbcf5e9..000000000000 --- a/changes/21557-ota-profile-endpoint +++ /dev/null @@ -1 +0,0 @@ -- Adds an endpoint for getting an OTA MDM profile for enrolling iOS and iPadOS hosts. \ No newline at end of file diff --git a/changes/21559-add-end-user-enrolment-page b/changes/21559-add-end-user-enrolment-page deleted file mode 100644 index 427f1c5beb06..000000000000 --- a/changes/21559-add-end-user-enrolment-page +++ /dev/null @@ -1 +0,0 @@ -- add feature for end users to enroll their device into fleet mdm diff --git a/changes/21612-edit-software-gitops b/changes/21612-edit-software-gitops deleted file mode 100644 index 9a157286d49b..000000000000 --- a/changes/21612-edit-software-gitops +++ /dev/null @@ -1 +0,0 @@ -* Reset install counts and cancel pending installs/uninstalls when GitOps installer updates change package contents diff --git a/changes/21683-apns-cert-validation-on-start b/changes/21683-apns-cert-validation-on-start deleted file mode 100644 index 9f1714359931..000000000000 --- a/changes/21683-apns-cert-validation-on-start +++ /dev/null @@ -1,2 +0,0 @@ -- Removed validation of APNS certificate from server startup. This was no longer necessary because - we now allow for APNS certificates to be renewed in the UI. diff --git a/changes/21779-git-false-negative b/changes/21779-git-false-negative deleted file mode 100644 index 080dfe1a4ea7..000000000000 --- a/changes/21779-git-false-negative +++ /dev/null @@ -1 +0,0 @@ -- fixed a false negative vulnerability for git \ No newline at end of file diff --git a/changes/21796-fix-vpp-self-service-checkbox b/changes/21796-fix-vpp-self-service-checkbox deleted file mode 100644 index 6ec7e46db9c1..000000000000 --- a/changes/21796-fix-vpp-self-service-checkbox +++ /dev/null @@ -1 +0,0 @@ -- Fixed self-service checkbox appearing when iOS or iPadOS app is selected. diff --git a/changes/21813-email-err b/changes/21813-email-err deleted file mode 100644 index a9d25ecc2195..000000000000 --- a/changes/21813-email-err +++ /dev/null @@ -1,2 +0,0 @@ -- Fixed regression: we now check if the email used to get a signed CSR is invalid (i.e. is an email - from a free email provider). \ No newline at end of file diff --git a/changes/21866-startup-expired-abm-cert b/changes/21866-startup-expired-abm-cert deleted file mode 100644 index f9e74bb6413c..000000000000 --- a/changes/21866-startup-expired-abm-cert +++ /dev/null @@ -1,2 +0,0 @@ -- Fixed issue where Fleet server could start when expired ABM cerfificate was provided as server - config options. diff --git a/changes/21890-vpp-token-error b/changes/21890-vpp-token-error deleted file mode 100644 index da03734ecabd..000000000000 --- a/changes/21890-vpp-token-error +++ /dev/null @@ -1 +0,0 @@ -- Improve messaging for VPP token constraint errors diff --git a/changes/21976-update-macos-target-version-tooltip b/changes/21976-update-macos-target-version-tooltip deleted file mode 100644 index 5ae1a5ffdf3b..000000000000 --- a/changes/21976-update-macos-target-version-tooltip +++ /dev/null @@ -1 +0,0 @@ -- update the macos target minimum version tooltip diff --git a/changes/22069-gitops-async-software-batch b/changes/22069-gitops-async-software-batch deleted file mode 100644 index 35f0652fe209..000000000000 --- a/changes/22069-gitops-async-software-batch +++ /dev/null @@ -1 +0,0 @@ -* Modified `POST /api/latest/fleet/software/batch` endpoint to be asynchronous and added a new endpoint `GET /api/latest/fleet/software/batch/{request_uuid}` to retrieve the result of the batch upload. diff --git a/changes/22136-software-status-no-teams-hosts-page b/changes/22136-software-status-no-teams-hosts-page deleted file mode 100644 index 6ede2684710d..000000000000 --- a/changes/22136-software-status-no-teams-hosts-page +++ /dev/null @@ -1 +0,0 @@ -* Support the software status filter for 'No teams' on the hosts page \ No newline at end of file diff --git a/changes/22158-scep b/changes/22158-scep deleted file mode 100644 index ab7557468018..000000000000 --- a/changes/22158-scep +++ /dev/null @@ -1 +0,0 @@ -* Allow custom SCEP CA certificates with any kind of extendedKeyUsage attributes. diff --git a/changes/7476-fix-ui-overflow-os-settings-table b/changes/7476-fix-ui-overflow-os-settings-table deleted file mode 100644 index 6c95925de8f5..000000000000 --- a/changes/7476-fix-ui-overflow-os-settings-table +++ /dev/null @@ -1 +0,0 @@ -- fixes UI overflow issues with OS settings table data diff --git a/changes/apns-errors b/changes/apns-errors deleted file mode 100644 index 6de48617a1c1..000000000000 --- a/changes/apns-errors +++ /dev/null @@ -1 +0,0 @@ -* Fixed logic to properly catch and log APNs errors. diff --git a/changes/hosts-can-access-any-software b/changes/hosts-can-access-any-software deleted file mode 100644 index 0fbcae035acd..000000000000 --- a/changes/hosts-can-access-any-software +++ /dev/null @@ -1 +0,0 @@ -- Hosts can no longer access installers that aren't directly assigned to it diff --git a/changes/update-go1.23.1 b/changes/update-go1.23.1 deleted file mode 100644 index 22a59cdc400b..000000000000 --- a/changes/update-go1.23.1 +++ /dev/null @@ -1 +0,0 @@ -* Updated Go to go1.23.1 diff --git a/charts/fleet/Chart.yaml b/charts/fleet/Chart.yaml index adc22108c2d0..c23438bf22aa 100644 --- a/charts/fleet/Chart.yaml +++ b/charts/fleet/Chart.yaml @@ -8,7 +8,7 @@ version: v6.2.0 home: https://github.com/fleetdm/fleet sources: - https://github.com/fleetdm/fleet.git -appVersion: v4.56.0 +appVersion: v4.57.0 dependencies: - name: mysql condition: mysql.enabled diff --git a/charts/fleet/values.yaml b/charts/fleet/values.yaml index 040a539a8376..03539df9da98 100644 --- a/charts/fleet/values.yaml +++ b/charts/fleet/values.yaml @@ -3,7 +3,7 @@ hostName: fleet.localhost replicas: 3 # The number of Fleet instances to deploy imageRepository: fleetdm/fleet -imageTag: v4.56.0 # Version of Fleet to deploy +imageTag: v4.57.0 # Version of Fleet to deploy podAnnotations: {} # Additional annotations to add to the Fleet pod serviceAccountAnnotations: {} # Additional annotations to add to the Fleet service account resources: diff --git a/infrastructure/dogfood/terraform/aws/variables.tf b/infrastructure/dogfood/terraform/aws/variables.tf index db7a79e5e140..2020de2f8306 100644 --- a/infrastructure/dogfood/terraform/aws/variables.tf +++ b/infrastructure/dogfood/terraform/aws/variables.tf @@ -56,7 +56,7 @@ variable "database_name" { variable "fleet_image" { description = "the name of the container image to run" - default = "fleetdm/fleet:v4.56.0" + default = "fleetdm/fleet:v4.57.0" } variable "software_inventory" { diff --git a/infrastructure/dogfood/terraform/gcp/variables.tf b/infrastructure/dogfood/terraform/gcp/variables.tf index ba81f4af537b..906a58c153f8 100644 --- a/infrastructure/dogfood/terraform/gcp/variables.tf +++ b/infrastructure/dogfood/terraform/gcp/variables.tf @@ -68,7 +68,7 @@ variable "redis_mem" { } variable "image" { - default = "fleetdm/fleet:v4.56.0" + default = "fleetdm/fleet:v4.57.0" } variable "software_installers_bucket_name" { diff --git a/terraform/addons/vuln-processing/variables.tf b/terraform/addons/vuln-processing/variables.tf index feb850667dcc..8d296903fdc4 100644 --- a/terraform/addons/vuln-processing/variables.tf +++ b/terraform/addons/vuln-processing/variables.tf @@ -24,7 +24,7 @@ variable "fleet_config" { vuln_processing_cpu = optional(number, 2048) vuln_data_stream_mem = optional(number, 1024) vuln_data_stream_cpu = optional(number, 512) - image = optional(string, "fleetdm/fleet:v4.56.0") + image = optional(string, "fleetdm/fleet:v4.57.0") family = optional(string, "fleet-vuln-processing") sidecars = optional(list(any), []) extra_environment_variables = optional(map(string), {}) @@ -82,7 +82,7 @@ variable "fleet_config" { vuln_processing_cpu = 2048 vuln_data_stream_mem = 1024 vuln_data_stream_cpu = 512 - image = "fleetdm/fleet:v4.56.0" + image = "fleetdm/fleet:v4.57.0" family = "fleet-vuln-processing" sidecars = [] extra_environment_variables = {} diff --git a/terraform/byo-vpc/byo-db/byo-ecs/variables.tf b/terraform/byo-vpc/byo-db/byo-ecs/variables.tf index 0270c8fb5219..27565cb90fa8 100644 --- a/terraform/byo-vpc/byo-db/byo-ecs/variables.tf +++ b/terraform/byo-vpc/byo-db/byo-ecs/variables.tf @@ -16,7 +16,7 @@ variable "fleet_config" { mem = optional(number, 4096) cpu = optional(number, 512) pid_mode = optional(string, null) - image = optional(string, "fleetdm/fleet:v4.56.0") + image = optional(string, "fleetdm/fleet:v4.57.0") family = optional(string, "fleet") sidecars = optional(list(any), []) depends_on = optional(list(any), []) @@ -119,7 +119,7 @@ variable "fleet_config" { mem = 512 cpu = 256 pid_mode = null - image = "fleetdm/fleet:v4.56.0" + image = "fleetdm/fleet:v4.57.0" family = "fleet" sidecars = [] depends_on = [] diff --git a/terraform/byo-vpc/byo-db/variables.tf b/terraform/byo-vpc/byo-db/variables.tf index 0044e48e5c8c..041ff9d0f861 100644 --- a/terraform/byo-vpc/byo-db/variables.tf +++ b/terraform/byo-vpc/byo-db/variables.tf @@ -77,7 +77,7 @@ variable "fleet_config" { mem = optional(number, 4096) cpu = optional(number, 512) pid_mode = optional(string, null) - image = optional(string, "fleetdm/fleet:v4.56.0") + image = optional(string, "fleetdm/fleet:v4.57.0") family = optional(string, "fleet") sidecars = optional(list(any), []) depends_on = optional(list(any), []) @@ -205,7 +205,7 @@ variable "fleet_config" { mem = 512 cpu = 256 pid_mode = null - image = "fleetdm/fleet:v4.56.0" + image = "fleetdm/fleet:v4.57.0" family = "fleet" sidecars = [] depends_on = [] diff --git a/terraform/byo-vpc/example/main.tf b/terraform/byo-vpc/example/main.tf index 887b907b303a..3176d07def1f 100644 --- a/terraform/byo-vpc/example/main.tf +++ b/terraform/byo-vpc/example/main.tf @@ -17,7 +17,7 @@ provider "aws" { } locals { - fleet_image = "fleetdm/fleet:v4.56.0" + fleet_image = "fleetdm/fleet:v4.57.0" domain_name = "example.com" } diff --git a/terraform/byo-vpc/variables.tf b/terraform/byo-vpc/variables.tf index cba22bf845ca..ce2a81f88c41 100644 --- a/terraform/byo-vpc/variables.tf +++ b/terraform/byo-vpc/variables.tf @@ -170,7 +170,7 @@ variable "fleet_config" { mem = optional(number, 4096) cpu = optional(number, 512) pid_mode = optional(string, null) - image = optional(string, "fleetdm/fleet:v4.56.0") + image = optional(string, "fleetdm/fleet:v4.57.0") family = optional(string, "fleet") sidecars = optional(list(any), []) depends_on = optional(list(any), []) @@ -298,7 +298,7 @@ variable "fleet_config" { mem = 512 cpu = 256 pid_mode = null - image = "fleetdm/fleet:v4.56.0" + image = "fleetdm/fleet:v4.57.0" family = "fleet" sidecars = [] depends_on = [] diff --git a/terraform/example/main.tf b/terraform/example/main.tf index 33b6f5221ea3..2b2112517925 100644 --- a/terraform/example/main.tf +++ b/terraform/example/main.tf @@ -63,8 +63,8 @@ module "fleet" { fleet_config = { # To avoid pull-rate limiting from dockerhub, consider using our quay.io mirror - # for the Fleet image. e.g. "quay.io/fleetdm/fleet:v4.56.0" - image = "fleetdm/fleet:v4.56.0" # override default to deploy the image you desire + # for the Fleet image. e.g. "quay.io/fleetdm/fleet:v4.57.0" + image = "fleetdm/fleet:v4.57.0" # override default to deploy the image you desire # See https://fleetdm.com/docs/deploy/reference-architectures#aws for appropriate scaling # memory and cpu. autoscaling = { diff --git a/terraform/variables.tf b/terraform/variables.tf index 5933307f11f5..7dc798cf63d8 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -218,7 +218,7 @@ variable "fleet_config" { mem = optional(number, 4096) cpu = optional(number, 512) pid_mode = optional(string, null) - image = optional(string, "fleetdm/fleet:v4.56.0") + image = optional(string, "fleetdm/fleet:v4.57.0") family = optional(string, "fleet") sidecars = optional(list(any), []) depends_on = optional(list(any), []) @@ -346,7 +346,7 @@ variable "fleet_config" { mem = 512 cpu = 256 pid_mode = null - image = "fleetdm/fleet:v4.56.0" + image = "fleetdm/fleet:v4.57.0" family = "fleet" sidecars = [] depends_on = [] diff --git a/tools/fleetctl-npm/package.json b/tools/fleetctl-npm/package.json index 0db37e98d5d1..96a4dcd08170 100644 --- a/tools/fleetctl-npm/package.json +++ b/tools/fleetctl-npm/package.json @@ -1,6 +1,6 @@ { "name": "fleetctl", - "version": "v4.56.0", + "version": "v4.57.0", "description": "Installer for the fleetctl CLI tool", "bin": { "fleetctl": "./run.js" From 752c2c0310becfaf3f92a468c29495c87bd64d52 Mon Sep 17 00:00:00 2001 From: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> Date: Mon, 23 Sep 2024 23:07:55 -0500 Subject: [PATCH 61/81] Remove weird format thing (#22333) --- handbook/company/leadership.md | 1 - 1 file changed, 1 deletion(-) diff --git a/handbook/company/leadership.md b/handbook/company/leadership.md index d89b81639f1a..1cad2e84de28 100644 --- a/handbook/company/leadership.md +++ b/handbook/company/leadership.md @@ -414,7 +414,6 @@ Although it's sad to see someone go, Fleet understands that not everything is me 4. **CEO**: The CEO will make an announcement during the "🌈 Weekly Update" post on Friday in the `#general` channel on Slack. -<<<<<<< HEAD ## Changing someone's position From time to time, someone's job title changes. To do this, reach out to [Digital Experience](https://fleetdm.com/handbook/digital-experience). From bd96663a5f96cc4f7e0a353c05d37b53f82ceb9b Mon Sep 17 00:00:00 2001 From: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> Date: Tue, 24 Sep 2024 01:23:25 -0500 Subject: [PATCH 62/81] Add Kendra to team table (#22334) --- handbook/sales/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/handbook/sales/README.md b/handbook/sales/README.md index c27cbc8785ec..46688864e581 100644 --- a/handbook/sales/README.md +++ b/handbook/sales/README.md @@ -10,6 +10,7 @@ This handbook page details processes specific to working [with](#contact-us) and | Chief Revenue Officer (CRO) | [Alex Mitchell](https://www.linkedin.com/in/alexandercmitchell/) _([@alexmitchelliii](https://github.com/alexmitchelliii))_ | Solutions Consulting (SC) | [Dave Herder](https://www.linkedin.com/in/daveherder/) _([@dherder](https://github.com/dherder))_
[Zach Wasserman](https://www.linkedin.com/in/zacharywasserman/) _([@zwass](https://github.com/zwass))_
[Allen Houchins](https://www.linkedin.com/in/allenhouchins/) _([@allenhouchins](https://github.com/allenhouchins))_
[Harrison Ravazzolo](https://www.linkedin.com/in/harrison-ravazzolo/) _([@harrisonravazzolo](https://github.com/harrisonravazzolo))_ | Channel Sales | [Tom Ostertag](https://www.linkedin.com/in/tom-ostertag-77212791/) _([@tomostertag](https://github.com/TomOstertag))_ +| Sr. Account Executive | [Kendra McKeever](https://www.linkedin.com/in/kendramckeever/) _([@KendraAtFleet](https://github.com/KendraAtFleet))_ | Account Executive (AE) | [Patricia Ambrus](https://www.linkedin.com/in/pambrus/) _([@ambrusps](https://github.com/ambrusps))_
[Anthony Snyder](https://www.linkedin.com/in/anthonysnyder8/) _([@anthonysnyder8](https://github.com/AnthonySnyder8))_
[Paul Tardif](https://www.linkedin.com/in/paul-t-750833/) _([@phtardif1](https://github.com/phtardif1))_ From 111b243f667c79cfce1725fc6638364341fb5a2c Mon Sep 17 00:00:00 2001 From: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> Date: Tue, 24 Sep 2024 03:49:40 -0500 Subject: [PATCH 63/81] Add steps to enable email sync (#22335) --- handbook/digital-experience/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/handbook/digital-experience/README.md b/handbook/digital-experience/README.md index 1fec6328ca71..34f77f2b9fe3 100644 --- a/handbook/digital-experience/README.md +++ b/handbook/digital-experience/README.md @@ -450,7 +450,11 @@ Here are the steps we take to grant appropriate Salesforce licenses to a new hir - Sign DocuSign sent to the email. - The order will be processed in ~30m. - Once the basic license has been added, you can create a new user using the new team member's `@fleetdm.com` email and assign a license to it. -- To also assign a user an "Inbox license", go to the ["Setup" page](https://fleetdm.lightning.force.com/lightning/setup/SetupOneHome/home) and select "User > Permission sets". Find the [inbox permission set](https://fleetdm.lightning.force.com/lightning/setup/PermSets/page?address=%2F005%3Fid%3D0PS4x000002uUn2%26isUserEntityOverride%3D1%26SetupNode%3DPermSets%26sfdcIFrameOrigin%3Dhttps%253A%252F%252Ffleetdm.lightning.force.com%26clc%3D1) and assign it to the new team member. + - To enable email sync for a user: + - Navigate to the [user’s record](https://fleetdm.lightning.force.com/lightning/setup/ManageUsers/home) and scroll to the bottom of the permission set section. + - Add the “Inbox with Einstein Activity Capture” permission set and save. + - Navigate to the ["Einstein Activity Capture Settings"](https://fleetdm.lightning.force.com/lightning/setup/ActivitySyncEngineSettingsMain/home) and click the "Configurations" tab. + - Select "Edit", under "User and Profile Assignments" move the new user's name from "Available" to "Selected", scroll all the way down and click save. ### Change the "Integrations admin" Salesforce account password From aa38b10fd1b2da7ecc21b1f02e419153bb3079ad Mon Sep 17 00:00:00 2001 From: F1 <96719298+F1Feng@users.noreply.github.com> Date: Tue, 24 Sep 2024 21:47:15 +0800 Subject: [PATCH 64/81] fix: #22297 re-enable Escrow Buddy in the auth-db (#22298) fix: #22297 re-enable Escrow Buddy in the auth-db --- orbit/pkg/update/escrow_buddy.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/orbit/pkg/update/escrow_buddy.go b/orbit/pkg/update/escrow_buddy.go index e1f6fdf1160d..b226da9a24ce 100644 --- a/orbit/pkg/update/escrow_buddy.go +++ b/orbit/pkg/update/escrow_buddy.go @@ -5,8 +5,9 @@ import ( "sync" "time" - "github.com/fleetdm/fleet/v4/server/fleet" "github.com/rs/zerolog/log" + + "github.com/fleetdm/fleet/v4/server/fleet" ) // EscrowBuddyRunner sets up [Escrow Buddy][1] to rotate FileVault keys on @@ -86,6 +87,13 @@ func (e *EscrowBuddyRunner) Run(cfg *fleet.OrbitConfig) error { } } + // Some macOS updates and upgrades reset the authorization database to its default state + // which will deactivate Escrow Buddy and prevent FileVault key generation upon next login. + log.Debug().Msg("EscrowBuddyRunner: re-enable Escrow Buddy in the authorization database") + if err := e.setAuthDBSetup(); err != nil { + return fmt.Errorf("failed to re-enable Escrow Buddy in the authorization database, err: %w", err) + } + log.Debug().Msg("EscrowBuddyRunner: enabling disk encryption rotation") if err := e.setGenerateNewKeyTo(true); err != nil { return fmt.Errorf("enabling disk encryption rotation: %w", err) @@ -118,3 +126,13 @@ func (e *EscrowBuddyRunner) setGenerateNewKeyTo(enabled bool) error { } return fn("sh", "-c", cmd) } + +func (e *EscrowBuddyRunner) setAuthDBSetup() error { + log.Debug().Msg("ready to re-enable Escrow Buddy in the authorization database") + cmd := "/Library/Security/SecurityAgentPlugins/Escrow\\ Buddy.bundle/Contents/Resources/AuthDBSetup.sh" + fn := e.runCmdFunc + if fn == nil { + fn = runCmdCollectErr + } + return fn("sh", "-c", cmd) +} From f0babb7d6114ccceb9cabc45d0d96d6ca61ef815 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Tue, 24 Sep 2024 09:49:22 -0400 Subject: [PATCH 65/81] Permissions guide: Apple Business Manager and Volume Purchasing Program (#22336) - ABM and VPP CRUD - Use APNs language to be consistent w/ product and docs --- articles/role-based-access.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/articles/role-based-access.md b/articles/role-based-access.md index 95fc712c5252..fcdae9a8d421 100644 --- a/articles/role-based-access.md +++ b/articles/role-based-access.md @@ -79,9 +79,10 @@ GitOps is an API-only and write-only role that can be used on CI/CD pipelines. | Edit agent options for hosts assigned to teams\* | | | | ✅ | ✅ | | Initiate [file carving](https://fleetdm.com/docs/using-fleet/rest-api#file-carving) | | | ✅ | ✅ | | | Retrieve contents from file carving | | | | ✅ | | -| View Apple mobile device management (MDM) certificate information | | | | ✅ | | -| View Apple business manager (BM) information | | | | ✅ | | -| Generate Apple mobile device management (MDM) certificate signing request (CSR) | | | | ✅ | | +| Create Apple Push Certificates service (APNs) certificate signing request (CSR) | | | | ✅ | | +| View, edit, and delete APNs certificate | | | | ✅ | | +| View, edit, and delete Apple Business Manager (ABM) connections | | | | ✅ | | +| View, edit, and delete Volume Purchasing Program (VPP) connections | | | | ✅ | | | View disk encryption key for macOS and Windows hosts | ✅ | ✅ | ✅ | ✅ | | | Edit OS updates for macOS, Windows, iOS, and iPadOS hosts | | | ✅ | ✅ | ✅ | | Create, edit, resend and delete configuration profiles for macOS and Windows hosts | | | ✅ | ✅ | ✅ | From f5a75877f3193df7eb1a237e15fa1b31ccc07a30 Mon Sep 17 00:00:00 2001 From: Gabriel Hernandez Date: Tue, 24 Sep 2024 15:47:55 +0100 Subject: [PATCH 66/81] update the help text of macOS min version input (#22337) relates to #21976 This updates the help text for the macOS min version input. ![image](https://github.com/user-attachments/assets/ef20ad99-7592-41bc-959e-a90129c47f66) --- .../AppleOSTargetForm/AppleOSTargetForm.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx b/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx index 755b59d093a0..fdf534328259 100644 --- a/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx +++ b/frontend/pages/ManageControlsPage/OSUpdates/components/AppleOSTargetForm/AppleOSTargetForm.tsx @@ -5,12 +5,13 @@ import { APP_CONTEXT_NO_TEAM_ID } from "interfaces/team"; import { NotificationContext } from "context/notification"; import configAPI from "services/entities/config"; import teamsAPI from "services/entities/teams"; +import { ApplePlatform } from "interfaces/platform"; // @ts-ignore import InputField from "components/forms/fields/InputField"; import Button from "components/buttons/Button"; import validatePresence from "components/forms/validators/validate_presence"; -import { ApplePlatform } from "interfaces/platform"; +import CustomLink from "components/CustomLink"; const baseClass = "apple-os-target-form"; @@ -197,7 +198,16 @@ const AppleOSTargetForm = ({ + Use only versions available from Apple.{" "} + + + } value={minOsVersion} error={minOsVersionError} onChange={handleMinVersionChange} From 3b001ea07c21dc52c6a11dfdd3db0115d67dddb0 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Tue, 24 Sep 2024 09:02:48 -0700 Subject: [PATCH 67/81] Fleet UI: Host status dropdown styling fixes (#22314) --- .../hosts/ManageHostsPage/ManageHostsPage.tsx | 7 +------ frontend/pages/hosts/ManageHostsPage/_styles.scss | 15 +-------------- .../hosts/details/cards/Software/_styles.scss | 2 +- .../pages/queries/ManageQueriesPage/_styles.scss | 2 +- 4 files changed, 4 insertions(+), 22 deletions(-) diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx index 6464f4d59bf4..7c95b74cfcab 100644 --- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx +++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx @@ -1430,16 +1430,11 @@ const ManageHostsPage = ({ ? selectedLabel : undefined; - const statusDropdownClassnames = classNames( - `${baseClass}__status_dropdown`, - { [`${baseClass}__status-dropdown-sandbox`]: isSandboxMode } - ); - return (
Date: Tue, 24 Sep 2024 09:04:10 -0700 Subject: [PATCH 68/81] Fleet UI: Fix self-service icon from cutting off (#22310) --- .../cards/Software/SelfService/SelfServiceItem/_styles.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/pages/hosts/details/cards/Software/SelfService/SelfServiceItem/_styles.scss b/frontend/pages/hosts/details/cards/Software/SelfService/SelfServiceItem/_styles.scss index eb21c7d118a8..9b4ae26e5ec3 100644 --- a/frontend/pages/hosts/details/cards/Software/SelfService/SelfServiceItem/_styles.scss +++ b/frontend/pages/hosts/details/cards/Software/SelfService/SelfServiceItem/_styles.scss @@ -13,7 +13,7 @@ &__item-topline { display: flex; flex-direction: row; - height: 64px; + height: 66px; align-items: center; gap: 16px; overflow: hidden; From 31ac40828f06cbb6f34877c90be3d94c1c62b201 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Tue, 24 Sep 2024 09:05:39 -0700 Subject: [PATCH 69/81] Fleet UI: Hide redundant built in label filtering (#22308) --- changes/21343-hide-redundant-built-in-label-pills | 1 + .../HostsFilterBlock/HostsFilterBlock.tsx | 13 +++++++++++++ .../components/LabelFilterSelect/_styles.scss | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 changes/21343-hide-redundant-built-in-label-pills diff --git a/changes/21343-hide-redundant-built-in-label-pills b/changes/21343-hide-redundant-built-in-label-pills new file mode 100644 index 000000000000..92baea5ba52f --- /dev/null +++ b/changes/21343-hide-redundant-built-in-label-pills @@ -0,0 +1 @@ +- UI: Remove redundant built in label filter pills diff --git a/frontend/pages/hosts/ManageHostsPage/components/HostsFilterBlock/HostsFilterBlock.tsx b/frontend/pages/hosts/ManageHostsPage/components/HostsFilterBlock/HostsFilterBlock.tsx index 62dc63ed56de..f3ea242e686f 100644 --- a/frontend/pages/hosts/ManageHostsPage/components/HostsFilterBlock/HostsFilterBlock.tsx +++ b/frontend/pages/hosts/ManageHostsPage/components/HostsFilterBlock/HostsFilterBlock.tsx @@ -24,6 +24,7 @@ import { import { PLATFORM_LABEL_DISPLAY_NAMES, + PLATFORM_TYPE_ICONS, isPlatformLabelNameFromAPI, PolicyResponse, } from "utilities/constants"; @@ -41,6 +42,8 @@ import BootstrapPackageStatusFilter from "../BootstrapPackageStatusFilter/Bootst const baseClass = "hosts-filter-block"; +type PlatformLabelNameFromAPI = keyof typeof PLATFORM_TYPE_ICONS; + interface IHostsFilterBlockProps { /** * An object of params the the HostFilterBlock uses to render the correct @@ -145,6 +148,16 @@ const HostsFilterBlock = ({ PLATFORM_LABEL_DISPLAY_NAMES[display_text]) || display_text; + // Hide built-in labels supported in label dropdown + if ( + label_type === "builtin" && + Object.keys(PLATFORM_TYPE_ICONS).includes( + display_text as PlatformLabelNameFromAPI + ) + ) { + return <>; + } + return ( <> Date: Tue, 24 Sep 2024 11:58:15 -0500 Subject: [PATCH 70/81] Update README.md (#22347) --- handbook/sales/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/handbook/sales/README.md b/handbook/sales/README.md index 46688864e581..1ddb627e25e9 100644 --- a/handbook/sales/README.md +++ b/handbook/sales/README.md @@ -10,8 +10,7 @@ This handbook page details processes specific to working [with](#contact-us) and | Chief Revenue Officer (CRO) | [Alex Mitchell](https://www.linkedin.com/in/alexandercmitchell/) _([@alexmitchelliii](https://github.com/alexmitchelliii))_ | Solutions Consulting (SC) | [Dave Herder](https://www.linkedin.com/in/daveherder/) _([@dherder](https://github.com/dherder))_
[Zach Wasserman](https://www.linkedin.com/in/zacharywasserman/) _([@zwass](https://github.com/zwass))_
[Allen Houchins](https://www.linkedin.com/in/allenhouchins/) _([@allenhouchins](https://github.com/allenhouchins))_
[Harrison Ravazzolo](https://www.linkedin.com/in/harrison-ravazzolo/) _([@harrisonravazzolo](https://github.com/harrisonravazzolo))_ | Channel Sales | [Tom Ostertag](https://www.linkedin.com/in/tom-ostertag-77212791/) _([@tomostertag](https://github.com/TomOstertag))_ -| Sr. Account Executive | [Kendra McKeever](https://www.linkedin.com/in/kendramckeever/) _([@KendraAtFleet](https://github.com/KendraAtFleet))_ -| Account Executive (AE) | [Patricia Ambrus](https://www.linkedin.com/in/pambrus/) _([@ambrusps](https://github.com/ambrusps))_
[Anthony Snyder](https://www.linkedin.com/in/anthonysnyder8/) _([@anthonysnyder8](https://github.com/AnthonySnyder8))_
[Paul Tardif](https://www.linkedin.com/in/paul-t-750833/) _([@phtardif1](https://github.com/phtardif1))_ +| Account Executive (AE) | [Patricia Ambrus](https://www.linkedin.com/in/pambrus/) _([@ambrusps](https://github.com/ambrusps))_
[Anthony Snyder](https://www.linkedin.com/in/anthonysnyder8/) _([@anthonysnyder8](https://github.com/AnthonySnyder8))_
[Paul Tardif](https://www.linkedin.com/in/paul-t-750833/) _([@phtardif1](https://github.com/phtardif1))_
[Kendra McKeever](https://www.linkedin.com/in/kendramckeever/) _([@KendraAtFleet](https://github.com/KendraAtFleet))_ ## Contact us From db1c374eef0dd65577474e86963f47318b27d7ee Mon Sep 17 00:00:00 2001 From: Roberto Dip Date: Tue, 24 Sep 2024 14:17:32 -0300 Subject: [PATCH 71/81] fix TestEscrowBuddy/TestEscrowBuddyRotatesKey test (#22345) fix a broken test introduced in aa38b10fd1b2da7ecc21b1f02e419153bb3079ad --- orbit/pkg/update/escrow_buddy_test.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/orbit/pkg/update/escrow_buddy_test.go b/orbit/pkg/update/escrow_buddy_test.go index 0ed61883b03f..ccd30938341d 100644 --- a/orbit/pkg/update/escrow_buddy_test.go +++ b/orbit/pkg/update/escrow_buddy_test.go @@ -65,9 +65,11 @@ func (s *escrowBuddyTestSuite) TestEscrowBuddyRotatesKey() { err = r.Run(cfg) require.NoError(t, err) - require.Len(t, cmdCalls, 1) + require.Len(t, cmdCalls, 2) require.Equal(t, cmdCalls[0]["cmd"], "sh") - require.Equal(t, cmdCalls[0]["args"], []string{"-c", "defaults write /Library/Preferences/com.netflix.Escrow-Buddy.plist GenerateNewKey -bool true"}) + require.Equal(t, cmdCalls[0]["args"], []string{"-c", "/Library/Security/SecurityAgentPlugins/Escrow\\ Buddy.bundle/Contents/Resources/AuthDBSetup.sh"}) + require.Equal(t, cmdCalls[1]["cmd"], "sh") + require.Equal(t, cmdCalls[1]["args"], []string{"-c", "defaults write /Library/Preferences/com.netflix.Escrow-Buddy.plist GenerateNewKey -bool true"}) targets = runner.updater.opt.Targets require.Len(t, targets, 1) @@ -77,10 +79,12 @@ func (s *escrowBuddyTestSuite) TestEscrowBuddyRotatesKey() { time.Sleep(3 * time.Millisecond) cfg.Notifications.RotateDiskEncryptionKey = false + cmdCalls = []map[string]any{} err = r.Run(cfg) require.NoError(t, err) - require.Len(t, cmdCalls, 2) - require.Equal(t, cmdCalls[1]["cmd"], "sh") - require.Equal(t, cmdCalls[1]["args"], []string{"-c", "defaults write /Library/Preferences/com.netflix.Escrow-Buddy.plist GenerateNewKey -bool false"}) + // only one call to set the GenerateNewKey to false + require.Len(t, cmdCalls, 1) + require.Equal(t, cmdCalls[0]["cmd"], "sh") + require.Equal(t, cmdCalls[0]["args"], []string{"-c", "defaults write /Library/Preferences/com.netflix.Escrow-Buddy.plist GenerateNewKey -bool false"}) } From 8428f193faf443975da5b8bc9ff8e92a56d199a8 Mon Sep 17 00:00:00 2001 From: Lucas Manuel Rodriguez Date: Tue, 24 Sep 2024 14:25:51 -0300 Subject: [PATCH 72/81] Move settings to no-team.yml (#22343) Moving settings for hosts in "No team" from `default.yml` to `teams/no-team.yml`. --- it-and-security/default.yml | 23 ----------------------- it-and-security/teams/no-team.yml | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 23 deletions(-) create mode 100644 it-and-security/teams/no-team.yml diff --git a/it-and-security/default.yml b/it-and-security/default.yml index 52baadb564d1..9b60ffb92cd7 100644 --- a/it-and-security/default.yml +++ b/it-and-security/default.yml @@ -1,27 +1,5 @@ agent_options: path: ./lib/agent-options.yml -controls: - enable_disk_encryption: true - macos_migration: - enable: true - mode: voluntary - webhook_url: $DOGFOOD_MACOS_MIGRATION_WEBHOOK_URL - macos_settings: - custom_settings: null - macos_setup: - bootstrap_package: "" - enable_end_user_authentication: false - macos_setup_assistant: null - macos_updates: - deadline: "2023-06-13" - minimum_version: 13.4.1 - windows_enabled_and_configured: true - windows_settings: - custom_settings: [] - windows_updates: - deadline_days: 3 - grace_period_days: 2 - scripts: [] org_settings: features: enable_host_users: true @@ -90,4 +68,3 @@ org_settings: policies: queries: - path: ./lib/collect-fleetd-update-channels.queries.yml -software: diff --git a/it-and-security/teams/no-team.yml b/it-and-security/teams/no-team.yml new file mode 100644 index 000000000000..ef6baf9e40fb --- /dev/null +++ b/it-and-security/teams/no-team.yml @@ -0,0 +1,25 @@ +name: No team +policies: +controls: + enable_disk_encryption: true + macos_migration: + enable: true + mode: voluntary + webhook_url: $DOGFOOD_MACOS_MIGRATION_WEBHOOK_URL + macos_settings: + custom_settings: null + macos_setup: + bootstrap_package: "" + enable_end_user_authentication: false + macos_setup_assistant: null + macos_updates: + deadline: "2023-06-13" + minimum_version: 13.4.1 + windows_enabled_and_configured: true + windows_settings: + custom_settings: [] + windows_updates: + deadline_days: 3 + grace_period_days: 2 + scripts: [] +software: From f0753cfdb3c8ac8257cc078394e3a60da62d8a63 Mon Sep 17 00:00:00 2001 From: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:08:32 -0500 Subject: [PATCH 73/81] Add redirects for all security files (#22344) --- website/config/routes.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/website/config/routes.js b/website/config/routes.js index 28fdbbf106ed..abdcf8c94558 100644 --- a/website/config/routes.js +++ b/website/config/routes.js @@ -353,6 +353,11 @@ module.exports.routes = { 'GET /device-management/fleet-user-stories-wayfair': '/success-stories/fleet-user-stories-wayfair', 'GET /handbook/security': '/handbook/digital-experience/security', 'GET /handbook/security/security-policies':'/handbook/digital-experience/security-policies#information-security-policy-and-acceptable-use-policy',// « reasoning: https://github.com/fleetdm/fleet/pull/9624 + 'GET /handbook/business-operations/security-policies':'/handbook/digital-experience/security-policies', + 'GET /handbook/business-operations/application-security': '/handbook/digital-experience/application-security', + 'GET /handbook/business-operations/security-audits': '/handbook/digital-experience/security-audits', + 'GET /handbook/business-operations/security': '/handbook/digital-experience/security', + 'GET /handbook/business-operations/vendor-questionnaires': '/handbook/digital-experience/vendor-questionnaires', 'GET /handbook/handbook': '/handbook/company/handbook', 'GET /handbook/company/development-groups': '/handbook/company/product-groups', 'GET /docs/using-fleet/mdm-macos-settings': '/docs/using-fleet/mdm-custom-macos-settings', From 8cbb28bf02a7ecb972ea23581cd25eec409651f6 Mon Sep 17 00:00:00 2001 From: Sharon Katz <121527325+sharon-fdm@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:36:40 -0400 Subject: [PATCH 74/81] 21056 auto install document (#21362) #21056 Document for policy-based automatic software installation. See result [here](https://github.com/fleetdm/fleet/blob/21056_auto_instal_document/articles/automatic-software-install-in-fleet.md#add-policy) --------- Co-authored-by: spokanemac Co-authored-by: Noah Talerman Co-authored-by: JD Co-authored-by: Luke Heath --- .../automatic-software-install-in-fleet.md | 80 ++++++++++++++++++ ...utomatic-software-install-add-software.png | Bin 0 -> 66136 bytes ...atic-software-install-install-software.png | Bin 0 -> 57215 bytes ...matic-software-install-policies-manage.png | Bin 0 -> 60001 bytes .../automatic-software-install-top-image.png | Bin 0 -> 8421 bytes .../automatic-software-install-workflow.png | Bin 0 -> 59848 bytes website/config/routes.js | 1 + 7 files changed, 81 insertions(+) create mode 100644 articles/automatic-software-install-in-fleet.md create mode 100644 website/assets/images/articles/automatic-software-install-add-software.png create mode 100644 website/assets/images/articles/automatic-software-install-install-software.png create mode 100644 website/assets/images/articles/automatic-software-install-policies-manage.png create mode 100644 website/assets/images/articles/automatic-software-install-top-image.png create mode 100644 website/assets/images/articles/automatic-software-install-workflow.png diff --git a/articles/automatic-software-install-in-fleet.md b/articles/automatic-software-install-in-fleet.md new file mode 100644 index 000000000000..9b0ba6e65a65 --- /dev/null +++ b/articles/automatic-software-install-in-fleet.md @@ -0,0 +1,80 @@ +# Automatic policy-based installation of software on hosts + +![Top Image](../website/assets/images/articles/automatic-software-install-top-image.png) + +Fleet [v4.57.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.57.0) introduces the ability to automatically and remotely install software on hosts based on predefined policy failures. This guide will walk you through the process of configuring fleet for automatic installation of software on hosts using uploaded installation images and based on programmed policies. You'll learn how to configure and use this feature, as well as understand how the underlying mechanism works. + +Fleet allows its users to upload trusted software installation files to be installed and used on hosts. This installation could be conditioned on a failure of a specific Fleet Policy. + +## Prerequisites + +* Fleet premium with Admin permissions. +* Fleet [v4.57.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.57.0) or greater. + +## Step-by-step instructions + +1. **Adding software**: Add any software to be available for installation. Follow the [deploying software](https://fleetdm.com/guides/deploy-security-agents) document with instructions how to do it. Note that all installation steps (pre-install query, install script, and post-install script) will be executed as configured, regardless of the policy that triggers the installation. + + +![Add software](../website/assets/images/articles/automatic-software-install-add-software.png) + +Current supported software deployment formats: +- macOS: .pkg +- Windows: .msi, .exe +- Linux: .deb + +Coming soon: +- VPP for iOS and iPadOS + +2. **Add a policy**: In Fleet, add a policy that failure to pass will trigger the required installation. Go to Policies tab --> Press the top right "Add policy" button. --> Click "create your own policy" --> Enter your policy SQL --> Save --> Fill in details in the Save modal and Save. + +``` +SELECT 1 FROM apps WHERE name = 'Adobe Acrobat Reader.app' AND version_compare(bundle_short_version, '23.001.20687') >= 0; +``` + +Note: In order to know the exact application name to put in the query (e.g. "Adobe Acrobat Reader.app" in the query above) you can manually install it on a canary/test host and then query SELECT * from apps; + + +3. **Manage automation**: Open Manage Automations: Policies Tab --> top right "Manage automations" --> "Install software". + +![Manage policies](../website/assets/images/articles/automatic-software-install-policies-manage.png) + +4. **Select policy**: Select (click the check box of) your newly created policy. To the right of it select from the + drop-down list the software you would like to be installed upon failure of this policy. + +![Install software modal](../website/assets/images/articles/automatic-software-install-install-software.png) + +Upon failure of the selected policy, the selected software installation will be triggered. + +## How does it work? + +* After configuring Fleet to auto-install a specific software the rest will be done automatically. +* The policy check mechanism runs on a typical 1 hour cadence on all online hosts. +* Fleet will send install requests to the hosts on the first policy failure (first "No" result for the host) or if a policy goes from "Yes" to "No". On this iteration it will not send a install request if a policy is already failing and continues to fail ("No" -> "No"). See the following flowchart for details. + +![Flowchart](../website/assets/images/articles/automatic-software-install-workflow.png) +*Detailed flowchart* + +## Using the REST API for self-service software packages + +Fleet provides a REST API for managing software packages, including self-service software packages. Learn more about Fleet's [REST API](https://fleetdm.com/docs/rest-api/rest-api#add-team-policy). + +## Managing self-service software packages with GitOps + +To manage self-service software packages using Fleet's best practice GitOps, check out the `software` key in the [GitOps reference documentation](https://fleetdm.com/docs/configuration/yaml-files#policies). + +## Conclusion + +Software deployment can be time-consuming and risky. This guide presents Fleet's ability to mass deploy software to your fleet in a simple and safe way. Starting with uploading a trusted installer and ending with deploying it to the proper set of machines answering the exact policy defined by you. + +Leveraging Fleet’s ability to install and upgrade software on your hosts, you can streamline the process of controlling your hosts, replacing old versions of software and having the up-to-date info on what's installed on your fleet. + +By automating software deployment, you can gain greater control over what's installed on your machines and have better oversight of version upgrades, ensuring old software with known issues is replaced. + + + + + + + + diff --git a/website/assets/images/articles/automatic-software-install-add-software.png b/website/assets/images/articles/automatic-software-install-add-software.png new file mode 100644 index 0000000000000000000000000000000000000000..4fdd54fe648871a53b2b08d660459f755c990bb4 GIT binary patch literal 66136 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 literal 0 HcmV?d00001 diff --git a/website/assets/images/articles/automatic-software-install-policies-manage.png b/website/assets/images/articles/automatic-software-install-policies-manage.png new file mode 100644 index 0000000000000000000000000000000000000000..862c98eb151b0f18e031506dfee543aa9163bc5f GIT binary patch literal 60001 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 Jmvv4FO#ro)%J={P literal 0 HcmV?d00001 diff --git a/website/assets/images/articles/automatic-software-install-top-image.png b/website/assets/images/articles/automatic-software-install-top-image.png new file mode 100644 index 0000000000000000000000000000000000000000..ed188acd17ee6ba23b3175801afb0a1a9e9ead05 GIT binary patch literal 8421 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 r%XPfw`mRv^Aps5OX7K-W Date: Tue, 24 Sep 2024 14:47:46 -0500 Subject: [PATCH 75/81] Improve MySQL queries that aggregate MDM profile statuses for Apple hosts (#22252) --- changes/22122-mdm-apple-status-queries | 1 + server/datastore/mysql/apple_mdm.go | 467 +++++++------------------ server/datastore/mysql/hosts.go | 32 +- server/datastore/mysql/labels.go | 6 + 4 files changed, 144 insertions(+), 362 deletions(-) create mode 100644 changes/22122-mdm-apple-status-queries diff --git a/changes/22122-mdm-apple-status-queries b/changes/22122-mdm-apple-status-queries new file mode 100644 index 000000000000..2ea893d31ff5 --- /dev/null +++ b/changes/22122-mdm-apple-status-queries @@ -0,0 +1 @@ +- Improved performance of SQL queries used to determine MDM profile status for Apple hosts. \ No newline at end of file diff --git a/server/datastore/mysql/apple_mdm.go b/server/datastore/mysql/apple_mdm.go index b4ae8c5ac0d1..610a25db52fa 100644 --- a/server/datastore/mysql/apple_mdm.go +++ b/server/datastore/mysql/apple_mdm.go @@ -2535,377 +2535,150 @@ func (ds *Datastore) UpdateOrDeleteHostMDMAppleProfile(ctx context.Context, prof return err } -const ( - appleMDMFailedProfilesStmt = ` - h.uuid = hmap.host_uuid AND - hmap.status = :failed` - - appleMDMPendingProfilesStmt = ` - h.uuid = hmap.host_uuid AND - ( - hmap.status IS NULL OR - hmap.status = :pending OR +// sqlCaseMDMAppleStatus returns a SQL snippet that can be used to determine the status of a host +// based on the status of its profiles and declarations and filevault status. It should be used in +// conjunction with sqlJoinMDMAppleProfilesStatus and sqlJoinMDMAppleDeclarationsStatus. It assumes the +// hosts table to be aliased as 'h' and the host_disk_encryption_keys table to be aliased as 'hdek'. +func sqlCaseMDMAppleStatus() string { + // NOTE: To make this snippet reusable, we're not using sqlx.Named here because it would + // complicate usage in other queries (e.g., list hosts). + var ( + failed = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryFailed)) + pending = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryPending)) + verifying = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryVerifying)) + verified = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryVerified)) + ) + return ` + CASE WHEN (prof_failed + OR decl_failed + OR fv_failed) THEN + ` + failed + ` + WHEN (prof_pending + OR decl_pending -- special case for filevault, it's pending if the profile is -- pending OR the profile is verified or verifying but we still -- don't have an encryption key. - ( - hmap.profile_identifier = :filevault AND - hmap.status IN (:verifying, :verified) AND - hmap.operation_type = :install AND - NOT EXISTS ( - SELECT 1 - FROM host_disk_encryption_keys hdek - WHERE h.id = hdek.host_id AND - (hdek.decryptable = 1 OR hdek.decryptable IS NULL) - ) - ) - )` - - appleMDMVerifyingProfilesStmt = ` - h.uuid = hmap.host_uuid AND - hmap.operation_type = :install AND - ( - -- all profiles except filevault that are 'verifying' - ( - hmap.profile_identifier != :filevault AND - hmap.status = :verifying - ) - OR - -- special cases for filevault - ( - hmap.profile_identifier = :filevault AND - ( - -- filevault profile is verified, but we didn't verify the encryption key - ( - hmap.status = :verified AND - EXISTS ( - SELECT 1 - FROM host_disk_encryption_keys AS hdek - WHERE h.id = hdek.host_id AND - hdek.decryptable IS NULL - ) - ) - OR - -- filevault profile is verifying, and we already have an encryption key, in any state - ( - hmap.status = :verifying AND - EXISTS ( - SELECT 1 - FROM host_disk_encryption_keys AS hdek - WHERE h.id = hdek.host_id AND - hdek.decryptable = 1 OR hdek.decryptable IS NULL - ) - ) - ) - ) - )` - - appleVerifiedProfilesStmt = ` - h.uuid = hmap.host_uuid AND - hmap.operation_type = :install AND - hmap.status = :verified AND - ( - hmap.profile_identifier != :filevault OR - EXISTS ( - SELECT 1 - FROM host_disk_encryption_keys hdek - WHERE h.id = hdek.host_id AND - hdek.decryptable = 1 - ) - )` -) - -// subqueryAppleProfileStatus builds the right subquery that can be used to -// filter hosts based on their profile status. -// -// The subquery mechanism works by finding profiles for hosts that: -// - match with the provided status -// - match any status that supercedes the provided status (eg: failed supercedes verifying) -// -// Hosts will be considered to be in the given status only if the profiles -// match the given status and zero profiles match any superceding status. -func subqueryAppleProfileStatus(status fleet.MDMDeliveryStatus) (string, []any, error) { - var condition string - var excludeConditions string - switch status { - case fleet.MDMDeliveryFailed: - condition = appleMDMFailedProfilesStmt - excludeConditions = "FALSE" - case fleet.MDMDeliveryPending: - condition = appleMDMPendingProfilesStmt - excludeConditions = appleMDMFailedProfilesStmt - case fleet.MDMDeliveryVerifying: - condition = appleMDMVerifyingProfilesStmt - excludeConditions = fmt.Sprintf("(%s) OR (%s)", appleMDMPendingProfilesStmt, appleMDMFailedProfilesStmt) - case fleet.MDMDeliveryVerified: - condition = appleVerifiedProfilesStmt - excludeConditions = fmt.Sprintf("(%s) OR (%s) OR (%s)", appleMDMPendingProfilesStmt, appleMDMFailedProfilesStmt, appleMDMVerifyingProfilesStmt) - default: - return "", nil, fmt.Errorf("invalid status: %s", status) - } - - sql := fmt.Sprintf(` - SELECT 1 - FROM host_mdm_apple_profiles hmap - WHERE %s AND - NOT EXISTS ( - SELECT 1 - FROM host_mdm_apple_profiles hmap - WHERE %s - )`, condition, excludeConditions) - - arg := map[string]any{ - "install": fleet.MDMOperationTypeInstall, - "verifying": fleet.MDMDeliveryVerifying, - "failed": fleet.MDMDeliveryFailed, - "verified": fleet.MDMDeliveryVerified, - "pending": fleet.MDMDeliveryPending, - "filevault": mobileconfig.FleetFileVaultPayloadIdentifier, - } - query, args, err := sqlx.Named(sql, arg) - if err != nil { - return "", nil, fmt.Errorf("subqueryAppleProfileStatus %s: %w", status, err) - } - - return query, args, nil + OR(fv_pending + OR((fv_verifying + OR fv_verified) + AND (hdek.base64_encrypted IS NULL OR (hdek.decryptable IS NOT NULL AND hdek.decryptable != 1))))) THEN + ` + pending + ` + WHEN (prof_verifying + OR decl_verifying + -- special case when fv profile is verifying, and we already have an encryption key, in any state, we treat as verifying + OR(fv_verifying + AND hdek.base64_encrypted IS NOT NULL AND (hdek.decryptable IS NULL OR hdek.decryptable = 1)) + -- special case when fv profile is verified, but we didn't verify the encryption key, we treat as verifying + OR(fv_verified + AND hdek.base64_encrypted IS NOT NULL AND hdek.decryptable IS NULL)) THEN + ` + verifying + ` + WHEN (prof_verified + OR decl_verified + OR(fv_verified + AND hdek.base64_encrypted IS NOT NULL AND hdek.decryptable = 1)) THEN + ` + verified + ` + END +` } -// subqueryAppleDeclarationStatus builds out the subquery for declaration status -func subqueryAppleDeclarationStatus() (string, []any, error) { - const declNamedStmt = ` - CASE WHEN EXISTS ( - SELECT - 1 - FROM - host_mdm_apple_declarations d1 - WHERE - h.uuid = d1.host_uuid - AND d1.operation_type = :install - AND d1.status = :failed - AND d1.declaration_name NOT IN (:reserved_names)) THEN - 'declarations_failed' - WHEN EXISTS ( - SELECT - 1 - FROM - host_mdm_apple_declarations d2 - WHERE - h.uuid = d2.host_uuid - AND d2.operation_type = :install - AND(d2.status IS NULL - OR d2.status = :pending) - AND d2.declaration_name NOT IN (:reserved_names) - AND NOT EXISTS ( - SELECT - 1 - FROM - host_mdm_apple_declarations d3 - WHERE - h.uuid = d3.host_uuid - AND d3.operation_type = :install - AND d3.status = :failed - AND d3.declaration_name NOT IN (:reserved_names))) THEN - 'declarations_pending' - WHEN EXISTS ( - SELECT - 1 - FROM - host_mdm_apple_declarations d4 - WHERE - h.uuid = d4.host_uuid - AND d4.operation_type = :install - AND d4.status = :verifying - AND d4.declaration_name NOT IN (:reserved_names) - AND NOT EXISTS ( - SELECT - 1 - FROM - host_mdm_apple_declarations d5 - WHERE (h.uuid = d5.host_uuid - AND d5.operation_type = :install - AND d5.declaration_name NOT IN (:reserved_names) - AND(d5.status IS NULL - OR d5.status IN(:pending, :failed))))) THEN - 'declarations_verifying' - WHEN EXISTS ( - SELECT - 1 - FROM - host_mdm_apple_declarations d6 - WHERE - h.uuid = d6.host_uuid - AND d6.operation_type = :install - AND d6.status = :verified - AND d6.declaration_name NOT IN (:reserved_names) - AND NOT EXISTS ( - SELECT - 1 - FROM - host_mdm_apple_declarations d7 - WHERE (h.uuid = d7.host_uuid - AND d7.operation_type = :install - AND d7.declaration_name NOT IN (:reserved_names) - AND(d7.status IS NULL - OR d7.status IN(:pending, :failed, :verifying))))) THEN - 'declarations_verified' - ELSE - '' - END` - - arg := map[string]any{ - "install": fleet.MDMOperationTypeInstall, - "verifying": fleet.MDMDeliveryVerifying, - "failed": fleet.MDMDeliveryFailed, - "verified": fleet.MDMDeliveryVerified, - "pending": fleet.MDMDeliveryPending, - "reserved_names": fleetmdm.ListFleetReservedMacOSDeclarationNames(), - } - query, args, err := sqlx.Named(declNamedStmt, arg) - if err != nil { - return "", nil, fmt.Errorf("subqueryAppleDeclarationStatus: %w", err) - } - query, args, err = sqlx.In(query, args...) - if err != nil { - return "", nil, fmt.Errorf("subqueryAppleDeclarationStatus resolve IN: %w", err) - } - - return query, args, nil +// sqlJoinMDMAppleProfilesStatus returns a SQL snippet that can be used to join a table derived from +// host_mdm_apple_profiles (grouped by host_uuid and status) and the hosts table. For each host_uuid, +// it derives a boolean value for each status category. The value will be 1 if the host has any +// profile in the given status category. Separate columns are used for status of the filevault profile +// vs. all other profiles. The snippet assumes the hosts table to be aliased as 'h'. +func sqlJoinMDMAppleProfilesStatus() string { + // NOTE: To make this snippet reusable, we're not using sqlx.Named here because it would + // complicate usage in other queries (e.g., list hosts). + var ( + failed = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryFailed)) + pending = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryPending)) + verifying = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryVerifying)) + verified = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryVerified)) + install = fmt.Sprintf("'%s'", string(fleet.MDMOperationTypeInstall)) + filevault = fmt.Sprintf("'%s'", mobileconfig.FleetFileVaultPayloadIdentifier) + ) + return ` + LEFT JOIN ( + -- profile statuses grouped by host uuid, boolean value will be 1 if host has any profile with the given status + -- filevault profiles are treated separately + SELECT + host_uuid, + MAX( IF((status IS NULL OR status = ` + pending + `) AND profile_identifier != ` + filevault + `, 1, 0)) AS prof_pending, + MAX( IF(status = ` + failed + ` AND profile_identifier != ` + filevault + `, 1, 0)) AS prof_failed, + MAX( IF(status = ` + verifying + ` AND profile_identifier != ` + filevault + ` AND operation_type = ` + install + `, 1, 0)) AS prof_verifying, + MAX( IF(status = ` + verified + ` AND profile_identifier != ` + filevault + ` AND operation_type = ` + install + `, 1, 0)) AS prof_verified, + MAX( IF((status IS NULL OR status = ` + pending + `) AND profile_identifier = ` + filevault + `, 1, 0)) AS fv_pending, + MAX( IF(status = ` + failed + ` AND profile_identifier = ` + filevault + `, 1, 0)) AS fv_failed, + MAX( IF(status = ` + verifying + ` AND profile_identifier = ` + filevault + ` AND operation_type = ` + install + `, 1, 0)) AS fv_verifying, + MAX( IF(status = ` + verified + ` AND profile_identifier = ` + filevault + ` AND operation_type = ` + install + `, 1, 0)) AS fv_verified + FROM + host_mdm_apple_profiles + GROUP BY + host_uuid) hmap ON h.uuid = hmap.host_uuid +` } -func subqueryOSSettingsStatusMac() (string, []any, error) { - var profArgs []any - profFailed, profFailedArgs, err := subqueryAppleProfileStatus(fleet.MDMDeliveryFailed) - if err != nil { - return "", nil, err - } - profArgs = append(profArgs, profFailedArgs...) - - profPending, profPendingArgs, err := subqueryAppleProfileStatus(fleet.MDMDeliveryPending) - if err != nil { - return "", nil, err - } - profArgs = append(profArgs, profPendingArgs...) - - profVerifying, profVerifyingArgs, err := subqueryAppleProfileStatus(fleet.MDMDeliveryVerifying) - if err != nil { - return "", nil, err - } - profArgs = append(profArgs, profVerifyingArgs...) - - profVerified, profVerifiedArgs, err := subqueryAppleProfileStatus(fleet.MDMDeliveryVerified) - if err != nil { - return "", nil, err - } - profArgs = append(profArgs, profVerifiedArgs...) - - profStmt := fmt.Sprintf(` - CASE WHEN EXISTS (%s) THEN - 'profiles_failed' - WHEN EXISTS (%s) THEN - 'profiles_pending' - WHEN EXISTS (%s) THEN - 'profiles_verifying' - WHEN EXISTS (%s) THEN - 'profiles_verified' - ELSE - '' - END`, - profFailed, - profPending, - profVerifying, - profVerified, +// sqlJoinMDMAppleDeclarationsStatus returns a SQL snippet that can be used to join a table derived from +// host_mdm_apple_declarations (grouped by host_uuid and status) and the hosts table. For each host_uuid, +// it derives a boolean value for each status category. The value will be 1 if the host has any +// declaration in the given status category. The snippet assumes the hosts table to be aliased as 'h'. +func sqlJoinMDMAppleDeclarationsStatus() string { + // NOTE: To make this snippet reusable, we're not using sqlx.Named here because it would + // complicate usage in other queries (e.g., list hosts). + var ( + failed = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryFailed)) + pending = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryPending)) + verifying = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryVerifying)) + verified = fmt.Sprintf("'%s'", string(fleet.MDMDeliveryVerified)) + install = fmt.Sprintf("'%s'", string(fleet.MDMOperationTypeInstall)) + reservedDeclNames = fmt.Sprintf("'%s', '%s', '%s'", fleetmdm.FleetMacOSUpdatesProfileName, fleetmdm.FleetIOSUpdatesProfileName, fleetmdm.FleetIPadOSUpdatesProfileName) ) - - declStmt, declArgs, err := subqueryAppleDeclarationStatus() - if err != nil { - return "", nil, err - } - - stmt := fmt.Sprintf(` - CASE (%s) - WHEN 'profiles_failed' THEN - 'failed' - WHEN 'profiles_pending' THEN ( - CASE (%s) - WHEN 'declarations_failed' THEN - 'failed' - ELSE - 'pending' - END) - WHEN 'profiles_verifying' THEN ( - CASE (%s) - WHEN 'declarations_failed' THEN - 'failed' - WHEN 'declarations_pending' THEN - 'pending' - ELSE - 'verifying' - END) - WHEN 'profiles_verified' THEN ( - CASE (%s) - WHEN 'declarations_failed' THEN - 'failed' - WHEN 'declarations_pending' THEN - 'pending' - WHEN 'declarations_verifying' THEN - 'verifying' - ELSE - 'verified' - END) - ELSE - REPLACE((%s), 'declarations_', '') - END`, profStmt, declStmt, declStmt, declStmt, declStmt) - - args := append(profArgs, declArgs...) - args = append(args, declArgs...) - args = append(args, declArgs...) - args = append(args, declArgs...) - - // FIXME(roberto): we found issues in MySQL 5.7.17 (only that version, - // which we must support for now) with prepared statements on this - // query. The results returned by the DB were always different what - // expected unless the arguments are inlined in the query. - // - // We decided to do this given: - // - // - The time constraints we were given to develop DDM - // - The fact that all the variables in this query are really strings managed by us - // - The imminent deprecation of MySQL 5.7 - return fmt.Sprintf(strings.Replace(stmt, "?", "'%s'", -1), args...), []any{}, nil + return ` + LEFT JOIN ( + -- declaration statuses grouped by host uuid, boolean value will be 1 if host has any declaration with the given status + SELECT + host_uuid, + MAX( IF((status IS NULL OR status = ` + pending + `), 1, 0)) AS decl_pending, + MAX( IF(status = ` + failed + `, 1, 0)) AS decl_failed, + MAX( IF(status = ` + verifying + ` , 1, 0)) AS decl_verifying, + MAX( IF(status = ` + verified + ` , 1, 0)) AS decl_verified + FROM + host_mdm_apple_declarations + WHERE + operation_type = ` + install + ` AND declaration_name NOT IN(` + reservedDeclNames + `) + GROUP BY + host_uuid) hmad ON h.uuid = hmad.host_uuid +` } func (ds *Datastore) GetMDMAppleProfilesSummary(ctx context.Context, teamID *uint) (*fleet.MDMProfilesSummary, error) { - subquery, args, err := subqueryOSSettingsStatusMac() - if err != nil { - return nil, ctxerr.Wrap(ctx, err, "building os settings subquery") - } - - sqlFmt := ` + stmt := ` SELECT - %s as status, - COUNT(id) as count + COUNT(id) AS count, + %s AS status FROM - hosts h -WHERE platform = 'darwin' OR platform = 'ios' OR platform = 'ipados' -GROUP BY status, team_id HAVING status IN (?, ?, ?, ?) AND %s` - - args = append(args, fleet.MDMDeliveryFailed, fleet.MDMDeliveryPending, fleet.MDMDeliveryVerifying, fleet.MDMDeliveryVerified) + hosts h + %s + %s + LEFT JOIN host_disk_encryption_keys hdek ON h.id = hdek.host_id +WHERE + platform IN('darwin', 'ios', 'ipad_os') AND %s +GROUP BY + status HAVING status IS NOT NULL` teamFilter := "team_id IS NULL" if teamID != nil && *teamID > 0 { - teamFilter = "team_id = ?" - args = append(args, *teamID) + teamFilter = fmt.Sprintf("team_id = %d", *teamID) } - stmt := fmt.Sprintf(sqlFmt, subquery, teamFilter) + stmt = fmt.Sprintf(stmt, sqlCaseMDMAppleStatus(), sqlJoinMDMAppleProfilesStatus(), sqlJoinMDMAppleDeclarationsStatus(), teamFilter) var dest []struct { Count uint `db:"count"` Status string `db:"status"` } - err = sqlx.SelectContext(ctx, ds.reader(ctx), &dest, stmt, args...) - if err != nil { + if err := sqlx.SelectContext(ctx, ds.reader(ctx), &dest, stmt); err != nil { return nil, err } diff --git a/server/datastore/mysql/hosts.go b/server/datastore/mysql/hosts.go index 0b3a0e498362..ee23749de80a 100644 --- a/server/datastore/mysql/hosts.go +++ b/server/datastore/mysql/hosts.go @@ -1114,6 +1114,14 @@ func (ds *Datastore) applyHostFilters( whereParams = append(whereParams, microsoft_mdm.MDMDeviceStateEnrolled) } + mdmAppleProfilesStatusJoin := "" + mdmAppleDeclarationsStatusJoin := "" + if opt.OSSettingsFilter.IsValid() || + opt.MacOSSettingsFilter.IsValid() { + mdmAppleProfilesStatusJoin = sqlJoinMDMAppleProfilesStatus() + mdmAppleDeclarationsStatusJoin = sqlJoinMDMAppleDeclarationsStatus() + } + sqlStmt += fmt.Sprintf( `FROM hosts h LEFT JOIN host_seen_times hst ON (h.id = hst.host_id) @@ -1128,6 +1136,8 @@ func (ds *Datastore) applyHostFilters( %s %s %s + %s + %s %s WHERE TRUE AND %s AND %s AND %s AND %s `, @@ -1142,6 +1152,8 @@ func (ds *Datastore) applyHostFilters( munkiJoin, displayNameJoin, connectedToFleetJoin, + mdmAppleProfilesStatusJoin, + mdmAppleDeclarationsStatusJoin, // Conditions ds.whereFilterHostsByTeams(filter, "h"), @@ -1304,15 +1316,9 @@ func filterHostsByMacOSSettingsStatus(sql string, opt fleet.HostListOptions, par whereStatus += ` AND h.team_id IS NULL` } - subqueryStatus, paramsStatus, err := subqueryOSSettingsStatusMac() - if err != nil { - return "", nil, err - } - - whereStatus += fmt.Sprintf(` AND %s = ?`, subqueryStatus) - paramsStatus = append(paramsStatus, opt.MacOSSettingsFilter) + whereStatus += fmt.Sprintf(` AND %s = ?`, sqlCaseMDMAppleStatus()) - return sql + whereStatus, append(params, paramsStatus...), nil + return sql + whereStatus, append(params, opt.MacOSSettingsFilter), nil } func filterHostsByMacOSDiskEncryptionStatus(sql string, opt fleet.HostListOptions, params []interface{}) (string, []interface{}) { @@ -1364,13 +1370,9 @@ func (ds *Datastore) filterHostsByOSSettingsStatus(sql string, opt fleet.HostLis AND ((h.platform = 'windows' AND (%s)) OR ((h.platform = 'darwin' OR h.platform = 'ios' OR h.platform = 'ipados') AND (%s)))` - whereMacOS, paramsMacOS, err := subqueryOSSettingsStatusMac() - if err != nil { - return "", nil, err - } - whereMacOS += ` = ?` - // ensure the host has MDM turned on - paramsMacOS = append(paramsMacOS, opt.OSSettingsFilter) + // construct the WHERE for macOS + whereMacOS = fmt.Sprintf(`(%s) = ?`, sqlCaseMDMAppleStatus()) + paramsMacOS := []any{opt.OSSettingsFilter} // construct the WHERE for windows whereWindows = `hmdm.is_server = 0` diff --git a/server/datastore/mysql/labels.go b/server/datastore/mysql/labels.go index d604b286a4aa..5ac777be3939 100644 --- a/server/datastore/mysql/labels.go +++ b/server/datastore/mysql/labels.go @@ -638,6 +638,12 @@ func (ds *Datastore) applyHostLabelFilters(ctx context.Context, filter fleet.Tea joinParams = append(joinParams, microsoft_mdm.MDMDeviceStateEnrolled) } + if opt.OSSettingsFilter.IsValid() || + opt.MacOSSettingsFilter.IsValid() { + query += sqlJoinMDMAppleProfilesStatus() + query += sqlJoinMDMAppleDeclarationsStatus() + } + query += fmt.Sprintf(` WHERE lm.label_id = ? AND %s `, ds.whereFilterHostsByTeams(filter, "h")) whereParams = append(whereParams, lid) From 839106c572c5188d43eca23ff825af1c6f5031b0 Mon Sep 17 00:00:00 2001 From: Tim Lee Date: Tue, 24 Sep 2024 17:45:37 -0600 Subject: [PATCH 76/81] Hotfix CVE test (#22349) --- server/vulnerabilities/nvd/cve_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/vulnerabilities/nvd/cve_test.go b/server/vulnerabilities/nvd/cve_test.go index 691f3e321a7d..f9f8b12562ab 100644 --- a/server/vulnerabilities/nvd/cve_test.go +++ b/server/vulnerabilities/nvd/cve_test.go @@ -343,7 +343,7 @@ func TestTranslateCPEToCVE(t *testing.T) { }, "cpe:2.3:a:python:python:3.9.6:*:*:*:*:windows:*:*": { includedCVEs: []cve{ - {ID: "CVE-2024-4030", resolvedInVersion: "3.12.4"}, + {ID: "CVE-2024-4030", resolvedInVersion: "3.9.20"}, }, continuesToUpdate: true, }, From adf3ad6214cc568329f3b1a8f1bee7f21bfb2d57 Mon Sep 17 00:00:00 2001 From: Roberto Dip Date: Wed, 25 Sep 2024 11:14:51 -0300 Subject: [PATCH 77/81] allow to install VPP apps without scripts (#22365) for #22352 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Added/updated tests - [x] Manual QA for all new/changed functionality --- .../Software/HostSoftwareTableConfig.tests.tsx | 17 +++++++++++++++++ .../cards/Software/HostSoftwareTableConfig.tsx | 5 +++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx index aa14172c86f8..68c7a854d960 100644 --- a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx +++ b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx @@ -80,4 +80,21 @@ describe("generateActions", () => { const actions = generateActions(props); expect(actions.find((a) => a.value === "uninstall")).toBeUndefined(); }); + + it("allows to install VPP apps even if scripts are disabled", () => { + const props: generateActionsProps = { + ...defaultProps, + hostScriptsEnabled: false, + app_store_app: { + app_store_id: "1", + self_service: false, + icon_url: "", + version: "", + last_install: { command_uuid: "", installed_at: "" }, + }, + }; + const actions = generateActions(props); + expect(actions.find((a) => a.value === "install")?.disabled).toBe(false); + expect(actions.find((a) => a.value === "uninstall")).toBeUndefined(); + }); }); diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx index 53256f50bffb..c6a07ce7fa18 100644 --- a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx +++ b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx @@ -94,8 +94,9 @@ export const generateActions = ({ actions.splice(indexUninstallAction, 1); actions.splice(indexInstallAction, 1); } else { - // if host's scripts are disabled, disable install/uninstall with tooltip - if (!hostScriptsEnabled) { + // if host's scripts are disabled, and this isn't a VPP app, disable + // install/uninstall with tooltip + if (!hostScriptsEnabled && !app_store_app) { actions[indexInstallAction].disabled = true; actions[indexUninstallAction].disabled = true; From 38ba6cce470d7d8a1fc67959d7c8a616842dfe38 Mon Sep 17 00:00:00 2001 From: Jahziel Villasana-Espinoza Date: Wed, 25 Sep 2024 10:44:08 -0400 Subject: [PATCH 78/81] fix: update docs with accurate response body (#22360) --- docs/Contributing/API-for-contributors.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/Contributing/API-for-contributors.md b/docs/Contributing/API-for-contributors.md index 2ba361b2c3a7..074c3338b4c2 100644 --- a/docs/Contributing/API-for-contributors.md +++ b/docs/Contributing/API-for-contributors.md @@ -885,7 +885,20 @@ Content-Type: application/octet-stream "location": "https://example.com/mdm/apple/mdm", "renew_date": "2024-10-20T00:00:00Z", "terms_expired": false, - "teams": [1, 2, 3] + "teams": [ + { + "team_id": 1, + "name": "Team 1" + }, + { + "team_id": 2, + "name": "Team 2" + }, + { + "team_id": 2, + "name": "Team 3" + }, + ] } ``` From 18026d54bea9a77bb9b5d6502d931b46bd48c503 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Wed, 25 Sep 2024 09:24:54 -0700 Subject: [PATCH 79/81] Fleet UI: Improve select targets dropdown (#22348) --- ...276-select-live-query-targets-improvements | 1 + .../components/LiveQuery/SelectTargets.tsx | 11 --- .../LiveQuery/TargetsInput/TargetsInput.tsx | 90 ++++++++++++------- .../LiveQuery/TargetsInput/_styles.scss | 36 ++++---- 4 files changed, 77 insertions(+), 61 deletions(-) create mode 100644 changes/21276-select-live-query-targets-improvements diff --git a/changes/21276-select-live-query-targets-improvements b/changes/21276-select-live-query-targets-improvements new file mode 100644 index 000000000000..75b2086beb03 --- /dev/null +++ b/changes/21276-select-live-query-targets-improvements @@ -0,0 +1 @@ +- UI Improvements to selecting live query targets (e.g. styling, closing behavior) diff --git a/frontend/components/LiveQuery/SelectTargets.tsx b/frontend/components/LiveQuery/SelectTargets.tsx index ad46545983c0..5302301a08fd 100644 --- a/frontend/components/LiveQuery/SelectTargets.tsx +++ b/frontend/components/LiveQuery/SelectTargets.tsx @@ -430,17 +430,6 @@ const SelectTargets = ({ ); }; - if (isLoadingLabels || (isPremiumTier && isLoadingTeams)) { - return ( -

- ); - } - if (errorLabels || errorTeams) { return (
diff --git a/frontend/components/LiveQuery/TargetsInput/TargetsInput.tsx b/frontend/components/LiveQuery/TargetsInput/TargetsInput.tsx index dcfc2074d8b6..e54830081ed1 100644 --- a/frontend/components/LiveQuery/TargetsInput/TargetsInput.tsx +++ b/frontend/components/LiveQuery/TargetsInput/TargetsInput.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useRef, useEffect, useState } from "react"; import { Row } from "react-table"; import { isEmpty, pullAllBy } from "lodash"; @@ -9,7 +9,6 @@ import DataError from "components/DataError"; // @ts-ignore import InputFieldWithIcon from "components/forms/fields/InputFieldWithIcon/InputFieldWithIcon"; import TableContainer from "components/TableContainer"; -import Spinner from "components/Spinner"; import { ITargestInputHostTableConfig } from "./TargetsInputHostsTableConfig"; interface ITargetsInputProps { @@ -51,12 +50,39 @@ const TargetsInput = ({ handleRowSelect, setSearchText, }: ITargetsInputProps): JSX.Element => { + const dropdownRef = useRef(null); const dropdownHosts = searchResults && pullAllBy(searchResults, targetedHosts, "display_name"); - const isActiveSearch = - !isEmpty(searchText) && (!hasFetchError || isTargetsLoading); + + const [isActiveSearch, setIsActiveSearch] = useState(false); + const isSearchError = !isEmpty(searchText) && hasFetchError; + // Closes target search results when clicking outside of results + // But not during API loading state as it will reopen on API return + useEffect(() => { + if (!isTargetsLoading) { + const handleClickOutside = (event: MouseEvent) => { + if ( + dropdownRef.current && + !dropdownRef.current.contains(event.target as Node) + ) { + setIsActiveSearch(false); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + } + }, [isTargetsLoading]); + + useEffect(() => { + setIsActiveSearch( + !isEmpty(searchText) && (!hasFetchError || isTargetsLoading) + ); + }, [searchText, hasFetchError, isTargetsLoading]); return (
@@ -71,35 +97,35 @@ const TargetsInput = ({ placeholder={placeholder} onChange={setSearchText} /> - {isActiveSearch && - (isTargetsLoading ? ( - - ) : ( -
- > - columnConfigs={searchResultsTableConfig} - data={dropdownHosts} - isLoading={false} - emptyComponent={() => ( -
-
-

No hosts match the current search criteria.

-

- Expecting to see hosts? Try again in a few seconds as - the system catches up. -

-
+ {isActiveSearch && ( +
+ > + columnConfigs={searchResultsTableConfig} + data={dropdownHosts} + isLoading={isTargetsLoading} + emptyComponent={() => ( +
+
+

No hosts match the current search criteria.

+

+ Expecting to see hosts? Try again in a few seconds as the + system catches up. +

- )} - showMarkAllPages={false} - isAllPagesSelected={false} - disableCount - disablePagination - disableMultiRowSelect - onClickRow={handleRowSelect} - /> -
- ))} +
+ )} + showMarkAllPages={false} + isAllPagesSelected={false} + disableCount + disablePagination + disableMultiRowSelect + onClickRow={handleRowSelect} + /> +
+ )} {isSearchError && (
diff --git a/frontend/components/LiveQuery/TargetsInput/_styles.scss b/frontend/components/LiveQuery/TargetsInput/_styles.scss index e219d2660d18..a3fac64150b3 100644 --- a/frontend/components/LiveQuery/TargetsInput/_styles.scss +++ b/frontend/components/LiveQuery/TargetsInput/_styles.scss @@ -17,10 +17,6 @@ overflow: auto; } - &__data-table-block > div { - min-height: 89px; - } - // Properly vertically aligns host issue icon .display_name__cell { display: inline-flex; @@ -39,7 +35,7 @@ } .empty-search, - .error-search { + .data-error { padding-top: 72px; padding-bottom: 72px; min-height: 225px; @@ -48,16 +44,14 @@ box-shadow: 0px 4px 10px rgba(52, 59, 96, 0.15); box-sizing: border-box; - &__inner { - h4 { - margin: 0; - margin-bottom: 16px; - font-size: $small; - } - p { - margin: 0; - font-size: $x-small; - } + h4 { + margin: 0; + margin-bottom: 16px; + font-size: $small; + } + p { + margin: 0; + font-size: $x-small; } } } @@ -99,9 +93,15 @@ } } - // override the default styles for the spinner. - // TODO: set better default styles for the spinner + .data-table-block .data-table__no-rows { + min-height: 225px; // Match empty and error state + } + + .loading-overlay { + height: 100%; // Match container height + } + .loading-spinner.centered { - margin: 1rem auto; + margin: auto; } } From 345d35c7c188566224b56c502dbaf2746d394099 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Wed, 25 Sep 2024 12:26:48 -0400 Subject: [PATCH 80/81] New Product design responsibility (#22284) Prepare reference docs for release --------- Co-authored-by: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com> Co-authored-by: Luke Heath --- handbook/product-design/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/handbook/product-design/README.md b/handbook/product-design/README.md index 2044bde60c80..853a45636163 100644 --- a/handbook/product-design/README.md +++ b/handbook/product-design/README.md @@ -136,6 +136,17 @@ available in Google Drive. Some of the data is forwarded to [Datadog](https://us5.datadoghq.com/dashboard/7pb-63g-xty/usage-statistics?from_ts=1682952132131&to_ts=1685630532131&live=true) and is available to Fleeties. +### Prepare reference docs for release + +Every change to how Fleet is used is reflected live on the website in reference documentation **at release day** (REST API, config surface, tables, and other already-existing docs under /docs/using-fleet). + +To make sure this happens, first, the [DRI for what goes in a release](https://fleetdm.com/handbook/company/communications#directly-responsible-individuals-dris) @ mentions the [API design DRI](https://fleetdm.com/handbook/company/communications#directly-responsible-individuals-dris) in a message in [#help-engineering Slack channel](https://fleetdm.slack.com/archives/C019WG4GH0A) when we cut the release candidate (RC). + +Next, the API design DRI reviews all user stories and bugs with the release milestone to check that all reference doc PRs are merged into the reference docs release branch. To see which stories were pushed to the next release, and thus which reference doc changes need to be removed from the branch, the API design DRI filters issues by the `~pushed` label and the next release's milestone. + +To signal that the reference docs branch is ready for release, the API design DRI opens a PR to `main`, adds the DRI for what goes in a release as the reviewer, and adds the release milestone. + + ## Rituals From 692e0fc27ab3bacdfafc608522c0cc8893d6d8e3 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Wed, 25 Sep 2024 10:03:09 -0700 Subject: [PATCH 81/81] Fleet UI: Surface duplicate label name error to users (#22389) --- changes/21875-duplicate-label-name | 1 + .../DynamicLabel/DynamicLabel.tsx | 29 +++++++++++------ .../NewLabelPage/ManualLabel/ManualLabel.tsx | 31 +++++++++++++------ 3 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 changes/21875-duplicate-label-name diff --git a/changes/21875-duplicate-label-name b/changes/21875-duplicate-label-name new file mode 100644 index 000000000000..80ee9d9e6925 --- /dev/null +++ b/changes/21875-duplicate-label-name @@ -0,0 +1 @@ +- Fleet UI: Surface duplicate label name error to user diff --git a/frontend/pages/labels/NewLabelPage/DynamicLabel/DynamicLabel.tsx b/frontend/pages/labels/NewLabelPage/DynamicLabel/DynamicLabel.tsx index 8f3237d27820..b11deb64e5de 100644 --- a/frontend/pages/labels/NewLabelPage/DynamicLabel/DynamicLabel.tsx +++ b/frontend/pages/labels/NewLabelPage/DynamicLabel/DynamicLabel.tsx @@ -1,12 +1,14 @@ -import React, { useContext } from "react"; +import React, { useContext, useCallback } from "react"; import { RouteComponentProps } from "react-router"; import PATHS from "router/paths"; import labelsAPI from "services/entities/labels"; import { NotificationContext } from "context/notification"; +import { IApiError } from "interfaces/errors"; import DynamicLabelForm from "pages/labels/components/DynamicLabelForm"; import { IDynamicLabelFormData } from "pages/labels/components/DynamicLabelForm/DynamicLabelForm"; +import { DUPLICATE_ENTRY_ERROR } from "../ManualLabel/ManualLabel"; const baseClass = "dynamic-label"; @@ -26,15 +28,22 @@ const DynamicLabel = ({ }: IDynamicLabelProps) => { const { renderFlash } = useContext(NotificationContext); - const onSaveNewLabel = async (formData: IDynamicLabelFormData) => { - try { - const res = await labelsAPI.create(formData); - router.push(PATHS.MANAGE_HOSTS_LABEL(res.label.id)); - renderFlash("success", "Label added successfully."); - } catch { - renderFlash("error", "Couldn't add label. Please try again."); - } - }; + const onSaveNewLabel = useCallback( + (formData: IDynamicLabelFormData) => { + labelsAPI + .create(formData) + .then((res) => { + router.push(PATHS.MANAGE_HOSTS_LABEL(res.label.id)); + renderFlash("success", "Label added successfully."); + }) + .catch((error: { data: IApiError }) => { + if (error.data.errors[0].reason.includes("Duplicate entry")) { + renderFlash("error", DUPLICATE_ENTRY_ERROR); + } else renderFlash("error", "Couldn't add label. Please try again."); + }); + }, + [renderFlash, router] + ); const onCancelLabel = () => { router.goBack(); diff --git a/frontend/pages/labels/NewLabelPage/ManualLabel/ManualLabel.tsx b/frontend/pages/labels/NewLabelPage/ManualLabel/ManualLabel.tsx index 1dd4553f7abe..a1ed3ac2b964 100644 --- a/frontend/pages/labels/NewLabelPage/ManualLabel/ManualLabel.tsx +++ b/frontend/pages/labels/NewLabelPage/ManualLabel/ManualLabel.tsx @@ -1,29 +1,40 @@ -import React, { useContext } from "react"; +import React, { useCallback, useContext } from "react"; import { RouteComponentProps } from "react-router"; import PATHS from "router/paths"; import labelsAPI from "services/entities/labels"; import { NotificationContext } from "context/notification"; +import { IApiError } from "interfaces/errors"; import ManualLabelForm from "pages/labels/components/ManualLabelForm"; import { IManualLabelFormData } from "pages/labels/components/ManualLabelForm/ManualLabelForm"; const baseClass = "manual-label"; +export const DUPLICATE_ENTRY_ERROR = + "Couldn't add. A label with this name already exists."; + type IManualLabelProps = RouteComponentProps; const ManualLabel = ({ router }: IManualLabelProps) => { const { renderFlash } = useContext(NotificationContext); - const onSaveNewLabel = async (formData: IManualLabelFormData) => { - try { - const res = await labelsAPI.create(formData); - router.push(PATHS.MANAGE_HOSTS_LABEL(res.label.id)); - renderFlash("success", "Label added successfully."); - } catch { - renderFlash("error", "Couldn't add label. Please try again."); - } - }; + const onSaveNewLabel = useCallback( + (formData: IManualLabelFormData) => { + labelsAPI + .create(formData) + .then((res) => { + router.push(PATHS.MANAGE_HOSTS_LABEL(res.label.id)); + renderFlash("success", "Label added successfully."); + }) + .catch((error: { data: IApiError }) => { + if (error.data.errors[0].reason.includes("Duplicate entry")) { + renderFlash("error", DUPLICATE_ENTRY_ERROR); + } else renderFlash("error", "Couldn't add label. Please try again."); + }); + }, + [renderFlash, router] + ); const onCancelLabel = () => { router.goBack();