Emphasize best practices for public certificates#612
Conversation
After auditing our partners' public certs in production, I noticed that quite a few do not adhere to standard best practices. And just today, we had a partner who thought that the OpenSSL command in our OIDC Certificates page was all they needed for their production config. This PR aims to clarify those best practices by making the following improvements: - Remove the OpenSSL command snippet from the OIDC Certificates page since that page relates to the Login.gov cert, not the partner's cert - Add a blurb in the OIDC Certificates page that links to the instructions for generating the partner's public/private keypair - In the instructions for generating a public/private keypair, emphasize that for production configs, the cert should be signed by a Certificate Authority - Add a checklist item in the "Before Deployment" section for the three main best practices for public certificates
nickttng
left a comment
There was a problem hiding this comment.
Overall, it looks good to me.
| If you chose to integrate your app using the OIDC private_key_jwt protocol, you will need to create a private key that will be used to sign your request to our token endpoint, and a corresponding public certificate that you will upload to your app in the Partner Portal. Login.gov will use your public certificate to verify the signature in your request. | ||
|
|
||
| More details on how to create this public/private keypair are available in the [Creating a public certificate](https://developers.login.gov/testing/#creating-a-public-certificate) section of our Testing documentation. | ||
| More details on how to create this public/private keypair are available in the [Creating a public certificate](/testing/#creating-a-public-certificate) section of our Testing documentation. |
| ### Creating a public certificate | ||
|
|
||
| You can use the following OpenSSL command to generate a self-signed 2048-bit PEM-encoded public certificate for your testing/sandbox application (with a 1-year validity period). Self-signed certificates should be for testing/sandbox purposes only. We recommend using Certificate Authority (CA) issued certificates for your production integration. | ||
| You can use the following OpenSSL command to generate a self-signed 2048-bit PEM-encoded public certificate for your testing/sandbox application (with a 1-year validity period). Self-signed certificates should be for testing/sandbox purposes only. **For security reasons, we highly recommend using Certificate Authority (CA) issued certificates for your production integration.** |
There was a problem hiding this comment.
This change makes sense to me
| - A public certificate that adheres to these industry standard best practices: | ||
| - Expiration date of one year or less | ||
| - Positive serial number at least 16 characters in length | ||
| - Signed by a trusted Certificate Authority |
There was a problem hiding this comment.
This gets away from being parallel in construction to the two previous "if" statements, and I'm worried that might be confusing or harder to read for someone going through this documentation, especially for the first time.
Do you want to say that this is more important for configurations using proofing even though we recommend it in general? Or do you want to say we recommend it and its importance is independent of the above paragraph about proofing?
If you want it to be independent, do you think it works better as listed first above both the "if...proofed" and "if this is a SAML..." sections?
There was a problem hiding this comment.
Good catch! I meant it to be right under the logo bullet. I will move it up higher.
| ### Creating a public certificate | ||
|
|
||
| You can use the following OpenSSL command to generate a self-signed 2048-bit PEM-encoded public certificate for your testing/sandbox application (with a 1-year validity period). Self-signed certificates should be for testing/sandbox purposes only. We recommend using Certificate Authority (CA) issued certificates for your production integration. | ||
| You can use the following OpenSSL command to generate a self-signed 2048-bit PEM-encoded public certificate for your testing/sandbox application (with a 1-year validity period). Self-signed certificates should be for testing/sandbox purposes only. **For security reasons, we highly recommend using Certificate Authority (CA) issued certificates for your production integration.** |
There was a problem hiding this comment.
I suspect that bolding (alone) will have little effect here. Is there some resource we can link to that could help with procuring a CA-issued certificate, especially in a government setting?
There was a problem hiding this comment.
Yes! I have some high level steps but wasn't sure where to put them.
| - **If this is an integration requesting identity proofed attributes, you must include a Failure to Proof URL.** Users will be redirected to this URL if they fail to complete the identity verification process. This page should communicate your agency and/or departments alternate methods of accessing your application. | ||
|
|
||
| - A public certificate that adheres to these industry standard best practices: | ||
| - Expiration date of one year or less |
There was a problem hiding this comment.
Do we have a reference for this best practice? NIST suggests Several years (depends on key size) or 1 to 2 years depending on use (https://csrc.nist.gov/pubs/sp/800/57/pt1/r5/final)
There was a problem hiding this comment.
Hmm. I could have sworn I saw some NIST guidance that was in the order of months. It was in some other context, not SP 800-57.
There was a problem hiding this comment.
OK, I read through that NIST doc, and for our purposes, we should be looking at the recommended cryptoperiod of the Private Signature Key, which is 1 to 3 years. The Public Signature-Verification Key that they allow to have a cryptoperiod of several years (depending on key size), is the public certificate that corresponds to the Private Signature Key in the partner's private/public keypair.
Therefore, if the private part of the pair cannot last more than 3 years, it means they have to generate a new pair after no more than 3 years, which will result in a new public certificate. By setting their public certificate expiration to no more than 3 years, it will remind them of when it's time to rotate their private key.
There was a problem hiding this comment.
It also says that the expiration should be based on several factors. See sections 5.3.1 and 5.3.2
Sensitivity refers to the lifespan of the information being protected (e.g.,
10 minutes, 10 days, or 10 years) and the potential consequences of a loss of protection for that
information (e.g., the disclosure of the information to unauthorized entities). In general, as the
sensitivity of the information or the criticality of the processes protected by cryptography increase,
the length of the associated cryptoperiods should decrease in order to limit the damage that might
result from each compromise.
There was a problem hiding this comment.
So, we might suggest 1 year or less for IdV apps, and 1 to 3 years for auth-only apps.
There was a problem hiding this comment.
I changed it to this. Thoughts?
Expiration date of 1 to 3 years depending on use and risk factors (see NIST 800-57 Part 1 Rev. 5). We recommend 1 year or less to be on the safe side.
1e3e019 to
a80d7ef
Compare
After auditing our partners' public certs in production, I noticed that quite a few do not adhere to standard best practices. And just today, we had a partner who thought that the OpenSSL command in our OIDC Certificates
page was all they needed for their production config.
This PR aims to clarify those best practices by making the following improvements:
page relates to the Login.gov cert, not the partner's cert
generating the partner's public/private keypair