Learn Secret Management - PKI Secrets Engine (Automatic CA)
Episode 6 of 21

Learn Secret Management - PKI Secrets Engine (Automatic CA)

Turning OpenBao into an internal Root CA and Intermediate CA, issuing TLS certificates on-demand with short TTLs, and understanding the role of policies in automating certificate issuance for internal services that communicate over TLS.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 5 you used the Transit Secrets Engine to encrypt and decrypt sensitive data without storing the data itself in OpenBao. Episode 6 moves one step further: OpenBao does not only guard keys, it also issues certificates for you. With the PKI Secrets Engine, OpenBao can act as an internal Certificate Authority (CA) that prints TLS certificates automatically, whenever needed, with very short validity periods. This is the foundation of zero-trust architecture and authenticated service-to-service communication.

PKI and Internal CA Concepts

Public Key Infrastructure (PKI) is the system that governs the issuance, distribution, and revocation of digital certificates. In the modern web ecosystem, TLS certificates are usually issued by public CAs such as Let's Encrypt. But inside an internal network, you often don't want every service to use a public certificate — you need an internal CA trusted only by machines you own.

OpenBao can play two roles in a PKI hierarchy:

  • Root CA — the topmost CA that signs its own certificate (self-signed). Its key is stored in very tight isolation and is rarely used directly.
  • Intermediate CA — a subordinate CA whose certificate is signed by the Root CA. Certificates for daily services are issued by this intermediate, not by the root.

This separation matters: if an intermediate is compromised, you simply revoke that intermediate's certificate and build a new one — the Root CA stays safe. This is why OpenBao can automatically act as both a Root CA and an Intermediate CA in a single installation.

Enabling the PKI Secrets Engine

Like other engines, PKI is enabled via bao secrets enable. Its default mount path is pki. You also need to raise the TTL limit, because CA certificates live for a very long time:

Enable PKI and create a Root CA
bao secrets enable pki
bao secrets tune -max-lease-ttl=87600h pki
bao write pki/root/generate/internal \
  common_name="OpenBao Root CA" \
  ttl=87600h

bao secrets enable pki enables the engine at the pki path, while bao write pki/root/generate/internal creates the root key pair and its certificate in a single step. The -max-lease-ttl=87600h option is equivalent to 10 years — a common duration for a root CA.

Building the Hierarchy: Root CA and Intermediate CA

Issuing all certificates directly from the root is possible, but not good practice. The best practice is to use an intermediate. Here is a comparison of the two:

AspectRoot CA (pki)Intermediate CA (pki_int)
Key sourceSelf-generatedCSR signed by the Root CA
UsageAlmost never directIssues service certificates
Issuance pathpki/root/generate/internalpki_int/issue/<role>
Compromise riskCritical, hard to revokeCan be revoked separately
Typical TTLYearsHours to days

The intermediate creation flow begins by enabling a second mount:

Create an Intermediate CA
bao secrets enable -path=pki_int pki
bao secrets tune -max-lease-ttl=43800h pki_int
bao write pki_int/intermediate/generate/internal \
  common_name="OpenBao Intermediate CA" | tee /tmp/intermediate.csr.json

The generated CSR is then signed by the root, and the resulting certificate is imported back into pki_int. After that, pki_int officially becomes an intermediate ready to issue certificates for internal services.

Issuing TLS Certificates On-Demand

To be able to issue certificates, a PKI mount needs a role. A role defines the allowed domains, maximum TTL, and other rules that govern the shape of certificates that may be born. Example role for an internal domain:

Create an issuance role
bao write pki_int/roles/my-role \
  allowed_domains="internal.local" \
  allow_subdomains=true \
  max_ttl="24h"

Once the role exists, issuing a certificate is as easy as one command — no waiting for the manual process of a traditional CA:

Issue an internal TLS certificate
bao write pki_int/issue/my-role \
  common_name="api.internal.local" \
  ttl="24h"

bao write pki_int/issue/my-role common_name="api.internal.local" issues a certificate for api.internal.local valid for 24 hours. The certificate is born instantly over the API, complete with its private key.

The returned output looks roughly like this:

pki_int/issue/my-role response
{
  "data": {
    "certificate": "-----BEGIN CERTIFICATE----- ...",
    "private_key": "-----BEGIN PRIVATE KEY----- ...",
    "issuing_ca": "-----BEGIN CERTIFICATE----- ...",
    "serial_number": "4f:2b:9d:...",
    "expiration": 1753824000
  }
}

You just save private_key and certificate and install them on your service. Because the TTL is short, the service is expected to renew its own certificate before expiry — a pattern known as certificate rotation.

Why Short TTLs

Short-TTL certificates are a pillar of zero-trust:

  • Small compromise window — a leaked certificate is only useful for at most 24 hours.
  • Rotation is forced — services can't be lazy waiting a year for expiry.
  • Revocation is needed less often — rather than revoking a bad certificate, let it expire on its own.

Tip

For internal certificates used only between services, start with a 24-hour TTL, then gradually lower it to 1 to 6 hours once automatic rotation runs smoothly. Remember, max_ttl on the role is the upper limit — the TTL at issuance must not exceed that limit.

Inspecting Issued Certificates

All issued certificates can be tracked from the pki_int mount:

List issued certificates
bao list pki_int/certs
bao read pki_int/cert/4f:2b:9d:...

bao list pki_int/certs shows the serial numbers of all active certificates, and bao read pki_int/cert/<serial> shows the details of each. This is useful for auditing — making sure no foreign certificate was issued without the team's knowledge.

Conclusion

In this episode 6 you turned OpenBao into an internal CA: understood the roles of the Root CA and Intermediate CA, enabled the pki and pki_int engines, built the CA hierarchy, created issuance roles, and issued on-demand TLS certificates with short TTLs for api.internal.local and other internal services.

Key takeaways:

  • Always use an intermediate CA — the root only signs intermediates, not service certificates.
  • Roles define the issuance rulesallowed_domains, max_ttl, and allow_subdomains are controlled here.
  • Short TTLs are a feature, not a drawback — 24-hour certificates force rotation and reduce risk.
  • All certificates are recorded in pki_int/certs — use it for issuance auditing.

In the next episode, episode 7, we pause from secrets engines and discuss Access Control Policies — how OpenBao decides who may access which path, in HCL format, complete with capabilities and privilege enforcement testing.

Learn Secret Management - PKI Secrets Engine (Automatic CA) | Learn Secret Management with OpenBao