2022-05-13 15:22:07 +00:00
|
|
|
---
|
|
|
|
layout: docs
|
2022-05-17 15:44:17 +00:00
|
|
|
page_title: 'PKI - Secrets Engines: Considerations'
|
2022-05-13 15:22:07 +00:00
|
|
|
description: The PKI secrets engine for Vault generates TLS certificates.
|
|
|
|
---
|
|
|
|
|
|
|
|
# PKI Secrets Engine - Considerations
|
|
|
|
|
|
|
|
To successfully deploy this secrets engine, there are a number of important
|
|
|
|
considerations to be aware of, as well as some preparatory steps that should be
|
|
|
|
undertaken. You should read all of these _before_ using this secrets engine or
|
|
|
|
generating the CA to use with this secrets engine.
|
|
|
|
|
2022-05-31 14:04:51 +00:00
|
|
|
## Table of Contents
|
|
|
|
|
|
|
|
- [Be Careful with Root CAs](#be-careful-with-root-cas)
|
|
|
|
- [Managed Keys](#managed-keys)
|
|
|
|
- [One CA Certificate, One Secrets Engine](#one-ca-certificate-one-secrets-engine)
|
|
|
|
- [Always Configure a Default Issuer](#always-configure-a-default-issuer)
|
|
|
|
- [Key Types Matter](#key-types-matter)
|
|
|
|
- [Use a CA Hierarchy](#use-a-ca-hierarchy)
|
2022-06-08 17:13:45 +00:00
|
|
|
- [Cross-Signed Intermediates](#cross-signed-intermediates)
|
2022-05-31 14:04:51 +00:00
|
|
|
- [Keep certificate lifetimes short, for CRL's sake](#keep-certificate-lifetimes-short-for-crls-sake)
|
|
|
|
- [NotAfter Behavior on Leaf Certificates](#notafter-behavior-on-leaf-certificates)
|
|
|
|
- [Cluster Performance and Quantity of Leaf Certificates](#cluster-performance-and-quantity-of-leaf-certificates)
|
|
|
|
- [You must configure issuing/CRL/OCSP information _in advance_](#you-must-configure-issuingcrlocsp-information-_in-advance_)
|
2022-09-12 16:46:01 +00:00
|
|
|
- [Distribution of CRLs and OCSP](#distribution-of-crls-ocsp)
|
|
|
|
- [Automate CRL Building and Tidying](#automate-crl-building-and-tidying)
|
2023-02-07 16:11:33 +00:00
|
|
|
- [Spectrum of Revocation Support](#spectrum-of-revocation-support)
|
|
|
|
- [What Are Cross-Cluster CRLs?](#what-are-cross-cluster-crls)
|
2023-02-03 19:51:30 +00:00
|
|
|
- [Issuer Subjects and CRLs](#issuer-subjects-and-crls)
|
|
|
|
- [Automate Leaf Certificate Renewal](#automate-leaf-certificate-renewal)
|
2022-05-31 14:04:51 +00:00
|
|
|
- [Safe Minimums](#safe-minimums)
|
|
|
|
- [Token Lifetimes and Revocation](#token-lifetimes-and-revocation)
|
|
|
|
- [Safe Usage of Roles](#safe-usage-of-roles)
|
|
|
|
- [Telemetry](#telemetry)
|
|
|
|
- [Auditing](#auditing)
|
|
|
|
- [Role-Based Access](#role-based-access)
|
|
|
|
- [Replicated DataSets](#replicated-datasets)
|
|
|
|
- [Cluster Scalability](#cluster-scalability)
|
2022-09-20 21:30:58 +00:00
|
|
|
- [PSS Support](#pss-support)
|
PKI - Fix order of chain building writes (#17772)
* Ensure correct write ordering in rebuildIssuersChains
When troubleshooting a recent migration failure from 1.10->1.11, it was
noted that some PKI mounts had bad chain construction despite having
valid, chaining issuers. Due to the cluster's leadership trashing
between nodes, the migration logic was re-executed several times,
partially succeeding each time. While the legacy CA bundle migration
logic was written with this in mind, one shortcoming in the chain
building code lead us to truncate the ca_chain: by sorting the list of
issuers after including non-written issuers (with random IDs), these
issuers would occasionally be persisted prior to storage _prior_ to
existing CAs with modified chains.
The migration code carefully imported the active issuer prior to its
parents. However, due to this bug, there was a chance that, if write to
the pending parent succeeded but updating the active issuer didn't, the
active issuer's ca_chain field would only contain the self-reference and
not the parent's reference as well. Ultimately, a workaround of setting
and subsequently unsetting a manual chain would force a chain
regeneration.
In this patch, we simply fix the write ordering: because we need to
ensure a stable chain sorting, we leave the sort location in the same
place, but delay writing the provided referenceCert to the last
position. This is because the reference is meant to be the user-facing
action: without transactional write capabilities, other chains may
succeed, but if the last user-facing action fails, the user will
hopefully retry the action. This will also correct migration, by
ensuring the subsequent issuer import will be attempted again,
triggering another chain build and only persisting this issuer when
all other issuers have also been updated.
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Remigrate ca_chains to fix any missing issuers
In the previous commit, we identified an issue that would occur on
legacy issuer migration to the new storage format. This is easy enough
to detect for any given mount (by an operator), but automating scanning
and remediating all PKI mounts in large deployments might be difficult.
Write a new storage migration version to regenerate all chains on
upgrade, once.
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Add changelog entry
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Add issue to PKI considerations documentation
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Correct %v -> %w in chain building errs
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-11-03 15:50:03 +00:00
|
|
|
- [Issuer Storage Migration Issues](#issuer-storage-migration-issues)
|
2022-05-31 14:04:51 +00:00
|
|
|
|
2022-05-13 15:22:07 +00:00
|
|
|
## Be Careful with Root CAs
|
|
|
|
|
|
|
|
Vault storage is secure, but not as secure as a piece of paper in a bank vault.
|
|
|
|
It is, after all, networked software. If your root CA is hosted outside of
|
|
|
|
Vault, don't put it in Vault as well; instead, issue a shorter-lived
|
|
|
|
intermediate CA certificate and put this into Vault. This aligns with industry
|
|
|
|
best practices.
|
|
|
|
|
|
|
|
Since 0.4, the secrets engine supports generating self-signed root CAs and
|
|
|
|
creating and signing CSRs for intermediate CAs. In each instance, for security
|
|
|
|
reasons, the private key can _only_ be exported at generation time, and the
|
|
|
|
ability to do so is part of the command path (so it can be put into ACL
|
|
|
|
policies).
|
|
|
|
|
|
|
|
If you plan on using intermediate CAs with Vault, it is suggested that you let
|
|
|
|
Vault create CSRs and do not export the private key, then sign those with your
|
|
|
|
root CA (which may be a second mount of the `pki` secrets engine).
|
|
|
|
|
|
|
|
### Managed Keys
|
|
|
|
|
|
|
|
Since 1.10, Vault Enterprise can access private key material in a
|
2023-01-26 00:12:15 +00:00
|
|
|
[_managed key_](/vault/docs/enterprise/managed-keys). In this case, Vault never sees the
|
2022-05-13 15:22:07 +00:00
|
|
|
private key, and the external KMS or HSM performs certificate signing operations.
|
|
|
|
Managed keys are configured by selecting the `kms` type when generating a root
|
|
|
|
or intermediate.
|
|
|
|
|
|
|
|
## One CA Certificate, One Secrets Engine
|
|
|
|
|
2022-05-16 17:13:37 +00:00
|
|
|
Since Vault 1.11.0, the PKI Secrets Engine supports multiple issuers in a single
|
|
|
|
mount. However, in order to simplify the configuration, it is _strongly_
|
|
|
|
recommended that operators limit a mount to a single issuer. If you want to issue
|
|
|
|
certificates from multiple disparate CAs, mount the PKI secrets engine at multiple
|
|
|
|
mount points with separate CA certificates in each.
|
2022-05-13 15:22:07 +00:00
|
|
|
|
2022-11-15 13:43:40 +00:00
|
|
|
The rationale for separating mounts is to simplify permissions management:
|
|
|
|
very few individuals need access to perform operations with the root, but
|
|
|
|
many need access to create leaves. The operations on a root should generally
|
|
|
|
be limited to issuing and revoking intermediate CAs, which is a highly
|
|
|
|
privileged operation; it becomes much easier to audit these operations when
|
|
|
|
they're in a separate mount than if they're mixed in with day-to-day leaf
|
|
|
|
issuance.
|
|
|
|
|
2022-05-13 15:22:07 +00:00
|
|
|
A common pattern is to have one mount act as your root CA and to use this CA
|
|
|
|
only to sign intermediate CA CSRs from other PKI secrets engines.
|
|
|
|
|
2022-05-16 17:13:37 +00:00
|
|
|
To keep old CAs active, there's two approaches to achieving rotation:
|
|
|
|
|
|
|
|
1. Use multiple secrets engines. This allows a fresh start, preserving the
|
|
|
|
old issuer and CRL. Vault ACL policy can be updated to deny new issuance
|
|
|
|
under the old mount point and roles can be re-evaluated before being
|
|
|
|
imported into the new mount point.
|
|
|
|
2. Use multiple issuers in the same mount point. The usage of the old issuer
|
|
|
|
can be restricted to CRL signing, and existing roles and ACL policy can be
|
|
|
|
kept as-is. This allows cross-signing within the same mount, and consumers
|
|
|
|
of the mount won't have to update their configuration. Once the transitional
|
|
|
|
period for this rotation has completed and all past issued certificate have
|
|
|
|
expired, it is encouraged to fully remove the old issuer and any unnecessary
|
|
|
|
cross-signed issuers from the mount point.
|
|
|
|
|
|
|
|
Another suggested use case for multiple issuers in the same mount is splitting
|
|
|
|
issuance by TTL lifetime. For short-lived certificates, an intermediate
|
|
|
|
stored in Vault will often out-perform a HSM-backed intermediate. For
|
|
|
|
longer-lived certificates, however, it is often important to have the
|
|
|
|
intermediate key material secured throughout the lifetime of the end-entity
|
|
|
|
certificate. This means that two intermediates in the same mount -- one backed
|
|
|
|
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.
|
|
|
|
|
2022-05-23 16:00:24 +00:00
|
|
|
### Always Configure a Default Issuer
|
|
|
|
|
2023-01-26 00:12:15 +00:00
|
|
|
For backwards compatibility, [the default issuer](/vault/api-docs/secret/pki#read-issuers-configuration)
|
2022-05-23 16:00:24 +00:00
|
|
|
is used to service PKI endpoints without an explicit issuer (either via path
|
|
|
|
selection or role-based selection). When certificates are revoked and their
|
|
|
|
issuer is no longer part of this PKI mount, Vault places them on the default
|
|
|
|
issuer's CRL. This means maintaining a default issuer is important for both
|
|
|
|
backwards compatibility for issuing certificates and for ensuring revoked
|
|
|
|
certificates land on a CRL.
|
|
|
|
|
2022-05-31 13:21:16 +00:00
|
|
|
### Key Types Matter
|
|
|
|
|
|
|
|
Certain key types have impacts on performance. Signing certificates from a RSA
|
|
|
|
key will be slower than issuing from an ECDSA or Ed25519 key. Key generation
|
|
|
|
(using `/issue/:role` endpoints) using RSA keys will also be slow: RSA key
|
|
|
|
generation involves finding suitable random primes, whereas Ed25519 keys can
|
|
|
|
be random data. As the number of bits goes up (RSA 2048 -> 4096 or ECDSA
|
|
|
|
P-256 -> P-521), signature times also increases.
|
|
|
|
|
|
|
|
This matters in both directions: not only is issuance more expensive,
|
|
|
|
but validation of the corresponding signature (in say, TLS handshakes) will
|
|
|
|
also be more expensive. Careful consideration of both issuer and issued key
|
|
|
|
types can have meaningful impacts on performance of not only Vault, but
|
|
|
|
systems using these certificates.
|
|
|
|
|
2022-05-19 15:43:38 +00:00
|
|
|
## 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
|
2023-01-26 00:12:15 +00:00
|
|
|
Roles](/vault/api-docs/secret/pki#allowed_domains) and the [`permitted_dns_domains`
|
|
|
|
parameter to set the Name Constraints extension](/vault/api-docs/secret/pki#permitted_dns_domains)
|
2022-05-19 15:43:38 +00:00
|
|
|
on root and intermediate generation. This allows for several layers of
|
|
|
|
separation of concerns between TLS-based services.
|
|
|
|
|
2022-06-08 17:13:45 +00:00
|
|
|
### Cross-Signed Intermediates
|
|
|
|
|
|
|
|
When cross-signing intermediates from two separate roots, two separate
|
|
|
|
intermediate issuers will exist within the Vault PKI mount. In order to
|
|
|
|
correctly serve the cross-signed chain on issuance requests, the
|
|
|
|
`manual_chain` override is required on either or both intermediates. This
|
|
|
|
can be constructed in the following order:
|
|
|
|
|
|
|
|
- this issuer (`self`)
|
|
|
|
- this root
|
|
|
|
- the other copy of this intermediate
|
|
|
|
- the other root
|
|
|
|
|
|
|
|
All requests to this issuer for signing will now present the full cross-signed
|
|
|
|
chain.
|
|
|
|
|
2022-05-13 15:22:07 +00:00
|
|
|
## Keep certificate lifetimes short, for CRL's sake
|
|
|
|
|
|
|
|
This secrets engine aligns with Vault's philosophy of short-lived secrets. As
|
|
|
|
such it is not expected that CRLs will grow large; the only place a private key
|
|
|
|
is ever returned is to the requesting client (this secrets engine does _not_
|
|
|
|
store generated private keys, except for CA certificates). In most cases, if the
|
|
|
|
key is lost, the certificate can simply be ignored, as it will expire shortly.
|
|
|
|
|
|
|
|
If a certificate must truly be revoked, the normal Vault revocation function can
|
2022-11-15 13:43:40 +00:00
|
|
|
be used, and any revocation action will cause the CRL to be regenerated. When
|
|
|
|
the CRL is regenerated, any expired certificates are removed from the CRL (and
|
|
|
|
any revoked, expired certificate are removed from secrets engine storage). This
|
|
|
|
is an expensive operation! Due to the structure of the CRL standard, Vault must
|
|
|
|
read **all** revoked certificates into memory in order to rebuild the CRL and
|
|
|
|
clients must fetch the regenerated CRL.
|
2022-05-13 15:22:07 +00:00
|
|
|
|
|
|
|
This secrets engine does not support multiple CRL endpoints with sliding date
|
|
|
|
windows; often such mechanisms will have the transition point a few days apart,
|
|
|
|
but this gets into the expected realm of the actual certificate validity periods
|
|
|
|
issued from this secrets engine. A good rule of thumb for this secrets engine
|
|
|
|
would be to simply not issue certificates with a validity period greater than
|
|
|
|
your maximum comfortable CRL lifetime. Alternately, you can control CRL caching
|
|
|
|
behavior on the client to ensure that checks happen more often.
|
|
|
|
|
|
|
|
Often multiple endpoints are used in case a single CRL endpoint is down so that
|
2022-05-16 17:13:37 +00:00
|
|
|
clients don't have to figure out what to do with a lack of response. Run Vault
|
|
|
|
in HA mode, and the CRL endpoint should be available even if a particular node
|
2022-05-13 15:22:07 +00:00
|
|
|
is down.
|
|
|
|
|
2022-05-16 17:13:37 +00:00
|
|
|
~> Note: Since Vault 1.11.0, with multiple issuers in the same mount point,
|
|
|
|
different issuers may have different CRLs (depending on subject and key
|
|
|
|
material). This means that Vault may need to regenerate multiple CRLs.
|
|
|
|
This is again a rationale for keeping TTLs short and avoiding revocation
|
|
|
|
if possible.
|
|
|
|
|
2022-11-15 13:43:40 +00:00
|
|
|
~> Note: Since Vault 1.12.0, we support two complementary revocation
|
|
|
|
mechanisms: Delta CRLs, which allow for rebuilds of smaller, incremental
|
|
|
|
additions to the last complete CRL, and OCSP, which allows responding to
|
|
|
|
revocation status requests for individual certificates. When coupled with
|
|
|
|
the new CRL auto-rebuild functionality, this means that the revoking step
|
|
|
|
isn't as costly (as the CRL isn't always rebuilt on each revocation),
|
|
|
|
outside of storage considerations. However, while the rebuild operation
|
|
|
|
still can be expensive with lots of certificates, it will be done on a
|
|
|
|
schedule rather than on demand.
|
|
|
|
|
2022-05-19 15:43:38 +00:00
|
|
|
### NotAfter Behavior on Leaf Certificates
|
|
|
|
|
|
|
|
In Vault 1.11.0, the PKI Secrets Engine has introduced a new
|
|
|
|
`leaf_not_after_behavior` [parameter on
|
2023-01-26 00:12:15 +00:00
|
|
|
issuers](/vault/api-docs/secret/pki#leaf_not_after_behavior).
|
2022-05-19 15:43:38 +00:00
|
|
|
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
|
2023-01-26 00:12:15 +00:00
|
|
|
sections](/vault/docs/secrets/pki/rotation-primitives), this should keep the
|
2022-05-19 15:43:38 +00:00
|
|
|
CRLs adequately small.
|
|
|
|
|
2022-05-23 16:00:24 +00:00
|
|
|
### Cluster Performance and Quantity of Leaf Certificates
|
|
|
|
|
2022-09-12 16:46:01 +00:00
|
|
|
As mentioned above, keeping TTLs short (or using `no_store=true`) and avoiding
|
|
|
|
leases is important for a healthy cluster. However it is important to note
|
|
|
|
this is a scale problem: 10-1000 long-lived, stored certificates are probably
|
|
|
|
fine, but 50k-100k become a problem and 500k+ stored, unexpired certificates
|
|
|
|
can negatively impact even large Vault clusters--even with short TTLs!
|
2022-05-23 16:00:24 +00:00
|
|
|
|
2023-01-26 00:12:15 +00:00
|
|
|
However, once these certificates are expired, a [tidy operation](/vault/api-docs/secret/pki#tidy)
|
2022-05-23 16:00:24 +00:00
|
|
|
will clean up CRLs and Vault cluster storage.
|
|
|
|
|
|
|
|
Note that organizational risk assessments for certificate compromise might
|
|
|
|
mean certain certificate types should always be issued with `no_store=false`;
|
|
|
|
even short-lived broad wildcard certificates (say, `*.example.com`) might be
|
|
|
|
important enough to have precise control over revocation. However, an internal
|
|
|
|
service with a well-scoped certificate (say, `service.example.com`) might be
|
|
|
|
of low enough risk to issue a 90-day TTL with `no_store=true`, preventing
|
|
|
|
the need for revocation in the unlikely case of compromise.
|
|
|
|
|
|
|
|
Having a shorter TTL decreases the likelihood of needing to revoke a cert
|
|
|
|
(but cannot prevent it entirely) and decrease the impact of any such
|
|
|
|
compromise.
|
|
|
|
|
2022-09-12 16:46:01 +00:00
|
|
|
~> Note: As of Vault 1.12, the PKI Secret Engine's [Bring-Your-Own-Cert
|
2023-01-26 00:12:15 +00:00
|
|
|
(BYOC)](/vault/api-docs/secret/pki#revoke-certificate)
|
2022-09-12 16:46:01 +00:00
|
|
|
functionality allows revocation of certificates not previously stored
|
|
|
|
(e.g., issued via a role with `no_store=true`). This means that setting
|
|
|
|
`no_store=true` _is now_ safe to be used globally, regardless of importance
|
|
|
|
of issued certificates (and their likelihood for revocation).
|
|
|
|
|
2022-05-13 15:22:07 +00:00
|
|
|
## You must configure issuing/CRL/OCSP information _in advance_
|
|
|
|
|
|
|
|
This secrets engine serves CRLs from a predictable location, but it is not
|
|
|
|
possible for the secrets engine to know where it is running. Therefore, you must
|
|
|
|
configure desired URLs for the issuing certificate, CRL distribution points, and
|
|
|
|
OCSP servers manually using the `config/urls` endpoint. It is supported to have
|
|
|
|
more than one of each of these by passing in the multiple URLs as a
|
|
|
|
comma-separated string parameter.
|
|
|
|
|
2022-05-23 16:00:24 +00:00
|
|
|
~> Note: when using Vault Enterprise's Performance Replication features with a
|
|
|
|
PKI Secrets Engine mount, each cluster will have its own CRL; this means
|
|
|
|
each cluster's unique CRL address should be included in the [AIA
|
|
|
|
information](https://datatracker.ietf.org/doc/html/rfc5280#section-5.2.7)
|
|
|
|
field separately, or the CRLs should be consolidated and served outside of
|
|
|
|
Vault.
|
|
|
|
|
2022-08-19 15:43:44 +00:00
|
|
|
~> Note: When using multiple issuers in the same mount, it is suggested to use
|
|
|
|
the per-issuer AIA fields rather than the global (`/config/urls`) variant.
|
|
|
|
This is for correctness: these fields are used for chain building and
|
|
|
|
automatic CRL detection in certain applications. If they point to the wrong
|
|
|
|
issuer's information, these applications may break.
|
|
|
|
|
2022-09-12 16:46:01 +00:00
|
|
|
## Distribution of CRLs and OCSP
|
|
|
|
|
|
|
|
Both CRLs and OCSP allow interrogating revocation status of certificates. Both
|
|
|
|
of these methods include internal security and authenticity (both CRLs and
|
|
|
|
OCSP responses are signed by the issuing CA within Vault). This means both are
|
|
|
|
fine to distribute over non-secure and non-authenticated channels, such as
|
|
|
|
HTTP.
|
|
|
|
|
|
|
|
## Automate CRL Building and Tidying
|
|
|
|
|
|
|
|
Since Vault 1.12, the PKI Secrets Engine supports automated CRL rebuilding
|
|
|
|
(including optional Delta CRLs which can be built more frequently than
|
|
|
|
complete CRLs) via the `/config/crl` endpoint. Additionally, tidying of
|
|
|
|
revoked and expired certificates can be configured automatically via the
|
|
|
|
`/config/auto-tidy` endpoint. Both of these should be enabled to ensure
|
|
|
|
compatibility with the wider PKIX ecosystem and performance of the cluster.
|
|
|
|
|
2023-02-03 19:51:30 +00:00
|
|
|
## Spectrum of Revocation Support
|
|
|
|
|
|
|
|
Starting with Vault 1.13, the PKI secrets engine has the ability to support a
|
|
|
|
spectrum of cluster sizes and certificate revocation quantities.
|
|
|
|
|
|
|
|
For users with few revocations or who want a unified view and have the
|
|
|
|
inter-cluster bandwidth to support it, we recommend turning on auto
|
|
|
|
rebuilding of CRLs, cross-cluster revocation queues, and cross-cluster CRLs.
|
|
|
|
This allows all consumers of the CRLs to have the most accurate picture of
|
|
|
|
revocations, regardless of which cluster they talk to.
|
|
|
|
|
|
|
|
If the unified CRL becomes too big for the underlying storage mechanism or
|
|
|
|
for a single host to build, we recommend relying on OCSP instead of CRLs.
|
|
|
|
These have much smaller storage entries, and the CRL `disabled` flag is
|
|
|
|
independent of `unified_crls`, allowing unified OCSP to remain.
|
|
|
|
|
|
|
|
However, when cross-cluster traffic becomes too high (or if CRLs are still
|
|
|
|
necessary in addition to OCSP), we recommend sharding the CRL between
|
|
|
|
different clusters. This has been the default behavior of Vault, but with
|
|
|
|
the introduction of per-cluster, templated AIA information, the leaf
|
|
|
|
certificate's Authority Information Access (AIA) info will point directly
|
|
|
|
to the cluster which issued it, allowing the correct CRL for this cert to
|
|
|
|
be identified by the application. This more correctly mimics the behavior
|
|
|
|
of [Let's Encrypt's CRL sharding](https://letsencrypt.org/2022/09/07/new-life-for-crls.html).
|
|
|
|
|
|
|
|
This sharding behavior can also be used for OCSP, if the cross-cluster
|
|
|
|
traffic for revocation entries becomes too high.
|
|
|
|
|
|
|
|
For users who wish to manage revocation manually, using the audit logs to
|
|
|
|
track certificate issuance would allow an external system to identify which
|
|
|
|
certificates were issued. These can be manually tracked for revocation, and
|
|
|
|
a [custom CRL can be built](/vault/api-docs/secret/pki#combine-crls-from-the-same-issuer)
|
|
|
|
using externally tracked revocations. This would allow usage of roles set to
|
|
|
|
`no_store=true`, so Vault is strictly used as an issuing authority and isn't
|
|
|
|
storing any certificates, issued or revoked. For the highest of revocation
|
|
|
|
volumes, this could be the best option.
|
|
|
|
|
|
|
|
Notably, this last approach can either be used for the creation of externally
|
|
|
|
stored unified or sharded CRLs. If a single external unified CRL becomes
|
|
|
|
unreasonably large, each cluster's certificates could have AIA info point
|
|
|
|
to an externally stored and maintained, sharded CRL. However,
|
|
|
|
Vault has no mechanism to sign OCSP requests at this time.
|
|
|
|
|
2023-02-07 16:11:33 +00:00
|
|
|
### What Are Cross-Cluster CRLs?
|
|
|
|
|
|
|
|
Vault Enterprise supports a clustering mode called [Performance
|
|
|
|
Replication](/vault/docs/enterprise/replication#performance-replication). In
|
|
|
|
a replicated PKI Secrets Engine mount, issuer and role information is synced
|
|
|
|
between the Performance Primary and all Performance Secondary clusters.
|
|
|
|
However, each Performance Secondary cluster has its own local storage of
|
|
|
|
issued certificates and revocations which is not synced. In Vault versions
|
|
|
|
before 1.13, this meant that each of these clusters had its own CRL and
|
|
|
|
OCSP data, and any revocation requests needed to be processed on the
|
|
|
|
cluster that issued it (or BYOC used).
|
|
|
|
|
|
|
|
Starting with Vault 1.13, we've added [two
|
|
|
|
features](/vault/api-docs/secret/pki#read-crl-configuration) to Vault
|
|
|
|
Enterprise to help manage this setup more correctly and easily: revocation
|
|
|
|
request queues (`cross_cluster_revocation=true` in `config/crl`) and unified
|
|
|
|
revocation entries (`unified_crl=true` in `config/crl`).
|
|
|
|
|
|
|
|
The former allows operators (revoking by serial number) to request a
|
|
|
|
certificate be revoked regardless of which cluster it was issued on. For
|
|
|
|
example, if a request goes into the Performance Primary, but it didn't
|
|
|
|
issue the certificate, it'll write a cross-cluster revocation request,
|
|
|
|
and mark the results as pending. If another cluster already has this
|
|
|
|
certificate in storage, it will revoke it and confirm the revocation back
|
|
|
|
to the main cluster. An operator can [list pending
|
|
|
|
revocations](/vault/api-docs/secret/pki#list-revocation-requests) to see
|
|
|
|
the status of these requests. To clean up invalid requests (e.g., if the
|
|
|
|
cluster which had that certificate disappeared, if that certificate was
|
|
|
|
issued with `no_store=true` on the role, or if it was an invalid serial
|
|
|
|
number), an operator can [use tidy](/vault/api-docs/secret/pki#tidy) with
|
|
|
|
`tidy_revocation_queue=true`, optionally shortening
|
|
|
|
`revocation_queue_safety_buffer` to remove them quicker.
|
|
|
|
|
|
|
|
The latter allows all clusters to have a unified view of revocations,
|
|
|
|
that is, to have access to a list of revocations performed by other clusters.
|
|
|
|
While the configuration parameter includes `crl` in the description, this
|
|
|
|
applies to [both CRLs](/vault/api-docs/secret/pki#read-issuer-crl) and the
|
|
|
|
[OCSP responder](/vault/api-docs/secret/pki#ocsp-request). When this
|
|
|
|
revocation replication occurs, if any cluster considers a cert revoked when
|
|
|
|
another doesn't (e.g., via BYOC revocation of a `no_store=false` certificate),
|
|
|
|
all clusters will now consider it revoked assuming it hasn't expired. Notably,
|
|
|
|
the active node of the primary cluster will be used to rebuild the CRL; as
|
|
|
|
this can grow large if many clusters have lots of revoked certs, an operator
|
|
|
|
might need to disable CRL building (`disabled=true` in `config/crl`) or
|
|
|
|
increase the [storage size](/vault/docs/configuration/storage/raft#max_entry_size).
|
|
|
|
|
|
|
|
As an aside, all new cross-cluster writes (from Performance Secondary up to
|
|
|
|
the Performance Primary) are performed synchronously. This gives the caller
|
|
|
|
confidence that the request actually went through, at the expense of incurring
|
|
|
|
a bit higher overhead for revoking certificates. When a node loses its GRPC
|
|
|
|
connection (e.g., during leadership election or being otherwise unable to
|
|
|
|
contact the active primary), errors will occur though the local portion of the
|
|
|
|
write (if any) will still succeed. For cross-cluster revocation requests, due
|
|
|
|
to there being no local write, this means that the operation will need to be
|
|
|
|
retried, but in the event of an issue writing a cross-cluster revocation entry
|
|
|
|
when the cert existed locally, the revocation will eventually be synced across
|
|
|
|
clusters when the connection comes back.
|
|
|
|
|
2023-02-03 19:51:30 +00:00
|
|
|
## Issuer Subjects and CRLs
|
|
|
|
|
|
|
|
As noted on several [GitHub issues](https://github.com/hashicorp/vault/issues/10176),
|
|
|
|
Go's x509 library has an opinionated parsing and structuring mechanism for
|
|
|
|
certificate's Subjects. Issuers created within Vault are fine, but when using
|
|
|
|
externally created CA certificates, these may not be parsed
|
|
|
|
correctly throughout all parts of the PKI. In particular, CRLs embed a
|
|
|
|
(modified) copy of the issuer name. This can be avoided by using OCSP to
|
|
|
|
track revocation, but note that performance characteristics are different
|
|
|
|
between OCSP and CRLs.
|
|
|
|
|
2023-02-07 20:51:03 +00:00
|
|
|
~> Note: As of Go 1.20 and Vault 1.13, Go correctly formats the CRL's issuer
|
|
|
|
name and this notice [does not apply](https://github.com/golang/go/commit/a367981b4c8e3ae955eca9cc597d9622201155f3).
|
2023-02-03 19:51:30 +00:00
|
|
|
|
|
|
|
## Automate Leaf Certificate Renewal
|
|
|
|
|
|
|
|
To manage certificates for services at scale, it is best to automate the
|
|
|
|
certificate renewal as much as possible. Vault Agent [has support for
|
|
|
|
automatically renewing requested certificates](/vault/docs/agent/template#certificates)
|
|
|
|
based on the `validTo` field. Other solutions might involve using
|
|
|
|
[cert-manager](https://cert-manager.io/) in Kubernetes or OpenShift, backed
|
|
|
|
by the Vault CA.
|
|
|
|
|
2022-05-13 15:22:07 +00:00
|
|
|
## Safe Minimums
|
|
|
|
|
|
|
|
Since its inception, this secrets engine has enforced SHA256 for signature
|
|
|
|
hashes rather than SHA1. As of 0.5.1, a minimum of 2048 bits for RSA keys is
|
|
|
|
also enforced. Software that can handle SHA256 signatures should also be able to
|
|
|
|
handle 2048-bit keys, and 1024-bit keys are considered unsafe and are disallowed
|
|
|
|
in the Internet PKI.
|
|
|
|
|
|
|
|
## Token Lifetimes and Revocation
|
|
|
|
|
|
|
|
When a token expires, it revokes all leases associated with it. This means that
|
|
|
|
long-lived CA certs need correspondingly long-lived tokens, something that is
|
|
|
|
easy to forget. Starting with 0.6, root and intermediate CA certs no longer have
|
|
|
|
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.
|
|
|
|
|
2022-05-19 15:43:38 +00:00
|
|
|
## Safe Usage of Roles
|
|
|
|
|
|
|
|
The Vault PKI Secrets Engine supports many options to limit issuance via
|
2023-01-26 00:12:15 +00:00
|
|
|
[Roles](/vault/api-docs/secret/pki#create-update-role).
|
2022-05-19 15:43:38 +00:00
|
|
|
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
|
2022-05-31 14:04:51 +00:00
|
|
|
[Replicated Datasets](#replicated-datasets) section below.
|
2022-05-19 15:43:38 +00:00
|
|
|
- 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.
|
|
|
|
|
2022-05-13 15:22:07 +00:00
|
|
|
## Telemetry
|
|
|
|
|
|
|
|
Beyond Vault's default telemetry around request processing, PKI exposes count and
|
2022-05-16 17:13:37 +00:00
|
|
|
duration metrics for the issue, sign, sign-verbatim, and revoke calls. The
|
|
|
|
metrics keys take the form `mount-path,operation,[failure]` with labels for
|
|
|
|
namespace and role name.
|
|
|
|
|
|
|
|
Note that these metrics are per-node and thus would need to be aggregated across
|
|
|
|
nodes and clusters.
|
|
|
|
|
|
|
|
## Auditing
|
|
|
|
|
|
|
|
Because Vault HMACs audit string keys by default, it is necessary to tune
|
|
|
|
PKI secrets mounts to get an accurate view of issuance that is occurring under
|
|
|
|
this mount.
|
|
|
|
|
2022-11-16 14:21:29 +00:00
|
|
|
~> Note: Depending on usage of Vault, CRLs (and rarely, CA chains) can grow to
|
|
|
|
be rather large. We don't recommend un-HMACing the `crl` field for this
|
|
|
|
reason, but note that the recommendations below suggest to un-HMAC the
|
|
|
|
`certificate` response parameter, which the CRL can be served in via
|
|
|
|
the `/pki/cert/crl` API endpoint. Additionally, the `http_raw_body` can
|
|
|
|
be used to return CRL both in PEM and raw binary DER form, so it is
|
2022-11-16 15:01:43 +00:00
|
|
|
suggested not to un-HMAC that field to not corrupt the log format.<br /><br />
|
2023-01-26 00:12:15 +00:00
|
|
|
If this is done with only a [syslog](/vault/docs/audit/syslog) audit device,
|
2022-11-16 14:21:29 +00:00
|
|
|
Vault can deny requests (with an opaque `500 Internal Error` message)
|
|
|
|
after the action has been performed on the server, because it was
|
2022-11-16 15:01:43 +00:00
|
|
|
unable to log the message.<br /><br />
|
2022-11-16 14:21:29 +00:00
|
|
|
The suggested workaround is to either leave the `certificate` and `crl`
|
2023-01-26 00:12:15 +00:00
|
|
|
response fields HMACed and/or to also enable the [`file`](/vault/docs/audit/file)
|
2022-11-16 14:21:29 +00:00
|
|
|
audit log type.
|
|
|
|
|
2022-05-16 17:13:37 +00:00
|
|
|
Some suggested keys to un-HMAC for requests are as follows:
|
|
|
|
|
|
|
|
- `csr` - the requested CSR to sign,
|
|
|
|
- `certificate` - the requested self-signed certificate to re-sign or
|
|
|
|
when importing issuers,
|
|
|
|
- Various issuance-related overriding parameters, such as:
|
|
|
|
- `issuer_ref` - the issuer requested to sign this certificate,
|
|
|
|
- `common_name` - the requested common name,
|
|
|
|
- `alt_names` - alternative requested DNS-type SANs for this certificate,
|
|
|
|
- `other_sans` - other (non-DNS, non-Email, non-IP, non-URI) requested SANs for this certificate,
|
|
|
|
- `ip_sans` - requested IP-type SANs for this certificate,
|
|
|
|
- `uri_sans` - requested URI-type SANs for this certificate,
|
|
|
|
- `ttl` - requested expiration date of this certificate,
|
|
|
|
- `not_after` - requested expiration date of this certificate,
|
|
|
|
- `serial_number` - the subject's requested serial number,
|
|
|
|
- `key_type` - the requested key type,
|
|
|
|
- `private_key_format` - the requested key format which is also
|
|
|
|
used for the public certificate format as well,
|
|
|
|
- Various role- or issuer-related generation parameters, such as:
|
|
|
|
- `managed_key_name` - when creating an issuer, the requested managed
|
|
|
|
key name,
|
|
|
|
- `managed_key_id` - when creating an issuer, the requested managed
|
|
|
|
key identifier,
|
|
|
|
- `ou` - the subject's organizational unit,
|
|
|
|
- `organization` - the subject's organization,
|
|
|
|
- `country` - the subject's country code,
|
|
|
|
- `locality` - the subject's locality,
|
|
|
|
- `province` - the subject's province,
|
|
|
|
- `street_address` - the subject's street address,
|
|
|
|
- `postal_code` - the subject's postal code,
|
|
|
|
- `permitted_dns_domains` - permitted DNS domains,
|
|
|
|
- `policy_identifiers` - the requested policy identifiers when creating a role, and
|
|
|
|
- `ext_key_usage_oids` - the extended key usage OIDs for the requested certificate.
|
|
|
|
|
|
|
|
Some suggested keys to un-HMAC for responses are as follows:
|
|
|
|
|
|
|
|
- `certificate` - the certificate that was issued,
|
|
|
|
- `issuing_ca` - the certificate of the CA which issued the requested
|
|
|
|
certificate,
|
|
|
|
- `serial_number` - the serial number of the certificate that was issued,
|
|
|
|
- `error` - to show errors associated with the request, and
|
|
|
|
- `ca_chain` - optional due to noise; the full CA chain of the issuer of
|
|
|
|
the requested certificate.
|
|
|
|
|
|
|
|
~> Note: These list of parameters to un-HMAC are provided as a suggestion and
|
|
|
|
may not be exhaustive.
|
|
|
|
|
|
|
|
The following keys are suggested **NOT** to un-HMAC, due to their sensitive
|
|
|
|
nature:
|
|
|
|
|
|
|
|
- `private_key` - this response parameter contains the private keys
|
|
|
|
generated by Vault during issuance, and
|
|
|
|
- `pem_bundle` this request parameter is only used on the issuer-import
|
|
|
|
paths and may contain sensitive private key material.
|
2022-05-13 15:22:07 +00:00
|
|
|
|
2022-05-19 15:43:38 +00:00
|
|
|
## Role-Based Access
|
|
|
|
|
2023-01-26 00:12:15 +00:00
|
|
|
Vault supports [path-based ACL Policies](/vault/tutorials/getting-started/getting-started-policies)
|
2022-05-19 15:43:38 +00:00
|
|
|
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 |
|
2022-09-12 16:46:01 +00:00
|
|
|
| `/crl/delta(/pem)?` | Read | Yes | Yes | Yes | Yes | Yes |
|
2022-05-19 15:43:38 +00:00
|
|
|
| `/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 |
|
2022-09-12 16:46:01 +00:00
|
|
|
| `/issuer/:issuer_ref/crl/delta(/der¦/pem)?` | Read | Yes | Yes | Yes | Yes | Yes |
|
|
|
|
| `/ocsp/<request>` | Read | Yes | Yes | Yes | Yes | Yes |
|
|
|
|
| `/ocsp` | Write | Yes | Yes | Yes | Yes | Yes |
|
2022-05-19 15:43:38 +00:00
|
|
|
| `/certs` | List | Yes | Yes | Yes | Yes | |
|
Add proof possession revocation for PKI secrets engine (#16566)
* Allow Proof of Possession based revocation
Revocation by proof of possession ensures that we have a private key
matching the (provided or stored) certificate. This allows callers to
revoke certificate they own (as proven by holding the corresponding
private key), without having an admin create innumerable ACLs around
the serial_number parameter for every issuance/user.
We base this on Go TLS stack's verification of certificate<->key
matching, but extend it where applicable to ensure curves match, the
private key is indeed valid, and has the same structure as the
corresponding public key from the certificate.
This endpoint currently is authenticated, allowing operators to disable
the endpoint if it isn't desirable to use, via ACL policies.
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Clarify error message on ParseDERKey
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Add changelog entry
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Leave revoke-with-key authenticated
After some discussion, given the potential for DoS (via submitting a lot
of keys/certs to validate, including invalid pairs), it seems best to
leave this as an authenticated endpoint. Presently in Vault, there's no
way to have an authenticated-but-unauthorized path (i.e., one which
bypasses ACL controls), so it is recommended (but not enforced) to make
this endpoint generally available by permissive ACL policies.
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Add API documentation on PoP
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Add acceptance tests for Proof of Possession
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Exercise negative cases in PoP tests
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-08-16 18:01:26 +00:00
|
|
|
| `/revoke-with-key` | Write | Yes | Yes | Yes | Yes | |
|
2022-05-19 15:43:38 +00:00
|
|
|
| `/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 | | |
|
2022-09-12 16:46:01 +00:00
|
|
|
| `/config/auto-tidy` | Read | Yes | Yes | | | |
|
2022-05-19 15:43:38 +00:00
|
|
|
| `/config/ca` | Read | Yes | Yes | | | |
|
|
|
|
| `/config/crl` | Read | Yes | Yes | | | |
|
|
|
|
| `/config/issuers` | Read | Yes | Yes | | | |
|
|
|
|
| `/crl/rotate` | Read | Yes | Yes | | | |
|
2022-09-12 16:46:01 +00:00
|
|
|
| `/crl/rotate-delta` | Read | Yes | Yes | | | |
|
2022-05-19 15:43:38 +00:00
|
|
|
| `/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 | | | |
|
2022-09-12 16:46:01 +00:00
|
|
|
| `/tidy-cancel` | Write | Yes | Yes | | | |
|
2022-05-19 15:43:38 +00:00
|
|
|
| `/tidy-status` | Read | Yes | Yes | | | |
|
2022-09-12 16:46:01 +00:00
|
|
|
| `/config/auto-tidy` | Write | Yes | | | | |
|
2022-05-19 15:43:38 +00:00
|
|
|
| `/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 | | | | |
|
2022-08-18 22:08:31 +00:00
|
|
|
| `/issuer/:issuer_ref/revoke` | Write | Yes | | | | |
|
2022-05-19 15:43:38 +00:00
|
|
|
| `/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 | | | | |
|
|
|
|
|
2022-06-02 16:42:56 +00:00
|
|
|
~> Note: With managed keys, operators might need access to [read the mount
|
2023-01-26 00:12:15 +00:00
|
|
|
point's tunable data](/vault/api-docs/system/mounts) (Read on `/sys/mounts`) and
|
|
|
|
may need access [to use or manage managed keys](/vault/api-docs/system/managed-keys).
|
2022-06-02 16:42:56 +00:00
|
|
|
|
2022-05-31 14:04:51 +00:00
|
|
|
## Replicated DataSets
|
|
|
|
|
2023-01-26 00:12:15 +00:00
|
|
|
When operating with [Performance Secondary](/vault/docs/enterprise/replication#architecture)
|
2022-05-31 14:04:51 +00:00
|
|
|
clusters, certain data-sets are maintained across all clusters, while others for performance
|
|
|
|
and scalability reasons are kept within a given cluster.
|
|
|
|
|
|
|
|
The following table breaks down by data type what data sets will cross the cluster boundaries.
|
|
|
|
For data-types that do not cross a cluster boundary, read requests for that data will need to be
|
|
|
|
sent to the appropriate cluster that the data was generated on.
|
|
|
|
|
|
|
|
| Data Set | Replicated Across Clusters |
|
|
|
|
|--------------------------|----------------------------|
|
|
|
|
| Issuers & Keys | Yes |
|
|
|
|
| Roles | Yes |
|
|
|
|
| CRL Config | Yes |
|
|
|
|
| URL Config | Yes |
|
|
|
|
| Issuer Config | Yes |
|
|
|
|
| Key Config | Yes |
|
|
|
|
| CRL | No |
|
|
|
|
| Revoked Certificates | No |
|
|
|
|
| Leaf/Issued Certificates | No |
|
|
|
|
|
|
|
|
The main effect is that within the PKI secrets engine leaf certificates
|
|
|
|
issued with `no_store` set to `false` are stored local to the cluster that issued them.
|
2023-01-26 00:12:15 +00:00
|
|
|
This allows for both primary and [Performance Secondary](/vault/docs/enterprise/replication#architecture)
|
2022-05-31 14:04:51 +00:00
|
|
|
clusters' active node to issue certificates for greater scalability. As a
|
|
|
|
result, these certificates and any revocations are visible only on the issuing
|
|
|
|
cluster. This additionally means each cluster has its own set of CRLs, distinct
|
|
|
|
from other clusters. These CRLs should either be unified into a single CRL for
|
|
|
|
distribution from a single URI, or server operators should know to fetch all
|
|
|
|
CRLs from all clusters.
|
|
|
|
|
|
|
|
## Cluster Scalability
|
|
|
|
|
|
|
|
Most non-introspection operations in the PKI secrets engine require a write to
|
|
|
|
storage, and so are forwarded to the cluster's active node for execution.
|
|
|
|
This table outlines which operations can be executed on performance standby nodes
|
|
|
|
and thus scale horizontally across all nodes within a cluster.
|
|
|
|
|
|
|
|
| Path | Operations |
|
|
|
|
|-------------------------------|----------------------|
|
|
|
|
| ca[/pem] | Read |
|
|
|
|
| cert/<em>serial-number</em> | Read |
|
|
|
|
| cert/ca_chain | Read |
|
|
|
|
| config/crl | Read |
|
|
|
|
| certs | List |
|
|
|
|
| ca_chain | Read |
|
|
|
|
| crl[/pem] | Read |
|
|
|
|
| issue | Update <sup>\*</sup> |
|
|
|
|
| revoke/<em>serial-number</em> | Read |
|
|
|
|
| sign | Update <sup>\*</sup> |
|
|
|
|
| sign-verbatim | Update <sup>\*</sup> |
|
|
|
|
|
|
|
|
\* Only if the corresponding role has `no_store` set to true and `generate_lease`
|
|
|
|
set to false. If `generate_lease` is true the lease creation will be forwarded to
|
|
|
|
the active node; if `no_store` is false the entire request will be forwarded to
|
|
|
|
the active node.
|
2022-05-19 15:43:38 +00:00
|
|
|
|
2022-09-20 21:30:58 +00:00
|
|
|
## PSS Support
|
|
|
|
|
|
|
|
Go lacks support for PSS certificates, keys, and CSRs using the `rsaPSS` OID
|
|
|
|
(`1.2.840.113549.1.1.10`). It requires all RSA certificates, keys, and CSRs
|
|
|
|
to use the alternative `rsaEncryption` OID (`1.2.840.113549.1.1.1`).
|
|
|
|
|
|
|
|
When using OpenSSL to generate CAs or CSRs from PKCS8-encoded PSS keys, the
|
|
|
|
resulting CAs and CSRs will have the `rsaPSS` OID. Go and Vault will reject
|
|
|
|
them. Instead, use OpenSSL to generate or convert to a PKCS#1v1.5 private
|
|
|
|
key file and use this to generate the CSR. Vault will, depending on the role
|
|
|
|
and the signing mechanism, still use a PSS signature despite the
|
|
|
|
`rsaEncryption` OID on the request as the SubjectPublicKeyInfo and
|
|
|
|
SignatureAlgorithm fields are orthogonal. When creating an external CA and
|
|
|
|
importing it into Vault, ensure that the `rsaEncryption` OID is present on
|
|
|
|
the SubjectPublicKeyInfo field even if the SignatureAlgorithm is PSS-based.
|
|
|
|
|
|
|
|
These certificates generated by Go (with `rsaEncryption` OID but PSS-based
|
|
|
|
signatures) are otherwise compatible with the fully PSS-based certificates.
|
|
|
|
OpenSSL and NSS support parsing and verifying chains using this type of
|
|
|
|
certificate. Note that some TLS implementations may not support these types
|
|
|
|
of certificates if they do not support `rsa_pss_rsae_*` signature schemes.
|
|
|
|
Additionally, some implementations allow rsaPSS OID certificates to contain
|
|
|
|
restrictions on signature parameters allowed by this certificate, but Go and
|
|
|
|
Vault do not support adding such restrictions.
|
|
|
|
|
2022-10-13 13:45:58 +00:00
|
|
|
At this time Go lacks support for signing CSRs with the PSS signature
|
|
|
|
algorithm. If using a managed key that requires a RSA PSS algorithm (such as GCP or
|
|
|
|
a PKCS#11 HSM) as a backing for an intermediate CA key, attempting to generate
|
|
|
|
a CSR (via `pki/intermediate/generate/kms`) will fail signature verification.
|
|
|
|
In this case, the CSR will need to be generated outside of Vault and the
|
|
|
|
signed final certificate can be imported into the mount.
|
2022-10-03 16:39:54 +00:00
|
|
|
|
2022-10-06 16:01:12 +00:00
|
|
|
Go additionally lacks support for creating OCSP responses with the PSS
|
|
|
|
signature algorithm. Vault will automatically downgrade issuers with
|
|
|
|
PSS-based revocation signature algorithms to PKCS#1v1.5, but note that
|
|
|
|
certain KMS devices (like HSMs and GCP) may not support this with the
|
|
|
|
same key. As a result, the OCSP responder may fail to sign responses,
|
|
|
|
returning an internal error.
|
|
|
|
|
PKI - Fix order of chain building writes (#17772)
* Ensure correct write ordering in rebuildIssuersChains
When troubleshooting a recent migration failure from 1.10->1.11, it was
noted that some PKI mounts had bad chain construction despite having
valid, chaining issuers. Due to the cluster's leadership trashing
between nodes, the migration logic was re-executed several times,
partially succeeding each time. While the legacy CA bundle migration
logic was written with this in mind, one shortcoming in the chain
building code lead us to truncate the ca_chain: by sorting the list of
issuers after including non-written issuers (with random IDs), these
issuers would occasionally be persisted prior to storage _prior_ to
existing CAs with modified chains.
The migration code carefully imported the active issuer prior to its
parents. However, due to this bug, there was a chance that, if write to
the pending parent succeeded but updating the active issuer didn't, the
active issuer's ca_chain field would only contain the self-reference and
not the parent's reference as well. Ultimately, a workaround of setting
and subsequently unsetting a manual chain would force a chain
regeneration.
In this patch, we simply fix the write ordering: because we need to
ensure a stable chain sorting, we leave the sort location in the same
place, but delay writing the provided referenceCert to the last
position. This is because the reference is meant to be the user-facing
action: without transactional write capabilities, other chains may
succeed, but if the last user-facing action fails, the user will
hopefully retry the action. This will also correct migration, by
ensuring the subsequent issuer import will be attempted again,
triggering another chain build and only persisting this issuer when
all other issuers have also been updated.
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Remigrate ca_chains to fix any missing issuers
In the previous commit, we identified an issue that would occur on
legacy issuer migration to the new storage format. This is easy enough
to detect for any given mount (by an operator), but automating scanning
and remediating all PKI mounts in large deployments might be difficult.
Write a new storage migration version to regenerate all chains on
upgrade, once.
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Add changelog entry
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Add issue to PKI considerations documentation
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
* Correct %v -> %w in chain building errs
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-11-03 15:50:03 +00:00
|
|
|
## Issuer Storage Migration Issues
|
|
|
|
|
|
|
|
When Vault migrates to the new multi-issuer storage layout on releases prior
|
|
|
|
to 1.11.6, 1.12.2, and 1.13, and storage write errors occur during the mount
|
|
|
|
initialization and storage migration process, the default issuer _may_ not
|
|
|
|
have the correct `ca_chain` value and may only have the self-reference. These
|
|
|
|
write errors most commonly manifest in logs as a message like
|
|
|
|
`failed to persist issuer ... chain to disk: <cause>` and indicate that Vault
|
|
|
|
was not stable at the time of migration. Note that this only occurs when more
|
|
|
|
than one issuer exists within the mount (such as an intermediate with root).
|
|
|
|
|
|
|
|
To fix this manually (until a new version of Vault automatically rebuilds the
|
|
|
|
issuer chain), a rebuild of the chains can be performed:
|
|
|
|
|
|
|
|
```
|
|
|
|
curl -X PATCH -H "Content-Type: application/merge-patch+json" -H "X-Vault-Request: true" -H "X-Vault-Token: $(vault print token)" -d '{"manual_chain":"self"}' https://.../issuer/default
|
|
|
|
curl -X PATCH -H "Content-Type: application/merge-patch+json" -H "X-Vault-Request: true" -H "X-Vault-Token: $(vault print token)" -d '{"manual_chain":""}' https://.../issuer/default
|
|
|
|
```
|
|
|
|
|
|
|
|
This temporarily sets the manual chain on the default issuer to a self-chain
|
|
|
|
only, before reverting it back to automatic chain building. This triggers a
|
|
|
|
refresh of the `ca_chain` field on the issuer, and can be verified with:
|
|
|
|
|
|
|
|
```
|
|
|
|
vault read pki/issuer/default
|
|
|
|
```
|
|
|
|
|
2022-05-23 15:53:13 +00:00
|
|
|
## Tutorial
|
2022-05-13 15:22:07 +00:00
|
|
|
|
2023-02-07 04:34:51 +00:00
|
|
|
Refer to the [Build Your Own Certificate Authority (CA)](/vault/tutorials/secrets-management/pki-engine)
|
2022-05-13 15:22:07 +00:00
|
|
|
guide for a step-by-step tutorial.
|
|
|
|
|
2023-01-26 00:12:15 +00:00
|
|
|
Have a look at the [PKI Secrets Engine with Managed Keys](/vault/tutorials/enterprise/managed-key-pki)
|
2022-05-13 15:22:07 +00:00
|
|
|
for more about how to use externally managed keys with PKI.
|
|
|
|
|
|
|
|
## API
|
|
|
|
|
|
|
|
The PKI secrets engine has a full HTTP API. Please see the
|
2023-01-26 00:12:15 +00:00
|
|
|
[PKI secrets engine API](/vault/api-docs/secret/pki) for more
|
2022-05-13 15:22:07 +00:00
|
|
|
details.
|