|
1 | 1 | --- |
2 | | -updated_at: September 18, 2025 |
| 2 | +updated_at: October 22, 2025 |
3 | 3 | title: Webhooks |
4 | 4 | html_title: Configure Certificate Webhooks in step-ca |
5 | 5 | description: Implement webhooks in step-ca for richer certificates. Integrate external data sources and automate certificate workflows with custom logic. |
@@ -111,31 +111,76 @@ or as the basis of your own custom webhook integration. |
111 | 111 |
|
112 | 112 | # Implementation Details |
113 | 113 |
|
114 | | -## Webhook Server Response |
| 114 | +## Authentication |
115 | 115 |
|
116 | | -The webhook server must include `"allow": true` in the response body, |
117 | | -or `step-ca` will refuse to sign the certificate request. |
| 116 | +Your webhook server must authenticate each request from the CA. |
118 | 117 |
|
119 | | -The `step-ca` template engine augments the template data with the `data` object in the response body. |
| 118 | +When you create a webhook, `step-ca` generates a signing secret |
| 119 | +and uses that secret to sign webhook requests. |
| 120 | +The webhook server must confirm this signature |
| 121 | +by verifying the `X-Smallstep-Signature` request header. |
120 | 122 |
|
121 | | -For example, a webhook server could send the following JSON response: |
122 | | -```json |
123 | | -{ |
124 | | - "allow": true, |
125 | | - "data": { |
126 | | - "role": "eng" |
127 | | - } |
128 | | -} |
| 123 | +In addition to the signature header, you can optionally enable two other request authentication methods: |
| 124 | +- **Authorization Header** |
| 125 | + The CA can send a bearer token or username and password in an `Authentication` header. |
| 126 | +- **Mutual TLS** |
| 127 | + The webhook server can require and verify the connection using mutual TLS. The CA will provide a client certificate when requested. |
| 128 | +
|
| 129 | +### Verifying Signature and ID Headers (required) |
| 130 | +
|
| 131 | +Every webhook has a signing secret that will be displayed when the webhook is created |
| 132 | +via `step ca provisioner webhook add`. |
| 133 | +
|
| 134 | +Using the signing secret, `step-ca` will include a signature of the request body in the `X-Smallstep-Signature` header. |
| 135 | +
|
| 136 | +To verify the `X-Smallstep-Signature` request header, |
| 137 | +webhook servers must compute an HMAC with the SHA256 hash function |
| 138 | +over the request body, |
| 139 | +using the webhook signing secret as the key. |
| 140 | +
|
| 141 | +To differentiate between several webhooks mapped to a single server, |
| 142 | +the webhook ID is included in the `X-Smallstep-Webhook-ID` header. |
| 143 | +
|
| 144 | +See the [webhook server example repository](https://github.com/smallstep/webhooks) for a Go example of signature verification. |
| 145 | +
|
| 146 | +### Authorization Header (optional) |
| 147 | +
|
| 148 | +For an additional layer of security, `step-ca` may be configured to send |
| 149 | +either a bearer token |
| 150 | +or a `username:password` value in the `Authorization` header. |
| 151 | +
|
| 152 | +To use a bearer token, run: |
| 153 | +
|
| 154 | +``` |
| 155 | +step ca provisioner webhook update my_provisioner my_webhook --bearer-token abc123xyz |
129 | 156 | ``` |
130 | 157 |
|
131 | | -A template on the provisioner will then be able to reference the response under the path `.Webhooks.webhook_name`. |
132 | | -If the webhook was named `people`, the role in the webhook response could be accessed in a template under the field `.Webhooks.people.role`. |
| 158 | +Or, to use basic authentication, run: |
133 | 159 |
|
134 | | -## Requests |
| 160 | +``` |
| 161 | +step ca provisioner webhook update my_provisioner my_webhook --basic-auth-username user --basic-auth-password-file pass.txt |
| 162 | +``` |
| 163 | +
|
| 164 | +### Mutual TLS Authentication (optional) |
| 165 | +
|
| 166 | +You can also use mutual TLS to authenticate `step-ca` as a client of your webhook server. |
135 | 167 |
|
136 | | -All requests will use the `POST` method to send a JSON body to the webhook server containing a `timestamp` field. |
137 | | -Additional data will vary based on the type of the certificate being signed. |
138 | | -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. |
| 168 | +By default, `step-ca` will send the CA's self-generated leaf certificate |
| 169 | +when asked for a client certificate as part of the TLS handshake. |
| 170 | +To enable mutual TLS, |
| 171 | +configure your webhook server to request and verify a client certificate |
| 172 | +that chains up to your root CA certificate. |
| 173 | +
|
| 174 | +## Webhook Requests |
| 175 | +
|
| 176 | +All requests from `step-ca` to the webhook server |
| 177 | +will use the `POST` method to send a JSON body |
| 178 | +to the webhook server containing a `timestamp` field. |
| 179 | +Additional data will vary |
| 180 | +based on the type of the certificate being signed. |
| 181 | +
|
| 182 | +See the [webhooks server example repository](https://github.com/smallstep/webhooks) |
| 183 | +for a Go example of parsing webhook request bodies for both X.509 and SSH certificate requests. |
139 | 184 |
|
140 | 185 | ### X.509 Request Body |
141 | 186 |
|
@@ -170,55 +215,24 @@ only a single one of the `SCEPCHALLENGE` webhooks needs to indicate the request |
170 | 215 | 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). |
171 | 216 |
|
172 | 217 |
|
173 | | -## Authentication |
174 | | -
|
175 | | -Your webhook server must authenticate each request from the CA. |
176 | | -To achieve this, the CA sends a signature of its payload in the webhook request header, |
177 | | -and the webhook server must confirm this signature. |
178 | | -The signature also tells the webhook server which webhook is currently being executed. |
179 | | -
|
180 | | -In addition the the signature header, you can optionally enable two other authentication schemes: |
181 | | -- **Authorization Header** |
182 | | - The CA can send a bearer token or username and password in an `Authentication` header. |
183 | | -- **Mutual TLS** |
184 | | - The webhook server can require and verify the connection using mutual TLS. The CA will provide a client certificate when requested. |
185 | | -
|
186 | | -### Signature and ID Headers |
187 | | -
|
188 | | -Every webhook has a unique secret that will be displayed when the webhook is created |
189 | | -via `step ca provisioner webhook add`. |
190 | | -`step-ca` will include a signature of the payload in the `X-Smallstep-Signature` header. |
191 | | -The webhook ID will also be included in the `X-Smallstep-Webhook-ID` header |
192 | | -to help associate the correct signing secret with the webhook request. |
193 | | -Webhook servers must compute an HMAC with the SHA256 hash function, |
194 | | -using the webhook signing secret as the key and the request body as the message. |
195 | | -See the [webhook server example repository](https://github.com/smallstep/webhooks) for an example of verifying the signature. |
196 | | -
|
197 | | -### Authorization Header (optional) |
198 | | -
|
199 | | -For an additional layer of security, `step-ca` may be configured to send |
200 | | -either a bearer token |
201 | | -or a `username:password` in the `Authorization` header. |
202 | | -
|
203 | | -To use a bearer token, run: |
| 218 | +## Webhook Server Response |
204 | 219 |
|
205 | | -``` |
206 | | -step ca provisioner webhook update my_provisioner my_webhook --bearer-token abc123xyz |
207 | | -``` |
| 220 | +The webhook server must include `"allow": true` in the response body, |
| 221 | +or `step-ca` will refuse to sign the certificate request. |
208 | 222 |
|
209 | | -Or, to use basic authentication, run: |
| 223 | +The `step-ca` template engine augments the template data with the `data` object in the response body. |
210 | 224 |
|
| 225 | +For example, a webhook server could send the following JSON response: |
| 226 | +```json |
| 227 | +{ |
| 228 | + "allow": true, |
| 229 | + "data": { |
| 230 | + "role": "eng" |
| 231 | + } |
| 232 | +} |
211 | 233 | ``` |
212 | | -step ca provisioner webhook update my_provisioner my_webhook --basic-auth-username user --basic-auth-password-file pass.txt |
213 | | -``` |
214 | | -
|
215 | | -### Mutual TLS Authentication (optional) |
216 | 234 |
|
217 | | -You can also use mutual TLS to authenticate `step-ca` as a client of your webhook server. |
| 235 | +A template on the provisioner will then be able to reference the response under the path `.Webhooks.webhook_name`. |
| 236 | +If the webhook was named `people`, the role in the webhook response could be accessed in a template under the field `.Webhooks.people.role`. |
218 | 237 |
|
219 | | -By default, `step-ca` will send the CA's self-generated leaf certificate |
220 | | -when asked for a client certificate as part of the TLS handshake. |
221 | | -To enable mutual TLS, |
222 | | -configure your webhook server to request and verify a client certificate |
223 | | -that chains up to your root CA certificate. |
224 | 238 |
|
0 commit comments