LogoLogo
Reliability HubAPI DocsPlatform
  • Welcome to Steadybit
  • Quick Start
    • First Steps
    • Compatibility
    • Install Agent and Extensions
    • Run an Experiment
    • Deploy Example Application
  • Concepts
    • Actions
    • Discovery
    • Query Language
  • Install and Configure
    • Install Agent
      • Architecture
      • Install on Kubernetes
      • Install on Linux Hosts
      • Install using Docker Compose
      • Install on Amazon ECS
      • Extension Registration
      • Using Mutual TLS for Extensions
      • Configuration Options
      • Agent State
      • Agent API
    • Install On-Prem Platform
      • Install on Minikube
      • Advanced Agent Authentication
      • Configuration Options
      • Maintenance & Incident Support
      • Syncing Teams via OIDC Attribute
    • Manage Environments
    • Manage Teams and Users
      • Users
      • Teams
      • Permissions
    • Manage Experiment Templates
  • Use Steadybit
    • Experiments
      • Design
      • Run
      • Run History
      • Schedule
      • Variables
      • Emergency Stop
      • Share
        • Templates
        • Duplicate
        • File
      • OpenTelemetry Integration
    • Explorer
      • Landscape
      • Targets
      • Advice
    • Reporting
  • Integrate with Steadybit
    • Extensions
      • Anatomy of an Extension
      • Extension Installation
      • Extension Kits
      • Available Extensions
    • API
      • Interactive API Documentation
    • CLI
    • Badges
    • Webhooks
      • Custom Webhooks
      • Preflight Webhooks
    • Preflight Actions
    • Slack Notifications
    • Audit Log
    • Hubs
  • Troubleshooting
    • How to troubleshoot
    • Common fixes
      • Extensions
      • Agents
      • On-prem platform
Powered by GitBook

Extension Docs

  • ActionKit
  • DiscoveryKit
  • EventKit

More Resources

  • Reliability Hub
  • API Docs
On this page
  • Configure
  • Experiment Runs
  • Developing Webhooks
  • Lifecycle of Preflight Webhooks
  • Examples
  • Verify Webhook Requests

Was this helpful?

Edit on GitHub
  1. Integrate with Steadybit
  2. Webhooks

Preflight Webhooks

Last updated 6 months ago

Was this helpful?

Preflight webhooks are an enterprise feature. Please if you want to get access.

Preflight webhooks are triggered by Steadybit whenever an experiment is about to start and allow you to prevent an experiment from running. To decide whether that specific experiment run is allowed to start, you get a list of all expected affected targets in the webhook call. Please note that, due to concurrency, these affected targets may change in case one of the targets is gone when the actual step starts or new ones are discovered.

Configure

You can add preflight webhooks at Settings -> Integrations -> Preflight webhook.

A webhook has the following parameters to be specified:

Name

The preflight webhook's name, it is shown in the experiment run.

URL

The URL, which will receive an HTTP Post request with the HTTP request body

Secret

Team

If no team is specified, preflight checks will be performed for all teams. If you specify a team, preflight checks are only made for this team.

Events

Right now, there is only one event here: Execution preflight checks, which is triggered before starting an experiment run.

Experiment Runs

During the experiment run, you can see the triggered preflight webhooks. If a webhook fails, the experiment run fails, and no targets are attacked.

Developing Webhooks

The webhook must return an HTTP status 2xx to allow an experiment to run. The experiment will not run if the webhook returns an HTTP status code other than 2xx.

Lifecycle of Preflight Webhooks

A preflight webhook can be in one of the following lifecycle statuses, indicated in the experiment run:

CREATED

The preflight webhook was created and has sent the request to the configured webhook. It is still waiting for the response.

SUCCESSFUL

The preflight webhook was resolved successfully with an HTTP status code 2xx. The experiment is allowed to continue (if all preflight webhooks are successful).

FAILED

The preflight webhook resolved with a non-2xx HTTP status code. The experiment will fail. Optionally, the response may contain a message as a reason for experiment failure.

ERRORED

Technical error happened while requesting the HTTP endpoint, e.g., the URL couldn't be resolved, or the HTTP request timed out.

A webhook will timeout after 55 seconds. In that case, the preflight check is marked as ERRORED, and the experiment will not start. If the webhook resolves later, the actual result will be submitted to the preflight check step in the experiment.

Examples

This section covers some example requests to ease the development of the preflight webhook endpoint. The request body sent to your endpoint depends on the experiment that is tried to be executed.

Request

The below curl command can be used to mock a preflight request from Steadybit to your endpoint.

Please note, that some of the metadata (i.e., step's parameters, and targetExecutions' attributes) have been omitted.

