smallstep/step-ca
π‘οΈ An online Certificate Authority and ACME server for secure automated certificate management.
10M+
step-ca
is a private online certificate authority (CA) for secure, automated X.509 and SSH certificate management.step-ca-hsm
image.)step-ca
documentationβ .The default image is suitable for most users.
It is tagged latest
and tagged with the version number, eg. 0.23.0
.
This is an Alpine-based image.
The HSM image is for use with keys stored in a PKCS#11 Hardware Security Module (HSM) or in Yubikey PIV slots.
It is tagged hsm
and hsm-
versions eg. hsm-0.23.0
, hsm-0.23.1
, ...
The step-ca
binary in this image is compiled with CGO enabled.
It's Bullseye-based, so you can integrate a glibc
-compatible pkcs11 module from your favorite HSM vendor.
Don't want to run your own CA?
To get up and running quickly, or as an alternative to running your own step-ca
server, consider creating a free hosted smallstep Certificate Manager authorityβ .
step-ca
, you'll want to install the step
client in your host environment. See our installation docsβ .To initialize your PKI, on your Docker host, run:
docker run -it -v step:/home/step \
-p 9000:9000 \
-e "DOCKER_STEPCA_INIT_NAME=Smallstep" \
-e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \
-e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \
smallstep/step-ca
π Note the CA fingerprint (SHA256), the remote management super admin username, and the remote management password in the output.
The following environment variables are available for initializing the CA configuration:
DOCKER_STEPCA_INIT_NAME
the name of your CAβthis will be the issuer of your CA certificatesDOCKER_STEPCA_INIT_DNS_NAMES
the hostname(s) or IPs that the CA will accept requests onDOCKER_STEPCA_INIT_REMOTE_MANAGEMENT
enable remote provisioner managementβ DOCKER_STEPCA_INIT_PROVISIONER_NAME
a label for the initial admin (JWK) provisioner. Default: "admin"DOCKER_STEPCA_INIT_SSH
set this to a non-empty value to enable SSH certificate supportDOCKER_STEPCA_INIT_ACME
also create an initial ACME provisioner for the CADOCKER_STEPCA_INIT_PASSWORD_FILE
the location of a password file to be used for both private keys and the default CA provisioner. Useful for pointing to a Docker secret located in /run/secrets
in the container. If both DOCKER_STEPCA_INIT_PASSWORD
and DOCKER_STEPCA_INIT_PASSWORD_FILE
are set, only DOCKER_STEPCA_INIT_PASSWORD_FILE
will be used.DOCKER_STEPCA_INIT_PASSWORD
Normally, CA passwords will be generated for you. With this option, you can specify a password for the encrypted CA keys and the default CA provisioner. Note: Passwords stored in environment variables are not safeβ . In a production environment, a more secure option for specifying a password is to use the manual installation process, below.These variables are only evaluated once, to configure step-ca
before its first run.
step
clientsOnce your CA is initialized, it will start running and you can connect to it. To connect, clients need to know the CA's URL and SHA256 fingerprint.
Let's bootstrap a step
client in the host environment and install the root CA certificate into the host's trust store.
In Bash, run:
{
CA_FINGERPRINT=$(docker run -v step:/home/step smallstep/step-ca step certificate fingerprint certs/root_ca.crt)
step ca bootstrap --ca-url https://localhost:9000 --fingerprint $CA_FINGERPRINT --install
}
Output:
The root certificate has been saved in /Users/alice/.step/certs/root_ca.crt.
Your configuration has been saved in /Users/alice/.step/config/defaults.json.
Installing the root certificate in the system truststore...
[sudo] password for alice: ....
done.
Your local step
CLI is now configured to use the container instance of step-ca
, and your root certificate is trusted by our host environment.
Run a health check:
curl https://localhost:9000/health
Output:
{"status":"ok"}
Your CA is ready for use.
This has been tested in Bash on Linux.
Get the latest version of step-ca
docker pull smallstep/step-ca
The Docker volume step
will hold your CA configuration, keys, and database.
docker run -it -v step:/home/step smallstep/step-ca step ca init --remote-management
The init command will step you through the bootstrapping process. Example output:
β What would you like to name your new PKI? (e.g. Smallstep): Smallstep
β What DNS names or IP addresses would you like to add to your new CA? (e.g. ca.smallstep.com[,1.1.1.1,etc.]): localhost
β What address will your new CA listen at? (e.g. :443): :9000
β What would you like to name the first provisioner for your new CA? (e.g. you@smallstep.com): admin@smallstep.com
β What do you want your password to be? [leave empty and we'll generate one]:
Generating root certificate... done!
Generating intermediate certificate... done!
β Root certificate: /home/step/certs/root_ca.crt
β Root private key: /home/step/secrets/root_ca_key
β Root fingerprint: fa08cceda8501b1d93d275cfc614a5af2a37c6c72e674192b4598808c5bae91e
β Intermediate certificate: /home/step/certs/intermediate_ca.crt
β Intermediate private key: /home/step/secrets/intermediate_ca_key
β Database folder: /home/step/db
β Default configuration: /home/step/config/defaults.json
β Certificate Authority configuration: /home/step/config/ca.json
β Admin provisioner: admin@smallstep.com (JWK)
β Super admin subject: step
Your PKI is ready to go. To generate certificates for individual services see 'step help ca'.
Save the root fingerprint value! You'll need it for client bootstrapping.
The image is expecting the intermediate CA private key password to be placed in /home/step/secrets/password
. Bring up the shell prompt in the container again and write that file:
docker run -it -v step:/home/step smallstep/step-ca sh
Inside your container, write the password file into the expected location:
echo -n "<your password here>" > /home/step/secrets/password
Your CA is configured and ready to run.
step-ca
The CA runs an HTTPS API on port 9000 inside the container. Expose the server address locally and run the step-ca
with:
docker run -d -p 9000:9000 -v step:/home/step smallstep/step-ca
Now, in the host environment, bootstrap your step
client configuration:
{
CA_FINGERPRINT=$(docker run -v step:/home/step smallstep/step-ca step certificate fingerprint /home/step/certs/root_ca.crt)
step ca bootstrap --ca-url https://localhost:9000 --fingerprint $CA_FINGERPRINT --install
}
Output:
The root certificate has been saved in /Users/alice/.step/certs/root_ca.crt.
Your configuration has been saved in /Users/alice/.step/config/defaults.json.
Installing the root certificate in the system truststore...
[sudo] password for alice: ...
done.
Your local step
CLI is now configured to use the container instance of step-ca
and our new root certificate is trusted by the host environment.
Run a health check:
curl https://localhost:9000/health
Output:
{"status":"ok"}
step-ca
to your infrastructure.step-ca
uses sigstore/cosignβ for signing and verifying containers.
Here is an example of how to use cosign
to verify a container:
cosign verify smallstep/step-ca:0.23.1 \
--certificate-identity-regexp "https://github\.com/smallstep/workflows/.*" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
You will need:
Run this section on your host machine where Docker is installed.
Once you've bootstrapped your local environment, you can now run web services configured with TLS and mTLS. First, get a certificate for localhost
:
step ca certificate localhost localhost.crt localhost.key
Output:
β Key ID: aTPGWP0qbuQdflR5VxtNouDIOXyNMH1H9KAZKP-UcHo (admin)
β Please enter the password to decrypt the provisioner key:
β CA: <https://localhost:9000/1.0/sign>
β Certificate: localhost.crt
β Private Key: localhost.key
Now save a copy of your root CA certificate:
step ca root root_ca.crt
Output:
The root certificate has been saved in root_ca.crt.
Next, let's launch a web server secured by HTTPS:
{
cat <<EOF > server.py
import BaseHTTPServer, ssl
class HelloHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200);
self.send_header('content-type', 'text/html; charset=utf-8');
self.end_headers()
self.wfile.write(b'\\n\\xf0\\x9f\\x91\\x8b Hello! Welcome to TLS \\xf0\\x9f\\x94\\x92\\xe2\\x9c\\x85\\n\\n')
httpd = BaseHTTPServer.HTTPServer(('', 8443), HelloHandler)
httpd.socket = ssl.wrap_socket(httpd.socket,
server_side=True,
keyfile="localhost.key",
certfile="localhost.crt",
ca_certs="root_ca.crt")
httpd.serve_forever()
EOF
python server.py
}
Open up another terminal to see your server running:
$ curl https://localhost:8443
π Hello! Welcome to TLS πβ
Or visit https://localhost:8443β from your browser.
When you run step-ca
on a Raspberry Pi, you might get the following error in
your container logs:
step-ca | badger 2021/05/08 20:13:12 INFO: All 0 tables opened in 0s
step-ca | Error opening database of Type badger with source /home/step/db: error opening Badger database: Mmap value log file. Path=/home/step/db/000000.vlog. Error=cannot allocate memory
To fix it, edit the db
configuration block in the file config/ca.json
.
docker run -v step:/home/step -it smallstep/step-ca vi /home/step/config/ca.json
Change the value of badgerFileLoadingMode
from ""
to "FileIO"
.
You will end up with this:
"db": {
"type": "badger",
"dataSource": "/home/step/db",
"badgerFileLoadingMode": "FileIO"
},
Save and restart the container.
Questions? Ask us on GitHub Discussionsβ or Discordβ .
docker pull smallstep/step-ca