-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PEM encoded certificate to external api response #5078
Conversation
Good idea! I'd love another +1 from someone more familiar with working with certificates. I wonder if it makes more sense to put a fingerprint here? If so, that'd make it less unwieldy to keep in the "list" endpoint. As it is, it does seem less than ideal to include it there. Maybe @ahl has an opinion? |
@ahl Any thoughts on this? Should we use an identifier in the list endpoint and then display the full contents in a view endpoint? Ran in to this again while doing a round of cert updates, and forgot that I had started on it. |
For what it's worth, the If we think most consumers of the API would want this as part of list then we should probably include it. |
+1 to adding it in the list too. I don't see the extra bytes being a big problem. There's always oxidecomputer/dropshot#221 (auto gzip if the accept header says to). |
70a51c3
to
288de0f
Compare
288de0f
to
dd3dfef
Compare
@davepacheco - Thoughts on getting this in to release 9? |
Thanks for the bump. Reading back through the comments:
|
Returning full certificates (not the private keys!) via the API is fine. The full certificate is sent to any HTTPS client anyway, whether the user is authenticated or not (for example, run I'm not sure I agree that the size of the certificates are that much of a concern; the wildcard certificates we use on our racks are less than 2 KiB PEM-encoded (so, already base64'd). An eventual snapshot block download endpoint would almost certainly return more than 10 or 20 times that that for efficiently backing up disks off-rack. I don't think fingerprints are particularly useful. (Certificate serial numbers would honestly be more useful, and they're still not that useful on their own.) There's supposed to be a standard way to calculate fingerprints but I think different tools have failed to completely agree on that. |
I do think that it is important to be able to retrieve the actual contents of the certificate (via some endpoint), and as @iliana noted making an https request retrieves the data of the the certificate that the Nexus decides to serve. The intention with returning the certificate contents is to be able to analyze the individual certificate fields (in particular expiration dates). This allows storing the key and certificate "only" in the silo, and no where else. Then when we near expiration we can generate a new key pair to rotate in to the silo. |
Sounds good! So the remaining thing then is: we accept certificates as bytes, not strings; here, we're returning them as strings, which is a little inconsistent and introduces the failure mode that they're not UTF-8 encoded (which produces a 500, which is a little weird, but there's not much else we can do). Should we just return them in bytes the same way we accept them? (@ahl?) |
I think the concern regard the size is not, say, the bandwidth but rather than it would make the CLI cumbersome. I think we can sort that out client-side if it becomes an issue--let's just make the API what we expect to be most useful. If fingerprints aren't useful then let's return the full cert.
Ugh! Should we only accept them as a string? Practically is there a way to encounter that 500? |
Is that difference because we accept certs in PEM or DER, but then always encode them internally as PEM? PEM-encoded certificates are always ASCII, so I don't think it'd be unreasonable to have input be bytes (to support whatever the user is planning to upload) but have output be strings. |
I thought that we only accepted new certificates as PEM encoded Strings, and then write them to a binary field in the database: https://github.com/oxidecomputer/omicron/blob/main/nexus/src/app/certificate.rs#L43 Thought is there a different location where we accept them as bytes? I'm certainly not as familiar with Nexus. It is definitely not great that a 500 is technically possible here. |
I am also not familiar with the full certificate lifecycle, but if we're already only accepting PEM-encoded strings, that seems right to me. |
Ugh, sorry -- I'm living in the past (pre-#3396). These have been Strings for a while now. Great! We do still store them as BYTES in the database, unfortunately. But that's out of scope here. Could you file an issue on that @augustuswm? |
Ugh, sorry for yet more confusion. I think my "approval" posted a comment I had drafted months ago and thought I sent but apparently didn't...and which we already talked about and resolved. Sorry again! This looks good. |
All good! I'll re-run the failed tests here and get an issue open on looking into the database schema. |
When managing multiple silos, it quickly becomes desirable to be able to use the oxide cli and/or sdk to manage them. Handling certificate rotation currently requires storing external state about what certificate is registered with which silo as our external API only returns identity metadata about the certificate. This PR proposes adding the the public certificate to the fields returned for a certificate.
This initial implementation tries to take the simplest approach to this:
An alternative approach may be to only return the full certificate as a part of the view endpoint, but I'm not sure if that is a pattern that we use.
The other consideration is how this should handle the failure to construct a String from the bytes form of a certificate. Currently it is very disruptive, and hard to debug if bad data were to be stored in the database.