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 `generate mdm-apple-bm` command to `fleetctl` #8724

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

2

lukeheath commented 1 year ago

@michalnicp We are creating this same process in the UI so that users can generate their keys via fleetctl or the UI.

In step 3 of the UI ticket, there is a requirement to click the "Download" button, which should generate both the public and private keys and download them in the browser.

I am wondering if you will create endpoints as part of this issue that we can leverage for #8870? If not, would it be better to expand the current issue to include API endpoints that return the files, or should that be spec'd in a separate ticket?

michalnicp commented 1 year ago

@lukeheath I think this should be done as a separate ticket, and requires some discussion.

In https://github.com/fleetdm/fleet/issues/8870#task3, there is a requirement to click the "Download" button, which should generate both the public and private keys and download them in the browser.

We cannot generate the public key certificate and private key using fleet via the API endpoint. This is because we are generating these using fleetctl and passing them via configuration to fleet. Generating them in fleet would require storing them in the database, which we have previously discussed and decided against.

Instead, the best we could do here is have the API endpoint return the previously generated certificate and key. It would have to return a 4xx error if the certificate and key were not provided.

Also, in Apple Business Manager, you only need to upload the public key certificate. Why do we need to include the private key?

Should this endpoint return a response with Content-Type: application/octet-stream. This would make it possible to download the file directly using the browser. I could be wrong, but I think it is more difficult to write to a file using javascript. This would be a departure from the rest of our api which typically returns json, but it may be worth considering.

@roperzh

lukeheath commented 1 year ago

@michalnicp Thanks for the clarification.

I think this should be done as a separate ticket, and requires some discussion.

Sure thing, I'll create a separate ticket for this work. I'll try to get some additional clarification in this comment thread so I can spec it correctly.

Generating them in fleet would require storing them in the database, which we have previously discussed and decided against.

When was this decision made? Based on current product requirements, it will be necessary to generate them via Fleet AND fleetctl. Do we need to store them in the DB? Couldn't we generate them in memory, return them directly to the browser, and not store them in the DB?

Also, in Apple Business Manager, you only need to upload the public key certificate. Why do we need to include the private key?

Current product requirements are to be able to generate everything necessary to configure MDM in the UI and not require usage of fleetctl as reflected in this frontend issue.

Should this endpoint return a response with Content-Type: application/octet-stream. This would make it possible to download the file directly using the browser.

This would be nice. It would be a departure but it would simplify the frontend.

cc @noahtalerman

roperzh commented 1 year ago

+1 to Luke's questions/answers, I would just want to clarify a couple of things:

Generating them in fleet would require storing them in the database, which we have previously discussed and decided against.

When was this decision made? Based on current product requirements, it will be necessary to generate them via Fleet AND fleetctl. Do we need to store them in the DB? Couldn't we generate them in memory, return them directly to the browser, and not store them in the DB?

this was my reaction as well, not storing them in the database means that the IT admin still has to restart the fleet server and provide the keys, but sounds like this is OK. cc: @zhumo for confirmation.

Should this endpoint return a response with Content-Type: application/octet-stream. This would make it possible to download the file directly using the browser. I could be wrong, but I think it is more difficult to write to a file using javascript. This would be a departure from the rest of our api which typically returns json, but it may be worth considering.

we already are doing this for sandbox installers and csv reports, so we have both UI and Go logic in place.

zhumo commented 1 year ago

Hey @lukeheath, yes, it is true, we did discuss wanting to save the certs in the Fleet server but then declined to go in that direction because of the amount of work involved. I definitely want to come back to that in the future as I think it's a better user experience, but it is not something we need for launch I think, esp. as an on-prem product.

So to summarize, the product expectation is that I would need to stop the server and then run fleet serve with the various environment variables pointing to the relevant certs.

lukeheath commented 1 year ago

@zhumo Yep, I understand we need to provide the relevant certs via fleet serve. What I'm asking about is how we are going to generate the certs via the UI. Please take a look at this: https://github.com/fleetdm/fleet/issues/8870#task3. It contains requirements for this UI:

image

In step 1, when the user clicks "Download", we need somewhere to download the keys from. It sounds like Michal is saying that currently, the only way to generate the keys is via fleetctl.

cc @noahtalerman

noahtalerman commented 1 year ago

https://github.com/fleetdm/fleet/issues/8724#issuecomment-1340882467

@roperzh, if I'm understanding correctly, we can generate the certs via fleetctl and the UI without storing the certs in the DB. Is this right?

how are going to generate the certs via the UI?

@lukeheath the above is right, I think the UI will hit some API endpoint to generate the certs (maybe the same API that fleetctl generate mdm-apple-bm hits?)

roperzh commented 1 year ago

if I'm understanding correctly, we can generate the certs via fleetctl and the UI without storing the certs in the DB. Is this right?

@noahtalerman yes, this is correct. This requires extra work (as in: it's totally doable, but not currently possible)

@michalnicp ~just double checking: why did you suggest storing the cert in the DB?~

edit: @noahtalerman I think Michal might have been worried about always providing the same certificate/private key when the user clicks "Download".

If we're OK providing a different certificate each time (which was my assumption) then this is doable, otherwise we need to store the cert in the DB (which we decided not to do).

Yep, I understand we need to provide the relevant certs via fleet serve

@lukeheath that might have been my mistake, I asked @zhumo if the expectation was for the user to have to restart the fleet server if they download the certificates from the UI.


My summary would be:

  1. It's possible for the fleet server to expose an API endpoint to generate the certificates.
  2. We don't need to store the certificate in the database to do that, as long as we're OK providing a different cert/key pair each time the user clicks "Download".
  3. +1 to following up with this in a separate issue.
zhumo commented 1 year ago

oh that's right! these certificates can be generated by your Fleet server instance.

michalnicp commented 1 year ago

@michalnicp ~just double checking: why did you suggest storing the cert in the DB?~

edit: @noahtalerman I think Michal might have been worried about always providing the same certificate/private key when the user clicks "Download".

If we're OK providing a different certificate each time (which was my assumption) then this is doable, otherwise we need to store the cert in the DB (which we decided not to do).

Yes, I wasn't sure if we should download the existing cert and key, or generate a new one each time. If we generate a new one, then the expectation would be that the user needs to upload the new certificate each time (instead of reusing the existing one).

I would recommend changing the text in the wireframe in https://github.com/fleetdm/fleet/issues/8724#issuecomment-1341545602 "1. Download your public and private keys" so that the user is aware that new cert and keys are generated. They may assume that you are downloading the same cert and key each time, and skip the step to upload the cert to apple business manager if they have previously done so. If they don't upload the new certificate, then we will fail to decrypt the new dep token later.

@lukeheath

roperzh commented 1 year ago

agreed on making the text clearer, I will defer to the product folks, but IMO it's okay to provide a different certificate/key each time as this is meant to be a one-time setup guide.

lukeheath commented 1 year ago

Thanks all; it sounds like we're aligned. I'll create a new ticket dedicated to the API endpoints. To summarize:

1) Generating a new cert/key is okay each time.

2) We will not store the cert in the DB.

3) We will create a new API endpoint (new issue) that generates the new cert/key.