curl --request POST \
--url https://<your-preflight-webhook-endpoint> \
--header 'accept: */*' \
--header 'accept-encoding: gzip' \
--header 'content-type: application/json' \
--data '{
  "event": "experiment.execution.preflight",
  "time": "2024-11-05T10:51:31.586222005Z",
  "execution": {
    "id": 60963,
    "experimentKey": "GITHUB-42",
    "teamKey": "GITHUB",
    "environment": "de75d3d2-6e23-4b9a-b5b5-0df898bd039e",
    "name": "Copy of AWS Zone Outage of eu-central-1a for toys-bestseller",
    "hypothesis": "When AWS Availability Zone eu-central-1a is down for toys-bestseller, Kubernetes manages this accordingly by routing the traffic within expected failure rates so that the offered features still work. As soon as the zone is available again, the pod is ready within 60s.",
    "created": "2024-11-05T10:51:31.316731Z",
    "createdVia": "UI",
    "experimentVersion": 1,
    "state": "CREATED",
    "steps": [
      {
        "id": "a8f99390-b906-43b5-b456-becacd295304",
        "state": "CREATED",
        "ignoreFailure": false,
        "parameters": {
          "url": "https://demo.steadybit.io/products",
          "method": "GET",
          "duration": "140s",
        },
        "customLabel": "HTTP Endpoint works all the time",
        "actionId": "com.steadybit.extension_http.check.periodically",
        "actionKind": "CHECK",
        "radius": {},
        "targetExecutions": [
          {
            "type": "agent",
            "name": "prod-demo/steadybit-agent/steadybit-agent-0",
            "attributes": [
              {
                "key": "agent.hostname",
                "value": "prod-demo/steadybit-agent/steadybit-agent-0"
              }
            ]
          }
        ],
        "totalTargetCount": 1
      }
      {
        "id": "0192fbf3-7c7c-701b-af5a-8bbc567b7b9f",
        "state": "PREPARED",
        "ignoreFailure": false,
        "parameters": {
          "duration": "20s"
        },
        "customLabel": "Wait for AWS Zone outage"
      },
      {
        "id": "0192fbf3-7c7c-701b-af5a-8bbc567b7ba0",
        "predecessorId": "0192fbf3-7c7c-701b-af5a-8bbc567b7b9f",
        "state": "CREATED",
        "ignoreFailure": false,
        "parameters": {
          "ip": [],
          "port": [],
          "duration": "60s",
          "hostname": [],
          "failOnHostNetwork": true
        },
        "customLabel": "WHEN: Zone outage of eu-central-1a for toys-bestseller",
        "actionId": "com.steadybit.extension_container.network_blackhole",
        "actionKind": "ATTACK",
        "radius": {
          "targetType": "com.steadybit.extension_container.container",
          "percentage": 50,
          "predicate": {
            "operator": "AND",
            "predicates": [
              {
                "operator": "AND",
                "predicates": [
                  {
                    "key": "aws.zone",
                    "operator": "EQUALS",
                    "values": [
                      "eu-central-1a"
                    ]
                  }
                ]
              }
            ]
          }
        },
        "targetExecutions": [
          {
            "type": "com.steadybit.extension_container.container",
            "name": "411f01843ca1fbe53a7d30367acf25f0a79242659ffc36b56516b880d2731847",
            "attributes": [
              {
                "key": "aws.account",
                "value": "111111111111"
              },
              {
                "key": "k8s.label.service-tier",
                "value": "2"
              },
              {
                "key": "aws.zone",
                "value": "eu-central-1a"
              }
            ]
          }
        ],
        "totalTargetCount": 1
      }
    ]
  }
}'

Response: Allow Run

The webhook must return an HTTP status 2xx to allow an experiment to run.

Optionally, you can return a message in the HTTP response to show details on why the experiment is allowed to start. For example:

{"message":  "Jane Doe authorized this experiment because it runs in a permitted execution window."}

Response: Disallow Run

To disallow an experiment to run, the webhook must return an HTTP status code other than 2xx.

Optionally, you can return a message in the HTTP response to show why the experiment isn't allowed to start.

{"message":  "Jane Doe rejected this experiment run because it needs to run in a permitted execution window."}

Verify Webhook Requests

You can verify that the call to the preflight webhook is legitimate by verifying the signature. as soon as the webhook's optional secret is configured. To do that, you need to configure the optional webhook's secret. The body's signature is computed using HMAC SHA-256 and sent as an X-SB-Signature HTTP header.

You can use this header to verify the message. Here is an example of doing this in Java:

private static boolean validateSignature(byte[]body,String secret,String header)throws Exception{
    //calculate the signature using the secret
    Mac mac=Mac.getInstance("HmacSHA256");
    mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8),"HmacSHA256"));
    byte[]signature=mac.doFinal(body);

    //remove the algorithm prefix and decode the hex to bytes[]
    byte[]receivedSignature=Hex.decode(header.replaceFirst("^hmac-sha256 ",""));

    //compare using time-constant algorithm
    return MessageDigest.isEqual(signature,receivedSignature);
}

optionalYou may specify a secret which is used to sign the body to .

A webhook uses an HTTP POST request at an endpoint reachable from the Steadybit platform. The HTTP request sends a body with the content-type application/json. Our describes the exact body in WebhookPayload.

Optionally, you can return a message in the HTTP response to show why the experiment isn't allowed to start. The response body can be found in the as PreflightWebhookResponseAO.

OpenAPI specification
OpenAPI specification
verify the webhook request
reach out to us
Add Preflight Webhook
Preflight Webhook Success
Preflight Webhook Failure - Stopped Experiment Run