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:
parent
c7efb97f08
commit
f3d52108b4
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue