Introduction:
This article shows you how to generate leaf certificates once you have created a Role in PKI Secrets Engine
Use Case:
You can use this CLI command to generate PKI roles or leaf certificates. You can automate the creation of many roles or leaf certificates with the use of scripts.
Pre-requisites:
- The pki secrets engine is already enabled (for this example on mount "pki_int")
- Root CA or Intermediate CA has been signed by an external Root CA and uploaded into Vault. This will be used to sign the Leaf Certificates.
- jq installed on Linux OS
Procedure:
- ROLES
After enabling the PKI Secrets engine on mount "pki_int" you can use the following command to create a Role.
vault write -force pki_int/roles/pki_role_name
Once the role name is created you can run the following command to "read" the role attributes.
$vault read pki_int/roles/pki_role_name
Key Value
--- -----
allow_any_name false
allow_bare_domains false
allow_glob_domains false
allow_ip_sans true
allow_localhost true
allow_subdomains false
allow_token_displayname false
allow_wildcard_certificates true
allowed_domains []
allowed_domains_template false
allowed_other_sans []
allowed_serial_numbers []
allowed_uri_sans []
allowed_uri_sans_template false
allowed_user_ids []
basic_constraints_valid_for_non_ca false
client_flag true
cn_validations [email hostname]
code_signing_flag false
country []
email_protection_flag false
enforce_hostnames true
ext_key_usage []
ext_key_usage_oids []
generate_lease false
issuer_ref default
key_bits 2048
key_type rsa
key_usage [DigitalSignature KeyAgreement KeyEncipherment]
locality []
max_ttl 0s
no_store false
no_store_metadata false
not_after n/a
not_before_duration 30s
organization []
ou []
policy_identifiers []
postal_code []
province []
require_cn true
server_flag true
signature_bits 256
street_address []
ttl 0s
use_csr_common_name true
use_csr_sans true
use_pss false
Currently, the role "ttl" is set to "0s". We will now update the role attribute "ttl" to 500 hours. We will update other attributes as well.
$ vault write -force pki_int/roles/pki_role_name \
allow_localhost=false \
allowed_domains=daniel.com \
max_ttl=500h \
allow_subdomains=true \
ttl=500h
Key Value
--- -----
allow_any_name false
allow_bare_domains false
allow_glob_domains false
allow_ip_sans true
allow_localhost false
allow_subdomains true
allow_token_displayname false
allow_wildcard_certificates true
allowed_domains [daniel.com]
allowed_domains_template false
allowed_other_sans []
allowed_serial_numbers []
allowed_uri_sans []
allowed_uri_sans_template false
allowed_user_ids []
basic_constraints_valid_for_non_ca false
client_flag true
cn_validations [email hostname]
code_signing_flag false
country []
email_protection_flag false
enforce_hostnames true
ext_key_usage []
ext_key_usage_oids []
generate_lease false
issuer_ref default
key_bits 2048
key_type rsa
key_usage [DigitalSignature KeyAgreement KeyEncipherment]
locality []
max_ttl 500h
no_store false
no_store_metadata false
not_after n/a
not_before_duration 30s
organization []
ou []
policy_identifiers []
postal_code []
province []
require_cn true
server_flag true
signature_bits 256
street_address []
ttl 500h
use_csr_common_name true
use_csr_sans true
use_pss false
- Leaf Certificates
To generate a leaf certificate please use the command below. Please save the private keys as this will not be displayed again.(You can redirect the output to a file as well)
$ vault write -force pki_int/issue/pki_role_name common_name=a.daniel.com
Key Value
--- -----
ca_chain [-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgIUZEC/fV+rLTJvzbmIhT9LIRUoTmIwDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAxMPcm9vdC5kYW5pZWwuY29tMB4XDTI1MDEyOTIzMTQxN1oX
DTI1MDIyODIzMTQ0N1owGjEYMBYGA1UEAxMPcm9vdC5kYW5pZWwuY29tMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwayrbtiZVtGXNc5vfnnzsjyEQxmD
S/stWEMg2TySKSITFaV1RDZj1CLNjsKQhwuSKAIsXChf/zyxbeI4dMoI9OugrEpJ
TqTpGfgf+zi/8ARWVrZ1tyfN38V05Efb9exYxkasB87SxR9gUFj+sJavffh8duvZ
7n4vNFGvdaoKdIm3npOMw4cuhXVXwPEpBigFThlneoFFgb2q/PvxYJbF1grnmq6n
v1MiD90SrFmyaZmugPMJBrVajMy8XUZrmlf1cnc7+zAsREyjI8uTtSp73Q11XnTN
7jLINGDX1pnDQXusqdYyvw5a6nF3pQf+YVnzso0yMKR/44qaJyqCtCnnhQIDAQAB
o38wfTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
J9hytfY4CUsQ/81bNhKn5cms2JQwHwYDVR0jBBgwFoAUJ9hytfY4CUsQ/81bNhKn
5cms2JQwGgYDVR0RBBMwEYIPcm9vdC5kYW5pZWwuY29tMA0GCSqGSIb3DQEBCwUA
A4IBAQBVf7N1EtplZHtu+by5DANh7DI/DkKvG2pnelfIWfWJW1BoIoVWYWuGihQ4
BXxyNWXKSYuFSHSBsDmhn94Dh6gSD1rNN+8juvfyKKYpiyazUYu1mjezBMJzdsNy
/mO2i9dtZMXpk1bWY52TM18g/+BJ9vjjdFO+Vs9homQsasUDI/YZWzbAnxJrDNiL
/4q0VYfCUTkYWnG0eQMtnNQetsppHAT0XTJieqYHPor5fgzWm02M3G1Zq0d9KAw9
9e6KgcrvaTQbgLFWE0dGEZHVaz97UOo6J5VqaLuaAXSANdUwUEwuGstxPHw49D/c
2F/pmvlcu7b3zTv05AzV9Yx1Wa2K
-----END CERTIFICATE-----]
certificate -----BEGIN CERTIFICATE-----
MIIDSzCCAjOgAwIBAgIUGq1se05F9rsYk95yFqepbj3hS8owDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAxMPcm9vdC5kYW5pZWwuY29tMB4XDTI1MDEzMDAwNTIyOFoX
DTI1MDIxOTIwNTI1OFowFzEVMBMGA1UEAxMMYS5kYW5pZWwuY29tMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxGp/axZyCCE0kWZwSRRHgigi3Wvenrj1
n3dJtEoUbiJiyTRAOEdL/d/W6vnvRVvAteQgeVxpxyxXepSj9OFojpUDchN/EOFQ
9C13nmMUWmeWbTt74YDRfQ+HYnMmLABH2I8A3mMgRxDeaw1RUV2VojSc4kpNvT0M
NHcgxvHTkUVLhNibEeaxHBHvlOPy9S3R6LziJMfZVDn7doGssEYMcW67CO5Xzs6U
FFJ1dlOuKvWGP/Ja4AQoDvUZrePi9JpGSlZRL3eDoBu7UMVA7KpvXJ3iAP4A+aQK
kcwx5CpmFvuH8RUK+Ms2XVkCfFYoEzL+VBEX3We8qf7v7AOs48L6MQIDAQABo4GL
MIGIMA4GA1UdDwEB/wQEAwIDqDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
AwIwHQYDVR0OBBYEFO+pzV3YLQKg/KxrdMD1eWDadLLmMB8GA1UdIwQYMBaAFCfY
crX2OAlLEP/NWzYSp+XJrNiUMBcGA1UdEQQQMA6CDGEuZGFuaWVsLmNvbTANBgkq
hkiG9w0BAQsFAAOCAQEAZDquBqheBs/grdOI03LG3SLk4naNqNUxVMy2Bs4Vzc/J
BkIrrVvEIEvA0q3hYrpeeImcCF6iQw/44l/ngS6p7OHpmGyCGCPzy9PUkwjxLvvM
C9u1F5pgVXoQ156VX5u1yNXD8GfM2zLeh2/jnNyIXQ2qZBanXpaSLv0wX7kvStlr
Ltj/CSPfRn1VLEERmaw6bB/C1B35qyP7+Em625Ua7Gl0HgtQqAZu5GdXiPyFRaLx
7H3L3EqdNvCZ4ZI//ba92ryGV+G/abQ+aOUmd4nNJiEnGmcF+5kL6kOjvQMvOY7N
zRFJA2vnG1K0auMEZ4O5lkHH/H35wpdMYC5khudEwg==
-----END CERTIFICATE-----
expiration 1739998378
issuing_ca -----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgIUZEC/fV+rLTJvzbmIhT9LIRUoTmIwDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAxMPcm9vdC5kYW5pZWwuY29tMB4XDTI1MDEyOTIzMTQxN1oX
DTI1MDIyODIzMTQ0N1owGjEYMBYGA1UEAxMPcm9vdC5kYW5pZWwuY29tMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwayrbtiZVtGXNc5vfnnzsjyEQxmD
S/stWEMg2TySKSITFaV1RDZj1CLNjsKQhwuSKAIsXChf/zyxbeI4dMoI9OugrEpJ
TqTpGfgf+zi/8ARWVrZ1tyfN38V05Efb9exYxkasB87SxR9gUFj+sJavffh8duvZ
7n4vNFGvdaoKdIm3npOMw4cuhXVXwPEpBigFThlneoFFgb2q/PvxYJbF1grnmq6n
v1MiD90SrFmyaZmugPMJBrVajMy8XUZrmlf1cnc7+zAsREyjI8uTtSp73Q11XnTN
7jLINGDX1pnDQXusqdYyvw5a6nF3pQf+YVnzso0yMKR/44qaJyqCtCnnhQIDAQAB
o38wfTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
J9hytfY4CUsQ/81bNhKn5cms2JQwHwYDVR0jBBgwFoAUJ9hytfY4CUsQ/81bNhKn
5cms2JQwGgYDVR0RBBMwEYIPcm9vdC5kYW5pZWwuY29tMA0GCSqGSIb3DQEBCwUA
A4IBAQBVf7N1EtplZHtu+by5DANh7DI/DkKvG2pnelfIWfWJW1BoIoVWYWuGihQ4
BXxyNWXKSYuFSHSBsDmhn94Dh6gSD1rNN+8juvfyKKYpiyazUYu1mjezBMJzdsNy
/mO2i9dtZMXpk1bWY52TM18g/+BJ9vjjdFO+Vs9homQsasUDI/YZWzbAnxJrDNiL
/4q0VYfCUTkYWnG0eQMtnNQetsppHAT0XTJieqYHPor5fgzWm02M3G1Zq0d9KAw9
9e6KgcrvaTQbgLFWE0dGEZHVaz97UOo6J5VqaLuaAXSANdUwUEwuGstxPHw49D/c
2F/pmvlcu7b3zTv05AzV9Yx1Wa2K
-----END CERTIFICATE-----
private_key -----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAxGp/axZyCCE0kWZwSRRHgigi3Wvenrj1n3dJtEoUbiJiyTRA
OEdL/d/W6vnvRVvAteQgeVxpxyxXepSj9OFojpUDchN/EOFQ9C13nmMUWmeWbTt7
4YDRfQ+HYnMmLABH2I8A3mMgRxDeaw1RUV2VojSc4kpNvT0MNHcgxvHTkUVLhNib
EeaxHBHvlOPy9S3R6LziJMfZVDn7doGssEYMcW67CO5Xzs6UFFJ1dlOuKvWGP/Ja
4AQoDvUZrePi9JpGSlZRL3eDoBu7UMVA7KpvXJ3iAP4A+aQKkcwx5CpmFvuH8RUK
+Ms2XVkCfFYoEzL+VBEX3We8qf7v7AOs48L6MQIDAQABAoIBAQCQNfkzsRksauTj
1Kign2kZYUqn8+lR9E8zNCxDWRjC/DA3tktohsB+t/heMf/BlupZIhPNx1JK0H2y
HKx8wXs5JKORAEuNI0GC5lcrTWfGMMQ7ky8TlLc68UnfuNfP+qzFjcl/fpxWUUZc
pzyLVwDkRWjipNeLF+V8J/NC3o8N2t9EBGPsQUgiyK620N/cQEUii5Shic2bEIvr
YUJ7vCzM1FBOkSTSDQLmNDuW8MbcqlMCdfpcJ3u19GeJG4GAaPW2uOoCfmymr38y
/SbS2RE8csz3wVdZwGT6XilNaZnOB9grNxenfBF5E8IGmSDzNscN3X+eMdWVJibw
iVlfZZ2hAoGBAOrV/hFsoKWNiH+X3wWNKfFHzK2K4ru4jg+QqJqKUMPeX3tbXZ7j
ZPDD7kA2SMTk24/eotYKGwAMWf1sZiq/Pxx1BC0rAA9DsZD86X6HBzjRdUEt2I0R
ZmUFsBuji3vnR0Clf2udPAzzn3zJ037oGfQO2POFy0LBsvuwmq/4JndtAoGBANYe
Gh1zELZ8TilvDkba5mgRPryfm0veT/CPDAom5tH4UcGrHDu6RpKJwlBS8uhEFYQ0
CmeH6qr/ce8vav/qTl9z1v6DRyP6CCKL+YAmMw0PDunIpzJ+gebSoQKJrzAz7iwl
Sw9QY174oX14ZXyoQ3kZN8W1Ca5RPBweovquj79VAoGBAK5Y0Zf+HgbLXVvdVSa5
9zm7JKpzQoI8Mrw7mfGiXvQMVLcwzgD4sihOTsQ9iSklAB2AHUTrm8Ada3JK2E9E
TYbDGaavFgw/JcWO/4uAlEwKthL+Bpg1IuA9qNHcSeJjgvLr6/3pbnvvI6lx7iN6
Dkqz+z5RRub5B/j01ONwSJ7BAoGARL5bYhMcTYpxSco3CjajfMv0mXig0mXownIa
ynOc7dLM5OH76Y0vtUJ3WXSYOkwJoG1Y3c58YDQtLz7JGqruSKUXZJVfVMSksfrA
uw0InOu1vQdH7uVA7Yu4V+k+jrpNgGzkwWDs1oP6zR7HbpNTPmEDT/2EwyufoeOQ
Le23hxUCgYBwlEk67pXFPNhbOsi3uWPtCTzaiPJpZ9ERsfkLUVxLFkcvZv4jUaFv
dzov0GsQXl7eb0mU3sl79RVBYzTlGBV9pQ19Ph66zVTVHp+N7nN2vwVU8LooJ4I2
+t9w1GEIRilWHEvcW+agr+EG7HY+stOx8hpF1rNieWUeRZzeyxzS3g==
-----END RSA PRIVATE KEY-----
private_key_type rsa
serial_number 1a:ad:6c:7b:4e:45:f6:bb:18:93:de:72:16:a7:a9:6e:3d:e1:4b:ca
This section is for testing ONLY!
You can use the following example script to generate multiple Leaf Certificates. USE at your OWN Risk.!!
Warning: DO NOT KEEP REPEATING THIS SCRIPT as it will keep adding Leaf Certificates to Vault.
To revoke the certificates see another script below!!!
#!/bin/bash
# Path to the file containing common names
COMMON_NAMES_FILE="common_names.txt"
# Path to the PKI secrets engine mount
PKI_PATH="pki_int"
# Role name
ROLE_NAME="pki_role_name"
# Loop through each common name from the file
while IFS= read -r common_name; do
echo "Generating certificate for $common_name"
# Generate the leaf certificate
response=$(vault write -force ${PKI_PATH}/issue/${ROLE_NAME} common_name="${common_name}" 2>&1)
# Check if the command was successful
if [[ $? -eq 0 ]]; then
echo "Certificate generated for $common_name $response"
else
echo "***All leaf certificates have been generated for given Common Names***"
fi
echo "-----------------------------------------"
done < "$COMMON_NAMES_FILE"
USE WITH CAUTION as this will revoke all leaf certificate related to the PKI Role!
#!/bin/bash
# Path to the PKI secrets engine mount
PKI_PATH="pki_int"
# List all issued certificates
certs=$(vault list -format=json ${PKI_PATH}/certs | jq -r '.[]')
# Revoke each certificate
for serial in $certs; do
echo "Revoking certificate with serial number $serial"
response=$(vault write -force ${PKI_PATH}/revoke serial_number=$serial 2>&1)
# Check if the command was successful
if [[ $? -eq 0 ]]; then
echo "Certificate with serial number $serial revoked"
else
echo "Error revoking certificate with serial number $serial: $response"
echo "***MAY NOT BE A LEAF CERTIFICATE***"
fi
echo "-----------------------------------------"
done