Some PKI topologies rely on one or more Registration Authority (RA) servers.
An RA server acts as a front-end to a Certificate Authority.
While the CA holds the signing keys, the RA is responsible for authenticating requests from its clients and enforcing policies before passing them along to the CA.
The CA implicitly trusts the RA and will sign certificates for it.
Local RA servers are often used to distribute certificates across several cloud providers or on-prem environments.
step-ca has a special operational mode that turns it into an RA server.
This mode allows you to centralize and simplifies key management,
because a single backing CA can serve several RAs.
Certificate Authority Service (CAS) vs. Key Management Service (KMS) In an RA setup, the upstream CA is also known as a Certificate Authority Service (CAS). A CAS is a service that implements an API to sign certificate requests from a trusted source. If you've used a KMS before, you may wonder: How is a CAS different from a KMS? A KMS can sign any data, while a CAS is intended to sign only X.509 certificates.
When in RA mode, step-ca can peer with one of three types of upstream CA:
StepCAS allows configuring a step-ca server as an RA, with a second, upstream step-ca server acting as the main CA.
StepCAS supports the JWK and X5C provisioners for requests between RAs and the CA.
The JWK provisioner balances security and simplicity, and it covers the most common use cases.
The X5C provisioner allows for more complex trust relationships and expiring certificates,
but it requires setting up ongoing certificate lifecycle management on the RAs.
Example: A Simple RA ↔ CA Configuration
Let's set up a simple RA ↔ CA pair, with one RA and one upstream CA.
The CA will be configured with a JWK provisioner,
and the RA will use that provisioner to make authenticated certificate requests to the CA.
The RA, in turn, can offer its clients certificates using any step-ca provisioners.
In this example, we'll configure an ACME provisioner in the RA.
Configure additional RA provisioners just as you would configure provisioners for a CA.
Setting up the CA
You can set up the CA using the Getting Started guide.
You will need the name and password of the first provisioner you created when running step ca init.
Setting up the RA
Here's an example configuration file for an RA that uses the JWK provisioner to connect to the CA,
and that offers an ACME provisioner to its clients:
The crucial bit of configuration here is the "certificateIssuer" section.
This section connects this RA to the CA using the JWK provisioner named firstname.lastname@example.org on the CA.
When step-ca starts up with this RA configuration, it will download the encrypted JWK key from the CA automatically.
The RA will still need the JWK provisioner password, to decrypt the key.
The JWK password can be supplied in a "password" field in the "certificateIssuer" block,
or it can be passed in via a file when starting the RA:
Finally, use --issuer-password-file to provide a password file when starting up the RA.
Using the X5C provisioner
Instead of a JWK, the RA can alternatively use certificate authentication with the CA, via the X5C Provisioner.
While this approach is more complex,
it offers more security because it uses expiring certificates instead of non-expiring JWKs.
In this scenario, the RA "certificateIssuer" block will need to be configured with a certificate and key signed by a CA that the CA's X5C provisioner is configured to trust.
To configure an RA ↔ CA connection using an X5C provisioner,
first add an X5C provisioner to the CA.
(See the X5C Provisioner configuration section.)
Next, change the "certificateIssuer" object in the RA configuration as follows:
Finally, download the service account credentials, which you will use to configure the RA:
$gcloud iam service-accounts keys create credentials.json \ --iam-account email@example.com
The RA will use the service account you just created, via the keys you exported into credentials.json.
Initialize your PKI.
Run step ca init --ra cloudcas to create a new PKI in CAS.
This will generate a root and intermediate certificate in Google CAS.
You will be prompted for your GCP project id, a resource id, region, and other information.
Here's an example of what a ca.json for a CloudCAS RA might look like:
The "credentialsFile" field isn't the only option for providing Google Cloud credentials.json filename to the RA.
You can alternatively set the GOOGLE_APPLICATION_CREDENTIALS environment variable.
step-ca will automatically download the root certificate from Google CAS.
In ca.json, you don't need to configure "root",
and because the intermediate is in Google Cloud, "crt" and "key" are also not needed.
The RA will print your CA's root fingerprint upon startup:
$step-ca /home/jane/.step/config/ca.json2020/09/22 13:17:15 Using root fingerprint '3ef16343cf0952eedbe2b843066bb798fa7a7bceb16aa285e8b0399f661b28b7'
2020/09/22 13:17:15 Serving HTTPS on :9000 ...
Save the fingerprint! You will need it to bootstrap new clients into your PKI:
$step ca bootstrap --ca-url https://ra.example.com --fingerprint 3ef16343cf0952eedbe2b843066bb798fa7a7bceb16aa285e8b0399f661b28b7
Finally, we can sign sign a certificate as always:
$step ca certificate test.example.com test.crt test.key
Hashicorp Vault RA mode
The RA mode in step-ca can peer with Vault's PKI secrets engine, using it as an upstream CA.
From the Vault Documentation:
"The PKI secrets engine generates dynamic X.509 certificates. With this secrets engine, services can get certificates without going through the usual manual process of generating a private key and CSR, submitting to a CA, and waiting for a verification and signing process to complete."
In this tutorial, we'll create a PKI and a Certificate Authority in Vault.
Then we'll configure step-ca's RA mode to use Vault to sign certificates.
For a proof of concept, you can run vault server -dev in a terminal window to start an ephemeral Vault server for testing, and use an HTTP Vault address as shown here. With Vault in dev mode, you will lose your PKI when you exit the Vault server.
In production, you'll need to run Vault as a daemon and use HTTPS.
Vault supports both server TLS verification, and mutual TLS authentication.
See Vault's Environment Variables documentation for more.
If you're running Vault in dev mode, set VAULT_ADDR:
Now login to Vault:
vault login token=xxxxx
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
2. Create your Root CA:
Let's create our PKI inside of Vault.
In this example, we're creating a 10 year root certificate.
Your root CA is created,
and your root CA certificate PEM is saved in root_ca.crt.
3. Create your Intermediate CA:
Now let's create and sign the intermediate CA using the root CA.
We'll call the intermediate PKI int1.
We may later want to sign additional intermediaries (int2, int3, etc.) from our root CA.
In this example, we'll create a 5 year intermediate certificate.
In this example, Vault will sign certificates of all three key types for the RA server: EC, RSA, and Ed25519.
Please limit this policy if your PKI will only use a subset of these key types.
Vault's Policy documentation describes the policy langauge used by Vault.
4. Enable Vault authentication for your RA.
For the last part of our Vault setup, we need to configure Vault authentication.
Version: 3 (0x2)
Serial Number: 181870544504760955575180789200133046316293037181 (0x1fdb5b761da50e99dac7dd1ce11eda0c6a921c7d)
Signature Algorithm: SHA256-RSA
Issuer: CN=Vault Intermediate CA
Not Before: Apr 25 23:14:26 2022 UTC
7. Issue a test certificate
Now, in another window, let's bootstrap the step client with your RA and get a test certificate:
$ step ca bootstrap --ca-url https://localhost:4443 \
The root certificate has been saved in /home/awesome/.step/certs/root_ca.crt.
The authority configuration has been saved in /home/awesome/.step/config/defaults.json.
$ step ca certificate example.com example.crt example.key
✔ Provisioner: firstname.lastname@example.org (JWK)[kid: oRxlIgpwI00GZUPZDMF-cASlh-sbmbdHS0pQOpNXszU]
Please enter the password to decrypt the provisioner key:
✔ CA: https://localhost:4443
✔ Certificate: example.crt
✔ Private Key: example.key