Build your own certificate authority (CA)
Vault's PKI secrets engine can dynamically generate X.509 certificates on demand. This allows services to request certificates without going through the usual manual process of generating a private key and Certificate Signing Request (CSR), submitting to a Certificate Authority (CA), and then waiting for the verification and signing process to complete.
Personas
The steps described in this tutorial are typically performed by a security engineer.
Challenge
Organizations should protect their website; however, the Traditional PKI process workflow takes a long time, which motivates organizations to create certificates which do not expire for a year or more.
Solution
Use Vault to create X.509 certificates for usage in Mutual Transport Layer Security (MTLS) or other arbitrary PKI encryption. You can use this solution to create web server certificates, but if users do not import the CA chains, browsers will complain about the self-signed certificates.
Creating PKI certificates is generally a cumbersome process using traditional
tools like openssl
or even more advanced frameworks like CFSSL. These tools
also require a human component to verify certificate distribution meets
organizational security policies.
Vault's PKI secrets engine makes this a lot simpler. The PKI secrets engine can be an intermediate-only certificate authority, which potentially allows for higher levels of security.
- Store CA outside of Vault (air-gapped).
- Create CSRs for the intermediate CA.
- Sign CSR outside Vault and import intermediate CA.
- Issue leaf certificates from the Intermediate CA.
Prerequisites
To perform the tasks described in this tutorial, you need:
A Vault environment. Refer to the Getting Started tutorial to install Vault.
The API and CLI versions of the example scenario use the
jq
tool to parse JSON output. Installjq
in your Vault environment to follow the examples which use this tool.
Launch Terminal
This tutorial includes a free interactive command-line lab that lets you follow along on actual cloud infrastructure.
Policy requirements
Note
For the purposes of this tutorial, you can use a root
token to
work with Vault. However, it is recommended that root tokens are only used for
just enough initial setup or in emergencies. As a best practice, use tokens
with appropriate set of policies based on your role in the organization.
To perform all tasks demonstrated in this tutorial, your policy must include the following capabilities:
If you are not familiar with policies, complete the policies tutorial.
Scenario introduction
In this tutorial, you are going to first generate a self-signed root certificate.
Then you are going to generate an intermediate certificate that is signed by
the root. You can then create a role and generate a certificate for the test.example.com
domain.

