Skip to content

Commit

Permalink
Disk encryption keys are now archived when created/updated (#25638)
Browse files Browse the repository at this point in the history
For #25609

Manual QA in progress. Putting this "In Review" since it is a P1.

Video explaining the PR: https://youtu.be/bUwIdjBLqiM

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] If database migrations are included, checked table schema to
confirm autoupdate
- For database migrations:
- [x] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [x] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [x] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
- [x] Added/updated automated tests
- [x] A detailed QA plan exists on the associated ticket (if it isn't
there, work with the product group's QA engineer to add it)
- [x] Manual QA for all new/changed functionality
  • Loading branch information
getvictor authored and georgekarrv committed Jan 24, 2025
1 parent 8deec20 commit 40b7f4d
Show file tree
Hide file tree
Showing 21 changed files with 599 additions and 267 deletions.
1 change: 1 addition & 0 deletions changes/25609-archive-encryption-keys
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Disk encryption keys are now archived when they are created or updated. They are never fully deleted from the database.
38 changes: 0 additions & 38 deletions server/datastore/mysql/apple_mdm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3551,27 +3551,6 @@ func (ds *Datastore) CleanupUnusedBootstrapPackages(ctx context.Context, pkgStor
return ctxerr.Wrap(ctx, err, "cleanup unused bootstrap packages")
}

func (ds *Datastore) CleanupDiskEncryptionKeysOnTeamChange(ctx context.Context, hostIDs []uint, newTeamID *uint) error {
return ds.withTx(ctx, func(tx sqlx.ExtContext) error {
return cleanupDiskEncryptionKeysOnTeamChangeDB(ctx, tx, hostIDs, newTeamID)
})
}

func cleanupDiskEncryptionKeysOnTeamChangeDB(ctx context.Context, tx sqlx.ExtContext, hostIDs []uint, newTeamID *uint) error {
_, err := getMDMAppleConfigProfileByTeamAndIdentifierDB(ctx, tx, newTeamID, mobileconfig.FleetFileVaultPayloadIdentifier)
if err != nil {
if fleet.IsNotFound(err) {
// the new team does not have a filevault profile so we need to delete the existing ones
if err := bulkDeleteHostDiskEncryptionKeysDB(ctx, tx, hostIDs); err != nil {
return ctxerr.Wrap(ctx, err, "reconcile filevault profiles on team change bulk delete host disk encryption keys")
}
} else {
return ctxerr.Wrap(ctx, err, "reconcile filevault profiles on team change get profile")
}
}
return nil
}

func getMDMAppleConfigProfileByTeamAndIdentifierDB(ctx context.Context, tx sqlx.QueryerContext, teamID *uint, profileIdentifier string) (*fleet.MDMAppleConfigProfile, error) {
if teamID == nil {
teamID = ptr.Uint(0)
Expand Down Expand Up @@ -3603,23 +3582,6 @@ WHERE
return &profile, nil
}

func bulkDeleteHostDiskEncryptionKeysDB(ctx context.Context, tx sqlx.ExtContext, hostIDs []uint) error {
if len(hostIDs) == 0 {
return nil
}

query, args, err := sqlx.In(
"DELETE FROM host_disk_encryption_keys WHERE host_id IN (?)",
hostIDs,
)
if err != nil {
return ctxerr.Wrap(ctx, err, "building query")
}

_, err = tx.ExecContext(ctx, query, args...)
return err
}

func (ds *Datastore) SetOrUpdateMDMAppleSetupAssistant(ctx context.Context, asst *fleet.MDMAppleSetupAssistant) (*fleet.MDMAppleSetupAssistant, error) {
const stmt = `
INSERT INTO
Expand Down
19 changes: 10 additions & 9 deletions server/datastore/mysql/apple_mdm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ func testUpdateHostTablesOnMDMUnenroll(t *testing.T, ds *Datastore) {
var hostID uint
err = sqlx.GetContext(context.Background(), ds.reader(context.Background()), &hostID, `SELECT id FROM hosts WHERE uuid = ?`, testUUID)
require.NoError(t, err)
err = ds.SetOrUpdateHostDiskEncryptionKey(ctx, hostID, "asdf", "", nil)
err = ds.SetOrUpdateHostDiskEncryptionKey(ctx, &fleet.Host{ID: hostID}, "asdf", "", nil)
require.NoError(t, err)

key, err := ds.GetHostDiskEncryptionKey(ctx, hostID)
Expand Down Expand Up @@ -1999,7 +1999,7 @@ func testAggregateMacOSSettingsStatusWithFileVault(t *testing.T, ds *Datastore)
require.Equal(t, uint(0), res.Verifying)
require.Equal(t, uint(0), res.Verified)

err = ds.SetOrUpdateHostDiskEncryptionKey(ctx, hosts[0].ID, "foo", "", nil)
err = ds.SetOrUpdateHostDiskEncryptionKey(ctx, hosts[0], "foo", "", nil)
require.NoError(t, err)
res, err = ds.GetMDMAppleProfilesSummary(ctx, nil)
require.NoError(t, err)
Expand Down Expand Up @@ -2041,7 +2041,7 @@ func testAggregateMacOSSettingsStatusWithFileVault(t *testing.T, ds *Datastore)
require.Equal(t, uint(0), res.Verifying)
require.Equal(t, uint(1), res.Verified) // hosts[0] now has filevault fully enforced and verified

err = ds.SetOrUpdateHostDiskEncryptionKey(ctx, hosts[1].ID, "bar", "", nil)
err = ds.SetOrUpdateHostDiskEncryptionKey(ctx, hosts[1], "bar", "", nil)
require.NoError(t, err)
err = ds.SetHostsDiskEncryptionKeyStatus(ctx, []uint{hosts[1].ID}, false, time.Now().Add(1*time.Hour))
require.NoError(t, err)
Expand Down Expand Up @@ -2107,7 +2107,7 @@ func testAggregateMacOSSettingsStatusWithFileVault(t *testing.T, ds *Datastore)
require.Equal(t, uint(0), res.Verifying)
require.Equal(t, uint(0), res.Verified)

err = ds.SetOrUpdateHostDiskEncryptionKey(ctx, hosts[9].ID, "baz", "", nil)
err = ds.SetOrUpdateHostDiskEncryptionKey(ctx, hosts[9], "baz", "", nil)
require.NoError(t, err)
err = ds.SetHostsDiskEncryptionKeyStatus(ctx, []uint{hosts[9].ID}, true, time.Now().Add(1*time.Hour))
require.NoError(t, err)
Expand Down Expand Up @@ -2652,10 +2652,11 @@ func testDeleteMDMAppleProfilesForHost(t *testing.T, ds *Datastore) {
require.Nil(t, gotProfs)
}

func createDiskEncryptionRecord(ctx context.Context, ds *Datastore, t *testing.T, hostId uint, key string, decryptable bool, threshold time.Time) {
err := ds.SetOrUpdateHostDiskEncryptionKey(ctx, hostId, key, "", nil)
func createDiskEncryptionRecord(ctx context.Context, ds *Datastore, t *testing.T, host *fleet.Host, key string, decryptable bool,
threshold time.Time) {
err := ds.SetOrUpdateHostDiskEncryptionKey(ctx, host, key, "", nil)
require.NoError(t, err)
err = ds.SetHostsDiskEncryptionKeyStatus(ctx, []uint{hostId}, decryptable, threshold)
err = ds.SetHostsDiskEncryptionKeyStatus(ctx, []uint{host.ID}, decryptable, threshold)
require.NoError(t, err)
}

Expand Down Expand Up @@ -2685,7 +2686,7 @@ func TestMDMAppleFileVaultSummary(t *testing.T) {
ctx, ds, t,
)
oneMinuteAfterThreshold := time.Now().Add(+1 * time.Minute)
createDiskEncryptionRecord(ctx, ds, t, verifyingHost.ID, "key-1", true, oneMinuteAfterThreshold)
createDiskEncryptionRecord(ctx, ds, t, verifyingHost, "key-1", true, oneMinuteAfterThreshold)

fvProfileSummary, err := ds.GetMDMAppleFileVaultSummary(ctx, nil)
require.NoError(t, err)
Expand Down Expand Up @@ -2871,7 +2872,7 @@ func TestMDMAppleFileVaultSummary(t *testing.T) {
require.NoError(t, err)

upsertHostCPs([]*fleet.Host{verifyingTeam1Host}, []*fleet.MDMAppleConfigProfile{team1FVProfile}, fleet.MDMOperationTypeInstall, &fleet.MDMDeliveryVerifying, ctx, ds, t)
createDiskEncryptionRecord(ctx, ds, t, verifyingTeam1Host.ID, "key-2", true, oneMinuteAfterThreshold)
createDiskEncryptionRecord(ctx, ds, t, verifyingTeam1Host, "key-2", true, oneMinuteAfterThreshold)

fvProfileSummary, err = ds.GetMDMAppleFileVaultSummary(ctx, &tm.ID)
require.NoError(t, err)
Expand Down
Loading

0 comments on commit 40b7f4d

Please sign in to comment.