Learn PKI - step-ca: Modern Private CA
Series/Learn PKI/Episode 9
Episode 9 of 23

Learn PKI - step-ca: Modern Private CA

This episode covers step-ca version 0.30, Smallstep's modern private CA: init and bootstrap, various provisioners such as JWK and ACME, template-based issuance, SSH certificate authority, plus the SCEP security fix for CVE-2026-30836.

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

Introduction

In the previous episode, episode 8, you mastered ACME and Let's Encrypt — automated issuance for public domains. But not every certificate in the world is a public certificate. Internal APIs, Kubernetes workloads, and SSH into internal servers do not always want to depend on a public CA. For that we need a modern private CA, and episode 9 brings it: step-ca from Smallstep.

Granted, in episode 4 we built a private CA with OpenSSL manually. That gave a deep understanding of the foundations, but in production, managing a manual CA is a burden. step-ca arrives as a single production-ready binary, supports many protocols, and is designed for automation from the start. Version 0.30, released in 2026, is our focus.

This episode's roadmap: we start with init and bootstrap, then explore provisioners, template-based issuance, SSH certificate authority, the security fixes in version 0.30, and finally use the step CLI for day-to-day needs.

Getting to Know step-ca 0.30

step-ca is a modern Certificate Authority that runs as a daemon, designed for cloud native environments. Unlike traditional CAs that use many complex configuration files, step-ca manages the root CA, intermediate CA, and its config in a single tidy directory. It was born from Smallstep's experience building TLS and SSH tooling at scale.

Version 0.30 is the latest release, carrying important security fixes and protocol refinements. For those just starting out, this release is the ideal entry point because it is a stable foundation for all the following episodes, including the cert-manager integration in episode 10.

Init and Bootstrap

The first step is creating the CA: step ca init builds the root CA and intermediate CA at once, complete with the first provisioner and a password to protect the keys. The process is interactive, but all parameters can be given via options so it can be automated.

init-ca.sh
step ca init --name "Internal CA" \
  --dns ca.internal --address ":443" \
  --provisioner admin@internal

The command above creates a root CA and intermediate CA named Internal CA, makes ca.internal the CA's public address, and creates the first admin provisioner. When finished, you get a directory containing the root, intermediate, and config, plus a password that must be stored safely.

The next step is bootstrapping from the client side. step ca bootstrap fetches the root certificate from the CA and places it where the step CLI and local trust store use it.

bootstrap-ca.sh
step ca bootstrap --ca-url https://ca.internal \
  --fingerprint root-fingerprint-here

--fingerprint is the root certificate fingerprint that ensures you are talking to the correct CA — a kind of out-of-band verification. After bootstrapping, all step CLI commands will talk to this CA directly.

Provisioners

The key concept in step-ca is the provisioner: the mechanism for authenticating who may request certificates, and under what policy. Think of a provisioner as a gateway — without a valid provisioner, no certificate is issued. step-ca supports several types.

  • JWK: a built-in provisioner based on JSON Web Keys, suitable for admins and machines.
  • OIDC: uses an identity provider such as Keycloak or Entra, good for SSO flows.
  • ACME: allows ACME clients such as certbot to request certificates from step-ca.
  • X5C: authentication based on an existing client certificate.
  • SCEP: a classic protocol for device enrollment, widely used in MDM.
add-provisioner.sh
step ca provisioner add acme --type ACME
step ca provisioner add oidc --type OIDC \
  --client-id client-id --client-secret client-secret \
  --issuer-url https://idp.internal

The step ca provisioner add commands above add an ACME provisioner for standard client integration, and an OIDC provisioner that forwards authentication to an identity provider. Each provisioner can be given its own restriction policy, for example a list of allowed emails or domains.

Template-Based Issuance

step-ca uses a template approach for issuing certificates. Instead of writing all the details on the client side, the admin defines certificate templates that will be rendered based on data from the provisioner. This is similar to the ACME Profiles concept we discussed in episode 8, but more flexible.

The benefit is large: certificate policy — SAN, validity period, Extended Key Usage — is controlled by the admin, not the requester. Clients only need to state the desired identity, and step-ca decides the final shape. You can create special profiles for servers, clients, or even very specific cases.

SSH Certificate Authority

A step-ca feature that is often underestimated: it can become an SSH Certificate Authority. Instead of scattering public keys across servers, you can issue short-lived SSH certificates that are automatically valid on all machines trusting step-ca. This removes the key distribution and rotation problem.

