Recovery Key password: Gitops (#40611)

This commit is contained in:
Tim Lee
2026-03-05 08:37:03 -07:00
committed by GitHub
parent cd439f6125
commit 943dc41ed5
13 changed files with 149 additions and 64 deletions
+6 -5
View File
@@ -162,9 +162,10 @@ type GitOpsControls struct {
AndroidEnabledAndConfigured any `json:"android_enabled_and_configured"`
AndroidSettings any `json:"android_settings"`
EnableDiskEncryption any `json:"enable_disk_encryption"`
RequireBitLockerPIN any `json:"windows_require_bitlocker_pin,omitempty"`
Scripts []BaseItem `json:"scripts"`
EnableDiskEncryption any `json:"enable_disk_encryption"`
EnableRecoveryLockPassword any `json:"enable_recovery_lock_password"`
RequireBitLockerPIN any `json:"windows_require_bitlocker_pin,omitempty"`
Scripts []BaseItem `json:"scripts"`
Defined bool
}
@@ -174,8 +175,8 @@ func (c GitOpsControls) Set() bool {
c.IPadOSUpdates != nil || c.MacOSSettings != nil ||
c.MacOSSetup != nil || c.MacOSMigration != nil ||
c.WindowsUpdates != nil || c.WindowsSettings != nil || c.WindowsEnabledAndConfigured != nil ||
c.WindowsMigrationEnabled != nil || c.EnableDiskEncryption != nil || len(c.Scripts) > 0 ||
c.AndroidEnabledAndConfigured != nil || c.AndroidSettings != nil
c.WindowsMigrationEnabled != nil || c.EnableDiskEncryption != nil || c.EnableRecoveryLockPassword != nil ||
len(c.Scripts) > 0 || c.AndroidEnabledAndConfigured != nil || c.AndroidSettings != nil
}
type Policy struct {
+2
View File
@@ -286,6 +286,8 @@ func TestValidGitOpsYaml(t *testing.T) {
assert.True(t, ok, "windows_settings not found")
_, ok = gitops.Controls.EnableDiskEncryption.(bool)
assert.True(t, ok, "enable_disk_encryption not found")
_, ok = gitops.Controls.EnableRecoveryLockPassword.(bool)
assert.True(t, ok, "enable_recovery_lock_password not found")
_, ok = gitops.Controls.MacOSMigration.(map[string]interface{})
assert.True(t, ok, "macos_migration not found")
assert.NotNil(t, gitops.Controls.MacOSSetup, "macos_setup not found")
+49 -43
View File
@@ -291,52 +291,58 @@ Missing: $FLEET_SECRET_MISSING`
}
func TestGetExclusionZones(t *testing.T) {
testCases := []struct {
fixturePath []string
expected map[[2]int]string
}{
{
[]string{"testdata", "policies", "policies.yml"},
map[[2]int]string{
{46, 106}: " description: This policy should always fail.\n resolution:",
{93, 155}: " resolution: There is no resolution for this policy.\n query:",
{268, 328}: " description: This policy should always pass.\n resolution:",
{315, 678}: " resolution: |\n Automated method:\n Ask your system administrator to deploy the following script which will ensure proper Security Auditing Retention:\n cp /etc/security/audit_control ./tmp.txt; origExpire=$(cat ./tmp.txt | grep expire-after); sed \"s/${origExpire}/expire-after:60d OR 5G/\" ./tmp.txt > /etc/security/audit_control; rm ./tmp.txt;\n query:",
},
},
{
[]string{"testdata", "global_config_no_paths.yml"},
map[[2]int]string{
{942, 1025}: " description: Collect osquery performance stats directly from osquery\n query:", //
{1830, 1894}: " description: This policy should always fail.\n resolution:", //
{1879, 1945}: " resolution: There is no resolution for this policy.\n query:", //
{2062, 2126}: " description: This policy should always pass.\n resolution:", //
{2111, 2177}: " resolution: There is no resolution for this policy.\n query:", //
{2470, 2534}: " description: This policy should always fail.\n resolution:", //
{2519, 2585}: " resolution: There is no resolution for this policy.\n query:", //
{2689, 2753}: " description: This policy should always fail.\n resolution:", //
{2738, 3111}: " resolution: |\n Automated method:\n Ask your system administrator to deploy the following script which will ensure proper Security Auditing Retention:\n cp /etc/security/audit_control ./tmp.txt; origExpire=$(cat ./tmp.txt | grep expire-after); sed \"s/${origExpire}/expire-after:60d OR 5G/\" ./tmp.txt > /etc/security/audit_control; rm ./tmp.txt;\n query:",
{6178, 6225}: " description: A cool global label\n query:", //
{6322, 6368}: " description: A fly global label\n hosts:", //
},
},
}
// Test with a small dedicated fixture where exact byte positions are stable
t.Run("testdata/policies/policies.yml", func(t *testing.T) {
fContents, err := os.ReadFile(filepath.Join("testdata", "policies", "policies.yml"))
require.NoError(t, err)
for _, tC := range testCases {
fPath := filepath.Join(tC.fixturePath...)
contents := string(fContents)
actual := getExclusionZones(contents)
t.Run(fPath, func(t *testing.T) {
fContents, err := os.ReadFile(fPath)
require.NoError(t, err)
expected := map[[2]int]string{
{46, 106}: " description: This policy should always fail.\n resolution:",
{93, 155}: " resolution: There is no resolution for this policy.\n query:",
{268, 328}: " description: This policy should always pass.\n resolution:",
{315, 678}: " resolution: |\n Automated method:\n Ask your system administrator to deploy the following script which will ensure proper Security Auditing Retention:\n cp /etc/security/audit_control ./tmp.txt; origExpire=$(cat ./tmp.txt | grep expire-after); sed \"s/${origExpire}/expire-after:60d OR 5G/\" ./tmp.txt > /etc/security/audit_control; rm ./tmp.txt;\n query:",
}
require.Equal(t, len(expected), len(actual))
contents := string(fContents)
actual := getExclusionZones(contents)
require.Equal(t, len(tC.expected), len(actual))
for pos, text := range expected {
assert.Contains(t, actual, pos)
assert.Equal(t, contents[pos[0]:pos[1]], text, pos)
}
})
for pos, text := range tC.expected {
assert.Contains(t, actual, pos)
assert.Equal(t, contents[pos[0]:pos[1]], text, pos)
// Test with a larger config file - verify expected text strings are found within zones
// without hardcoding byte positions (which shift when the file is modified)
t.Run("testdata/global_config_no_paths.yml", func(t *testing.T) {
fContents, err := os.ReadFile(filepath.Join("testdata", "global_config_no_paths.yml"))
require.NoError(t, err)
contents := string(fContents)
actual := getExclusionZones(contents)
// Expected text strings that should be found within exclusion zones
expectedTexts := []string{
" description: Collect osquery performance stats directly from osquery\n query:",
" description: This policy should always fail.\n resolution:",
" resolution: There is no resolution for this policy.\n query:",
" description: This policy should always pass.\n resolution:",
" resolution: |\n Automated method:",
" description: A cool global label\n query:",
" description: A fly global label\n hosts:",
}
for _, expectedText := range expectedTexts {
found := false
for _, zone := range actual {
zoneText := contents[zone[0]:zone[1]]
if zoneText == expectedText || strings.Contains(zoneText, strings.TrimPrefix(expectedText, " ")) {
found = true
break
}
}
})
}
assert.True(t, found, "expected text not found in any exclusion zone: %q", expectedText)
}
})
}
+1
View File
@@ -7,6 +7,7 @@ windows_settings:
scripts:
- path: ./lib/collect-fleetd-logs.sh
enable_disk_encryption: true
enable_recovery_lock_password: true
macos_migration:
enable: false
mode: ""
+1
View File
@@ -9,6 +9,7 @@ controls: # Controls added to "No team"
scripts:
- path: ./lib/collect-fleetd-logs.sh
enable_disk_encryption: true
enable_recovery_lock_password: true
macos_migration:
enable: false
mode: ""
+1
View File
@@ -39,6 +39,7 @@ controls:
scripts:
- path: ./lib/collect-fleetd-logs.sh
enable_disk_encryption: true
enable_recovery_lock_password: true
windows_require_bitlocker_pin: true
macos_setup:
bootstrap_package: null