This tutorial does not cover how to expose your Tracecat instance to the public internet.

  • If you’re running Tracecat locally, you’ll need use a tunneling service like ngrok to receive webhook requests from the public internet.
  • If you’re running Tracecat on AWS Fargate, Tracecat is automatically exposed to the public internet via an Application Load Balancer.

What you’ll learn

By the end of this tutorial, you’ll learn how to create two types of workflows:

  • A webhook workflow that receives a JSON string and decodes it using the FN.deserialize_json function.
  • A scheduled workflow that sends a notification to a Slack channel at a regular interval.

Trigger action

Every Tracecat workflow comes with a single Trigger action. This trigger action cannot be deleted. Click on the Trigger action to activate the webhooks and schedules configuration panel.

Webhooks

Webhook URLs are secrets and should not be exposed in public. The webhook URL shown in the UI screenshots are for demonstration only.

Webhooks are disabled by default. To activate a workflow’s webhook, click on the Trigger action, then toggle the webhook on. Events can then be triggered by making a POST request to the webhook URL. Webhook URLs are formatted as:

WEBHOOK_URL=https://<tracecat-public-url>/api/webhooks/<workflow-id>/<webhook-secret>

Schedules

Schedules are disabled by default. To activate a workflow’s schedule, click on the Trigger action, then toggle the schedule on.

Webhook verification

Some tools (e.g. Slack, Okta) that send webhooks require a specific response after the webhook payload is received. This is used to verify that the webhook was received and processed by Tracecat.

To echo the webhook payload back to the server, add the query parameter echo=true to the webhook URL.

https://${WEBHOOK_URL}?echo=true

By default, we return the workflow context (e.g. execution_id) as the response to the webhook POST request. To return an empty response with status code 200, set the query parameter empty_echo=true.

https://${WEBHOOK_URL}?empty_echo=true

Vendor-specific webhooks

Can’t find the vendor you’re looking for? Open an issue on GitHub and we’ll add support for it.

Some vendors have more complex webhook verification requirements. To support this, Tracecat supports vendor-specific webhook verification.

https://${WEBHOOK_URL}?vendor=okta

Vendors currently supported:

  • okta

Pause or delete schedule

You can pause or delete the schedule by selecting the schedule menu in the Trigger settings panel.

Reference webhook data

Use the ${{ TRIGGER }} expression context to reference data passed via webhooks. A child workflow also receives input data via ${{ TRIGGER }} context.

Learn more in the child workflows and expressions docs.

Webhook content types

Traceat’s webhook parser supports the following Content-Type headers:

  • application/json
  • application/x-ndjson
  • application/www-form-urlencoded

The webhook sender must set the Content-Type header to the appropriate value. If no Content-Type header is set, Tracecat defaults to application/json.

Example: Elastic Security

To ingest alerts from Elastic Security, you’ll need to configure their webhook connector in Kibana to send NDJSON with the expected content type (application/x-ndjson).

Parse webhook payload

1

Deserialize JSON action

Add the core.transform.reshape action to the workflow. Use the FN.deserialize_json function to decode an incoming JSON string via webhook.

value: ${{ FN.deserialize_json(TRIGGER.payload)}}

2

Save workflow

Save the workflow.

3

Toggle webhook

Click on the Trigger action. Enable the webhook by clicking on the toggle switch. The workflow will now receive webhook events.

4

POST webhook request

Copy the webhook URL to your clipboard, then make a POST request to the webhook URL. For example, using curl:

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"payload": "{\"name\": \"John\", \"age\": 30}"}' \
  <webhook-url>
5

View workflow runs

Go to the Runs view and check that the workflow has run successfully. The workflow should have received the webhook payload and deserialized it into a JSON object.