Getting Started

One could write several telephone books about the innards of X.509, asn.1 and the vast topics of infosec, netsec, and public key cryptography that are implicated in the design of a PKI. It's daunting. So let's begin at the beginning, with a simple online CA and a humble TLS-enabled "Hello World" application.

In this guide we will:


Initialize 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 the command step ca init in a terminal to configure the step ca and reply to the prompts with information about your project, DNS setup, etc.

Note that one of the prompts is about the default provisioner, 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 will 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.

Make a note of the root fingerprint! You'll need it to connect to your CA from other environments or hosts.

Run your certificate authority

Run your certificate authority and pass 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 ...

Accessing your Certificate Authority

Accessing step-ca locally

You can use step ca and step ssh command groups to interact with the CA.

See Basic CA Operations for an overview of common operations.

Accessing step-ca remotely

To configure step to access your CA from a new machine, run:

$ step ca bootstrap --ca-url [CA URL] --fingerprint [root certificate fingerprint]

This command will download the root CA certificate and write CA connection details to $HOME/.step/config/defaults.json.

Using the Golang wrapper

You can access your CA programmatically using our Go client wrapper.

Example: Run A Local Web Server Using TLS

Now that the certificate authority is running, let's create an example server and use our new certificate authority to issue an X.509 certificate and connect to the server using HTTP over TLS.

For this example, you'll need to have go installed.

Get a certificate

First, let's ask the CA for a certificate (srv.crt) and private key (srv.key) for our example server on localhost:

$ 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

Run a hello world example server configured for TLS connections

We've got our certificates. Now let's create an example server that will run on localhost and use TLS. You can follow along with this go server to get a better idea of how X.509 certificates work with a real server.

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

Here's the code for the go server:

package main import ( "net/http" "log" ) 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 { log.Fatal(err) } }

Run the server as a background process:

$ go run srv.go &

Connecting to the 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. Although 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!

Nice! We've just generated and integrated our first certificate using step-ca.

Next Steps

  • Familiarize yourself with Basic CA Operations using step ca and step ssh command groups.
  • Check out the Configuration and Core Concepts sections to learn more about tailoring step-ca to your infrastructure needs.
  • Or, head straight to our tutorials to see more examples of using step-ca in the wild.

Unsubscribe anytime. See our privacy policy.