You can choose to complete this tutorial at this point or you can continue with the advanced section on multiple issuer functionality beginning with step 7.
There, you will learn how enable a second root CA in the same secrets engine mount. You will also learn how to rotate the older root CA, and begin issuing certificates from the existing role with the new root CA. Finally, you will learn how to sunset the older CA.
In this tutorial, you will perform the following:
- Generate Root CA
- Generate Intermediate CA
- Create a Role
- Request Certificates
- Revoke Certificates
- Remove Expired Certificates
- Enable new Root CA (optional)
- Rotate older Root CA (optional)
- Set default issuer and issue certificate (optional)
- Sunset older Root CA (optional)
Notice about multi-issuer functionality
Vault version 1.11.0 and greater allows a single PKI mount to have many Certificate Authority (CA) certificates ("issuers") in a single mount. All issuers within a single mount get treated as a single Authority, meaning that:
- Certificate Revocation List (CRL) configuration is common to all issuers/
- All authority access URLs are common to all issuers.
- Issued certificates' serial numbers will be unique across all issuers.
However, since each issuer may have a distinct subject and keys, different issuers may have different CRLs.
It is strongly encouraged to limit the scope of CAs within a mount and not to mix different types of CAs (roots and intermediates).
Note
Some functionality will not work if a default issuer is not configured. Vault automatically selects the default issuer from the current issuing certificate on migration from an older Vault version (Vault < 1.11.0).
Lab setup
In another terminal, start a Vault dev server with
root
as the root token.The Vault dev server defaults to running at
127.0.0.1:8200
. The server is also initialized and unsealed.
Insecure operation
Do not run a Vault dev server in production. This approach is only used here to simplify the unsealing process for this demonstration.
Export an environment variable for the
vault
CLI to address the Vault server.Export an environment variable for the
vault
CLI to authenticate with the Vault server.
The Vault server is ready.
Step 1: Generate root CA
In this step, you are going to generate a self-signed root certificate using PKI secrets engine.
Enable the
pki
secrets engine at thepki
path.Successful output example:
Tune the
pki
secrets engine to issue certificates with a maximum time-to-live (TTL) of 87600 hours.Successful output example:
Generate the example.com root CA, give it an issuer name, and save its certificate in the file
root_2022_ca.crt
.This command is not expected to produce any output.
This generates a new self-signed CA certificate and private key. Vault will automatically revoke the generated root at the end of its lease period (TTL); the CA certificate will sign its own Certificate Revocation List (CRL).
List the issuer information for the root CA.
You can read the issuer with its ID to get the certificates and other metadata about the issuer. Let's skip the certificate output, but list the issuer metadata and usage information.
Example output:
Create a role for the root CA; creating this role allows for specifying an issuer when necessary for the purposes of this scenario. This also provides a simple way to transition from one issuer to another by referring to it by name.
Note
This role is only overly permissive in the names that it allows for the purposes of simplification in this tutorial.
Configure the CA and CRL URLs.
Successful output example:
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.
Step 2: Generate intermediate CA
Now, you are going to create an intermediate CA using the root CA you regenerated in the previous step.
Tip
If you have Vault version 1.13.0 or later, you can use the new CLI helper pki issue
to generate your intermediate CA. Follow the steps in the pki issue command tab to use the helper instead of the standard CLI workflow.
First, enable the
pki
secrets engine at thepki_int
path.Successful output example:
Tune the
pki_int
secrets engine to issue certificates with a maximum time-to-live (TTL) of 43800 hours.Successful output example:
Execute the following command to generate an intermediate and save the CSR as
pki_intermediate.csr
.This command is expected to produce no output.
Sign the intermediate certificate with the root CA private key, and save the generated certificate as
intermediate.cert.pem
.This command is expected to produce no output.
Once the CSR is signed and the root CA returns a certificate, it can be imported back into Vault.
Successful output example:
Step 3: Create a role
A role is a logical name that maps to a policy used to generate those credentials. It allows configuration parameters to control certificate common names, alternate names, the key uses that they are valid for, and more.
Here are a few noteworthy parameters:
Param | Description |
---|---|
allowed_domains | Specifies the domains of the role (used with allow_bare_domains and allow-subdomains options) |
allow_bare_domains | Specifies if clients can request certificates matching the value of the actual domains themselves |
allow_subdomains | Specifies if clients can request certificates with CNs that are subdomains of the CNs allowed by the other role options (NOTE: This includes wildcard subdomains.) |
allow_glob_domains | Allows names specified in allowed_domains to contain glob patterns (e.g. ftp*.example.com) |
In this step, you are going to create a role named example-dot-com
.
Create a role named example-dot-com
which allows subdomains, and specify the default issuer ref ID as the value of issuer_ref
.
Step 4: Request certificates
Keep certificate lifetimes short to align with Vault's philosophy of short-lived secrets.
Execute the following command to request a new certificate for the
test.example.com
domain based on the example-dot-com
role.
The response contains the PEM-encoded private key, key type and certificate serial number.
Step 5: Revoke certificates
If a certificate must be revoked, you can easily perform the revocation action which will cause the CRL to be regenerated. When you regenerate the CRL, Vault removes any expired certificates from it.
Note
As of Vault version 1.12.0, the PKI Secret Engine's Bring-Your-Own-Cert (BYOC) 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.
In certain circumstances, you may wish to revoke an issued certificate.
To revoke a certificate, execute the following command.
Example:
Step 6: Remove expired certificates
Keep the storage backend and CRL by periodically removing certificates that have expired and are past a certain buffer period beyond their expiration time.
To remove revoked certificate and clean the CRL.
Note
You can expect the warning message on every invocation of the tidy command. It serves to alert the operator that they can observe progress from the tidy operation in the Vault operational log.
You are now finished with the steps in the main scenario, and can move to the Cleanup section from here.
The following steps 7-10 are optional and for learning about Root CA rotation; these steps also require that you are using Vault version 1.11.0 or greater.
Step 7: Rotate Root CA
Before version 1.11.0, you could not enable more than one root CA in the same PKI secrets engine mount. This makes rotating the root CA challenging when coordinating multiple PKI secrets engine mounts, and manually managing two root CAs while simultaneously deploying the new root CA to clients.
Vault version 1.11.0 introduces a set of new features in the PKI secrets engine, including multi-issuer capabilities, which include more than one root CA in the same secrets engine mount. This enables less burdensome root CA rotation. You can also use CA migration helpers to ease the operational burden of migrating a root CA controlled by Vault.
To begin learning about this functionality, enable another root CA in the existing PKI secrets engine mount using the new rotate feature.
Example output:
Note that the certificate information has multi-issuer information, such as the
issuer_ref
andissuer_name
values.You can also list the issuers to confirm the addition of the new Root CA.
Both root CA issuers are now enabled in the same PKI secrets engine mount. While the new root CA is enabled, it's not yet actively used, and all later issuance from the mount will use the original root CA issuer,
root-2022
.Tip
At this point, the new root CA certificate can be deployed to all devices which require it as part of rotating out the old root CA.
Create a role for the new example.com root CA; creating this role allows for specifying an issuer when necessary. This also provides a simple way to transition from one issuer to another by referring to it by name.
Note
This role is only overly permissive in the names that it allows for the purposes of simplification in this tutorial.
Step 8: Create a cross-signed intermediate
A significant step in rotating an older root CA involves handling devices which might be offline for long periods of time, but which need to eventually come online and fetch the new root certificate.
If you want to effectively handle this situation, you can do so with the use of a cross-signed Intermediate CA between the older root to the new root, such that clients of the older root can trust certificates which the new root signs.
The new cross-sign command provides this functionality to the Vault operator in a familiar way, resembling the command syntax for creating a new intermediate CA with an existing key.
Create the cross-signed Intermediate CSR.
Example output:
Sign the resulting CSR with the older root CA.
Example output:
The result is a cross-signed certificate, but no issuer gets created yet. Import the signed certificate to create the new issuer.
Import the cross-signed certificate.
Example output:
You now have 2 root CAs with a cross-signed intermediate CA providing a trust chain between them. You are ready to handle migration of devices which were not initially possible to migrate to the new root CA.
Read the issuer for the new root CA. You'll notice that there are now more certificates in the
ca_chain
field.Example output:
Specifically, there are 3 certificates in
ca_chain
, as follows:The new root CA certificate (root-2023).
The new cross-signed intermediate CA certificate.
The older root CA certificate (root-2022).
If you do not want the chain composed in this way, you can specify a custom chain with the
manual_chain
parameter when creating the intermediate CA. More information is available in the API documentation.
Step 9: Set default issuer
After your defined cutoff point for the older root CA, and after you have distributed the new root CA to all devices, you can switch the default issuer to the new root CA.
Use the root replace command to do this, and specify the issuer name of the new root CA as the value to the default
parameter.
From this point forward, Vault will issue new certificates based on the new root CA (root-2023).
Step 10: Sunset defunct Root CA
The last step is to sunset the older root CA.
You can effectively sunset the older root CA by removing its ability to issue certificates, while preserving the ability to sign CRLs and revoke certificates.
Remove issuing-certificates
from the Root CA capabilities.
Example output:
You'll notice "issuing-certificates" removed from usage
, and now only "crl-signing", and "read-only" are available on the older root CA. This means it cannot issue any further certificates going forward.
You can confirm this by attempting to issue a certificate directly from the older root CA.
The request fails.
Certificate Revocation Lists (CRL) and Online Certificate Status Protocol (OCSP)
Both CRLs and OCSP allow interrogating revocation status of certificates.
These methods include internal security and authenticity (both CRLs and OCSP responses get signed by the issuing CA within Vault). This means both are fine to distribute over non-secure and non-authenticated channels, such as HTTP.
Vault version 1.12.0 and greater supports automated CRL rebuilding (including optional Delta CRLs which it can rebuild more often than complete CRLs) via the /config/crl API endpoint.
You can also configure automatic tidying of revoked and expired certificates with the /config/auto-tidy endpoint.
Tip
It is suggested that these features be enabled when possible to ensure compatibility with the wider PKIX ecosystem, and to enhance performance of the cluster.
Cleanup
You can unset the two environment variables, VAULT_ADDR
and VAULT_TOKEN
, that you set in the beginning of this tutorial and remove the files you created to clean up.
Unset the environment variables.
Remove the files.
If you also followed the advanced steps, you'll need to remove some additional files.
Stop the Vault server process.
Next steps
Check out the Streamline Certificate Management with HashiCorp Vault webinar recording.
Also, refer to the Vault PKI Secrets Engine Integration tutorial for an example of Nomad using the PKI secrets engine to generate and renew the X.509 certificates it uses. To automate the process, this tutorial leverages the Consul Template tool.