Getting Started

In this guide we’ll cover how to install step and step-ca, how to use them to generate a certificate for an example server, and how to make a TLS authenticated connection to that example server.

What are step and step-ca

The step toolchain is a suite of services and command line components that make it easy to manage credentials and orchestrate security at “agile devopsy” shops in “cloud-ish” environments that use things like containers, microservices, and serverless functions.

step-ca or step certificates is an online certificate authority (CA) and related tools for secure automated certificate management.

Using step certificates in conjunction with the step CLI you can:

  • Easily Bootstrap public key infrastructure (PKI): get up and running with a certificate authority and other basic infrastructure necessary to use TLS internally in minutes.
  • Automate Certificate Management: provision and roll certificates automatically using standard-based protocols & APIs.
  • Manage Public and Private Keys: securely generate and distribute shared secrets as a key distribution center (KDC) in addition to handling certificate signing requests (CSRs).

To get up and running quickly with step and step-ca, configure your applications, and learn about PKI, try our interactive onboarding utility.

1. Installing step and step-ca

When setting up PKI you’ll need to consider the following components:

  • certificate authority: a trusted server running step-ca, that issues the root certificate.
  • any machine connecting to the CA requires only the step CLI for convenience, to download and verify the root certifcate.

In this quick start guide we’ll be running both of these locally on the same machine.

For more detailed instructions, or binaries for different distributions, see the installation guide.


  1. Install step and step-ca using Homebrew:
$ brew install step
  1. If you’re conecting to a remote certificate authority, follow the instructions in Bootstrapping.

Debian Linux

  1. Install step using dpkg, where X.Y.Z is the latest release:
  $ wget
  $ sudo dpkg -i step_X.Y.Z_amd64.deb
  1. Install step-ca using dpkg, with the same version number as step:
  $ wget
  $ sudo dpkg -i step-certificates_X.Y.Z_amd64.deb
  1. If you’re conecting to a remote certificate authority, follow the instructions in Bootstrapping.


If you’re running step only on the machine where you configure the CA, as in this getting started guide, you can ignore this section.

However, if you’re running step on a different machine from where you configured the CA, you’ll need to run step ca bootstrap to get the correct configuration for your CA.

step ca bootstrap downloads the CA root certificate and creates a configuration file containing the CA url, the root certificate location and its fingerprint, so you don’t have to supply this information every time you run step ca.

  1. On the machine running the CA, find the fingerprint for your root certificate:
   $ step certificate fingerprint $(step path)/certs/root_ca.crt
  1. On your local machine, that you’re bootstrapping, run:
   $ step ca bootstrap --fingerprint $FP --ca-url $CA

  • where $FP is the fingerprint you saw in step 1, for example a713967d3a94b7a86a24c658a4788c7919ff29d62399569899e9ff7a881a92ec.
  • and $CA is the url and port of your CA, for example “".
  1. Finally, test the configuration:
   $ step ca health

2. Configuring your Certificate Authority

The certificate authority is what you’ll be using to issue and sign certificates, knowing that you can trust anything using a certificate signed by the root certificate.

Run step ca init to configure the Step Certificate Authority, and reply to the prompts with information about your project, DNS setup, etc.

Note that one of the prompts is about the default provisioner, more on that later, but for now an email address works fine as an identifier.

$ step ca init
 ✔ What would you like to name your new PKI? (e.g. Smallstep): Example Inc.
 ✔ What DNS names or IP addresses would you like to add to your new CA? (e.g.[,,etc.]): localhost
 ✔ What address will your new CA listen at? (e.g. :443):
 ✔ What would you like to name the first provisioner for your new CA? (e.g.
 ✔ What do you want your password to be? [leave empty and we'll generate one]: abc123

 Generating root certificate...
 all done!

 Generating intermediate certificate...
 all done!

 ✔ Root certificate: /Users/bob/.step/certs/root_ca.crt
 ✔ Root private key: /Users/bob/.step/secrets/root_ca_key
 ✔ Root fingerprint: 702a094e239c9eec6f0dcd0a5f65e595bf7ed6614012825c5fe3d1ae1b2fd6ee
 ✔ Intermediate certificate: /Users/bob/.step/certs/intermediate_ca.crt
 ✔ Intermediate private key: /Users/bob/.step/secrets/intermediate_ca_key
 ✔ Default configuration: /Users/bob/.step/config/defaults.json
 ✔ Certificate Authority configuration: /Users/bob/.step/config/ca.json

 Your PKI is ready to go. To generate certificates for individual services see 'step help ca'.

This does two things:

3. Running your Certificate Authority

Run your Certificate Authority, passing it the configuration file you just generated.

$ step-ca $(step path)/config/ca.json
 Please enter the password to decrypt /Users/bob/.step/secrets/intermediate_ca_key: abc123
 2019/02/18 13:28:58 Serving HTTPS on ...

You can use the step CLI to interact with the CA, common actions include:

See the step ca docs for full details.

4. Running an example server

Now the certificate authority is running, we can use it to get a certificate (srv.crt) and private key (srv.key) for the example server we’re about to write:

$ step ca certificate localhost srv.crt srv.key
✔ Key ID: rQxROEr7Kx9TNjSQBTETtsu3GKmuW9zm02dMXZ8GUEk (
✔ Please enter the password to decrypt the provisioner key: abc123
✔ CA: https://localhost:8443/1.0/sign
✔ Certificate: srv.crt
✔ Private Key: srv.key

Note that we’re accessing the certificate authority on localhost in this example, as that is the URL we configured the CA with.


Notice that it uses the certificate (srv.crt) and private key (srv.key) that we just got the CA to generate.

This example server listens to port 9443 on localhost, and serves Hello, world! to any client that accepts the server certificate as trusted.

package main

import (

func HiHandler(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Content-Type", "text/plain")
    w.Write([]byte("Hello, world!\n"))

func main() {
    http.HandleFunc("/hi", HiHandler)
    err := http.ListenAndServeTLS(":9443", "srv.crt", "srv.key", nil)
    if err != nil {

Run the server as a background process:

$ go run srv.go &

5. Connecting to our example server

First, let’s try making a curl request to our example server. In a new terminal, run:

$ curl https://localhost:9443/hi
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here:

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

As you can see, that doesn’t work, curl has no way of telling if the example server can be trusted. But if we get the root certificate from the CA, we can use that:

$ step ca root root.crt
The root certificate has been saved in root.crt.

Now we can make a curl request using the root certificate we got from the CA. When we add --cacert root.crt to the curl command, it will verify that the server certificate was signed by the CA, and at that point we see “Hello, world!”

$ curl --cacert root.crt https://localhost:9443/hi
Hello, world!

This isn’t yet true mutual TLS. We’re verifying that the server certificate is issued by the trusted CA, but for the example server to verify that our curl client is also trusted by the same CA is out of scope for this getting started guide.

Next steps