Step-CA Private PKI for Zero-Trust Infrastructure: Complete 2026 Deployment Guide
Every zero-trust architecture rests on one assumption: you can cryptographically identify every user, workload, and device before granting access. That means short-lived, automatically rotated certificates instead of static API keys. The public CA world does not scale here β Let’s Encrypt cannot issue client certificates for your internal workloads, and commercial PKI from Entrust or DigiCert is priced for a handful of certificates, not thousands of pods rotating every hour. Step-CA from Smallstep is the open-source answer: a tiny, hardened certificate authority that you run yourself, with ACME, OIDC, JWK, and AWS/GCP/Azure identity provisioners built in. This guide walks through deploying Step-CA on AlmaLinux 9, configuring provisioners, and issuing certificates to Linux hosts and Kubernetes workloads in 2026.
## Why Step-CA
Step-CA is written in Go, ships as a single binary, and stores its root key in an HSM, KMS, YubiKey, or a password-protected file. It supports X.509 and SSH certificates, ACME for Let’s Encrypt-style workflows inside your network, and OIDC so you can issue user certs gated by your Google Workspace or Okta login. The whole thing runs in under 100 MB of RAM and handles tens of thousands of certificates per hour.
## Installing Step-CA
On AlmaLinux 9:
“`bash
curl -LO https://dl.smallstep.com/cli/docs-ca-install/latest/step-cli_amd64.rpm
curl -LO https://dl.smallstep.com/certificates/docs-ca-install/latest/step-ca_amd64.rpm
sudo rpm -i step-cli_amd64.rpm step-ca_amd64.rpm
“`
Create a dedicated user and initialize the CA:
“`bash
sudo useradd –system –home /etc/step-ca –shell /bin/false step
sudo -u step step ca init \
–name “Acme Internal CA” \
–dns “ca.internal.acme.com” \
–address “:8443” \
–provisioner admin@acme.com \
–password-file /etc/step-ca/password
“`
This generates the root CA, an intermediate, and a default JWK provisioner. Write the password to `/etc/step-ca/password` with `chmod 600` so the service can unlock the intermediate on start.
Create a systemd unit at `/etc/systemd/system/step-ca.service`:
“`ini
[Unit]
Description=step-ca service
After=network-online.target
[Service]
User=step
Group=step
Environment=STEPPATH=/etc/step-ca
ExecStart=/usr/bin/step-ca /etc/step-ca/config/ca.json –password-file /etc/step-ca/password
Restart=on-failure
[Install]
WantedBy=multi-user.target
“`
Enable and start:
“`bash
sudo systemctl daemon-reload
sudo systemctl enable –now step-ca
“`
## Bootstrapping Clients
Every host that will request certificates needs the root fingerprint. Print it on the CA host:
“`bash
step certificate fingerprint /etc/step-ca/certs/root_ca.crt
“`
On any client:
“`bash
step ca bootstrap –ca-url https://ca.internal.acme.com:8443 –fingerprint abc123…
“`
This writes `~/.step/config/defaults.json` and stores the root cert so future `step` commands trust the CA.
## Issuing a Server Certificate
Request a certificate for a web server:
“`bash
step ca certificate web01.internal.acme.com web01.crt web01.key \
–provisioner admin@acme.com \
–san web01.internal.acme.com \
–not-after 24h
“`
Short lifetimes force automation. Schedule a renewal daemon:
“`bash
step ca renew –daemon –exp-backoff web01.crt web01.key &
“`
The daemon wakes up before the cert expires, renews it, and reloads nginx via a post-renew hook.
## ACME Provisioner for Internal Services
Add an ACME provisioner so any tool that speaks ACME (cert-manager, caddy, Traefik, certbot) can get certificates from your internal CA without custom code:
“`bash
step ca provisioner add acme –type ACME
sudo systemctl restart step-ca
“`
In Kubernetes, install cert-manager and point a ClusterIssuer at your Step-CA:
“`yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: step-ca
spec:
acme:
server: https://ca.internal.acme.com:8443/acme/acme/directory
email: devops@acme.com
privateKeySecretRef:
name: step-ca-account
solvers:
– http01:
ingress:
class: nginx
“`
Now every Ingress with the annotation `cert-manager.io/cluster-issuer: step-ca` gets a rotating internal certificate automatically.
## SSH Certificates
Step-CA can also sign SSH certificates. Add an SSH certificate authority:
“`bash
step ca provisioner add admins@acme.com –type JWK –ssh
“`
On a bastion:
“`bash Was this article helpful?
sudo tee /etc/ssh/sshd_config.d/90-step.conf <
About Ramesh Sundararamaiah
Red Hat Certified Architect
Expert in Linux system administration, DevOps automation, and cloud infrastructure. Specializing in Red Hat Enterprise Linux, CentOS, Ubuntu, Docker, Ansible, and enterprise IT solutions.