Add more CA usage best practices (#15467)

* Add leaf not after best practice

Also suggest concrete recommendations for lifetimes of various issuers.

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Add advice to use a proper CA hierarchy

Also mention name constraints and HSM backing.

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Add section on safer usage of Roles

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Add initial RBAC example for PKI

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
This commit is contained in:
Alexander Scheel 2022-05-19 11:43:38 -04:00 committed by GitHub
parent c7efb97f08
commit f3d52108b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 153 additions and 0 deletions

View File

@ -72,6 +72,31 @@ by the HSM and one backed by Vault -- can satisfy both use cases. Operators
can make roles setting maximum TTLs for each issuer and consumers of the
mount can decide which to use.
## Use a CA Hierarchy
It is generally recommended to use a hierarchical CA setup, with a root
certificate which issues one or more intermediates (based on usage), which
in turn issue the leaf certificates.
This allows stronger storage or policy guarantees around [protection of the
root CA](#be-careful-with-root-cas), while letting Vault manage the
intermediate CAs and issuance of leaves. Different intermediates might be
issued for different usage, such as VPN signing, Email signing, or testing
versus production TLS services. This helps to keep CRLs limited to specific
purposes: for example, VPN services don't care about the revoked set of
email signing certificates if they're using separate certificates and
different intermediates, and thus don't need both CRL contents. Additionally,
this allows higher risk intermediates (such as those issuing longer-lived
email signing certificates) to have HSM-backing without impacting the
performance of easier-to-rotate intermediates and certificates (such as
TLS intermediates).
Vault supports the use of both the [`allowed_domains` parameter on
Roles](/api-docs/secret/pki#allowed_domains) and the [`permitted_dns_domains`
parameter to set the Name Constraints extension](/api-docs/secret/pki#permitted_dns_domains)
on root and intermediate generation. This allows for several layers of
separation of concerns between TLS-based services.
## Keep certificate lifetimes short, for CRL's sake
This secrets engine aligns with Vault's philosophy of short-lived secrets. As
@ -108,6 +133,27 @@ is down.
This is again a rationale for keeping TTLs short and avoiding revocation
if possible.
### NotAfter Behavior on Leaf Certificates
In Vault 1.11.0, the PKI Secrets Engine has introduced a new
`leaf_not_after_behavior` [parameter on
issuers](/api-docs/secret/pki#leaf_not_after_behavior).
This allows modification of the issuance behavior: should Vault `err`,
preventing issuance of a longer-lived leaf cert than issuer, silently
`truncate` to that of the issuer's `NotAfter` value, or `permit` longer
expirations.
It is strongly suggested to use `err` or `truncate` for intermediates;
`permit` is only useful for root certificates, as intermediate's NotAfter
expiration are checked when validating presented chains.
In combination with a cascading expiration with longer lived roots (perhaps
on the range of 2-10 years), shorter lived intermediates (perhaps on the
range of 6 months to 2 years), and short-lived leaf certificates (on the
range of 30 to 90 days), and the [rotation strategies discussed in other
sections](/docs/secrets/pki/rotation-primitives), this should keep the
CRLs adequately small.
## You must configure issuing/CRL/OCSP information _in advance_
This secrets engine serves CRLs from a predictable location, but it is not
@ -134,6 +180,40 @@ associated leases, to prevent unintended revocation when not using a token with
a long enough lifetime. To revoke these certificates, use the `pki/revoke`
endpoint.
## Safe Usage of Roles
The Vault PKI Secrets Engine supports many options to limit issuance via
[Roles](http://localhost:3000/api-docs/secret/pki#create-update-role).
Careful consideration of construction is necessary to ensure that more
permissions are not given than necessary. Additionally, roles should generally
do _one_ thing; multiple roles should be preferable over having too permissive
roles that allow arbitrary issuance (e.g., `allow_any_name` should generally
be used sparingly, if at all).
- `allow_any_name` should generally be set to `false`; this is the default.
- `allow_localhost` should generally be set to `false` for production
services, unless listening on `localhost` is expected.
- Unless necessary, `allow_wildcard_certificates` should generally be set to
`false`. This is **not** the default due to backwards compatibility
concerns.
- This is especially necessary when `allow_subdomains` or `allow_glob_domains`
are enabled.
- `enforce_hostnames` should generally be enabled for TLS services; this is
the default.
- `allow_ip_sans` should generally be set to `false` (but defaults to `true`),
unless IP address certificates are explicitly required.
- When using short TTLs (< 30 days) or with high issuance volume, it is
generally recommend to set `no_store` to `true` (defaults to `false`).
This prevents revocation but allows higher throughput as Vault no longer
needs to store every issued certificate. This is discussed more in the
[Certificate Storage](#certificate-storage) section below.
- Do not use roles with root certificates (`issuer_ref`). Root certificates
should generally only issue intermediates (see the section on [CA hierarchy
above](#use-a-ca-hierarchy)), which doesn't rely on roles.
- Limit `key_usage` and `ext_key_usage`; don't attempt to allow all usages
for all purposes. Generally the default values are useful for client and
server TLS authentication.
## Certificate Storage
Unlike many secrets engines which replicate their state to all clusters
@ -217,6 +297,79 @@ nature:
- `pem_bundle` this request parameter is only used on the issuer-import
paths and may contain sensitive private key material.
## Role-Based Access
Vault supports [path-based ACL Policies](https://learn.hashicorp.com/tutorials/vault/getting-started-policies)
for limiting access to various paths within Vault.
The following is a condensed example reference of ACLing the PKI Secrets
Engine. These are just a suggestion; other personas and policy approaches
may also be valid.
We suggest the following personas:
- *Operator*; a privileged user who manages the health of the PKI
subsystem; manages issuers and key material.
- *Agent*; a semi-privileged user that manages roles and handles
revocation on behalf of an operator; may also handle delegated
issuance. This may also be called an *administrator* or *role
manager*.
- *Advanced*; potentially a power-user or service that has access to
additional issuance APIs.
- *Requester*; a low-level user or service that simply requests certificates.
- *Unauthed*; any arbitrary user or service that lacks a Vault token.
For these personas, we suggest the following ACLs, in condensed, tabular form:
| Path | Operations | Operator | Agent | Advanced | Requester | Unauthed |
| :--- | :--------- | :------- | :---- | :------- | :-------- | :------- |
| `/ca(/pem)?` | Read | Yes | Yes | Yes | Yes | Yes |
| `/ca_chain` | Read | Yes | Yes | Yes | Yes | Yes |
| `/crl(/pem)?` | Read | Yes | Yes | Yes | Yes | Yes |
| `/cert/:serial(/raw(/pem)?)?` | Read | Yes | Yes | Yes | Yes | Yes |
| `/issuers` | List | Yes | Yes | Yes | Yes | Yes |
| `/issuer/:issuer_ref/(json¦der¦pem)` | Read | Yes | Yes | Yes | Yes | Yes |
| `/issuer/:issuer_ref/crl(/der¦/pem)?` | Read | Yes | Yes | Yes | Yes | Yes |
| `/certs` | List | Yes | Yes | Yes | Yes | |
| `/roles` | List | Yes | Yes | Yes | Yes | |
| `/roles/:role` | Read | Yes | Yes | Yes | Yes | |
| `/(issue¦sign)/:role` | Write | Yes | Yes | Yes | Yes | |
| `/issuer/:issuer_ref/(issue¦sign)/:role` | Write | Yes | Yes | Yes | | |
| `/config/ca` | Read | Yes | Yes | | | |
| `/config/crl` | Read | Yes | Yes | | | |
| `/config/issuers` | Read | Yes | Yes | | | |
| `/crl/rotate` | Read | Yes | Yes | | | |
| `/roles/:role` | Write | Yes | Yes | | | |
| `/issuer/:issuer_ref` | Read | Yes | Yes | | | |
| `/sign-verbatim(/:role)?` | Write | Yes | Yes | | | |
| `/issuer/:issuer_ref/sign-verbatim(/:role)?` | Write | Yes | Yes | | | |
| `/revoke` | Write | Yes | Yes | | | |
| `/tidy` | Write | Yes | Yes | | | |
| `/tidy-status` | Read | Yes | Yes | | | |
| `/config/ca` | Write | Yes | | | | |
| `/config/crl` | Write | Yes | | | | |
| `/config/issuers` | Write | Yes | | | | |
| `/config/keys` | Read, Write | Yes | | | | |
| `/config/urls` | Read, Write | Yes | | | | |
| `/issuer/:issuer_ref` | Write | Yes | | | | |
| `/issuer/:issuer_ref/sign-intermediate` | Write | Yes | | | | |
| `/issuer/issuer_ref/sign-self-issued` | Write | Yes | | | | |
| `/issuers/generate/+/+` | Write | Yes | | | | |
| `/issuers/import/+` | Write | Yes | | | | |
| `/intermediate/generate/+` | Write | Yes | | | | |
| `/intermediate/cross-sign` | Write | Yes | | | | |
| `/intermediate/set-signed` | Write | Yes | | | | |
| `/keys` | List | Yes | | | | |
| `/key/:key_ref` | Read, Write | Yes | | | | |
| `/keys/generate/+` | Write | Yes | | | | |
| `/keys/import` | Write | Yes | | | | |
| `/root/generate/+` | Write | Yes | | | | |
| `/root/sign-intermediate` | Write | Yes | | | | |
| `/root/sign-self-issued` | Write | Yes | | | | |
| `/root/rotate/+` | Write | Yes | | | | |
| `/root/replace` | Write | Yes | | | | |
## Learn
Refer to the [Build Your Own Certificate Authority (CA)](https://learn.hashicorp.com/vault/secrets-management/sm-pki-engine)