From 3412c24a0201ea3bfbf43de436a94e460b0ccdbf Mon Sep 17 00:00:00 2001 From: Chris Kim Date: Thu, 6 Aug 2026 10:01:41 +1200 Subject: [PATCH 1/4] Add documentation for webhook triggers --- .../runbooks/webhook-runbook-trigger/index.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/pages/docs/runbooks/webhook-runbook-trigger/index.md diff --git a/src/pages/docs/runbooks/webhook-runbook-trigger/index.md b/src/pages/docs/runbooks/webhook-runbook-trigger/index.md new file mode 100644 index 0000000000..8cc2948a74 --- /dev/null +++ b/src/pages/docs/runbooks/webhook-runbook-trigger/index.md @@ -0,0 +1,98 @@ +--- +layout: src/layouts/Default.astro +pubDate: 2026-08-06 +modDate: 2026-08-06 +title: Webhook runbook triggers +description: Webhook runbook triggers let an external system run a runbook by sending an HTTP request to Octopus. +navOrder: 45 +--- + +Webhook runbook triggers let an external system run a [runbook](/docs/runbooks) by sending an HTTP request to Octopus. This is useful when the runbook needs to run in response to something happening outside Octopus, for instance: + +- Run a diagnostic runbook when your monitoring tool raises an alert. +- Restart a service when your incident management tool creates an incident. + +:::div{.warning} +Webhook runbook triggers are available from Octopus version **2026.3**. This feature can be disabled for your instance under **Configuration ➜ Features**. +::: + +:::div{.hint} +Only published snapshots can be used by a webhook runbook trigger, draft snapshots cannot. For config-as-code runbooks, webhook runbook triggers will always run the runbook from the latest commit on your default branch. +::: + +## Add a webhook runbook trigger + +1. In a project, select **Runbook Triggers**, then **Create trigger** and select **Webhook**. +2. Give the trigger a name. +3. Select a runbook. +4. Specify the target environments the runbook will run against. + + If you are using [tenants](/docs/tenants) you can select the tenants that the runbook will run against. For each tenant, the published runbook will run against the tenant's environment. + +5. Choose how callers [authenticate](#authentication) with the webhook. +6. Save the trigger. + +Once the trigger is saved, the **Endpoint** section shows the URL to call. Select the copy icon to copy it. + +## Endpoint + +Octopus generates a unique endpoint for each webhook trigger: + +```plaintext +POST https://your-octopus-url/api/{spaceId}/webhook/{webhookId} +``` + +The endpoint only accepts `POST` requests. A request body is optional, and can be up to **5 MB**. + +A successful request returns `200 OK` with an empty body. This means Octopus accepted the request and queued the runbook run, not that the run has finished. Use the trigger's run history, or the task log for the runbook run, to see the outcome. + +## Authentication {#authentication} + +Every request to the endpoint must be authenticated. Each webhook trigger uses one of two methods, chosen in the **Authentication** section when you create or edit the trigger. + +### Shared secret + +With **Shared secret**, callers send a secret that only the trigger knows in the `X-Octopus-Webhook-Secret` header: + +```bash +curl -X POST https://your-octopus-url/api/Spaces-1/webhook/{trigger-guid} \ + -H "X-Octopus-Webhook-Secret: your-secret" \ + -H "Content-Type: application/json" \ + -d '{ "reason": "Disk usage above threshold" }' +``` + +Requests with a missing or incorrect secret are rejected with `401 Unauthorized`, and Octopus records an audit event including the caller's IP address. + +Runbook runs created this way are not attributed to an Octopus user, so no permission checks are applied to the run. Anyone who holds the secret can run the runbook against the environments and tenants configured on the trigger. + +### Octopus API key + +With **Octopus API key**, callers authenticate as an Octopus user by sending an [API key](/docs/octopus-rest-api/how-to-create-an-api-key) in the `X-Octopus-ApiKey` header: + +```bash +curl -X POST https://your-octopus-url/api/Spaces-1/webhook/00000000-0000-0000-0000-000000000000 \ + -H "X-Octopus-ApiKey: API-YOUR-KEY" \ + -H "Content-Type: application/json" \ + -d '{ "reason": "Disk usage above threshold" }' +``` + +The runbook run is created as the owner of the API key, which means: + +- The key's owner needs the `RunbookRunCreate` [permission](/docs/runbooks/runbook-permissions) for the project, and for every environment and tenant the trigger targets. +- The run appears in the audit log and task list as being run by that user, rather than by the Octopus system user. + +We recommend using a [service account](/docs/security/users-and-teams/service-accounts) scoped to only what the runbook needs, rather than a key belonging to a person. + +## Rate limiting + +The webhook endpoint is rate limited. The limit applies to all webhook triggers on the instance: + +- Up to **60** requests can be made in a burst. +- The bucket replenishes at **1 request per second**. + + +:::div{.hint} +This limit is separate from the [rate limiting](/docs/administration/managing-infrastructure/rate-limiting) policies you configure under **Configuration ➜ Settings ➜ Rate Limiting**, and is always active. + +As with those policies, the count is not shared across nodes when Octopus Server is configured for [high availability](/docs/administration/high-availability). Each node counts requests independently. +::: \ No newline at end of file From 9c407f3d097894bf7d41211937424f2407aff85f Mon Sep 17 00:00:00 2001 From: Chris Kim Date: Thu, 6 Aug 2026 10:07:21 +1200 Subject: [PATCH 2/4] happy lint --- src/pages/docs/runbooks/webhook-runbook-trigger/index.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/docs/runbooks/webhook-runbook-trigger/index.md b/src/pages/docs/runbooks/webhook-runbook-trigger/index.md index 8cc2948a74..c958a0a2d2 100644 --- a/src/pages/docs/runbooks/webhook-runbook-trigger/index.md +++ b/src/pages/docs/runbooks/webhook-runbook-trigger/index.md @@ -82,7 +82,7 @@ The runbook run is created as the owner of the API key, which means: - The run appears in the audit log and task list as being run by that user, rather than by the Octopus system user. We recommend using a [service account](/docs/security/users-and-teams/service-accounts) scoped to only what the runbook needs, rather than a key belonging to a person. - + ## Rate limiting The webhook endpoint is rate limited. The limit applies to all webhook triggers on the instance: @@ -90,9 +90,8 @@ The webhook endpoint is rate limited. The limit applies to all webhook triggers - Up to **60** requests can be made in a burst. - The bucket replenishes at **1 request per second**. - :::div{.hint} This limit is separate from the [rate limiting](/docs/administration/managing-infrastructure/rate-limiting) policies you configure under **Configuration ➜ Settings ➜ Rate Limiting**, and is always active. As with those policies, the count is not shared across nodes when Octopus Server is configured for [high availability](/docs/administration/high-availability). Each node counts requests independently. -::: \ No newline at end of file +::: From ec98a7ef3462fcfb9564156bacfa3393e64e6397 Mon Sep 17 00:00:00 2001 From: Chris Kim Date: Thu, 6 Aug 2026 10:29:36 +1200 Subject: [PATCH 3/4] Add section about webhook signature verification --- src/pages/docs/runbooks/webhook-runbook-trigger/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/docs/runbooks/webhook-runbook-trigger/index.md b/src/pages/docs/runbooks/webhook-runbook-trigger/index.md index c958a0a2d2..e42e464452 100644 --- a/src/pages/docs/runbooks/webhook-runbook-trigger/index.md +++ b/src/pages/docs/runbooks/webhook-runbook-trigger/index.md @@ -83,6 +83,10 @@ The runbook run is created as the owner of the API key, which means: We recommend using a [service account](/docs/security/users-and-teams/service-accounts) scoped to only what the runbook needs, rather than a key belonging to a person. +:::div{.warning} +**Payload signature verification is not supported.** Webhook runbook triggers are generic, and signing schemes are specific to the system sending the request so Octopus ignores signed payload headers. +::: + ## Rate limiting The webhook endpoint is rate limited. The limit applies to all webhook triggers on the instance: From 051deb09b40f06f86348eabb8603533d638820ec Mon Sep 17 00:00:00 2001 From: Chris Kim Date: Thu, 6 Aug 2026 11:58:07 +1200 Subject: [PATCH 4/4] Update rate limiting section to include webhook triggers and its snowflake behaviour --- .../managing-infrastructure/rate-limiting.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/pages/docs/administration/managing-infrastructure/rate-limiting.md b/src/pages/docs/administration/managing-infrastructure/rate-limiting.md index 5af02bc2e0..e125b46860 100644 --- a/src/pages/docs/administration/managing-infrastructure/rate-limiting.md +++ b/src/pages/docs/administration/managing-infrastructure/rate-limiting.md @@ -19,7 +19,7 @@ Rate limiting is configured using policies, managed in the **Configuration ➜ S ![A screenshot of the rate limiting policies list screen. Three policies are shown, with varying configured values.](/docs/img/administration/managing-infrastructure/rate-limiting/policies-list.png) ::: -There are three built-in policies: +There are four built-in policies: ### Unauthenticated Requests @@ -36,6 +36,12 @@ The rate limit applies per user. This policy applies to any HTTP requests associated with an authenticated user which authenticate using an [agent API key](/docs/octopus-rest-api/how-to-create-an-api-key#creating-an-agent-api-key). The rate limit applies per user, counted separately from non-AI requests. +### Webhook Trigger Requests + +This policy applies to any HTTP requests made to the [webhook runbook trigger](/docs/runbooks/webhook-runbook-trigger) endpoint. +The rate limit applies per instance, shared across all webhook triggers. +This policy is always enabled, and its rate and burst limit cannot be changed. + ## Configuring the Rate limiter You can use the configuration screen to enable or disable the rate limiting policies, and alter their configured values. @@ -51,6 +57,10 @@ Each policy has the following settings you can modify: - **Rate**: The sustained rate of incoming HTTP requests that the limiter will allow. See [Understanding the Rate Limiter](#understanding-the-rate-limiter). - **Burst limit**: The number of requests that must be consumed before the rate limiter activates and starts rejecting them. See [Understanding the Rate Limiter](#understanding-the-rate-limiter). +:::div{.hint} +The [Webhook Trigger Requests](#webhook-trigger-requests) policy is an exception; its settings cannot be modified. +::: + Rate limiting policies can also be enabled and configured using the Octopus.Server command line's `rate-limiting-policy` command. ### Default Enabled State