Files
Jordan Montgomery c70f6796a0 Add cert rollover tool, update Filevault key decryption for rollover process (#46226)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46226

# Checklist for submitter

If some of the following don't apply, delete the relevant line.


- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.

## Testing
- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually



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

* **New Features**
* Add CA certificate rollover CLI to renew MDM CA certs with an
extend-years option while preserving the private key and certificate
properties.
* **Improvements**
* Decryption logic updated to accept previously-rolled CA certificates
so escrowed disk-encryption keys can be decrypted after rollover.
* **Tests**
  * Expanded tests and mocks to cover rollover and decryption scenarios.
* **Chores**
* Updated ignore rules and added a changelog entry for the rollover
process.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/46226?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-28 16:31:18 -04:00
..

MDM asset manager

The MDM Asset Manager is a tool designed to manage MDM assets in a Fleet database. The assets are exported unencrypted and imported encrypted; hence, the key used for encrypting the assets must be provided.

Usage

Export

To export all MDM assets:

go run tools/mdm/assets/main.go export -key=E6Ow1t2dbKARxEF6O9GFI3DDQRMROhI8 -dir=mdm_assets

You can also specify the asset you want:

go run tools/mdm/assets/main.go export -key=E6Ow1t2dbKARxEF6O9GFI3DDQRMROhI8 -dir=mdm_assets -name=vpp_token

Supported flags are:

  -db-address string
    	Address used to connect to the MySQL instance (default "localhost:3306")
  -db-name string
    	Name of the database with the asset information in the MySQL instance (default "fleet")
  -db-password string
    	Password used to connect to the MySQL instance (default "insecure")
  -db-user string
    	Username used to connect to the MySQL instance (default "fleet")
  -dir string
    	Directory to put the exported assets
  -key string
    	Key used to encrypt the assets
  -name string
    	Name of the MDM asset to export

Import

To import an MDM asset:

go run tools/mdm/assets/main.go import -key=E6Ow1t2dbKARxEF6O9GFI3DDQRMROhI8 -name=vpp_token -value='{"foo": "bar"}'

Supported flags are:

  -db-address string
    	Address used to connect to the MySQL instance (default "localhost:3306")
  -db-name string
    	Name of the database with the asset information in the MySQL instance (default "fleet")
  -db-password string
    	Password used to connect to the MySQL instance (default "insecure")
  -db-user string
    	Username used to connect to the MySQL instance (default "fleet")
  -key string
    	Key used to encrypt the assets
  -name string
    	Name of the MDM asset to import
  -value string
    	Value to be set for the asset

Rollover CA cert

Re-signs the Apple MDM CA certificate (ca_cert) in place, reusing the existing CA private key so previously-issued SCEP client certificates remain valid. Use this when the CA cert is approaching (or has passed) its expiry. Stop all Fleet server containers for the target deployment before running this

go run tools/mdm/assets/main.go rollover-ca-cert -key=E6Ow1t2dbKARxEF6O9GFI3DDQRMROhI8 -extend-years=5

The previous ca_cert row is soft-deleted (kept for audit) and the renewed cert is inserted. The ca_key is untouched. A fresh serial is reserved from identity_serials so the new CA cert can't collide with a client cert issued by the previous CA. After restarting the servers, the "Fleet root certificate authority (CA)" profile redelivers to all Apple-MDM-enrolled hosts on the next profile reconcile.

See Rolling over the Apple MDM CA certificate for the full procedure and expected side effects.

Supported flags are:

  -db-address string
    	Address used to connect to the MySQL instance (default "localhost:3306")
  -db-name string
    	Name of the database with the asset information in the MySQL instance (default "fleet")
  -db-password string
    	Password used to connect to the MySQL instance (default "insecure")
  -db-user string
    	Username used to connect to the MySQL instance (default "fleet")
  -extend-years int
    	Number of years to extend the Apple MDM CA certificate from now (default 5)
  -key string
    	Key used to encrypt the assets