step-ca
step-ca
step-ca
in a Docker containerstep-ca
step-ca
step-ca
in a Docker containerWebhooks let you enrich X.509 or SSH certificates with data requested from an external endpoint. The CA fetches key/value pairs from a configured webhook when a CSR is being processed, and the webhook data is passed along to the provisioner's certificate template.
Attach webhooks to provisioners via the step ca provisioner webhook
command group.
We've created an example webhook server. You can use it to try out webhooks locally, or as the basis of your own custom webhook integration.
Initialize a new Certificate Authority with remote management enabled.
step ca init --remote-management --context webhooks
Then, in another window, start step-ca
:
step-ca --context webhooks
Clone the example webhook repository.
git clone https://github.com/smallstep/webhooks.git
cd webhooks
Generate a server certificate for your webhook server.
step ca certificate localhost webhook.crt webhook.key
Export your root CA certificate for the webhook server.
step ca root > root_ca.crt
Add a new provisioner to associate with your webhook.
When asked, the default admin username is step
.
step ca provisioner add my_provisioner --create
Add a webhook to your provisioner for a webhook server that will be listening on localhost:9443
.
☠️ Don't add your webhook to the default (administrative) CA provisioner! You may lock yourself out of your CA.
step ca provisioner webhook add my_provisioner people --url 'https://localhost:9443/{{ .Token.sub }}'
This command will print out the ID and secret for the people
webhook.
Update the webhookIDsToSecrets
map in the webhook server's main.go
file with the ID and secret printed above.
Update the db
map in the webhook server's main.go
file with the Common Name (CN) you will be issuing test certificates for.
Start the webhook server:
go run main.go
Add a template to the provisioner to incorporate the data returned from the people
webhook:
cat <<EOF > external_ou.tmpl
{
"subject": {
"organizationalUnit": {{ toJson .Webhooks.people.role }}
}
}
EOF
step ca provisioner update my_provisioner --x509-template external_ou.tmpl
Get a certificate with the provisioner you configured earlier:
step ca certificate andrew@smallstep.com my.crt my.key --provisioner my_provisioner
Inspect the certificate. Notice that the user's role returned from the webhook server appears in the OU.
step certificate inspect my.crt --format json | jq .subject
The webhook server must include "allow": true
in the response body,
or step-ca
will refuse to sign the certificate request.
The step-ca
template engine augments the template data with the data
object in the response body.
For example, a webhook server could send the following JSON response:
{
"allow": true,
"data": {
"role": "eng"
}
}
A template on the provisioner will then be able to reference the response under the path .Webhooks.webhook_name
.
If the webhook was named people
, the role in the webhook response could be accessed in a template under the field .Webhooks.people.role
.
All requests will use the POST
method to send a JSON body to the webhook server containing a timestamp
field.
Additional data will vary based on the type of the certificate being signed.
The webhooks server example repository contains examples in Go of parsing webhook request bodies for both X.509 and SSH certificate requests.
For X.509 certificates, step-ca
will include an x509CertificateRequest
field
that will hold a JSON representation of the request
using the same schema as x509 template functions
with a few extra fields.
You can use webhooks to enrich device certificates issued via an ACME device-attest-01
challenge.
When used with the ACME provisioner
and the ACME device-attest-01
challenge,
the request body will also contain the verified device ID in the attestationData.permanentIdentifier
field.
For SSH certificates step-ca
will include an sshCertificateRequest
field with data from the request.
Your webhook server must authenticate each request from the CA. To achieve this, the CA sends a signature of its payload in the webhook request header, and the webhook server must confirm this signature. The signature also tells the webhook server which webhook is currently being executed.
In addition the the signature header, you can optionally enable two other authentication schemes:
Authentication
header.Every webhook has a unique secret that will be displayed when the webhook is created
via step ca provisioner webhook add
.
step-ca
will include a signature of the payload in the X-Smallstep-Signature
header.
The webhook ID will also be included in the X-Smallstep-Webhook-ID
header
to help associate the correct signing secret with the webhook request.
Webhook servers must compute an HMAC with the SHA256 hash function,
using the webhook signing secret as the key and the request body as the message.
See the webhook server example repository for an example of verifying the signature.
For an additional layer of security, step-ca
may be configured to send
either a bearer token
or a username:password
in the Authorization
header.
To use a bearer token, run:
step ca provisioner webhook update my_provisioner my_webhook --bearer-token abc123xyz
Or, to use basic authentication, run:
step ca provisioner webhook update my_provisioner my_webhook --basic-auth-username user --basic-auth-password-file pass.txt
You can also use mutual TLS to authenticate step-ca
as a client of your webhook server.
By default, step-ca
will send the CA's self-generated leaf certificate
when asked for a client certificate as part of the TLS handshake.
To enable mutual TLS,
configure your webhook server to request and verify a client certificate
that chains up to your root CA certificate.
Unsubscribe anytime. See our privacy policy.
© 2023 Smallstep Labs, Inc. All rights reserved.