HashiCorp Learn
Infrastructure
  • TerraformTerraformLearn terraformDocs
  • PackerPackerLearn packerDocs
  • VagrantVagrantLearn vagrantDocs
Security
  • VaultVaultLearn vaultDocs
  • BoundaryBoundaryLearn boundaryDocs
Networking
  • ConsulConsulLearn consulDocs
Applications
  • NomadNomadLearn nomadDocs
  • WaypointWaypointLearn waypointDocs
  • HashiCorp Cloud Platform (HCP) LogoHashiCorp Cloud Platform (HCP)HashiCorp Cloud Platform (HCP)Docs
Type '/' to Search
Loading account...
  • Bookmarks
  • Manage Account
  • Overview
  • Prerequisites
  • Scenario Introduction
  • Step 1: Generate Root CA
  • Step 2: Generate Intermediate CA
  • Step 3: Create a Role
  • Step 4: Request Certificates
  • Step 5: Revoke Certificates
  • Step 6: Remove Expired Certificates
  • Next steps
  • Help and Reference
DocsForum
Back to vault
Secrets ManagementView Collection
    Static Secrets: Key/Value Secrets EngineVersioned Key/Value Secrets EngineCubbyhole Response WrappingDynamic Secrets: Database Secrets EngineDatabase Root Credential RotationDatabase Static Roles and Credential RotationActive Directory Service Account Check-outOpenLDAP Secrets EngineAzure Secrets EngineBuild Your Own Certificate Authority (CA)SSH Secrets Engine: One-Time SSH PasswordUser Configurable Password Generation for Secret Engines[Tech Preview] Key Management Secrets EngineKMIP Secrets EngineBuild Your Own PluginsGenerate Nomad Tokens with HashiCorp VaultGenerate mTLS Certificates for Nomad using VaultVault Integration and Retrieving Dynamic SecretsInject secrets into Terraform using the Vault provider

Build Your Own Certificate Authority (CA)

  • 14 min
  • Products Usedvault
  • This tutorial also appears in: Vault and Interactive.

Vault's PKI secrets engine can dynamically generate X.509 certificates on demand. This allows services to acquire certificates without going through the usual manual process of generating a private key and Certificate Signing Request (CSR), submitting to a 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 X509 certificates for usage in MTLS or other arbitrary PKI encryption. While this can be used to create web server certificates. If users do not import the CA chains, the browser will complain about 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 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.

  1. Store CA outside the Vault (air gapped)
  2. Create CSRs for the intermediates
  3. Sign CSR outside Vault and import intermediate
  4. Issue leaf certificates from the Intermediate CA

»Prerequisites

To perform the tasks described in this tutorial, you need to have a Vault environment. Refer to the Getting Started to install Vault.

NOTE: An interactive tutorial is also available if you do not have a Vault environment to perform the steps described in this tutorial. Click the Show Terminal button to start.

»Policy requirements

NOTE: For the purpose of this tutorial, you can use 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 permissions:

# Enable secrets engine
path "sys/mounts/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

# List enabled secrets engine
path "sys/mounts" {
  capabilities = [ "read", "list" ]
}

# Work with pki secrets engine
path "pki*" {
  capabilities = [ "create", "read", "update", "delete", "list", "sudo" ]
}

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 which is signed by the root. Finally, you are going to generate a certificate for the test.example.com domain.

Each step will be illustrated in three ways but you only need to follow the steps for one.

  • CLI command
  • API calls with cURL
  • Web UI

Overview

In this tutorial, you will perform the following:

  1. Generate Root CA
  2. Generate Intermediate CA
  3. Create a Role
  4. Request Certificates
  5. Revoke Certificates
  6. Remove Expired Certificates

»Step 1: Generate Root CA