create-ssh-cert.sh
step ssh certificate dev@internal ssh-user.crt \
  ssh-user.key --principal dev --ttl 8h

The command above issues an SSH certificate for user dev with an 8-hour validity. After expiry, the user automatically loses access — without needing to revoke anything. SSH hosts in your environment just need to configure TrustedUserCAKeys to trust the step-ca CA.

Security Fixes in 0.30

Every step-ca release carries security fixes, and 0.30 is no exception. The most important is CVE-2026-30836, a weakness in the SCEP UpdateReq that allowed certificate issuance without proper authentication. Because SCEP is widely used for device enrollment, this weakness could potentially be exploited to obtain certificates that should not be issued.

The 0.30 fix closes that gap so SCEP update requests are validated correctly. For those already running a previous step-ca version, upgrading to 0.30 is a priority, not a choice. If your step-ca has ever been publicly exposed, also check whether any suspicious certificates were issued.

Info

CA security is the security of the entire ecosystem that trusts it. Get into the habit of monitoring step-ca releases and security bulletins regularly, and schedule upgrades quickly when security fixes are released. For SCEP in particular, make sure the device enrollment path cannot be reached from an untrusted network.

step CLI 0.30.x

Creating, Inspecting, and Verifying Certificates

The step CLI is the essential companion to step-ca. With a single binary, you can create certificates, inspect their details, verify validity, and renew expired ones. For quick creation without a CA, there is step certificate create.

create-cert.sh
step certificate create internal/web01 web01.crt \
  web01.key --profile leaf \
  --san web01.internal --san 10.0.5.12

The command above creates a leaf certificate with two SANs at once, one DNS name and one IP. The leaf profile ensures the resulting certificate is for an end entity, not a CA. To inspect the certificate contents and verify its validity:

inspect-cert.sh
step certificate inspect web01.crt
step certificate verify web01.crt \
  --roots /etc/ssl/certs/root-ca.crt

step certificate inspect displays all the certificate details in an easy-to-read form, while verify ensures the chain is valid against the given root. The combination of the two is a reliable quick check before installing a certificate.

Renewing Certificates

For certificates issued by step-ca, renewal is done via step ca renew. This command uses the renewal credentials from the still-valid certificate to obtain a new version without a lengthy re-authentication process.

renew-cert.sh
step ca renew web01.crt web01.key --force

Schedule renewal before the validity period ends, not at expiry. step-ca can be configured to issue certificates with short validity — 24 hours or even less — as long as renewal runs automatically. This aligns with the short-lived certificate trend from episode 8.

Integration with ACME Clients

One of the reasons step-ca is easy to adopt is that it speaks ACME. After adding an ACME-type provisioner, standard clients such as certbot can directly request certificates from step-ca, complete with the validation mechanisms we already learned. This makes step-ca a kind of private Let's Encrypt for your environment.

certbot-stepca.sh
certbot certonly --standalone \
  --server https://ca.internal/acme/acme/directory \
  -d web01.internal

Simply point --server at step-ca's ACME endpoint, and certbot handles the rest. This way, all the ACME skills from episode 8 can be reused on top of a private CA — a foundation we will use again in episode 10.

Closing

Episode 9 introduced a modern private CA worthy of production. You learned to initialize and bootstrap step-ca, understood the role of provisioners as an authentication gateway, leveraged templates to control the shape of certificates, and made step-ca an SSH Certificate Authority. The CVE-2026-30836 security fix also reinforces the importance of keeping a CA up to date.

Key takeaways:

  • step-ca is a modern private CA with a single binary designed for automation.
  • step ca init and step ca bootstrap are the entry gateways to building and using a CA.
  • Provisioners determine who may request certificates: JWK, OIDC, ACME, X5C, and SCEP.
  • Template-based issuance enforces uniform, admin-controlled certificate profiles.
  • step-ca can be an SSH Certificate Authority with short-lived certificates and no manual key distribution.
  • CVE-2026-30836 fixed a SCEP UpdateReq weakness; upgrading to 0.30 is mandatory for SCEP users.
  • The step CLI covers create, inspect, verify, renew, and ACME client integration.

In episode 10, you will see step-ca used at a larger scale. We will learn cert-manager, certificate automation in Kubernetes: the Issuer and Certificate resources, installation via Helm, step-ca integration as an ExternalIssuer, and trust-manager for managing CA bundles. See you there!

Learn PKI - step-ca: Modern Private CA | Learn PKI