fleetdm / fleet

Open-source platform for IT, security, and infrastructure teams. (Linux, macOS, Chrome, Windows, cloud, data center)
https://fleetdm.com
Other
3.01k stars 418 forks source link

Add new configuration options for Apple Business Manager #8725

Closed lukeheath closed 1 year ago

lukeheath commented 1 year ago

Goal

As a Fleet admin, I want to be able to connect Fleet to my Apple Business Manager account so that I can automatically enroll new, macOS hosts to Fleet. This way, I can order a new MacBook that automatically appears in Fleet when it's unboxed.

Related

Requirements

Tasks

1

Note that --mdm_apple_bm_server_token references the encrypted form of the server token, and --mdm_apple_bm_key is the private key used to decrypt the token.

All three flags have an equivalent flag to specify the file's content instead of its path. The names are the same, with _bytes appended as suffix, e.g. --mdm_apple_bm_server_token_bytes.

2

3

4

mna commented 1 year ago

Estimation: 3

mna commented 1 year ago

@noahtalerman Given that we want --mdm_apple_bm_server_token to be the encrypted form of the server token, and to decrypt it automatically, we will need the Apple BM public certificate to be provided as argument to fleet serve too, not just the private key. We need to call this function to decrypt the token, and it requires both the certificate and the private key: https://pkg.go.dev/github.com/micromdm/nanodep/tokenpki#DecryptTokenJSON

So I'd add an additional --mdm_apple_bm_cert flag, does that work for you? This is consistent with how we name the certificate part of e.g. the apple apns and scep flags (in https://github.com/fleetdm/fleet/issues/7456).

mna commented 1 year ago