In this step, you are going to generate a self-signed root certificate using PKI secrets engine.

  1. First, enable the pki secrets engine at the pki path.

    $ vault secrets enable pki
    
  2. Tune the pki secrets engine to issue certificates with a maximum time-to-live (TTL) of 87600 hours.

    $ vault secrets tune -max-lease-ttl=87600h pki
    
  3. Generate the root certificate and save the certificate in CA_cert.crt.

    $ vault write -field=certificate pki/root/generate/internal \
            common_name="example.com" \
            ttl=87600h > CA_cert.crt
    

    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).

  4. Configure the CA and CRL URLs.

    $ vault write pki/config/urls \
            issuing_certificates="http://127.0.0.1:8200/v1/pki/ca" \
            crl_distribution_points="http://127.0.0.1:8200/v1/pki/crl"
    

»Step 2: Generate Intermediate CA

Now, you are going to create an intermediate CA using the root CA you regenerated in the previous step.

  1. First, enable the pki secrets engine at the pki_int path.

    $ vault secrets enable -path=pki_int pki
    
  2. Tune the pki_int secrets engine to issue certificates with a maximum time-to-live (TTL) of 43800 hours.

    $ vault secrets tune -max-lease-ttl=43800h pki_int
    
  3. Execute the following command to generate an intermediate and save the CSR as pki_intermediate.csr.

    $ vault write -format=json pki_int/intermediate/generate/internal \
            common_name="example.com Intermediate Authority" \
            | jq -r '.data.csr' > pki_intermediate.csr
    
  4. Sign the intermediate certificate with the root certificate and save the generated certificate as intermediate.cert.pem.

    $ vault write -format=json pki/root/sign-intermediate csr=@pki_intermediate.csr \
            format=pem_bundle ttl="43800h" \
            | jq -r '.data.certificate' > intermediate.cert.pem
    
  5. Once the CSR is signed and the root CA returns a certificate, it can be imported back into Vault.

    $ vault write pki_int/intermediate/set-signed certificate=@intermediate.cert.pem
    

»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:

ParamDescription
allowed_domainsSpecifies the domains of the role (used with allow_bare_domains and allow-subdomains options)
allow_bare_domainsSpecifies if clients can request certificates matching the value of the actual domains themselves
allow_subdomainsSpecifies 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_domainsAllows 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.

$ vault write pki_int/roles/example-dot-com \
        allowed_domains="example.com" \
        allow_subdomains=true \
        max_ttl="720h"

»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.

$ vault write pki_int/issue/example-dot-com common_name="test.example.com" ttl="24h"

Key                 Value
---                 -----
certificate         -----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIUTQABMCAsXjG6ExFTX8201xKVH4IwDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAxMPd3d3LmV4YW1wbGUuY29tMB4XDTE4MDcyNDIxMTMxOVoX
             ...

-----END CERTIFICATE-----
issuing_ca          -----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgIUbMYp39mdj7dKX033ZjK18rx05x8wDQYJKoZIhvcNAQEL
             ...

-----END CERTIFICATE-----
private_key         -----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAte1fqy2Ekj+EFqKV6N5QJlBgMo/U4IIxwLZI6a87yAC/rDhm
W58liadXrwjzRgWeqVOoCRr/B5JnRLbyIKBVp6MMFwZVkynEPzDmy0ynuomSfJkM
             ...

-----END RSA PRIVATE KEY-----
private_key_type    rsa
serial_number       4d:00:01:30:20:2c:5e:31:ba:13:11:53:5f:cd:b4:d7:12:95:1f:82

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 the CRL is regenerated, any expired certificates are removed from the CRL.

In certain circumstances, you may wish to revoke an issued certificate.

To revoke a certificate, execute the following command.

$ vault write pki_int/revoke serial_number=<serial_number>

Example:

$ vault write pki_int/revoke \
        serial_number="48:97:82:dd:f0:d3:d9:7e:53:25:ba:fd:f6:77:3e:89:e5:65:cc:e7"
Key                        Value
---                        -----
revocation_time            1532539632
revocation_time_rfc3339    2018-07-25T17:27:12.165206399Z

»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.

$ vault write pki_int/tidy tidy_cert_store=true tidy_revoked_certs=true

»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.

»Help and Reference

  • PKI (Certificates) Secrets Engine
  • PKI Secrets Engine (API)
  • RFC 5280 Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
  • OpenSSL x509 Man Pages


Back to Collection
HashiCorp
  • System Status
  • Terms of Use
  • Security
  • Privacy
stdin: is not a tty