Step CA
Step CA is a private certificate authority that issues and manages TLS certificates. It is used in this lab to bootstrap TLS for services that need trusted certificates signed by a local root CA.
Quickstart
# First-time setup: auto-generate .env + start container
make deploy-step-ca
# Export the root CA certificate (trust this for clients)
make step-ca-root-cert
# Check health
make step-ca-health
Access
The CA runs via Docker Compose (not in Kubernetes) and binds to port 9000 on the Docker host. The nip.io hostname is auto-resolved using HOST_IP (the Docker host's local IP from the default route).
| Endpoint | URL |
|---|---|
| API | https://step-ca.HOST_IP.nip.io:9000 |
| Health | https://step-ca.HOST_IP.nip.io:9000/health |
| Root cert | https://step-ca.HOST_IP.nip.io:9000/roots.pem |
| Local (direct) | https://localhost:9000 |
Note
Replace HOST_IP with the actual IP from ip route show default.
Makefile Targets
| Target | Description |
|---|---|
deploy-step-ca | Full setup — creates .env if missing, then starts the CA |
step-ca-up | Start the CA container |
step-ca-down | Stop the CA container |
step-ca-restart | Restart the CA |
step-ca-logs | Tail container logs |
step-ca-health | Check CA health and print root cert fingerprint |
step-ca-root-cert | Export root CA cert to step-ca/root-ca.crt |
step-ca-root-cert-fingerprint | Print SHA256 fingerprint of the root CA |
step-ca-provisioner-list | List registered provisioners |
step-ca-token SUBJECT=<dns> | Generate a one-time activation token |
step-ca-cert SUBJECT=<dns> | Issue a TLS certificate (1 year expiry) |
step-ca-destroy | Stop CA and delete all data (irreversible) |
Configuration
The CA is configured via environment variables passed from the Makefile to docker-compose.yaml. Init vars only apply on first run (empty volume).
| Variable | Default | Description |
|---|---|---|
DOCKER_STEPCA_INIT_NAME | k8s-lab CA | CA display name |
DOCKER_STEPCA_INIT_DNS_NAMES | step-ca.HOST_IP.nip.io,localhost,step-ca | SANs in the CA certificate |
DOCKER_STEPCA_INIT_LISTEN_ADDRESS | :9000 | Listen address |
DOCKER_STEPCA_INIT_PROVISIONER_NAME | admin@k8slabs.com | Default provisioner |
DOCKER_STEPCA_INIT_PASSWORD | auto-generated | Password encrypting CA keys |
Environment (.env)
The file step-ca/.env stores the CA password. It is auto-generated on first deploy and reused on subsequent starts.
Warning
Keep .env safe — without it the CA keys cannot be decrypted.
Additional variables can be overridden in .env: - CA_DNS — comma-separated DNS names for the CA certificate - CA_ADDRESS — listen address - CA_NAME — CA display name - CA_PROVISIONER — default provisioner identity - NETWORK_NAME — Docker network for k3d integration
Credentials
| Item | Value |
|---|---|
| Provisioner | admin@k8slabs.com |
| CA password | Stored in step-ca/.env (auto-generated, Base64 32-byte) |
LDAP bind (cn=admin,dc=example,dc=com) | admin |
Certificate Management
Issue a Certificate
Output: - Cert: step-ca/certs/myservice.HOST_IP.nip.io.crt - Key: step-ca/certs/myservice.HOST_IP.nip.io.key - Expiry: 1 year (8760h)
Generate a Token
Trust the Root CA
# Export the root CA cert
make step-ca-root-cert
# Add to system trust (Linux)
sudo cp step-ca/root-ca.crt /usr/local/share/ca-certificates/k8s-lab-root-ca.crt
sudo update-ca-certificates
# Or use directly with curl
curl --cacert step-ca/root-ca.crt https://step-ca.HOST_IP.nip.io:9000/health
View Root CA Fingerprint
Architecture
flowchart LR
A[Docker Compose<br/>step-ca:9000] --> B[Docker Volume<br/>step_ca_data]
C[make step-ca-cert] -->|docker exec| A
D[make step-ca-token] -->|docker exec| A
E[curl / apps] -->|https://step-ca.HOST_IP.nip.io:9000| A The CA runs as a standalone Docker container outside Kubernetes. It uses a named Docker volume (step_ca_data) to persist the CA keys, certificates, and configuration. All Makefile targets communicate with the CA via docker exec or direct HTTP to localhost:9000.
Files
| File | Purpose |
|---|---|
step-ca/docker-compose.yaml | Docker Compose service definition |
step-ca/.env | CA password (auto-generated, keep safe) |
step-ca/.env.example | Template with all configurable variables |
step-ca/root-ca.crt | Exported root CA certificate |
step-ca/certs/ | Output directory for issued certificates |
Makefile (lines 579–715) | All step-ca Makefile targets |
Note
The CA is not deployed into Kubernetes — it runs as a Docker container so it can issue certificates for both in-cluster and host services.
Warning
The init environment variables only take effect on the first run with an empty volume. To change the CA DNS names after initialization, patch ca.json inside the container or destroy and recreate.
Tip
The CA's own HTTPS certificate contains the DNS names from init. Clients connecting via nip.io hostname should either trust the root CA or use localhost to avoid hostname mismatch warnings.
Info
All issued certificates are fully functional (SANs, key usage, etc.) and trusted by any client that has imported root-ca.crt.
Danger
make step-ca-destroy wipes all CA data — this invalidates every certificate ever issued by this CA.