Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 78 additions & 64 deletions step-ca/webhooks.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
updated_at: September 18, 2025
updated_at: October 22, 2025
title: Webhooks
html_title: Configure Certificate Webhooks in step-ca
description: Implement webhooks in step-ca for richer certificates. Integrate external data sources and automate certificate workflows with custom logic.
Expand Down Expand Up @@ -111,31 +111,76 @@ or as the basis of your own custom webhook integration.

# Implementation Details

## Webhook Server Response
## Authentication

The webhook server must include `"allow": true` in the response body,
or `step-ca` will refuse to sign the certificate request.
Your webhook server must authenticate each request from the CA.

The `step-ca` template engine augments the template data with the `data` object in the response body.
When you create a webhook, `step-ca` generates a signing secret
and uses that secret to sign webhook requests.
The webhook server must confirm this signature
by verifying the `X-Smallstep-Signature` request header.

For example, a webhook server could send the following JSON response:
```json
{
"allow": true,
"data": {
"role": "eng"
}
}
In addition to the signature header, you can optionally enable two other request authentication methods:
- **Authorization Header**
The CA can send a bearer token or username and password in an `Authentication` header.
- **Mutual TLS**
The webhook server can require and verify the connection using mutual TLS. The CA will provide a client certificate when requested.

### Verifying Signature and ID Headers (required)

Every webhook has a signing secret that will be displayed when the webhook is created
via `step ca provisioner webhook add`.

Using the signing secret, `step-ca` will include a signature of the request body in the `X-Smallstep-Signature` header.

To verify the `X-Smallstep-Signature` request header,
webhook servers must compute an HMAC with the SHA256 hash function
over the request body,
using the webhook signing secret as the key.

To differentiate between several webhooks mapped to a single server,
the webhook ID is included in the `X-Smallstep-Webhook-ID` header.

See the [webhook server example repository](https://github.com/smallstep/webhooks) for a Go example of signature verification.

### Authorization Header (optional)

For an additional layer of security, `step-ca` may be configured to send
either a bearer token
or a `username:password` value in the `Authorization` header.

To use a bearer token, run:

```
step ca provisioner webhook update my_provisioner my_webhook --bearer-token abc123xyz
```

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`.
Or, to use basic authentication, run:

## Requests
```
step ca provisioner webhook update my_provisioner my_webhook --basic-auth-username user --basic-auth-password-file pass.txt
```

### Mutual TLS Authentication (optional)

You can also use mutual TLS to authenticate `step-ca` as a client of your webhook server.

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](https://github.com/smallstep/webhooks) contains examples in Go of parsing webhook request bodies for both X.509 and SSH certificate requests.
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.

## Webhook Requests

All requests from `step-ca` to the webhook server
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.

See the [webhooks server example repository](https://github.com/smallstep/webhooks)
for a Go example of parsing webhook request bodies for both X.509 and SSH certificate requests.

### X.509 Request Body

Expand Down Expand Up @@ -170,55 +215,24 @@ only a single one of the `SCEPCHALLENGE` webhooks needs to indicate the request
For SSH certificates `step-ca` will include an `sshCertificateRequest` field with [data from the request](https://github.com/smallstep/certificates/blob/c169defc73db6ba4b83e1acd5bd31feafb4df050/webhook/types.go#L37).


## Authentication

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:
- **Authorization Header**
The CA can send a bearer token or username and password in an `Authentication` header.
- **Mutual TLS**
The webhook server can require and verify the connection using mutual TLS. The CA will provide a client certificate when requested.

### Signature and ID Headers

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](https://github.com/smallstep/webhooks) for an example of verifying the signature.

### Authorization Header (optional)

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:
## Webhook Server Response

```
step ca provisioner webhook update my_provisioner my_webhook --bearer-token abc123xyz
```
The webhook server must include `"allow": true` in the response body,
or `step-ca` will refuse to sign the certificate request.

Or, to use basic authentication, run:
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:
```json
{
"allow": true,
"data": {
"role": "eng"
}
}
```
step ca provisioner webhook update my_provisioner my_webhook --basic-auth-username user --basic-auth-password-file pass.txt
```

### Mutual TLS Authentication (optional)

You can also use mutual TLS to authenticate `step-ca` as a client of your webhook server.
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`.

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.