@noahtalerman I went ahead and also added the _bytes version of the cert, key and token flags so that they can be set either as a file path or as the raw content, same as we did for apns/scep (here: https://github.com/fleetdm/fleet/pull/8730/files#diff-ac2e116fdc020a592bafe47e45117d69ad8e4490e8b197b193b54267b193ca6fR2357-R2371), so there's also the --mdm_apple_bm_cert_bytes, --mdm_apple_bm_server_token_bytes and mdm_apple_bm_key_bytes flags.

mna commented 1 year ago

@noahtalerman I haven't seen the error message we wanted to print when using those Apple BM flags with a free license, but this is the one I came up with:

Failed to start: validate Apple BM: Apple Business Manager configuration is only available in Fleet Premium

(the "Failed to start:" prefix is automatically added for all issues when running fleet serve, and validate Apple BM is the prefix for all Apple BM-related issues)

mna commented 1 year ago

@noahtalerman @chiiph @lukeheath

I was going to add this validation at Fleet startup, to make sure the Apple BM token was valid not only in format, but was actually accepted by Apple's API:

Validate a connection with the token/key to Apple (TBD how that is done exactly, possibly by making a request to https://developer.apple.com/documentation/devicemanagement/get_account_detail, as it takes no argument and returns information about the account)

However, @chiiph raised valid concerns that we were doing quite a bit of network requests at Fleet startup, and this makes it take that much longer for a fleet instance to report as "online" and healthy and could end up causing issues in large/automated deployments (it could timeout waiting for it to report as healthy, and kill it and start another, entering a loop). Also, this is a network call to an external server, it could be down temporarily or the network could be experiencing issues, failing to connect for whatever reason, and that would prevent Fleet from starting. When running fleet serve manually that's not a big issue, but in automated deployments it could be.

So with that in mind, I'm wondering if we should just do the "format" validation of the Apple BM token at startup (decrypt and ensure it is a valid JSON token), and not do an Apple API call at this point (wait until we actually need to make a call).

However, what we could do that I haven't done yet is to fail with an error if the token is already expired at startup. This does not require an Apple API call.

mna commented 1 year ago

@noahtalerman regarding this:

Add doc to Fleet documenting how to renew the ABM server token and when it is necessary.

Should we start a new page dedicated to MDM, under Using Fleet (or Deploying)? We'll likely have a bunch of other MDM-related features we'll want to document, e.g. things related to APNs generation and setup... If not, any preference on where that token renewal section should go?

noahtalerman commented 1 year ago

@chiiph raised valid concerns that we were doing quite a bit of network requests at Fleet startup, and this makes it take that much longer for a fleet instance to report as "online" and healthy and could end up causing issues in large/automated deployments (it could timeout waiting for it to report as healthy, and kill it and start another, entering a loop)

How does this kill and start mechanism work? Is this something that the user configures in their hosting solution? (AWS, GCP, etc.)

What I'm trying to get a feel for is how common this set up/scenario is for our users/customers. Could this kill / start loop happen a lot?

I'm wondering if we should just do the "format" validation of the Apple BM token at startup (decrypt and ensure it is a valid JSON token), and not do an Apple API call at this point (wait until we actually need to make a call).

@zhumo looping you in here on Martin's proposal.

zhumo commented 1 year ago

I'm wondering if we should just do the "format" validation of the Apple BM token at startup (decrypt and ensure it is a valid JSON token), and not do an Apple API call at this point (wait until we actually need to make a call).

@mna @noahtalerman what's the user impact of doing that?

noahtalerman commented 1 year ago

just do the "format" validation of the Apple BM token at startup...what's the user impact?

@zhumo the user isn't told that their certificate doesn't work when they're in the configuring certificate workflow.

If user supplies a valid certificate that doesn't work for Apple, user is later notified that their token doesn't work (Fleet UI / fleetctl will have to handle this at a later point). User will have to stop / start Fleet server with a token that works.

I'm not sure how common the scenario is in which the user supplies a cert that doesn't work for Apple. I'm thinking uncommon. This is making me think we should just do the "format" validation. Maybe we can display an error message on later calls to Apple Business Manager (like we plan on doing to detect expired certs).

zhumo commented 1 year ago

@noahtalerman @mna "user is later notified that their token doesn't work." What does "later" mean? If I do upload a certificate that Apple rejects, and then I go on and use the product, how far do I go down the rabbit hole until I find out there's a problem?

noahtalerman commented 1 year ago

What does "later" mean? If I do upload a certificate that Apple rejects, and then I go on and use the product, how far do I go down the rabbit hole until I find out there's a problem?

@zhumo @mna I don't think we for sure know yet. My guess is that you'd find out there's a problem when Fleet first tries to get all the hosts pending automatic enrollment (hosts that exist in ABM).

If this is the case, then I think "later" would likely be the next time you visit a page in the UI or run a fleetctl command.

zhumo commented 1 year ago

Let's do the check later and come back to this if it becomes an issue.

mna commented 1 year ago

@noahtalerman @zhumo

Let's do the check later and come back to this if it becomes an issue.

SGTM, thanks.

michalnicp commented 1 year ago

If this is the case, then I think "later" would likely be the next time you visit a page in the UI or run a fleetctl command.

This would be fairly silent. You may seem some errors being logged from the fleet instance, but you would likely still be able to issue mdm commands and most other mdm features would likely continue to work.

mna commented 1 year ago

@michalnicp my understanding is that what @noahtalerman refers to here:

My guess is that you'd find out there's a problem when Fleet first tries to get all the https://github.com/fleetdm/fleet/issues/7958 (hosts that exist in ABM).

is in the UI and the error would show up to the user, if so it wouldn't be silent but the user would have to visit that page at some point. Note that we will have to rely on that anyway for when the token becomes invalid/expired - even with the startup validation, the token could be valid at that point, and we need a way to inform the user at a later time if it becomes invalid. In that sense, validating "later" does not introduce a new problem.

When the user needs to accept new Apple BM terms, we plan to set a flag to true whenever we notice that this is the case, and the frontend will display a banner to notify the user (https://github.com/fleetdm/fleet/issues/8537). We could take a similar approach for if the Apple BM token is invalid/expired if we want to be more explicit in raising the issue.