diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 3f5c878a3..07e812726 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -7,6 +7,8 @@ repos:
rev: v4.6.0
hooks:
- id: check-added-large-files
+ args:
+ - --maxkb=1000
- id: check-toml
- id: check-yaml
args:
diff --git a/docs/integrations/expressions.mdx b/docs/cheatsheets/functions.mdx
similarity index 98%
rename from docs/integrations/expressions.mdx
rename to docs/cheatsheets/functions.mdx
index a8652a112..8c4ba1249 100644
--- a/docs/integrations/expressions.mdx
+++ b/docs/cheatsheets/functions.mdx
@@ -1,11 +1,30 @@
---
-title: Expressions Cheatsheet
-description: A cheatsheet of all the expressions supported by Tracecat.
+title: Functions
+description: A cheatsheet of all operators and functions supported by Tracecat.
---
-## Expressions
+## Operators
-| Expression | Arguments | Description |
+| Operator | Description |
+| -------- | --------------------------------------------------------------- |
+| `\|\|` | Logical OR operation. |
+| `&&` | Logical AND operation. |
+| `==` | Check if a is equal to b. |
+| `!=` | Check if a is not equal to b. |
+| `<` | Check if a is less than b. |
+| `<=` | Check if a is less than or equal to b. |
+| `>` | Check if a is greater than b. |
+| `>=` | Check if a is greater than or equal to b. |
+| `+` | Add two numbers together. |
+| `-` | Subtract second number from first number. |
+| `*` | Multiply two numbers together. |
+| `/` | Divide first number by second number. |
+| `%` | Calculate modulo (remainder) of first number divided by second. |
+| `!` | Logical NOT operation. |
+
+## Functions
+
+| Function | Arguments | Description |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `slice` | (x: str, start_index: int, length: int) -> str | Extract a substring from start_index with given length. |
| `less_than` | (a: Any, b: Any) -> bool | Check if a is less than b. |
@@ -66,22 +85,3 @@ description: A cheatsheet of all the expressions supported by Tracecat.
| `ipv4_is_public` | (ipv4: str) -> bool | Check if IPv4 address is public/global. |
| `ipv6_is_public` | (ipv6: str) -> bool | Check if IPv6 address is public/global. |
| `check_ip_version` | (ip: str) -> int | Get IP address version (4 or 6). |
-
-## Built-in Operators
-
-| Operator | Description |
-| -------- | --------------------------------------------------------------- |
-| `\|\|` | Logical OR operation. |
-| `&&` | Logical AND operation. |
-| `==` | Check if a is equal to b. |
-| `!=` | Check if a is not equal to b. |
-| `<` | Check if a is less than b. |
-| `<=` | Check if a is less than or equal to b. |
-| `>` | Check if a is greater than b. |
-| `>=` | Check if a is greater than or equal to b. |
-| `+` | Add two numbers together. |
-| `-` | Subtract second number from first number. |
-| `*` | Multiply two numbers together. |
-| `/` | Divide first number by second number. |
-| `%` | Calculate modulo (remainder) of first number divided by second. |
-| `!` | Logical NOT operation. |
diff --git a/docs/integrations/secrets_cheatsheet.mdx b/docs/cheatsheets/integrations.mdx
similarity index 98%
rename from docs/integrations/secrets_cheatsheet.mdx
rename to docs/cheatsheets/integrations.mdx
index 040c332ad..3fbc72375 100644
--- a/docs/integrations/secrets_cheatsheet.mdx
+++ b/docs/cheatsheets/integrations.mdx
@@ -1,6 +1,6 @@
---
-title: Secrets Cheatsheet
-description: A cheatsheet of all the secrets required by the UDFs and integrations.
+title: Integrations
+description: A cheatsheet of all the integrations and their required secrets.
---
## API Credentials
The secret keys required by each secret are listed below.
diff --git a/docs/concepts/actions.mdx b/docs/concepts/actions.mdx
deleted file mode 100644
index 0c600f532..000000000
--- a/docs/concepts/actions.mdx
+++ /dev/null
@@ -1,87 +0,0 @@
----
-title: Actions
-description: Building blocks for workflows
----
-
-Actions are individual tasks performed at each step of a Tracecat workflow.
-You can find all available Actions in the workspace catalog (left sidebar).
-
-## Core Actions
-
-There are only 5 core action types, but they can be configured to perform almost any task.
-For example, a [HTTP request](#action-types) can be configured to send a GET request to an API endpoint.
-See [Quickstart](/quickstart) for a worked example.
-
-
-
- Make HTTP requests to interact with external APIs.
-
-
- Transform data in-flight.
-
-
- Send emails to specified recipients.
-
-
- Perform AI-powered tasks (e.g. summarize, label, translate).
-
-
- Open and prepopulate a case in the case management system.
-
-
-
-### Extending Actions
-
-Actions are built on top of our [user-defined functions](/concepts/user-defined-functions) (UDF) framework.
-You can add your own UDFs if you self-host Tracecat and even change the core actions!
-
-
- In Tracecat enterprise, users will eventually be able to host their own
- private UDFs for any custom actions or integrations they wish to run.
-
-
-## Control Flow
-
-Every action manages its own control flow logic.
-
-### Conditional logic
-
-Every action has a `run_if` clause that can be used to conditionally run the action.
-Any [full expression](/concepts/expressions#full-templates) that evaluates to a `boolean` can be passed to the `run_if` clause.
-
-```yaml
-actions:
- - ref: check_virustotal
- action: core.http_request
- run_if: ${{ FN.not_null(TRIGGER.hash) }} # TRIGGER.hash != null
- args:
- url: https://www.virustotal.com/api/v3/files/${{ TRIGGER.hash }}
- method: GET
-```
-
-### Loops (WIP)
-
-This feature is a work in progress
-Every action will have a `loop` clause that can be used to run the action multiple
-times.
-
-```yaml
-inputs:
- hashes:
- - "1234567890"
- - "0987654321"
- - "5678901234"
-actions:
- - ref: check_virustotal
- action: core.http_request
- for_each: ${{ for ENV.curr_hash in INPUTS.hashes }} # Assigns each hash to ENV.curr_hash
- args:
- url: https://www.virustotal.com/api/v3/files/${{ ENV.curr_hash }}
- method: GET
-```
-
-This will hit the urls:
-
-- `https://www.virustotal.com/api/v3/files/1234567890`
-- `https://www.virustotal.com/api/v3/files/0987654321`
-- `https://www.virustotal.com/api/v3/files/5678901234`
diff --git a/docs/concepts/case-management.mdx b/docs/concepts/case-management.mdx
deleted file mode 100644
index 8fe02200c..000000000
--- a/docs/concepts/case-management.mdx
+++ /dev/null
@@ -1,88 +0,0 @@
----
-title: Case Management
-description: Built-in incident tracking and management.
----
-
-Tracecat's case management system is designed to help you track and manage security incidents.
-It's design is inspired by [Rapid7's SMAC (status, malice, action, context)](https://www.rapid7.com/blog/post/2021/02/12/talkin-smac-alert-labeling-and-why-it-matters/) methodology
-and the [alert management system at Brex](https://medium.com/brexeng/elevating-security-alert-management-using-automation-828004ad596c).
-
-## Open case
-
-Use the [Open Case Action](/core/actions#action-types) in a workflow to open a new case.
-
-## View cases
-
-Go to the `Cases` tab to view all cases.
-Cases are displayed in a table with the following columns:
-
-
- A JSON object containing information about the case.
-
-
-
- Is the case `open`, `closed`, `reported`, `escalated`, or `resolved`?
-
-
-
- Is the case payload indicative of malicious activity? There are only two
- options avaiable: `malicious` or `benign`.
-
-
-
- What steps can I take to move towards closing or resolving this case?
-
-
-
- Context represents information not already captured in the case payload.
-
-
-## Best Practices
-
-
-To keep incident response repeatable, we recommend expressing case actions as a list of tags.
-
-For example, given a newly opened phishing email case, you might want want to set the tags: "quarantine" and "user-education".
-
-Check out the [MITRE D3FEND](https://d3fend.mitre.org/) matrix for ideas.
-
-
-
-
-Tracecat automatically fills the case context with the following [MITRE ATT&CK](https://attack.mitre.org/) labels (if applicable).
-
-For example:
-
-```json
-{
- "tactic": "initial-access",
- "technique": "phishing",
- "procedure": "email-attachment",
- "threat_group": "0ktapus"
-}
-```
-
-You can disable this AI feature in `settings`.
-
-
-
-## Add evidence
-
-_Coming soon_
-
-
-Multi-media evidence can be added to a case from the side panel.
-Tracecat supports the following evidence types:
-- Text
-- Images
-- Video
-- Audio
-- PDF
-
-
-
-## Close case
-
-Select the case you want to close in the case table.
-The case side panel will open.
-Use the case status dropdown menu to change the case status to `Closed`.
diff --git a/docs/concepts/expressions.mdx b/docs/concepts/expressions.mdx
deleted file mode 100644
index a77ebba59..000000000
--- a/docs/concepts/expressions.mdx
+++ /dev/null
@@ -1,420 +0,0 @@
----
-title: Expressions
-description: Powerful templating language and formulas to manipulate data.
----
-
-The concepts explained in this section are all very interdependent on one another, so we've added a [cheatsheet](/concepts/expressions#cheatsheet) to help you get started.
-
-## Expressions Overview
-
-Expressions are a powerful feature in Tracecat that gives you fine-grained control over your action logic.
-They are strings that can be evaluated into a value or data/object reference, prefixed with a [context](#expression-contexts) and wrapped in [template](#template-syntax) `${{ ... }}` syntax.
-We use [JSONPath](https://www.ietf.org/archive/id/draft-goessner-dispatch-jsonpath-00.html) expressions (dot notation) to access data, objects, or functions inside JSON-like data structures.
-
-In object-oriented programming terms, you can think of this as method invocation or attribute access on a specific context (analagous to a class or instance).
-
-Some examples of expressions:
-
-```css
-${{ SECRETS.my_secret.SUPER_SECRET }}
-${{ ACTIONS.my_action.result }}
-${{ FN.add(1, 2) }}
-${{ INPUTS.my_input }}
-${{ TRIGGER.my_trigger }}
-```
-
-
- Our convention is to use `lower_snake_case` if you need to replace whitespace
- in your paths.
-
-
-We also support **typecasting** for expressions:
-
-```css
-${{ -> }}
-```
-
-Types we currently support are `int`, `str`, `bool`, and `float`.
-
-For example, this expression will return the integer literal 3:
-
-```css
-${{ FN.add(1, 2) -> int }}
-```
-
-## Expression Contexts
-
-An expression context is a top-level namespace that changes the behavior of an expression.
-Tracecat expression contexts are all uppercase qualifiers, e.g. `SECRETS`.
-
-We use dot notation or JSONPath expressions to access data, objects, or functions in a particular context.
-We currently support the following contexts:
-
-| Qualifier | Expression syntax | Description |
-| --------- | ----------------------------------- | --------------------------------------- |
-| `SECRETS` | `SECRETS..` | Secrets manager |
-| `ACTIONS` | `ACTIONS..result` | The active workflow's execution results |
-| `FN` | `FN.(, , ...)` | Inline functions |
-| `INPUTS` | `INPUTS.` | The active workflow's static inputs |
-| `TRIGGER` | `TRIGGER.` | The active workflow's trigger inputs |
-
-## Template syntax
-
-Tracecat's template syntax takes inspiration from Github Actions, so it may feel familiar to you!
-
-A template is a string with a `${{ ... }}` pattern that wraps an expression:
-
-```css
-${{ }}
-```
-
-Templates can exist in two forms: full templates and inline templates.
-
-### Full templates
-
-A full template is a sstring that only contains a single template with no surrounding whitespace:
-
-```php
-"${{ ... }}"
-```
-
-It follow that when a full template wraps an expression, we call this a **full expression**:
-
-```php
-"${{ }}"
-```
-
-The final datatype of the above expression depends on the return type of the expression and whether there is a typecast.
-
-This expression will return integer literal `3` because `FN.add(1, 2)` returns an integer:
-
-```php
-"${{ FN.add(1, 2) }}"
-```
-
-In contrast, this expression will return string literal `"3"` because `FN.add(1, 2)` was cast to a string:
-
-```php
-"${{ FN.add(1, 2) -> str}}"
-```
-
-In YAML, by convention we omit the quotes around full expressions:
-
-```yaml
-actions:
- - ref: my_action
- action: example.action
- args:
- value: ${{ FN.add(1, 2) }}
-```
-
-### Inline templates
-
-An inline template is a string where all templates are in the string body:
-
-```php
-"An inline template ${{ ... }} looks ${{ ... }} like this."
-```
-
-As you'd expect, the following is called an **inline expression**:
-
-```php
-"An inline template ${{ }} looks ${{ }} like this."
-```
-
-The final datatype of the above expression is always a string.
-
-For example, this expression:
-
-```php
-"An inline template ${{ FN.add(1, 2) }} looks ${{ FN.add(1, 2) -> str }} like this."
-```
-
-will return string literal `"An inline template 3 looks 3 like this."`:
-
-In YAML, by convention we wrap quotes around inline expressions:
-
-```yaml
-actions:
- - ref: my_action
- action: example.action
- args:
- value: "An inline template ${{ FN.add(1, 2) }} looks ${{ FN.add(1, 2) -> str }} like this."
-```
-
-## Expression Types
-
-### Action Expressions
-
-Action expressions are JSONPaths that target the `ACTIONS` context. It references data or objects that are returned from completed actions.
-
-```css
-${{ ACTIONS..result }}
-```
-
-For example, if you have an action that was defined with the following [UDF](/concepts/user-defined-functions) in your workflow definition:
-
-```python
-@registry.register(namespace="example", description="Adds two numbers.")
-def add(lhs: int, rhs: int) -> int:
- return lhs + rhs
-```
-
-and the following snippet of YAML in your workflow definition:
-
-```yaml
-actions:
- - ref: add_two_numbers
- action: example.add
- args:
- lhs: 1
- rhs: 2
-```
-
-Then anywhere else in your workflow definition and given `add_two_numbers` has completed, you can use the `ACTIONS.add_two_numbers.result` expression to access the result of the action.
-
-Revisiting the example above, if you added another action to the same workflow:
-
-```yaml
-actions:
- - ref: add_two_numbers
- action: example.add
- args:
- lhs: 1
- rhs: 2
- - ref: add_three_numbers
- action: example.add
- depends_on:
- - add_two_numbers
- args:
- lhs: ${{ ACTIONS.add_two_numbers.result }} # This evaluates to 3!
- rhs: 3
-```
-
-you can use upstream computations in your downstream actions.
-
-
- Tracecat's workflow engine doesn't enforce that actions require hierarchical
- dependencies on other actions to use their results. So long an action in the
- same workflow is completed, another action can use its result.
-
-
-Action expressions always contain the following predefined keys:
-
-| Key | Description |
-| ----------------- | -------------------------------------------------- |
-| `result` | Contains the action's result. |
-| `result_typename` | The Python type annotation of the action's result. |
-
-### Input Expressions
-
-Input expressions are JSONPath expressions that target the `INPUTS` context.
-
-```css
-${{ INPUTS. }}
-```
-
-Given the following static workflow inputs:
-
-```yaml
-inputs:
- company: Tracecat
- url: https://tracecat.com
- contact:
- email: founders@tracecat.com
- location: San Francisco, CA
-```
-
-Some valid input expressions would look like:
-
-```css
-${{ INPUTS.company }}
-${{ INPUTS.url }}
-${{ INPUTS.contact.email -> str }}
-${{ INPUTS.contact.location }}
-```
-
-### Trigger Expressions
-
-Trigger expressions are JSONPath expressions that target the `TRIGGER` context.
-
-```css
-${{ TRIGGER. }}
-```
-
-Given the following webhook call:
-
-```sh
-curl -X POST $WEBHOOK_URL -H "Content-Type: application/json" -d '{
- "event_type": "update",
- "source": "http://data-source.com",
- "metadata": {
- "time":"Thursday, May 20th 11:40pm",
- "platform":"cool_platform"
- }
- }'
-```
-
-Some valid input expressions would look like:
-
-```css
-${{ TRIGGER.event_type }}
-${{ TRIGGER.metadata.time }}
-```
-
-### Secret Expressions
-
-Secret expressions are JSONPath expressions that target the `SECRETS` context.
-They allow you to pull created secrets from the Secrets Manager at runtime.
-
-```css
-${{ SECRETS.. }}
-```
-
-Given the following secrets created like such:
-
-```sh
-curl -X PUT $TRACECAT__API_URL/secrets \
- -H "Content-Type: application/json" \
- -d '{
- "type":"custom",
- "name":"some_secret",
- "keys":[
- {
- "key":"SOME_API_KEY",
- "value": "SOME_SECRET_VALUE"
- }
- ]
- }'
-```
-
-To use `SOME_SECRET_VALUE` in your workflow, you would use the following expression:
-
-```css
-${{ SECRETS.my_secret.SOME_API_KEY }}
-```
-
-For instance, to make an API call:
-
-```yaml
-actions:
- - ref: my_action
- action: core.http_request
- args:
- url: https://api.some-example.com
- headers:
- Authorization: Bearer ${{ SECRETS.some_secret.SOME_API_KEY }}
- ...
-```
-
-### Function Expressions
-
-Function expressions are expressions that target the `FN` context.
-
-```css
-${{ FN.(, , ...) }}
-
-```
-
-Our syntax allows for nested expressions, so you can use the result of one function as an argument to another function:
-
-```css
-${{ FN.add(FN.add(1, 2), 3) }}
-```
-
-#### Supported Functions
-
-| Name | Description |
-| ----------------------- | ------------------------------------------ |
-| `less_than` | less than comparison |
-| `less_than_or_equal` | less than or equal comparison |
-| `greater_than` | greater than comparison |
-| `greater_than_or_equal` | greater than or equal comparison |
-| `not_equal` | not equal comparison |
-| `is_equal` | equal comparison |
-| `not_null` | check if value is not null |
-| `is_null` | check if value is null |
-| `regex_extract` | extract match using regex pattern |
-| `regex_match` | check if text matches regex pattern |
-| `regex_not_match` | check if text does not match regex pattern |
-| `contains` | check if container contains item |
-| `does_not_contain` | check if container does not contain item |
-| `length` | get the length of a collection |
-| `is_empty` | check if collection is empty |
-| `not_empty` | check if collection is not empty |
-| `add` | add two numbers |
-| `sub` | subtract two numbers |
-| `mul` | multiply two numbers |
-| `div` | divide two numbers |
-| `mod` | get the modulus of two numbers |
-| `pow` | raise a number to a power |
-| `sum` | sum a collection of numbers |
-| `join` | join items in a list with a separator |
-| `concat` | concatenate multiple items into a string |
-| `format` | format a string |
-| `and` | logical and operation |
-| `or` | logical or operation |
-| `not` | logical not operation |
-| `serialize_json` | convert json to string |
-| `from_timestamp` | convert timestamp to datetime |
-
-
- This list is not exhaustive, and we plan to add more functions in the future.
-
-
-### Typecasts
-
-We support the following typecasts:
-| Type | Python Type |
-|-------|-------------|
-| int | `int` |
-| float | `float` |
-| str | `str` |
-| bool | Custom `bool` - true for any truthy value, `1`, or upper/lower case `true` |
-
-You can perform a typecast on an expression like so:
-
-
-```php Inline
-${{ int() }}
-```
-
-```php Trailing
-${{ -> int }}
-```
-
-
-
-## Evaluation Procedure
-
-Before an action runs, Tracecat performs the following steps to evaluate the expressions in the action:
-
-1. Find all secrets that are declared in secret expressions
-2. Pull these into the execution context
-3. Evaluate all types of expressions in one pass
-
-After doing the above it then proceeds to run the action's associated UDF.
-
-## Cheatsheet
-
-### Terminology
-
-| Term | Description |
-| ----------------- | ----------------------------------------------------------------------------------------------------------- |
-| Context | A top-level namespace that changes the behavior of an expression, e.g. `SECRETS` or `ACTIONS` |
-| Expression | A string that can be evaluated into a value or data/object reference, often involving a `context`. |
-| Template | A string holding an expression `${{ }}` that evaluates into a value or data/object reference. |
-| Full template | A string that only contains one template: `"${{ ... }}"` |
-| Full expression | A full template string with an expression: `"${{ }}"` |
-| Inline template | All templates are inline, e.g. `"An inline template ${{ ... }} looks like this."` |
-| Inline expression | All templates have expressions and are inline, e.g. `"An inline expression ${{ }} looks like this."` |
-
-### Contexts
-
-| Qualifier | Description |
-| --------- | ----------------------------------------------------------------------------------------------------------------------------- |
-| `SECRETS` | Secrets manager context. The expression `SECRETS.my_secret.SUPER_SECRET` will return `my_secret.SUPER_SECRET`'s stored value. |
-| `ACTIONS` | The active workflow's execution context. Lets you access results from completed actions. |
-| `FN` | Inline functions. The expression `FN.add(1, 2)` will return `3`. |
-| `INPUTS` | The active workflow's static inputs. Lets you access static inputs from the workflow definition. |
-| `TRIGGER` | The active workflow's trigger inputs. Lets you access dynamic inputs from a webhook. |
diff --git a/docs/concepts/schedules.mdx b/docs/concepts/schedules.mdx
deleted file mode 100644
index 9462ff9e1..000000000
--- a/docs/concepts/schedules.mdx
+++ /dev/null
@@ -1,86 +0,0 @@
----
-title: Schedules
-description: Schedule workflows to run at regular internals.
----
-
-Scheduling is one of the primary reasons for using an orchestrator such as Tracecat.
-Tracecat allows you to use schedules to automatically create new workflow runs.
-
-A Schedule contains information that Tracecat uses to execute workflows for you automatically on a specified cadence.
-You can add multiple schedules to any workflow. The Tracecat scheduler (built on Temporal) periodically reviews every workflow and executes them according to their configued schedule.
-
-Find the CLI reference for schedules [here](/using-the-cli/#schedules-management).
-
-## Creating a schedule
-
-Schedules use [ISO8601 duration](https://www.digi.com/resources/documentation/digidocs/90001488-13/reference/r_iso_8601_duration_format.htm) strings to specify the schedule interval.
-
-Assuming the following:
-
-1. You already have a workflow created
-2. This workflow takes inputs with field `hello`
-3. You'd like to schedule this workflow to run every 15 seconds
-
-You can incoke the following command to achieve this like so:
-
-```bash
-tracecat schedule create --every PT15S --data '{ "hello": "world" }'
-```
-
-
- The inputs passed here will be accessible from the `TRIGGER` context, and can
- be changed if you update the schedule.
-
-
-If a schedules was successfully created, you should see a response like this:
-
-```bash
-{
- 'owner_id': 'default-tracecat-user',
- 'created_at': '2024-07-02T00:40:22.135461Z',
- 'id': '',
- 'cron': None,
- 'every': 'PT15S',
- 'offset': None,
- 'start_at': None,
- 'end_at': None,
- 'updated_at': '2024-07-02T00:42:06.962683Z',
- 'status': 'online',
- 'inputs': { "hello": "world"},
- 'workflow_id': ''
-}
-```
-
-For convenience, you can put the input data in a json file:
-
-```In inputs.json
-{
- "hello": "world"
-}
-```
-
-and invoke the command like so (note the filename prefixed with `@`):
-
-```bash
-tracecat schedule create --every PT15S --data @inputs.json
-```
-
-# Updating a schedule
-
-You can pause a schedule (without deleting the underlying Temporal schedule) by running
-
-```bash
-traceat schedule update --offline
-```
-
-and unpause it with
-
-```bash
-traceat schedule update --online
-```
-
-To update the input data for the scheduled workflow run,
-
-```bash
-tracecat schedule update --data @new_inputs.json
-```
diff --git a/docs/concepts/secrets.mdx b/docs/concepts/secrets.mdx
deleted file mode 100644
index cba2a0180..000000000
--- a/docs/concepts/secrets.mdx
+++ /dev/null
@@ -1,74 +0,0 @@
----
-title: Secrets
-description: Securely store and use sensitive credentials.
----
-
-Secrets are crendentials that you can pull into your workflows to access APIs and tooling.
-
-You can find the complete list of secrets and requirements in the [secrets cheatsheet](/integrations/secrets_cheatsheet).
-
-## Secret Types
-
-We currently only support `custom` type secrets, where the encrypted credentials are a list of key-value pair JSON objects with only the keys `key` and `value`.
-
-For example:
-
-```json
-{
- "type": "custom",
- "name": "my_secret",
- "keys": [
- {
- "key": "SOME_API_KEY",
- "value": "SOME_SECRET_VALUE"
- },
- {
- "key": "ANOTHER_API_KEY",
- "value": "ANOTHER_SECRET_VALUE"
- }
- ]
-}
-```
-
-
-We have planned support for other secret types like `oauth2`, `token`.
-
-
-
-## Just-In-Time Secrets Access
-
-Tracecat's secret manager manages the lifecycle of secrets during execution.
-We actively try to minimize secret exposure in the execution context and environment by making them available only at the time of execution.
-When an action completes, Tracecat removes secrets from the execution context.
-
-Secrets also use `pydantic.SecretStr` to ensure that the secrets are not accidentally logged or exposed in the UI/logs.
-
-## Creating Secrets
-
-You can create secrets using the Tracecat CLI or the API.
-
-
-```sh CLI
-tracecat secrets create some_secret KEY1=VALUE1 KEY2=VALUE2
-```
-
-```sh curl
-curl -X PUT $TRACECAT__API_URL/secrets \
- -H "Content-Type: application/json" \
- -d '{
- "type":"custom",
- "name":"some_secret",
- "keys":[
- {
- "key":"KEY1",
- "value": "VALUE1"
- },
- {
- "key":"KEY2",
- "value": "VALUE2"
- }
- ]
- }'
-```
-
-
diff --git a/docs/concepts/user-defined-functions.mdx b/docs/concepts/user-defined-functions.mdx
deleted file mode 100644
index b6d893c3a..000000000
--- a/docs/concepts/user-defined-functions.mdx
+++ /dev/null
@@ -1,107 +0,0 @@
----
-title: User-Defined Functions
-description: Build custom integrations with a single Python decorator
----
-
-A User-Defined Function (UDF) is a custom function that you can use as an action in your workflows.
-All Tracecat Actions use this underlying UDF framework to perform tasks.
-
-## Motivations
-
-- Automatically generate input/output validators for frontend actions through backend code.
-- Provide a customizable and extensible framework for defining actions.
-
-## Framework
-
-We've developed a simple framework that takes UDFs and converts them into Temporal activities and UI action blocks.
-The framework currently only supports using Python functions as UDFs.
-
-### Registry
-
-The `registry` singleton is a global Python object that stores all the decorated UDFs.
-At runtime, Tracecat's workflow runner dynamically executes these functions according to the [workflow definition](/workflow-definition).
-
-### API
-
-In Tracecat, the way we create UDFs is by defining a Python function and decorating it with `@registry.register`.
-In Python, we support using both synchronous and asynchronous functions. For example:
-
-```python Example UDFs
-import asyncio
-from tracecat.registry import registry
-
-@registry.register(
- description="Adds two numbers.",
- namespace="example",
-)
-def add(
- lhs: Annotated[int, Field(..., description="The first number")],
- rhs: Annotated[int, Field(..., description="The second number")],
-) -> int:
- return lhs + rhs
-
-@registry.register(
- description="Sleeps and subtracts two numbers.",
- namespace="example",
-)
-async def sleeping_subtract(
- lhs: Annotated[int, Field(..., description="The first number")],
- rhs: Annotated[int, Field(..., description="The second number")],
-) -> int:
- await asyncio.sleep(1)
- return lhs - rhs
-```
-
-These UDFs will be registered under the `example` namespace, and their keys are `example.add` and `example.sleeping_subtract`.
-
-The `register` decorator also accepts arbitrary keyword arguments that are stored in the registry.
-We plan on using this to further extend the capabilities of UDFs, for example by using a `version` keyword argument to specify the version of the UDF.
-
-### Secrets injection
-
-You can declare a list of secrets in your UDFs using the `secrets` parameter.
-You will have to create these secrets on the platform either through the `settings/credentials` UI or through the API/CLI.
-The declared secrets are pulled from Tracecat's secret manager at runtime.
-
-For example, given `my_secret` with key `MY_SECRET_KEY`:
-
-```python Example UDF with a declared secret
-@registry.register(
- description="This is a sample UDF with secrets",
- secrets=["my_secret"] # Accepts more than one secret name
-)
-async def requires_api_key(resource_name: str, value: int) -> str:
- # Call this normally like regular Python code!
- api_key = os.environ["MY_SECRET_KEY"]
-
- async with httpx.AsyncClient() as client:
- response = await client.post(
- f"https://api.example.com/resource/{resource_name}",
- headers={"Authorization": f"Bearer {api_key}"},
- json={"value": value}
- )
- response.raise_for_status()
- return response.text
-```
-
-For more information on how to create secrets and how Tracecat's secret manager works, see [Secrets](/secrets).
-
-## Schemas
-
-Tracecat performs schema validation on all inputs and outputs of actions.
-
-### Schema Generation
-
-- Tracecat UDFs automatically generate Pydantic models for input and output validation.
-
-### Schema validation
-
-Currently all input validation is performed on the server side using the registered UDF Pydantic validators.
-
-### UI Generation
-
-- Motivation: All dyanmic forms and schema validation should be driven by server-side code.
-- UDFs can capture a lot more infromation through the `typing.Annotated` annotations and `registry.register` decorator.
-- This information is used to generate extended JSONSchema that can be used to generate UI in our NextJS frontend.
-
-_NOTE: This feature is currently a work in progress._
diff --git a/docs/concepts/webhooks.mdx b/docs/concepts/webhooks.mdx
deleted file mode 100644
index b4b9b6ba2..000000000
--- a/docs/concepts/webhooks.mdx
+++ /dev/null
@@ -1,69 +0,0 @@
----
-title: Webhooks
-description: Receive events from external events and trigger workflows.
----
-
-Webhooks allow workflows to interact with external systems by listening for and responding to events.
-
-## Overview
-
-A workflow has only one webhook by design.
-Each webhook exposes a unique URL endpoint to receive events from other systems and forward them entrypoints in Tracecat Workflows.
-
-The webhook format is:
-
-```bash
-$TRACECAT__PUBLIC_RUNNER_URL/$WORKFLOW_ID/$WEBHOOK_SECRET
-```
-
-You can get this URL from the Trigger block in the UI, or by making a GET request to the API.
-Using the CLI this would be:
-
-```bash
-tracecat workflow inspect $WORKFLOW_ID
-```
-
-## Filters
-
-A webhook can be configured with filters.
-A filter performs checks on incoming data or other factors to decide if a workflow should run.
-
-Some benefits of using filters include the ability to:
-
-- Ignore certain events from triggering a workflow
-- Prevent a workflow from being executed if certain conditions are not met
-- Apply rate limiting to prevent abuse or overloading the system (coming soon)
-- Reject events that do not conform to some HTTP headers or other network security requirements (coming soon)
-- Perform callbacks without scheduling a workflow (coming soon)
-
-A filter is a set of conditions that must be satisfied before a workflow is executed.
-Each condition is a [full expression](/concepts/expressions#full-templates) that returns a `boolean`.
-
-```yaml example_filter.yaml
-triggers:
- - type: webhook
- ref: my_webhook_with_filters
- filters:
- - kind: all # all conditions must be satisfied
- conditions:
- - ${{ FN.not_null(TRIGGER.value) }}
- - ${{ FN.equals(TRIGGER.value, "123456") }}
- - kind: any # any condition must be satisfied
- conditions:
- - ${{ FN.not_null(TRIGGER.value) }}
- - ${{ FN.contains([1, 2, 3], TRIGGER.value) }}
-```
-
-Filters are always evaluated in the order they are defined, and likewise for the conditions within each filter.
-If no filters are configured, a webhook will simply always schedule a workflow for execution.
-
-This feature is not yet implemented.
-
-## Authentication
-
-Our current webhook implementation uses a secret attached to the path to verify the authenticity of incoming requests.
-
-
- We are migrating our webhook infrastructure to use [Svix](https://svix.com)
- for secure and resilient webhook delivery.
-
diff --git a/docs/concepts/workflow-definitions.mdx b/docs/concepts/workflow-definitions.mdx
deleted file mode 100644
index ff3799a57..000000000
--- a/docs/concepts/workflow-definitions.mdx
+++ /dev/null
@@ -1,184 +0,0 @@
----
-title: Workflow Definitions
-description: Develop playbooks using configuration-as-code (YAML).
----
-
-A workflow definition is the configuration data that defines and controls how a workflow executes.
-It is the source of truth when reasoning about any workflow's execution.
-
-## Overview
-
-A workflow defintion is analagous to an instruction manual or blueprint that tells Tracecat runners how to execute a workflow.
-Workflow definitions are created when a workflow is committed from the UI, and are immutable once created.
-You can think of them as a snapshot of the workflow (that you view and edit in the UI) at a specific point in time.
-
-These snapshots becomes deployed workflow instances (workflow runs) at runtime.
-When a workflow is triggered, Tracecat will find and execute its latest workflow definition version.
-
-One workflow can have many different workflow definitions due to versioning
-
-## Workflow Definition Schema
-
-Top level attributes for a workflow definition `DSLInput` object.
-
-| Attribute | Type | Description |
-| ---------------- | ----------------------- | ----------------------------------------------------------------- |
-| `title` | `str` | The title of the DSL workflow. |
-| `description` | `str` | A description of the DSL workflow. |
-| `entrypoint` | `str` | The entry point for the DSL workflow. |
-| `actions` | `list[ActionStatement]` | A list of [action statements](#action-statement) in the workflow. |
-| `config` | `DSLConfig` | Configuration settings for the DSL workflow. |
-| `triggers` | `list[Trigger]` | A list of triggers for the workflow. |
-| `inputs` | `dict[str, Any]` | Static input parameters for the workflow. |
-| `trigger_inputs` | `dict[str, Any]` | Dynamic input parameters for the workflow. |
-| `model_config` | `ConfigDict` | Configuration allowing arbitrary types. |
-
-## Action Statement
-
-An `ActionStatement` is the configuration for single action in a workflow.
-
-| Attribute | Type | Description |
-| ------------ | ---------------- | ----------------------------------------------------------------------------- |
-| `ref` | `str` | Unique reference for the task (`lower_snake_case` slug of the action's title) |
-| `action` | `str` | The action's UDF key `.` |
-| `args` | `dict[str, Any]` | Arguments (key-value pairs) for the action |
-| `depends_on` | `list[str]` | Uptream action dependencies (other action `ref`s) |
-| `run_if` | `str \| None` | If conditional. Evaluating to `True` runs the task. (optional) |
-| `for_each` | `str \| None` | _Coming soon: An iterable over which the action should be applied (optional)_ |
-
-## Data Model
-
-Workflows are modeled as a [directed acyclic graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph) (DAG).
-Accordingly, the workflow definition expresses the graph dependencies between actions.
-Each action statement's `depends_on` attribute is a list of references to other actions that must complete before the action can run.
-
-## Using YAML
-
-You can create a workflow definition using a YAML file and Tracecat's YAML-like Domain-Specific Language (DSL).
-Some benefits of using YAML include:
-
-- **Version Control**: You can track changes to the workflow over time -- better audit trails!
-- **Inline comments**: Nice to have for documentation and debugging.
-- **IDE Support**: You can use your favorite IDE or text editor work with YAML files.
-- **AI Autocompletion**: When used with an IDE AI copilot like `Github Copilot` or `Supermaven` that learns your editing behavior, you can get AI-powered autocompletion for your YAML file.
-
-You can find the full schema for the YAML file at [traceat/dsl/common.py](https://github.com/TracecatHQ/tracecat/blob/7aa616e8bec04ee5a54c72a8e4cf5e26259ac1a3/tracecat/dsl/common.py#L67).
-
-An example YAML file for a workflow definition:
-
-```yaml
-title: Send Slack notifications for GuardDuty findings
-description: Pull GuardDuty findings from the API and send them to Slack
-config:
- scheduler: dynamic
-entrypoint: pull_aws_guardduty_findings
-inputs:
- url: http://api.example.com/v1
- num_days: 1
-
-triggers:
- - type: webhook
- ref: my_webhook
- entrypoint: pull_aws_guardduty_findings
- - type: schedule
- ref: my_schedule
- entrypoint: pull_aws_guardduty_findings
-
-actions:
- - ref: pull_aws_guardduty_findings
- action: core.http_request
- args:
- url: ${{ INPUTS.url }}/cdr/alerts
- method: GET
- params:
- start_time: "2023-05-27T00:00:00Z"
- end_time: "2024-05-28T12:00:00Z"
- vendor: aws_guardduty
-
- - ref: smaccify_guardduty_findings
- action: core.http_request
- depends_on:
- - pull_aws_guardduty_findings
- args:
- url: ${{ INPUTS.url }}/smac/aws_guardduty
- method: POST
- headers:
- Content-Type: application/json
- payload: ${{ ACTIONS.pull_aws_guardduty_findings.result.data }} # List of findings
-
- - ref: send_slack_notifications
- action: core.http_request
- depends_on:
- - smaccify_guardduty_findings
- args:
- url: ${{ INPUTS.url }}/chatops/messages
- headers:
- Content-Type: application/json
- method: POST
- payload:
- vendor: slack
- channel: C0XXXXXXXXX
- contexts: ${{ ACTIONS.smaccify_guardduty_findings.result.data }} # List of SMAC findings
- text: GuardDuty findings for past 24h
- template:
- - type: header
- text:
- type: plain_text
- text: "{title}"
- emoji: true
- - type: section
- text:
- type: mrkdwn
- text: "{description}"
- - type: section
- fields:
- - type: mrkdwn
- text: "*Status:* {status}"
- - type: mrkdwn
- text: "*Malice:* {malice}"
- - type: mrkdwn
- text: "*Action:* {action}"
- - type: mrkdwn
- text: "*Context:* {context}"
- - type: actions
- elements:
- - type: button
- text:
- type: plain_text
- emoji: true
- text: "Suppress"
- style: primary
- value: "click_me_123"
- - type: button
- text:
- type: plain_text
- emoji: true
- text: "Escalate"
- style: danger
- value: "click_me_123"
-```
-
-## Committing Workflow changes
-
-A new workflow definition is created for a workflow when:
-
-- A YAML file is committed to a workflow through the API/CLI
-- A workflow is committed through the GUI
-
-
- When a workflow is committed without a YAML file, Tracecat will look for the
- workflow's GUI-configured actions in the database `Action` table and use those
- to create the workflow definition.
-
-
-## Versioning
-
-- Our versioning system is intentionally extremely simple
-- You can checkout a specific version of a workflow definition, but to promote it to the exe
-- Tracecat will always look for the latest version of the workflow definition to execute
-- Workflow versions are monotonically increasing integers
-
-## Immutability
-
-We do not allow editing of workflow definitions after they are created, nor do we allow deletion of workflow definitions.
-This ensures that for any compliance or audit purposes, you can always trace back to the exact configuration that was used to execute a workflow.
diff --git a/docs/concepts/workflows.mdx b/docs/concepts/workflows.mdx
deleted file mode 100644
index c0cc4517b..000000000
--- a/docs/concepts/workflows.mdx
+++ /dev/null
@@ -1,55 +0,0 @@
----
-title: Workflows
-description: Powerful automation made easy
----
-
-A workflow is the most central Tracecat object.
-It is a collection of actions that are executed in a specific order.
-Workflows can be triggered by a variety of events, such as a schedule or an external event.
-
-## Overview
-
-Workflows can be thought of as a special class of functions that manage the running of actions.
-
-- Workflows can be committed in either operating mode into a [Workflow Definition](/concepts/workflow-definitions).
-
-## Triggers
-
-Each workflow has only one entrypoint, which is the first action to run when the workflow is triggered.
-A workflow with more than one entrypoint will fail at commit time.
-
-Kinds of triggers we support:
-
-- [**Webhooks**](/concepts/webhooks): Trigger a workflow by sending an HTTP request to a webhook URL.
-- [**Schedules**](/concepts/schedules): Trigger a workflow at a specific time or interval.
-
-## Workflow Orchestration Layer
-
-Tracecat's workflow orchestration layer is responsible for managing how workflows and actions get executed.
-
-It's built on top of [Temporal](https://temporal.io/), which is an open-source platform for building durable and scalable applications.
-It provides a fault-tolerant runtime that ensures your application workflows can reliably execute to completion, even in the face of failures, network outages, or infrastructure issues.
-
-Tracecat's workflow runners (worker service) are built using Temporal's Python SDK. Temporal is responsible for distribuing workflow execution tasks to our workers.
-
-### Key Features
-
-- **Durable Execution**: Temporal preserves the entire state of your application workflows, allowing them to resume execution from the exact point they left off, even after crashes or infrastructure failures.
-
-- **Scalability**: Temporal can scale to handle high loads and a massive number of concurrent workflow executions.
-
-- **Reliability**: Workflow executions are designed to be resilient to worker process failures or cluster outages, ensuring progress can resume after any interruptions.
-
-- **Language Agnostic**: Temporal supports multiple programming languages, including Go, Java, Python, PHP, and TypeScript, enabling polyglot development.
-
-- **Visibility and Monitoring**: Temporal records every execution, its progress, and state, providing insights into errors and application performance. At the moment, Tracecat only supports the Python SDK.
-
-## Child Workflows
-
-Workflows can trigger other workflows through a simple HTTP request. This allows you to create complex workflows by composing together simpler workflows.
-
-
- We are working towards better design and implementation of child workflows.
- Currently child workflows don't inherit the parent workflow's execution
- context.
-
diff --git a/docs/img/branching.png b/docs/img/branching.png
deleted file mode 100644
index 4ab17b7a4..000000000
Binary files a/docs/img/branching.png and /dev/null differ
diff --git a/docs/img/configure-action.png b/docs/img/configure-action.png
deleted file mode 100644
index 99a1f67d0..000000000
Binary files a/docs/img/configure-action.png and /dev/null differ
diff --git a/docs/img/dnd.gif b/docs/img/dnd.gif
deleted file mode 100644
index ca7f75698..000000000
Binary files a/docs/img/dnd.gif and /dev/null differ
diff --git a/docs/img/env-script.png b/docs/img/env-script.png
deleted file mode 100644
index fcce9a260..000000000
Binary files a/docs/img/env-script.png and /dev/null differ
diff --git a/docs/img/past-runs.png b/docs/img/past-runs.png
deleted file mode 100644
index 994e1e9c2..000000000
Binary files a/docs/img/past-runs.png and /dev/null differ
diff --git a/docs/img/phishing.png b/docs/img/phishing.png
deleted file mode 100644
index 9fcb133c2..000000000
Binary files a/docs/img/phishing.png and /dev/null differ
diff --git a/docs/img/quickstart/add-node.png b/docs/img/quickstart/add-node.png
deleted file mode 100644
index 01ba9fe84..000000000
Binary files a/docs/img/quickstart/add-node.png and /dev/null differ
diff --git a/docs/img/quickstart/case-panel.png b/docs/img/quickstart/case-panel.png
deleted file mode 100644
index 20ef8ae5c..000000000
Binary files a/docs/img/quickstart/case-panel.png and /dev/null differ
diff --git a/docs/img/quickstart/case.png b/docs/img/quickstart/case.png
deleted file mode 100644
index 56bd38d2b..000000000
Binary files a/docs/img/quickstart/case.png and /dev/null differ
diff --git a/docs/img/quickstart/change-workflow-name.png b/docs/img/quickstart/change-workflow-name.png
deleted file mode 100644
index ca9ecd61c..000000000
Binary files a/docs/img/quickstart/change-workflow-name.png and /dev/null differ
diff --git a/docs/img/quickstart/commit-workflow.png b/docs/img/quickstart/commit-workflow.png
deleted file mode 100644
index a99d26ad6..000000000
Binary files a/docs/img/quickstart/commit-workflow.png and /dev/null differ
diff --git a/docs/img/quickstart/configure-open-case.png b/docs/img/quickstart/configure-open-case.png
deleted file mode 100644
index 7c38741b4..000000000
Binary files a/docs/img/quickstart/configure-open-case.png and /dev/null differ
diff --git a/docs/img/quickstart/configure-vt-input.png b/docs/img/quickstart/configure-vt-input.png
deleted file mode 100644
index 58226215b..000000000
Binary files a/docs/img/quickstart/configure-vt-input.png and /dev/null differ
diff --git a/docs/img/quickstart/create-new-workflow.png b/docs/img/quickstart/create-new-workflow.png
deleted file mode 100644
index da031330b..000000000
Binary files a/docs/img/quickstart/create-new-workflow.png and /dev/null differ
diff --git a/docs/img/quickstart/create-secret.png b/docs/img/quickstart/create-secret.png
deleted file mode 100644
index a08575d58..000000000
Binary files a/docs/img/quickstart/create-secret.png and /dev/null differ
diff --git a/docs/img/quickstart/credentials-setting.png b/docs/img/quickstart/credentials-setting.png
deleted file mode 100644
index d5f8d824b..000000000
Binary files a/docs/img/quickstart/credentials-setting.png and /dev/null differ
diff --git a/docs/img/quickstart/new-workflow.png b/docs/img/quickstart/new-workflow.png
deleted file mode 100644
index 39eba1d32..000000000
Binary files a/docs/img/quickstart/new-workflow.png and /dev/null differ
diff --git a/docs/img/quickstart/run-context.png b/docs/img/quickstart/run-context.png
deleted file mode 100644
index 95b131a82..000000000
Binary files a/docs/img/quickstart/run-context.png and /dev/null differ
diff --git a/docs/img/quickstart/trigger-workflow.png b/docs/img/quickstart/trigger-workflow.png
deleted file mode 100644
index 76406f59c..000000000
Binary files a/docs/img/quickstart/trigger-workflow.png and /dev/null differ
diff --git a/docs/img/fargate-secret-arn.png b/docs/img/secrets/fargate-secret-arn.png
similarity index 100%
rename from docs/img/fargate-secret-arn.png
rename to docs/img/secrets/fargate-secret-arn.png
diff --git a/docs/img/fargate-secrets-manager.png b/docs/img/secrets/fargate-secrets-manager.png
similarity index 100%
rename from docs/img/fargate-secrets-manager.png
rename to docs/img/secrets/fargate-secrets-manager.png
diff --git a/docs/img/google-oauth-client-secrets.png b/docs/img/secrets/google-oauth-client-secrets.png
similarity index 100%
rename from docs/img/google-oauth-client-secrets.png
rename to docs/img/secrets/google-oauth-client-secrets.png
diff --git a/docs/img/google-oauth-consent.png b/docs/img/secrets/google-oauth-consent.png
similarity index 100%
rename from docs/img/google-oauth-consent.png
rename to docs/img/secrets/google-oauth-consent.png
diff --git a/docs/img/signin-page.png b/docs/img/signin-page.png
deleted file mode 100644
index fc4f6649e..000000000
Binary files a/docs/img/signin-page.png and /dev/null differ
diff --git a/docs/img/slack-to-guardduty.jpeg b/docs/img/slack-to-guardduty.jpeg
deleted file mode 100644
index 56b0defef..000000000
Binary files a/docs/img/slack-to-guardduty.jpeg and /dev/null differ
diff --git a/docs/img/trigger-workflow.png b/docs/img/trigger-workflow.png
deleted file mode 100644
index 9331263cc..000000000
Binary files a/docs/img/trigger-workflow.png and /dev/null differ
diff --git a/docs/img/tutorials/control-flow/vt-search-result.png b/docs/img/tutorials/control-flow/vt-search-result.png
new file mode 100644
index 000000000..33a0a7652
Binary files /dev/null and b/docs/img/tutorials/control-flow/vt-search-result.png differ
diff --git a/docs/img/tutorials/quickstart/add-vt-node.png b/docs/img/tutorials/quickstart/add-vt-node.png
new file mode 100644
index 000000000..7bf2a0668
Binary files /dev/null and b/docs/img/tutorials/quickstart/add-vt-node.png differ
diff --git a/docs/img/tutorials/quickstart/commit-workflow.png b/docs/img/tutorials/quickstart/commit-workflow.png
new file mode 100644
index 000000000..028f61b61
Binary files /dev/null and b/docs/img/tutorials/quickstart/commit-workflow.png differ
diff --git a/docs/img/tutorials/quickstart/configure-vt-inputs.png b/docs/img/tutorials/quickstart/configure-vt-inputs.png
new file mode 100644
index 000000000..569b8c343
Binary files /dev/null and b/docs/img/tutorials/quickstart/configure-vt-inputs.png differ
diff --git a/docs/img/tutorials/quickstart/create-new-workflow.png b/docs/img/tutorials/quickstart/create-new-workflow.png
new file mode 100644
index 000000000..a279abd3a
Binary files /dev/null and b/docs/img/tutorials/quickstart/create-new-workflow.png differ
diff --git a/docs/img/tutorials/quickstart/create-secret.png b/docs/img/tutorials/quickstart/create-secret.png
new file mode 100644
index 000000000..1e50bd58e
Binary files /dev/null and b/docs/img/tutorials/quickstart/create-secret.png differ
diff --git a/docs/img/tutorials/quickstart/credentials-setting.png b/docs/img/tutorials/quickstart/credentials-setting.png
new file mode 100644
index 000000000..0d9ee22da
Binary files /dev/null and b/docs/img/tutorials/quickstart/credentials-setting.png differ
diff --git a/docs/img/tutorials/quickstart/rename-workflow.png b/docs/img/tutorials/quickstart/rename-workflow.png
new file mode 100644
index 000000000..8dbf90668
Binary files /dev/null and b/docs/img/tutorials/quickstart/rename-workflow.png differ
diff --git a/docs/img/tutorials/quickstart/signin-page.png b/docs/img/tutorials/quickstart/signin-page.png
new file mode 100644
index 000000000..d9e05a6d0
Binary files /dev/null and b/docs/img/tutorials/quickstart/signin-page.png differ
diff --git a/docs/img/tutorials/quickstart/trigger-workflow.png b/docs/img/tutorials/quickstart/trigger-workflow.png
new file mode 100644
index 000000000..37b6e20e2
Binary files /dev/null and b/docs/img/tutorials/quickstart/trigger-workflow.png differ
diff --git a/docs/img/tutorials/quickstart/view-runs.png b/docs/img/tutorials/quickstart/view-runs.png
new file mode 100644
index 000000000..37e8572d1
Binary files /dev/null and b/docs/img/tutorials/quickstart/view-runs.png differ
diff --git a/docs/img/welcome-page.png b/docs/img/welcome-page.png
deleted file mode 100644
index cf9fb334a..000000000
Binary files a/docs/img/welcome-page.png and /dev/null differ
diff --git a/docs/integrations/introduction.mdx b/docs/integrations/introduction.mdx
deleted file mode 100644
index d87156358..000000000
--- a/docs/integrations/introduction.mdx
+++ /dev/null
@@ -1,14 +0,0 @@
----
-title: Overview
-description: Integrations
----
-
-
-Can't find the integration you're looking for?
-Check out the docs on custom integrations AKA [user-defined functions](/concepts/user-defined-functions).
-
-If you believe the integration will benefit other Tracecat users,
-please consider opening a pull request in the open source repo!
-
-
-Tracecat comes with pre-built integrations to tools such as Crowdstrike, Microsoft Defender, VirusTotal, Slack and more.
diff --git a/docs/integrations/udfs/core_ai_action.mdx b/docs/integrations/udfs/core_ai_action.mdx
deleted file mode 100644
index 044f5b657..000000000
--- a/docs/integrations/udfs/core_ai_action.mdx
+++ /dev/null
@@ -1,92 +0,0 @@
----
-title: AI Action
-description: core.ai_action
----
-
-Call an LLM.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `core.ai_action` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `openai` | `OPENAI_API_KEY` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "additional_config": {
- "anyOf": [
- {
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Additional configuration",
- "title": "Additional Config"
- },
- "execution_context": {
- "anyOf": [
- {
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "The execution context",
- "title": "Execution Context"
- },
- "model": {
- "default": "gpt-4o",
- "description": "The AI Model to use",
- "enum": [
- "gpt-4o",
- "gpt-4-turbo",
- "gpt-4-turbo-preview",
- "gpt-4-0125-preview",
- "gpt-4-vision-preview",
- "gpt-3.5-turbo-0125"
- ],
- "title": "Model",
- "type": "string"
- },
- "prompt": {
- "description": "The prompt to send to the LLM",
- "title": "Prompt",
- "type": "string"
- },
- "system_context": {
- "default": "You will be provided with a body of text and your task is to do exactly as instructed.",
- "description": "The system context",
- "title": "System Context",
- "type": "string"
- }
- },
- "required": [
- "prompt"
- ],
- "title": "CoreAiAction",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{}
-```
-
-
diff --git a/docs/integrations/udfs/core_http_request.mdx b/docs/integrations/udfs/core_http_request.mdx
deleted file mode 100644
index 71261dbf0..000000000
--- a/docs/integrations/udfs/core_http_request.mdx
+++ /dev/null
@@ -1,124 +0,0 @@
----
-title: HTTP Request
-description: core.http_request
----
-
-Perform a HTTP request to a given URL.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `core.http_request` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "headers": {
- "additionalProperties": {
- "type": "string"
- },
- "default": null,
- "description": "HTTP request headers",
- "title": "Headers",
- "type": "object"
- },
- "method": {
- "default": "GET",
- "description": "HTTP request method",
- "enum": [
- "GET",
- "POST",
- "PUT",
- "DELETE"
- ],
- "title": "Method",
- "type": "string"
- },
- "params": {
- "default": null,
- "description": "URL query parameters",
- "title": "Params",
- "type": "object"
- },
- "payload": {
- "anyOf": [
- {
- "type": "object"
- },
- {
- "items": {},
- "type": "array"
- }
- ],
- "default": null,
- "description": "HTTP request payload",
- "title": "Payload"
- },
- "url": {
- "description": "The destination of the HTTP request",
- "title": "Url",
- "type": "string"
- }
- },
- "required": [
- "url"
- ],
- "title": "CoreHttpRequest",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "properties": {
- "data": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "object"
- },
- {
- "items": {},
- "type": "array"
- },
- {
- "type": "null"
- }
- ],
- "title": "Data"
- },
- "headers": {
- "additionalProperties": {
- "type": "string"
- },
- "title": "Headers",
- "type": "object"
- },
- "status_code": {
- "title": "Status Code",
- "type": "integer"
- }
- },
- "required": [
- "status_code",
- "headers",
- "data"
- ],
- "title": "HTTPResponse",
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/core_open_case.mdx b/docs/integrations/udfs/core_open_case.mdx
deleted file mode 100644
index ecedcfe32..000000000
--- a/docs/integrations/udfs/core_open_case.mdx
+++ /dev/null
@@ -1,173 +0,0 @@
----
-title: Open Case
-description: core.open_case
----
-
-Open a new case in the case management system.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `core.open_case` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "$defs": {
- "CaseContext": {
- "properties": {
- "key": {
- "title": "Key",
- "type": "string"
- },
- "value": {
- "title": "Value",
- "type": "string"
- }
- },
- "required": [
- "key",
- "value"
- ],
- "title": "CaseContext",
- "type": "object"
- },
- "Tag": {
- "properties": {
- "tag": {
- "title": "Tag",
- "type": "string"
- },
- "value": {
- "title": "Value",
- "type": "string"
- }
- },
- "required": [
- "tag",
- "value"
- ],
- "title": "Tag",
- "type": "object"
- }
- },
- "additionalProperties": false,
- "properties": {
- "action": {
- "description": "Action to be taken",
- "enum": [
- "ignore",
- "quarantine",
- "informational",
- "sinkhole",
- "active_compromise"
- ],
- "title": "Action",
- "type": "string"
- },
- "case_title": {
- "description": "Title of the case",
- "title": "Case Title",
- "type": "string"
- },
- "context": {
- "anyOf": [
- {
- "items": {
- "$ref": "#/$defs/CaseContext"
- },
- "type": "array"
- },
- {
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "List of case contexts",
- "title": "Context"
- },
- "malice": {
- "description": "Malice type",
- "enum": [
- "malicious",
- "benign"
- ],
- "title": "Malice",
- "type": "string"
- },
- "payload": {
- "description": "Payload of the case",
- "title": "Payload",
- "type": "object"
- },
- "priority": {
- "description": "Priority of the case",
- "enum": [
- "low",
- "medium",
- "high",
- "critical"
- ],
- "title": "Priority",
- "type": "string"
- },
- "status": {
- "description": "Status of the case",
- "enum": [
- "open",
- "closed",
- "in_progress",
- "reported",
- "escalated"
- ],
- "title": "Status",
- "type": "string"
- },
- "tags": {
- "anyOf": [
- {
- "items": {
- "$ref": "#/$defs/Tag"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "List of tags",
- "title": "Tags"
- }
- },
- "required": [
- "case_title",
- "payload",
- "malice",
- "status",
- "priority",
- "action"
- ],
- "title": "CoreOpenCase",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/core_send_email_smtp.mdx b/docs/integrations/udfs/core_send_email_smtp.mdx
deleted file mode 100644
index 7321a30fd..000000000
--- a/docs/integrations/udfs/core_send_email_smtp.mdx
+++ /dev/null
@@ -1,63 +0,0 @@
----
-title: Send Email (SMTP)
-description: core.send_email_smtp
----
-
-Perform a send email action using SMTP.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `core.send_email_smtp` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "body": {
- "title": "Body",
- "type": "string"
- },
- "recipients": {
- "items": {
- "type": "string"
- },
- "title": "Recipients",
- "type": "array"
- },
- "sender": {
- "default": "mail@tracecat.com",
- "title": "Sender",
- "type": "string"
- },
- "subject": {
- "title": "Subject",
- "type": "string"
- }
- },
- "required": [
- "recipients",
- "subject",
- "body"
- ],
- "title": "CoreSendEmailSmtp",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/core_transform_build_reference_table.mdx b/docs/integrations/udfs/core_transform_build_reference_table.mdx
deleted file mode 100644
index 3dd719889..000000000
--- a/docs/integrations/udfs/core_transform_build_reference_table.mdx
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: Build Reference Table
-description: core.transform.build_reference_table
----
-
-Build a reference table from a collection of items.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `core.transform.build_reference_table` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "items": {
- "description": "A collection of items.",
- "items": {},
- "title": "Items",
- "type": "array"
- },
- "key": {
- "description": "The key to index the reference table.",
- "title": "Key",
- "type": "string"
- }
- },
- "required": [
- "items",
- "key"
- ],
- "title": "CoreTransformBuildReferenceTable",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{}
-```
-
-
diff --git a/docs/integrations/udfs/core_transform_filter.mdx b/docs/integrations/udfs/core_transform_filter.mdx
deleted file mode 100644
index 074bdb546..000000000
--- a/docs/integrations/udfs/core_transform_filter.mdx
+++ /dev/null
@@ -1,121 +0,0 @@
----
-title: Filter
-description: core.transform.filter
----
-
-Filter a collection based on a condition.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `core.transform.filter` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "$defs": {
- "FunctionConstraint": {
- "properties": {
- "function": {
- "title": "Function",
- "type": "string"
- },
- "jsonpath": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "title": "Jsonpath"
- }
- },
- "required": [
- "jsonpath",
- "function"
- ],
- "title": "FunctionConstraint",
- "type": "object"
- },
- "OperatorConstraint": {
- "properties": {
- "jsonpath": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "title": "Jsonpath"
- },
- "operator": {
- "title": "Operator",
- "type": "string"
- },
- "target": {
- "title": "Target"
- }
- },
- "required": [
- "jsonpath",
- "operator",
- "target"
- ],
- "title": "OperatorConstraint",
- "type": "object"
- }
- },
- "additionalProperties": false,
- "properties": {
- "constraint": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "items": {},
- "type": "array"
- },
- {
- "$ref": "#/$defs/FunctionConstraint"
- },
- {
- "$ref": "#/$defs/OperatorConstraint"
- }
- ],
- "description": "A constraint to filter the collection.If a list is provided, it will be used as a set filter.If a string is provided, it will be evaluated as a restricted conditional expression. Container items are refereneced by `x` e.g. 'x > 2 and x < 6'",
- "title": "Constraint"
- },
- "items": {
- "description": "A collection of items.",
- "items": {},
- "title": "Items",
- "type": "array"
- }
- },
- "required": [
- "items",
- "constraint"
- ],
- "title": "CoreTransformFilter",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{}
-```
-
-
diff --git a/docs/integrations/udfs/core_transform_reshape.mdx b/docs/integrations/udfs/core_transform_reshape.mdx
deleted file mode 100644
index c35131f63..000000000
--- a/docs/integrations/udfs/core_transform_reshape.mdx
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: Reshape
-description: core.transform.reshape
----
-
-Reshapes the input value to the output. You can use this to reshape a JSON-like structure into another easier to manipulate JSON object.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `core.transform.reshape` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "value": {
- "description": "The value to reshape",
- "title": "Value"
- }
- },
- "required": [
- "value"
- ],
- "title": "CoreTransformReshape",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{}
-```
-
-
diff --git a/docs/integrations/udfs/core_workflow_execute.mdx b/docs/integrations/udfs/core_workflow_execute.mdx
deleted file mode 100644
index f45c0ce13..000000000
--- a/docs/integrations/udfs/core_workflow_execute.mdx
+++ /dev/null
@@ -1,506 +0,0 @@
----
-title: Execute Child Workflow
-description: core.workflow.execute
----
-
-Execute a child workflow. The child workflow inherits the parent's execution context.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `core.workflow.execute` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "batch_size": {
- "default": 16,
- "description": "The number of child workflows to execute in parallel.",
- "title": "Batch Size",
- "type": "integer"
- },
- "fail_strategy": {
- "default": "isolated",
- "description": "Fail strategy to use when a child workflow fails.",
- "enum": [
- "isolated",
- "all"
- ],
- "title": "Fail Strategy",
- "type": "string"
- },
- "loop_strategy": {
- "default": "parallel",
- "description": "The execution strategy to use for the child workflow.",
- "enum": [
- "parallel",
- "batch",
- "sequential"
- ],
- "title": "Loop Strategy",
- "type": "string"
- },
- "trigger_inputs": {
- "description": "The inputs to pass to the child workflow.",
- "title": "Trigger Inputs",
- "type": "object"
- },
- "version": {
- "anyOf": [
- {
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "The version of the child workflow definition, if any.",
- "title": "Version"
- },
- "workflow_id": {
- "description": "The title of the child workflow. ",
- "pattern": "wf-[0-9a-f]{32}",
- "title": "Workflow Id",
- "type": "string"
- }
- },
- "required": [
- "workflow_id",
- "trigger_inputs"
- ],
- "title": "CoreWorkflowExecute",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "$defs": {
- "AccessLevel": {
- "description": "Access control levels for roles.",
- "enum": [
- 0,
- 999
- ],
- "title": "AccessLevel",
- "type": "integer"
- },
- "ActionStatement": {
- "properties": {
- "action": {
- "description": "Action type. Equivalent to the UDF key.",
- "pattern": "^[a-z0-9_.]+$",
- "title": "Action",
- "type": "string"
- },
- "args": {
- "description": "Arguments for the action",
- "title": "Args",
- "type": "object"
- },
- "depends_on": {
- "description": "Task dependencies",
- "items": {
- "type": "string"
- },
- "title": "Depends On",
- "type": "array"
- },
- "description": {
- "default": "",
- "title": "Description",
- "type": "string"
- },
- "for_each": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Iterate over a list of items and run the task for each item.",
- "title": "For Each"
- },
- "id": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "The action ID. If this is populated means there is a corresponding actionin the database `Action` table.",
- "title": "Id"
- },
- "ref": {
- "description": "Unique reference for the task",
- "pattern": "^[a-z0-9_]+$",
- "title": "Ref",
- "type": "string"
- },
- "run_if": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Condition to run the task",
- "title": "Run If"
- }
- },
- "required": [
- "ref",
- "action"
- ],
- "title": "ActionStatement",
- "type": "object"
- },
- "ActionTest": {
- "properties": {
- "enable": {
- "default": true,
- "title": "Enable",
- "type": "boolean"
- },
- "failure": {
- "default": null,
- "description": "Patched failure output",
- "title": "Failure"
- },
- "ref": {
- "description": "Action reference",
- "pattern": "^[a-z0-9_]+$",
- "title": "Ref",
- "type": "string"
- },
- "success": {
- "description": "Patched success output. This can be any data structure.If it's a fsspec file, it will be read and the contents will be used.",
- "title": "Success"
- },
- "validate_args": {
- "default": true,
- "title": "Validate Args",
- "type": "boolean"
- }
- },
- "required": [
- "ref",
- "success"
- ],
- "title": "ActionTest",
- "type": "object"
- },
- "DSLConfig": {
- "properties": {
- "enable_runtime_tests": {
- "default": false,
- "description": "Enable runtime action tests. This is dynamically set on workflow entry.",
- "title": "Enable Runtime Tests",
- "type": "boolean"
- },
- "scheduler": {
- "default": "dynamic",
- "enum": [
- "static",
- "dynamic"
- ],
- "title": "Scheduler",
- "type": "string"
- }
- },
- "title": "DSLConfig",
- "type": "object"
- },
- "DSLEntrypoint": {
- "properties": {
- "expects": {
- "anyOf": [
- {},
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Expected trigger input shape",
- "title": "Expects"
- },
- "ref": {
- "description": "The entrypoint action ref",
- "title": "Ref",
- "type": "string"
- }
- },
- "required": [
- "ref"
- ],
- "title": "DSLEntrypoint",
- "type": "object"
- },
- "DSLInput": {
- "description": "DSL definition for a workflow.\n\nThe difference between this and a normal workflow engine is that here,\nour workflow execution order is defined by the DSL itself, independent\nof a workflow scheduler.\n\nWith a traditional\nThis allows the execution of the workflow to be fully deterministic.",
- "properties": {
- "actions": {
- "items": {
- "$ref": "#/$defs/ActionStatement"
- },
- "title": "Actions",
- "type": "array"
- },
- "config": {
- "$ref": "#/$defs/DSLConfig"
- },
- "description": {
- "title": "Description",
- "type": "string"
- },
- "entrypoint": {
- "$ref": "#/$defs/DSLEntrypoint"
- },
- "inputs": {
- "description": "Static input parameters",
- "title": "Inputs",
- "type": "object"
- },
- "returns": {
- "anyOf": [
- {},
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "The action ref or value to return.",
- "title": "Returns"
- },
- "tests": {
- "description": "Action tests",
- "items": {
- "$ref": "#/$defs/ActionTest"
- },
- "title": "Tests",
- "type": "array"
- },
- "title": {
- "title": "Title",
- "type": "string"
- },
- "triggers": {
- "items": {
- "$ref": "#/$defs/Trigger"
- },
- "title": "Triggers",
- "type": "array"
- }
- },
- "required": [
- "title",
- "description",
- "entrypoint",
- "actions"
- ],
- "title": "DSLInput",
- "type": "object"
- },
- "Role": {
- "description": "The identity and authorization of a user or service.\n\nParams\n------\ntype : Literal[\"user\", \"service\"]\n The type of role.\nuser_id : UUID | None\n The user's ID, or the service's user_id.\n This can be None for internal services, or when a user hasn't been set for the role.\nservice_id : str | None = None\n The service's role name, or None if the role is a user.\n\n\nUser roles\n----------\n- User roles are authenticated via JWT.\n- The `user_id` is the user's JWT 'sub' claim.\n- User roles do not have an associated `service_id`, this must be None.\n\nService roles\n-------------\n- Service roles are authenticated via API key.\n- Used for internal services to authenticate with the API.\n- A service's `user_id` is the user it's acting on behalf of. This can be None for internal services.",
- "properties": {
- "access_level": {
- "allOf": [
- {
- "$ref": "#/$defs/AccessLevel"
- }
- ],
- "default": 0
- },
- "service_id": {
- "enum": [
- "tracecat-runner",
- "tracecat-api",
- "tracecat-cli",
- "tracecat-schedule-runner",
- "tracecat-service"
- ],
- "title": "Service Id",
- "type": "string"
- },
- "type": {
- "enum": [
- "user",
- "service"
- ],
- "title": "Type",
- "type": "string"
- },
- "user_id": {
- "anyOf": [
- {
- "format": "uuid4",
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "title": "User Id"
- },
- "workspace_id": {
- "anyOf": [
- {
- "format": "uuid4",
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "title": "Workspace Id"
- }
- },
- "required": [
- "type",
- "service_id"
- ],
- "title": "Role",
- "type": "object"
- },
- "RunContext": {
- "properties": {
- "wf_exec_id": {
- "anyOf": [
- {
- "pattern": "wf-[0-9a-f]{32}:exec-[\\w-]+",
- "type": "string"
- },
- {
- "pattern": "wf-[0-9a-f]{32}:sch-[0-9a-f]{32}-.*",
- "type": "string"
- }
- ],
- "title": "Wf Exec Id"
- },
- "wf_id": {
- "pattern": "wf-[0-9a-f]{32}",
- "title": "Wf Id",
- "type": "string"
- },
- "wf_run_id": {
- "format": "uuid4",
- "title": "Wf Run Id",
- "type": "string"
- }
- },
- "required": [
- "wf_id",
- "wf_exec_id",
- "wf_run_id"
- ],
- "title": "RunContext",
- "type": "object"
- },
- "Trigger": {
- "properties": {
- "args": {
- "title": "Args",
- "type": "object"
- },
- "ref": {
- "pattern": "^[a-z0-9_]+$",
- "title": "Ref",
- "type": "string"
- },
- "type": {
- "enum": [
- "schedule",
- "webhook"
- ],
- "title": "Type",
- "type": "string"
- }
- },
- "required": [
- "type",
- "ref"
- ],
- "title": "Trigger",
- "type": "object"
- }
- },
- "properties": {
- "dsl": {
- "$ref": "#/$defs/DSLInput"
- },
- "parent_run_context": {
- "anyOf": [
- {
- "$ref": "#/$defs/RunContext"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "role": {
- "$ref": "#/$defs/Role"
- },
- "run_config": {
- "title": "Run Config",
- "type": "object"
- },
- "trigger_inputs": {
- "anyOf": [
- {
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "title": "Trigger Inputs"
- },
- "wf_id": {
- "pattern": "wf-[0-9a-f]{32}",
- "title": "Wf Id",
- "type": "string"
- }
- },
- "required": [
- "role",
- "dsl",
- "wf_id"
- ],
- "title": "DSLRunArgs",
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/etl_extraction_extract_emails.mdx b/docs/integrations/udfs/etl_extraction_extract_emails.mdx
deleted file mode 100644
index d6ad2bb63..000000000
--- a/docs/integrations/udfs/etl_extraction_extract_emails.mdx
+++ /dev/null
@@ -1,58 +0,0 @@
----
-title: Extract emails
-description: etl.extraction.extract_emails
----
-
-Extract unique emails from a list of strings.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `etl.extraction.extract_emails` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "normalize": {
- "default": false,
- "description": "Whether to normalize emails by removing sub-addresses",
- "title": "Normalize",
- "type": "boolean"
- },
- "texts": {
- "description": "The list of strings to extract emails from",
- "items": {
- "type": "string"
- },
- "title": "Texts",
- "type": "array"
- }
- },
- "required": [
- "texts"
- ],
- "title": "EtlExtractionExtractEmails",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "string"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/etl_extraction_extract_ipv4_addresses.mdx b/docs/integrations/udfs/etl_extraction_extract_ipv4_addresses.mdx
deleted file mode 100644
index 59b93bd51..000000000
--- a/docs/integrations/udfs/etl_extraction_extract_ipv4_addresses.mdx
+++ /dev/null
@@ -1,52 +0,0 @@
----
-title: Extract IPv4 addresses
-description: etl.extraction.extract_ipv4_addresses
----
-
-Extract unique IPv4 addresses from a list of strings.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `etl.extraction.extract_ipv4_addresses` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "texts": {
- "description": "The list of strings to extract IP addresses from",
- "items": {
- "type": "string"
- },
- "title": "Texts",
- "type": "array"
- }
- },
- "required": [
- "texts"
- ],
- "title": "EtlExtractionExtractIpv4Addresses",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "string"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/etl_extraction_extract_urls.mdx b/docs/integrations/udfs/etl_extraction_extract_urls.mdx
deleted file mode 100644
index 6c04bfef2..000000000
--- a/docs/integrations/udfs/etl_extraction_extract_urls.mdx
+++ /dev/null
@@ -1,52 +0,0 @@
----
-title: Extract URLs
-description: etl.extraction.extract_urls
----
-
-Extract unique URLs from a list of strings.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `etl.extraction.extract_urls` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "texts": {
- "description": "The list of strings to extract URLs from",
- "items": {
- "type": "string"
- },
- "title": "Texts",
- "type": "array"
- }
- },
- "required": [
- "texts"
- ],
- "title": "EtlExtractionExtractUrls",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "string"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_aws_guardduty_list_guardduty_alerts.mdx b/docs/integrations/udfs/integrations_aws_guardduty_list_guardduty_alerts.mdx
deleted file mode 100644
index 1ae14f8da..000000000
--- a/docs/integrations/udfs/integrations_aws_guardduty_list_guardduty_alerts.mdx
+++ /dev/null
@@ -1,65 +0,0 @@
----
-title: List Amazon GuardDuty alerts
-description: integrations.aws.guardduty.list_guardduty_alerts
----
-
-Fetch Amazon GuardDuty alerts and filter by time range.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.aws.guardduty.list_guardduty_alerts` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `aws_guardduty` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "limit": {
- "default": 5000,
- "description": "Maximum number of alerts to return.",
- "title": "Limit",
- "type": "integer"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsAwsGuarddutyListGuarddutyAlerts",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_chat_slack_list_slack_conversations.mdx b/docs/integrations/udfs/integrations_chat_slack_list_slack_conversations.mdx
deleted file mode 100644
index 5257d3d4e..000000000
--- a/docs/integrations/udfs/integrations_chat_slack_list_slack_conversations.mdx
+++ /dev/null
@@ -1,92 +0,0 @@
----
-title: List Slack Conversation History
-description: integrations.chat.slack.list_slack_conversations
----
-
-Fetch past messages from a Slack channel.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.chat.slack.list_slack_conversations` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `slack` | `SLACK_BOT_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "channel": {
- "description": "The Slack channel ID to fetch the message history from",
- "title": "Channel",
- "type": "string"
- },
- "latest": {
- "anyOf": [
- {
- "format": "date-time",
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "End of time range of messages to include in results",
- "title": "Latest"
- },
- "limit": {
- "anyOf": [
- {
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": 100,
- "description": "The maximum number of messages to retrieve",
- "title": "Limit"
- },
- "oldest": {
- "anyOf": [
- {
- "format": "date-time",
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Start of time range of messages to include in results",
- "title": "Oldest"
- }
- },
- "required": [
- "channel"
- ],
- "title": "IntegrationsChatSlackListSlackConversations",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_chat_slack_list_slack_users.mdx b/docs/integrations/udfs/integrations_chat_slack_list_slack_users.mdx
deleted file mode 100644
index 79d9d6f2a..000000000
--- a/docs/integrations/udfs/integrations_chat_slack_list_slack_users.mdx
+++ /dev/null
@@ -1,59 +0,0 @@
----
-title: List Slack Users
-description: integrations.chat.slack.list_slack_users
----
-
-Fetch Slack users by team ID or list of emails.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.chat.slack.list_slack_users` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `slack` | `SLACK_BOT_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "team_id": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "The Slack team ID to filter users by",
- "title": "Team Id"
- }
- },
- "title": "IntegrationsChatSlackListSlackUsers",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "additionalProperties": {
- "type": "string"
- },
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_chat_slack_post_slack_message.mdx b/docs/integrations/udfs/integrations_chat_slack_post_slack_message.mdx
deleted file mode 100644
index 071064127..000000000
--- a/docs/integrations/udfs/integrations_chat_slack_post_slack_message.mdx
+++ /dev/null
@@ -1,90 +0,0 @@
----
-title: Post Slack Message
-description: integrations.chat.slack.post_slack_message
----
-
-Send Slack message to channel.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.chat.slack.post_slack_message` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `slack` | `SLACK_BOT_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "blocks": {
- "anyOf": [
- {
- "items": {
- "type": "object"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Slack blocks definition",
- "title": "Blocks"
- },
- "channel": {
- "description": "The Slack channel ID to send a message to",
- "title": "Channel",
- "type": "string"
- },
- "text": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "The message text",
- "title": "Text"
- },
- "thread_ts": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "The timestamp of the parent message. Used to create a thread.",
- "title": "Thread Ts"
- }
- },
- "required": [
- "channel"
- ],
- "title": "IntegrationsChatSlackPostSlackMessage",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_chat_slack_tag_slack_users.mdx b/docs/integrations/udfs/integrations_chat_slack_tag_slack_users.mdx
deleted file mode 100644
index 18230dafc..000000000
--- a/docs/integrations/udfs/integrations_chat_slack_tag_slack_users.mdx
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: Tag Slack users in JSON objects
-description: integrations.chat.slack.tag_slack_users
----
-
-Extract emails from list of JSON objects, tags users (if exists), and returns list of JSONs with tagged users.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.chat.slack.tag_slack_users` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `slack` | `SLACK_BOT_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "jsons": {
- "description": "List of JSONs to extract emails from and tag Slack users",
- "items": {
- "type": "object"
- },
- "title": "Jsons",
- "type": "array"
- },
- "team_id": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "The Slack team ID to filter users by",
- "title": "Team Id"
- }
- },
- "required": [
- "jsons"
- ],
- "title": "IntegrationsChatSlackTagSlackUsers",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_crowdstrike_list_crowdstrike_alerts.mdx b/docs/integrations/udfs/integrations_crowdstrike_list_crowdstrike_alerts.mdx
deleted file mode 100644
index 2b8b767aa..000000000
--- a/docs/integrations/udfs/integrations_crowdstrike_list_crowdstrike_alerts.mdx
+++ /dev/null
@@ -1,78 +0,0 @@
----
-title: List Crowdstrike alerts
-description: integrations.crowdstrike.list_crowdstrike_alerts
----
-
-Fetch all Crowdstrike alerts from Falcon SIEM.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.crowdstrike.list_crowdstrike_alerts` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `crowdstrike` | `CROWDSTRIKE_CLIENT_ID`, `CROWDSTRIKE_CLIENT_SECRET` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "filter": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "(Optional) Falcon Query Language (FQL) filter to apply to alerts. If specified, overrides `start_time` and `end_time`.",
- "title": "Filter"
- },
- "limit": {
- "default": 9999,
- "description": "Maximum number of alerts to return.",
- "title": "Limit",
- "type": "integer"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsCrowdstrikeListCrowdstrikeAlerts",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_crowdstrike_list_crowdstrike_detects.mdx b/docs/integrations/udfs/integrations_crowdstrike_list_crowdstrike_detects.mdx
deleted file mode 100644
index bb8a9ec20..000000000
--- a/docs/integrations/udfs/integrations_crowdstrike_list_crowdstrike_detects.mdx
+++ /dev/null
@@ -1,78 +0,0 @@
----
-title: List Crowdstrike detects
-description: integrations.crowdstrike.list_crowdstrike_detects
----
-
-Fetch all Crowdstrike detections from Falcon SIEM.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.crowdstrike.list_crowdstrike_detects` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `crowdstrike` | `CROWDSTRIKE_CLIENT_ID`, `CROWDSTRIKE_CLIENT_SECRET` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "filter": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "(Optional) Falcon Query Language (FQL) filter to apply to alerts. If specified, overrides `start_time` and `end_time`.",
- "title": "Filter"
- },
- "limit": {
- "default": 9999,
- "description": "Maximum number of alerts to return.",
- "title": "Limit",
- "type": "integer"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsCrowdstrikeListCrowdstrikeDetects",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_crowdstrike_update_crowdstrike_alert_status.mdx b/docs/integrations/udfs/integrations_crowdstrike_update_crowdstrike_alert_status.mdx
deleted file mode 100644
index 4ead55527..000000000
--- a/docs/integrations/udfs/integrations_crowdstrike_update_crowdstrike_alert_status.mdx
+++ /dev/null
@@ -1,64 +0,0 @@
----
-title: Update Crowdstrike alert status
-description: integrations.crowdstrike.update_crowdstrike_alert_status
----
-
-Update the status of Crowdstrike alerts.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.crowdstrike.update_crowdstrike_alert_status` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `crowdstrike` | `CROWDSTRIKE_CLIENT_ID`, `CROWDSTRIKE_CLIENT_SECRET` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "alert_ids": {
- "description": "List of alert IDs to update",
- "items": {
- "type": "string"
- },
- "title": "Alert Ids",
- "type": "array"
- },
- "status": {
- "description": "New status for the alerts",
- "enum": [
- "ignored",
- "new",
- "in_progress",
- "true_positive",
- "false_positive"
- ],
- "title": "Status",
- "type": "string"
- }
- },
- "required": [
- "alert_ids",
- "status"
- ],
- "title": "IntegrationsCrowdstrikeUpdateCrowdstrikeAlertStatus",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_crowdstrike_update_crowdstrike_detect_status.mdx b/docs/integrations/udfs/integrations_crowdstrike_update_crowdstrike_detect_status.mdx
deleted file mode 100644
index 862b15233..000000000
--- a/docs/integrations/udfs/integrations_crowdstrike_update_crowdstrike_detect_status.mdx
+++ /dev/null
@@ -1,64 +0,0 @@
----
-title: Update Crowdstrike detect status
-description: integrations.crowdstrike.update_crowdstrike_detect_status
----
-
-Update the status of Crowdstrike detects.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.crowdstrike.update_crowdstrike_detect_status` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `crowdstrike` | `CROWDSTRIKE_CLIENT_ID`, `CROWDSTRIKE_CLIENT_SECRET` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "detection_ids": {
- "description": "List of detect IDs to update",
- "items": {
- "type": "string"
- },
- "title": "Detection Ids",
- "type": "array"
- },
- "status": {
- "description": "New status for the alerts",
- "enum": [
- "ignored",
- "new",
- "in_progress",
- "true_positive",
- "false_positive"
- ],
- "title": "Status",
- "type": "string"
- }
- },
- "required": [
- "detection_ids",
- "status"
- ],
- "title": "IntegrationsCrowdstrikeUpdateCrowdstrikeDetectStatus",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_datadog_list_datadog_alerts.mdx b/docs/integrations/udfs/integrations_datadog_list_datadog_alerts.mdx
deleted file mode 100644
index cf2fe4a84..000000000
--- a/docs/integrations/udfs/integrations_datadog_list_datadog_alerts.mdx
+++ /dev/null
@@ -1,65 +0,0 @@
----
-title: List Datadog SIEM alerts
-description: integrations.datadog.list_datadog_alerts
----
-
-Fetch Datadog SIEM alerts (signals) and filter by time range.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.datadog.list_datadog_alerts` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `datadog` | `DD_APP_KEY`, `DD_API_KEY`, `DD_REGION` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "limit": {
- "default": 1000,
- "description": "The maximum number of alerts to return",
- "title": "Limit",
- "type": "integer"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsDatadogListDatadogAlerts",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_elastic_list_elastic_alerts.mdx b/docs/integrations/udfs/integrations_elastic_list_elastic_alerts.mdx
deleted file mode 100644
index 6aafea5e1..000000000
--- a/docs/integrations/udfs/integrations_elastic_list_elastic_alerts.mdx
+++ /dev/null
@@ -1,65 +0,0 @@
----
-title: List Elastic Security alerts
-description: integrations.elastic.list_elastic_alerts
----
-
-Fetch all alerts from Elastic Security and filter by time range.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.elastic.list_elastic_alerts` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `elastic` | `ELASTIC_API_KEY`, `ELASTIC_API_URL` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "limit": {
- "default": 1000,
- "description": "Maximum number of alerts to return.",
- "title": "Limit",
- "type": "integer"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsElasticListElasticAlerts",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_email_resend_send_email_resend.mdx b/docs/integrations/udfs/integrations_email_resend_send_email_resend.mdx
deleted file mode 100644
index d1d6863d3..000000000
--- a/docs/integrations/udfs/integrations_email_resend_send_email_resend.mdx
+++ /dev/null
@@ -1,70 +0,0 @@
----
-title: Send Email (Resend)
-description: integrations.email.resend.send_email_resend
----
-
-Perform a send email action using Resend.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.email.resend.send_email_resend` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `resend_api_key` | `RESEND_API_KEY` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "body": {
- "title": "Body",
- "type": "string"
- },
- "provider": {
- "const": "resend",
- "default": "resend",
- "title": "Provider"
- },
- "recipients": {
- "items": {
- "type": "string"
- },
- "title": "Recipients",
- "type": "array"
- },
- "sender": {
- "default": "mail@tracecat.com",
- "title": "Sender",
- "type": "string"
- },
- "subject": {
- "title": "Subject",
- "type": "string"
- }
- },
- "required": [
- "recipients",
- "subject",
- "body"
- ],
- "title": "IntegrationsEmailResendSendEmailResend",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_ldap_disable_ad_user.mdx b/docs/integrations/udfs/integrations_ldap_disable_ad_user.mdx
deleted file mode 100644
index abb89401b..000000000
--- a/docs/integrations/udfs/integrations_ldap_disable_ad_user.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Disable AD User
-description: integrations.ldap.disable_ad_user
----
-
-Disable AD user by distinguished name.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.ldap.disable_ad_user` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `ldap` | `LDAP_BIND_DN`, `LDAP_BIND_PASS` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "user_dn": {
- "description": "User distinguished name",
- "title": "User Dn",
- "type": "string"
- }
- },
- "required": [
- "user_dn"
- ],
- "title": "IntegrationsLdapDisableAdUser",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_ldap_enable_ad_user.mdx b/docs/integrations/udfs/integrations_ldap_enable_ad_user.mdx
deleted file mode 100644
index 888b29365..000000000
--- a/docs/integrations/udfs/integrations_ldap_enable_ad_user.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Enable AD User
-description: integrations.ldap.enable_ad_user
----
-
-Enable AD user by distinguished name.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.ldap.enable_ad_user` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `ldap` | `LDAP_BIND_DN`, `LDAP_BIND_PASS` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "user_dn": {
- "description": "User distinguished name",
- "title": "User Dn",
- "type": "string"
- }
- },
- "required": [
- "user_dn"
- ],
- "title": "IntegrationsLdapEnableAdUser",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_ldap_find_ldap_users.mdx b/docs/integrations/udfs/integrations_ldap_find_ldap_users.mdx
deleted file mode 100644
index e822432ec..000000000
--- a/docs/integrations/udfs/integrations_ldap_find_ldap_users.mdx
+++ /dev/null
@@ -1,57 +0,0 @@
----
-title: Find LDAP Users
-description: integrations.ldap.find_ldap_users
----
-
-Find LDAP users by login username or email.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.ldap.find_ldap_users` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `ldap` | `LDAP_BIND_DN`, `LDAP_BIND_PASS` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "base_dn": {
- "description": "Search base DN for querying LDAP",
- "title": "Base Dn",
- "type": "string"
- },
- "username_or_email": {
- "description": "Login username or e-mail to find",
- "title": "Username Or Email",
- "type": "string"
- }
- },
- "required": [
- "username_or_email",
- "base_dn"
- ],
- "title": "IntegrationsLdapFindLdapUsers",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_microsoft_defender_list_defender_cloud_alerts.mdx b/docs/integrations/udfs/integrations_microsoft_defender_list_defender_cloud_alerts.mdx
deleted file mode 100644
index cef1ba7f6..000000000
--- a/docs/integrations/udfs/integrations_microsoft_defender_list_defender_cloud_alerts.mdx
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: List Microsoft Defender for Cloud alerts
-description: integrations.microsoft_defender.list_defender_cloud_alerts
----
-
-Fetch Microsoft Defender for Cloud alerts and filter by time range.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.microsoft_defender.list_defender_cloud_alerts` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `microsoft_defender_cloud` | `MICROSOFT_GRAPH_CLIENT_ID`, `MICROSOFT_GRAPH_CLIENT_SECRET`, `MICROSOFT_GRAPH_TENANT_ID` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "limit": {
- "default": 1000,
- "description": "Maximum number of alerts to return.",
- "title": "Limit",
- "type": "integer"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsMicrosoftDefenderListDefenderCloudAlerts",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_microsoft_defender_list_defender_endpoint_alerts.mdx b/docs/integrations/udfs/integrations_microsoft_defender_list_defender_endpoint_alerts.mdx
deleted file mode 100644
index 454036ebb..000000000
--- a/docs/integrations/udfs/integrations_microsoft_defender_list_defender_endpoint_alerts.mdx
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: List Microsoft Defender for Endpoint alerts
-description: integrations.microsoft_defender.list_defender_endpoint_alerts
----
-
-Fetch all Microsoft Defender for Endpoint alerts and filter by time range.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.microsoft_defender.list_defender_endpoint_alerts` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `microsoft_defender_endpoint` | `MICROSOFT_GRAPH_CLIENT_ID`, `MICROSOFT_GRAPH_CLIENT_SECRET`, `MICROSOFT_GRAPH_TENANT_ID` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "limit": {
- "default": 1000,
- "description": "Maximum number of alerts to return.",
- "title": "Limit",
- "type": "integer"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsMicrosoftDefenderListDefenderEndpointAlerts",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_okta_expire_okta_sessions.mdx b/docs/integrations/udfs/integrations_okta_expire_okta_sessions.mdx
deleted file mode 100644
index 7cf58285b..000000000
--- a/docs/integrations/udfs/integrations_okta_expire_okta_sessions.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Expire Okta sessions
-description: integrations.okta.expire_okta_sessions
----
-
-Expire current Okta sessions for a user.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.okta.expire_okta_sessions` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `okta` | `OKTA_BASE_URL`, `OKTA_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "okta_user_id": {
- "description": "Okta user id to expire sessions for",
- "title": "Okta User Id",
- "type": "string"
- }
- },
- "required": [
- "okta_user_id"
- ],
- "title": "IntegrationsOktaExpireOktaSessions",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "boolean"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_okta_find_okta_users.mdx b/docs/integrations/udfs/integrations_okta_find_okta_users.mdx
deleted file mode 100644
index c69987661..000000000
--- a/docs/integrations/udfs/integrations_okta_find_okta_users.mdx
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: Find Okta Users
-description: integrations.okta.find_okta_users
----
-
-Find Okta users by login username or email.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.okta.find_okta_users` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `okta` | `OKTA_BASE_URL`, `OKTA_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "username_or_email": {
- "description": "Login username or e-mail to find",
- "title": "Username Or Email",
- "type": "string"
- }
- },
- "required": [
- "username_or_email"
- ],
- "title": "IntegrationsOktaFindOktaUsers",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_okta_list_okta_user_events.mdx b/docs/integrations/udfs/integrations_okta_list_okta_user_events.mdx
deleted file mode 100644
index 13dd8182d..000000000
--- a/docs/integrations/udfs/integrations_okta_list_okta_user_events.mdx
+++ /dev/null
@@ -1,71 +0,0 @@
----
-title: List Okta user events
-description: integrations.okta.list_okta_user_events
----
-
-List Okta events for a user.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.okta.list_okta_user_events` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `okta` | `OKTA_BASE_URL`, `OKTA_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "limit": {
- "default": 1000,
- "description": "Maximum number of alerts to return.",
- "title": "Limit",
- "type": "integer"
- },
- "okta_user_id": {
- "description": "Okta user id to list events for.",
- "title": "Okta User Id",
- "type": "string"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "okta_user_id",
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsOktaListOktaUserEvents",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_okta_suspend_okta_user.mdx b/docs/integrations/udfs/integrations_okta_suspend_okta_user.mdx
deleted file mode 100644
index de8154a38..000000000
--- a/docs/integrations/udfs/integrations_okta_suspend_okta_user.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Suspend Okta user
-description: integrations.okta.suspend_okta_user
----
-
-Suspend an Okta user.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.okta.suspend_okta_user` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `okta` | `OKTA_BASE_URL`, `OKTA_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "okta_user_id": {
- "description": "Okta user id to suspend",
- "title": "Okta User Id",
- "type": "string"
- }
- },
- "required": [
- "okta_user_id"
- ],
- "title": "IntegrationsOktaSuspendOktaUser",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "boolean"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_okta_unsuspend_okta_user.mdx b/docs/integrations/udfs/integrations_okta_unsuspend_okta_user.mdx
deleted file mode 100644
index 9e607b1ad..000000000
--- a/docs/integrations/udfs/integrations_okta_unsuspend_okta_user.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Unsuspend Okta user
-description: integrations.okta.unsuspend_okta_user
----
-
-Unsuspend an Okta user.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.okta.unsuspend_okta_user` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `okta` | `OKTA_BASE_URL`, `OKTA_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "okta_user_id": {
- "description": "Okta user id to unsuspend",
- "title": "Okta User Id",
- "type": "string"
- }
- },
- "required": [
- "okta_user_id"
- ],
- "title": "IntegrationsOktaUnsuspendOktaUser",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "boolean"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_sentinel_one_get_sentinel_one_firewall_rule.mdx b/docs/integrations/udfs/integrations_sentinel_one_get_sentinel_one_firewall_rule.mdx
deleted file mode 100644
index 9026d139d..000000000
--- a/docs/integrations/udfs/integrations_sentinel_one_get_sentinel_one_firewall_rule.mdx
+++ /dev/null
@@ -1,64 +0,0 @@
----
-title: Get Sentinel One firewall rule
-description: integrations.sentinel_one.get_sentinel_one_firewall_rule
----
-
-.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.sentinel_one.get_sentinel_one_firewall_rule` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `sentinel_one` | `SENTINEL_ONE_BASE_URL`, `SENTINEL_ONE_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "rule_id": {
- "description": "ID of the rule to get",
- "title": "Rule Id",
- "type": "string"
- },
- "scope_id": {
- "description": "ID of the scope the rule is attached to",
- "title": "Scope Id",
- "type": "string"
- },
- "scope_type": {
- "enum": [
- "accountIds",
- "siteIds",
- "groupIds"
- ],
- "title": "Scope Type",
- "type": "string"
- }
- },
- "required": [
- "rule_id",
- "scope_type",
- "scope_id"
- ],
- "title": "IntegrationsSentinelOneGetSentinelOneFirewallRule",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_sentinel_one_get_sentinelone_agents_by_hostname.mdx b/docs/integrations/udfs/integrations_sentinel_one_get_sentinelone_agents_by_hostname.mdx
deleted file mode 100644
index 2c40abae8..000000000
--- a/docs/integrations/udfs/integrations_sentinel_one_get_sentinelone_agents_by_hostname.mdx
+++ /dev/null
@@ -1,57 +0,0 @@
----
-title: Get Sentinel One agents by hostname
-description: integrations.sentinel_one.get_sentinelone_agents_by_hostname
----
-
-Find Sentinel One agent(s) by hostname.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.sentinel_one.get_sentinelone_agents_by_hostname` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `sentinel_one` | `SENTINEL_ONE_BASE_URL`, `SENTINEL_ONE_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "exact_match": {
- "description": "Exact match only, otherwise partial matches are returned",
- "title": "Exact Match",
- "type": "boolean"
- },
- "hostname": {
- "description": "Hostname to search for",
- "title": "Hostname",
- "type": "string"
- }
- },
- "required": [
- "hostname",
- "exact_match"
- ],
- "title": "IntegrationsSentinelOneGetSentineloneAgentsByHostname",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_sentinel_one_get_sentinelone_agents_by_username.mdx b/docs/integrations/udfs/integrations_sentinel_one_get_sentinelone_agents_by_username.mdx
deleted file mode 100644
index c62784c8b..000000000
--- a/docs/integrations/udfs/integrations_sentinel_one_get_sentinelone_agents_by_username.mdx
+++ /dev/null
@@ -1,57 +0,0 @@
----
-title: Get Sentinel One agents by username
-description: integrations.sentinel_one.get_sentinelone_agents_by_username
----
-
-Find Sentinel One agent(s) by the last used username field.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.sentinel_one.get_sentinelone_agents_by_username` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `sentinel_one` | `SENTINEL_ONE_BASE_URL`, `SENTINEL_ONE_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "exact_match": {
- "description": "Exact match only, otherwise partial matches are returned",
- "title": "Exact Match",
- "type": "boolean"
- },
- "username": {
- "description": "Username to search for",
- "title": "Username",
- "type": "string"
- }
- },
- "required": [
- "username",
- "exact_match"
- ],
- "title": "IntegrationsSentinelOneGetSentineloneAgentsByUsername",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_sentinel_one_isolate_sentinelone_agent.mdx b/docs/integrations/udfs/integrations_sentinel_one_isolate_sentinelone_agent.mdx
deleted file mode 100644
index 0882c8fd8..000000000
--- a/docs/integrations/udfs/integrations_sentinel_one_isolate_sentinelone_agent.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Isolate Sentinel One agent
-description: integrations.sentinel_one.isolate_sentinelone_agent
----
-
-Isolate a Sentinel One agent from the network.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.sentinel_one.isolate_sentinelone_agent` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `sentinel_one` | `SENTINEL_ONE_BASE_URL`, `SENTINEL_ONE_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "agent_id": {
- "description": "ID of the agent to isolate",
- "title": "Agent Id",
- "type": "string"
- }
- },
- "required": [
- "agent_id"
- ],
- "title": "IntegrationsSentinelOneIsolateSentineloneAgent",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_sentinel_one_list_sentinelone_alerts.mdx b/docs/integrations/udfs/integrations_sentinel_one_list_sentinelone_alerts.mdx
deleted file mode 100644
index e66c1a4ab..000000000
--- a/docs/integrations/udfs/integrations_sentinel_one_list_sentinelone_alerts.mdx
+++ /dev/null
@@ -1,65 +0,0 @@
----
-title: List Sentinel One alerts
-description: integrations.sentinel_one.list_sentinelone_alerts
----
-
-Fetch all Sentinel One alerts and filter by time range.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.sentinel_one.list_sentinelone_alerts` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `sentinel_one` | `SENTINEL_ONE_BASE_URL`, `SENTINEL_ONE_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "limit": {
- "default": 1000,
- "description": "Maximum number of alerts to return.",
- "title": "Limit",
- "type": "integer"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsSentinelOneListSentineloneAlerts",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_sentinel_one_unisolate_sentinelone_agent.mdx b/docs/integrations/udfs/integrations_sentinel_one_unisolate_sentinelone_agent.mdx
deleted file mode 100644
index 513d347b7..000000000
--- a/docs/integrations/udfs/integrations_sentinel_one_unisolate_sentinelone_agent.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Unisolate Sentinel One agent
-description: integrations.sentinel_one.unisolate_sentinelone_agent
----
-
-Unisolate a Sentinel One agent from the network.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.sentinel_one.unisolate_sentinelone_agent` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `sentinel_one` | `SENTINEL_ONE_BASE_URL`, `SENTINEL_ONE_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "agent_id": {
- "description": "ID of the agent to unisolate",
- "title": "Agent Id",
- "type": "string"
- }
- },
- "required": [
- "agent_id"
- ],
- "title": "IntegrationsSentinelOneUnisolateSentineloneAgent",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_sentinel_one_update_sentinel_one_firewall_rule.mdx b/docs/integrations/udfs/integrations_sentinel_one_update_sentinel_one_firewall_rule.mdx
deleted file mode 100644
index 3a84a8aa8..000000000
--- a/docs/integrations/udfs/integrations_sentinel_one_update_sentinel_one_firewall_rule.mdx
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: Update Sentinel One firewall rule
-description: integrations.sentinel_one.update_sentinel_one_firewall_rule
----
-
-Update an existing Sentinel One firewall rule.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.sentinel_one.update_sentinel_one_firewall_rule` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `sentinel_one` | `SENTINEL_ONE_BASE_URL`, `SENTINEL_ONE_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "rule_data": {
- "description": "Updated rule data to set",
- "title": "Rule Data",
- "type": "object"
- },
- "rule_id": {
- "description": "Existing rule ID",
- "title": "Rule Id",
- "type": "string"
- }
- },
- "required": [
- "rule_id",
- "rule_data"
- ],
- "title": "IntegrationsSentinelOneUpdateSentinelOneFirewallRule",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_sentinel_one_update_sentinelone_alert_status.mdx b/docs/integrations/udfs/integrations_sentinel_one_update_sentinelone_alert_status.mdx
deleted file mode 100644
index c797c7019..000000000
--- a/docs/integrations/udfs/integrations_sentinel_one_update_sentinelone_alert_status.mdx
+++ /dev/null
@@ -1,63 +0,0 @@
----
-title: Update Sentinel One alert status
-description: integrations.sentinel_one.update_sentinelone_alert_status
----
-
-Update the analyst verdict of Sentinel One alerts.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.sentinel_one.update_sentinelone_alert_status` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `sentinel_one` | `SENTINEL_ONE_BASE_URL`, `SENTINEL_ONE_API_TOKEN` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "alert_ids": {
- "description": "List of alert IDs to update",
- "items": {
- "type": "string"
- },
- "title": "Alert Ids",
- "type": "array"
- },
- "status": {
- "description": "New status for the alerts",
- "enum": [
- "FALSE_POSITIVE",
- "SUSPICIOUS",
- "TRUE_POSITIVE",
- "UNDEFINED"
- ],
- "title": "Status",
- "type": "string"
- }
- },
- "required": [
- "alert_ids",
- "status"
- ],
- "title": "IntegrationsSentinelOneUpdateSentineloneAlertStatus",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_sinks_write_to_database.mdx b/docs/integrations/udfs/integrations_sinks_write_to_database.mdx
deleted file mode 100644
index ee7418c49..000000000
--- a/docs/integrations/udfs/integrations_sinks_write_to_database.mdx
+++ /dev/null
@@ -1,88 +0,0 @@
----
-title: Write to database
-description: integrations.sinks.write_to_database
----
-
-Write list of JSON objects to a database using the ADBC engine.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.sinks.write_to_database` integration.
-
-
-## Secrets
-_No secrets required._
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "data": {
- "description": "The list of JSON objects to write to the database",
- "items": {
- "additionalProperties": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "integer"
- },
- {
- "type": "number"
- },
- {
- "type": "boolean"
- }
- ]
- },
- "type": "object"
- },
- "title": "Data",
- "type": "array"
- },
- "if_table_exists": {
- "description": "The behavior if the table already exists",
- "enum": [
- "append",
- "replace",
- "fail"
- ],
- "title": "If Table Exists",
- "type": "string"
- },
- "table_name": {
- "description": "The name of the table to write to",
- "title": "Table Name",
- "type": "string"
- },
- "uri": {
- "description": "Database URI string",
- "title": "Uri",
- "type": "string"
- }
- },
- "required": [
- "data",
- "table_name",
- "uri",
- "if_table_exists"
- ],
- "title": "IntegrationsSinksWriteToDatabase",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "integer"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_virustotal_analyze_ip_address.mdx b/docs/integrations/udfs/integrations_virustotal_analyze_ip_address.mdx
deleted file mode 100644
index 0ca7ccc9e..000000000
--- a/docs/integrations/udfs/integrations_virustotal_analyze_ip_address.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Analyze IP address
-description: integrations.virustotal.analyze_ip_address
----
-
-Analyze an IP address using VirusTotal.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.virustotal.analyze_ip_address` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `virustotal` | `VIRUSTOTAL_API_KEY` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "ip_address": {
- "description": "The IP address to analyze",
- "title": "Ip Address",
- "type": "string"
- }
- },
- "required": [
- "ip_address"
- ],
- "title": "IntegrationsVirustotalAnalyzeIpAddress",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_virustotal_analyze_malware_sample.mdx b/docs/integrations/udfs/integrations_virustotal_analyze_malware_sample.mdx
deleted file mode 100644
index 849f89165..000000000
--- a/docs/integrations/udfs/integrations_virustotal_analyze_malware_sample.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Analyze malware sample
-description: integrations.virustotal.analyze_malware_sample
----
-
-Analyze a malware sample using VirusTotal.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.virustotal.analyze_malware_sample` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `virustotal` | `VIRUSTOTAL_API_KEY` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "file_hash": {
- "description": "The hash of the malware sample to analyze",
- "title": "File Hash",
- "type": "string"
- }
- },
- "required": [
- "file_hash"
- ],
- "title": "IntegrationsVirustotalAnalyzeMalwareSample",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_virustotal_analyze_url.mdx b/docs/integrations/udfs/integrations_virustotal_analyze_url.mdx
deleted file mode 100644
index 379f3e58b..000000000
--- a/docs/integrations/udfs/integrations_virustotal_analyze_url.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Analyze URL
-description: integrations.virustotal.analyze_url
----
-
-Analyze a URL using VirusTotal.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.virustotal.analyze_url` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `virustotal` | `VIRUSTOTAL_API_KEY` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "url": {
- "description": "The URL to analyze",
- "title": "Url",
- "type": "string"
- }
- },
- "required": [
- "url"
- ],
- "title": "IntegrationsVirustotalAnalyzeUrl",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "type": "object"
-}
-```
-
-
diff --git a/docs/integrations/udfs/integrations_wiz_list_wiz_alerts.mdx b/docs/integrations/udfs/integrations_wiz_list_wiz_alerts.mdx
deleted file mode 100644
index 11bef2da2..000000000
--- a/docs/integrations/udfs/integrations_wiz_list_wiz_alerts.mdx
+++ /dev/null
@@ -1,65 +0,0 @@
----
-title: List Wiz detection findings
-description: integrations.wiz.list_wiz_alerts
----
-
-Fetch Wiz detection findings and filter by time range.
-
-This is the [JSONSchema7](https://json-schema.org/draft-07/json-schema-release-notes) definition for the `integrations.wiz.list_wiz_alerts` integration.
-
-
-## Secrets
-| Name | Keys |
-| --- | --- |
-| `wiz` | `WIZ_API_URL`, `WIZ_AUTH_URL`, `WIZ_CLIENT_ID`, `WIZ_CLIENT_SECRET` |
-
-## Inputs
-
-
-```json JSONSchema7 Definition
-{
- "additionalProperties": false,
- "properties": {
- "end_time": {
- "description": "End time, return alerts created before this time.",
- "format": "date-time",
- "title": "End Time",
- "type": "string"
- },
- "limit": {
- "default": 5000,
- "description": "Maximum number of alerts to return.",
- "title": "Limit",
- "type": "integer"
- },
- "start_time": {
- "description": "Start time, return alerts created after this time.",
- "format": "date-time",
- "title": "Start Time",
- "type": "string"
- }
- },
- "required": [
- "start_time",
- "end_time"
- ],
- "title": "IntegrationsWizListWizAlerts",
- "type": "object"
-}
-```
-
-
-
-## Response
-
-
-```json JSONSchema7 Definition
-{
- "items": {
- "type": "object"
- },
- "type": "array"
-}
-```
-
-
diff --git a/docs/introduction.mdx b/docs/introduction.mdx
index 383050215..65f9cc8b2 100644
--- a/docs/introduction.mdx
+++ b/docs/introduction.mdx
@@ -1,11 +1,11 @@
---
title: What is Tracecat?
-description: An introduction to the Tracecat security automation platform.
+description: Introduction to the Tracecat security automation platform.
---
[Tracecat](https://tracecat.com) is the [open-source](https://github.com/TracecatHQ/tracecat) Tines / Splunk SOAR alternative built for security engineers.
-## Who uses Tracecat?
+## Why Tracecat?
- **Security Operations (SecOps):** Unify playbook development across security analysts and security engineers
- **Security Engineers (SecEng):** Build and maintain complex playbooks using open source integrations and configuration-as-code (YAML)
@@ -15,60 +15,57 @@ description: An introduction to the Tracecat security automation platform.
- Learn how to self-host Tracecat on your own infrastructure.
+ Self-host Tracecat on your own infrastructure (Docker Compose, AWS, Kubernetes).
-
- Build and deploy the classic VirusTotal enrichment playbook in 15 minutes.
+
+ Learn the basics of Tracecat by building a VirusTotal enrichment playbook.
+
+
+ Pre-built integrations and their required secrets.
-## Core Features
+
+## Tutorials
+
+Self-guided tutorials to go from zero-to-hero in Tracecat.
-
- Automated event-driven workflows
+
+ Learn how to use if-conditions in your workflows.
-
- Core building blocks for automations
+
+ Learn how to use pre-built integrations in your workflows.
-
- Built-in secrets manager
+
+ Learn how to combine smaller workflows into a single workflow.
-
- Trigger playbooks given external events
+
+ Learn how to trigger workflows via webhooks or schedules.
-
- Run workflows at regular intervals
+
+ Learn how to add custom integrations to the Actions Registry.
-
- Powerful templating language and formulas
-
-
- Manage cases directly in Tracecat
+
+ Learn how to update Tracecat to the latest version.
-## Developer Features
+## Core Features
-Develop and scale playbooks headlessly (without the UI) using configuration-as-code.
-Write custom integrations in code that automatically convert to no-code.
+Check out the following docs for more details on Tracecat's core features.
-
- Build repeatable playbooks using YAML
+
+ Building blocks for automations and integrations.
+
+
+ Store and retrieve sensitive data.
-
- Add custom integrations with a single Python decorator
+
+ Reference action results and workflow metadata.
-
- Manage workflows and secrets from the terminal
+
+ Powerful utility functions for automations.
diff --git a/docs/mint.json b/docs/mint.json
index 3e38c300e..236a9ac3a 100644
--- a/docs/mint.json
+++ b/docs/mint.json
@@ -38,8 +38,8 @@
},
"tabs": [
{
- "name": "Integrations",
- "url": "integrations"
+ "name": "Cheatsheets",
+ "url": "cheatsheets"
},
{
"name": "API Reference",
@@ -68,7 +68,18 @@
"group": "Getting Started",
"pages": [
"introduction",
- "quickstart"
+ "tutorials/1-quickstart",
+ {
+ "group": "Tutorials",
+ "pages": [
+ "tutorials/2-control-flow",
+ "tutorials/3-actions-registry",
+ "tutorials/4-child-workflows",
+ "tutorials/5-triggers",
+ "tutorials/6-custom-integrations",
+ "tutorials/updating"
+ ]
+ }
]
},
{
@@ -87,31 +98,25 @@
"pages": [
"self-hosting/authentication/introduction",
"self-hosting/authentication/basic",
- "self-hosting/authentication/google"
+ "self-hosting/authentication/google",
+ "self-hosting/authentication/okta"
]
- },
- "self-hosting/external-facing-webhooks",
- "self-hosting/updating"
+ }
]
},
{
"group": "Core Features",
"pages": [
- "concepts/workflows",
- "concepts/actions",
- "concepts/secrets",
- "concepts/webhooks",
- "concepts/schedules",
- "concepts/expressions",
- "concepts/case-management"
+ "platform/actions",
+ "platform/secrets",
+ "platform/expressions"
]
},
{
- "group": "Developer Features",
+ "group": "Cheatsheets",
"pages": [
- "concepts/user-defined-functions",
- "concepts/workflow-definitions",
- "concepts/command-line-interface"
+ "cheatsheets/functions",
+ "cheatsheets/integrations"
]
},
{
@@ -262,184 +267,6 @@
]
}
]
- },
- {
- "group": "Integrations",
- "pages": [
- "integrations/introduction",
- "integrations/secrets_cheatsheet",
- "integrations/expressions"
- ]
- },
- {
- "group": "Schemas",
- "pages": [
- {
- "group": "core",
- "pages": [
- "integrations/udfs/core_ai_action",
- "integrations/udfs/core_http_request",
- "integrations/udfs/core_open_case",
- "integrations/udfs/core_send_email_smtp",
- {
- "group": "transform",
- "pages": [
- "integrations/udfs/core_transform_build_reference_table",
- "integrations/udfs/core_transform_filter",
- "integrations/udfs/core_transform_reshape"
- ]
- },
- {
- "group": "workflow",
- "pages": [
- "integrations/udfs/core_workflow_execute"
- ]
- }
- ]
- },
- {
- "group": "etl",
- "pages": [
- {
- "group": "extraction",
- "pages": [
- "integrations/udfs/etl_extraction_extract_emails",
- "integrations/udfs/etl_extraction_extract_ipv4_addresses",
- "integrations/udfs/etl_extraction_extract_urls"
- ]
- }
- ]
- },
- {
- "group": "example",
- "pages": [
- "integrations/udfs/example_add",
- "integrations/udfs/example_another_function",
- "integrations/udfs/example_my_function",
- "integrations/udfs/example_passthrough"
- ]
- },
- {
- "group": "integrations",
- "pages": [
- {
- "group": "aws",
- "pages": [
- {
- "group": "guardduty",
- "pages": [
- "integrations/udfs/integrations_aws_guardduty_list_guardduty_alerts"
- ]
- }
- ]
- },
- {
- "group": "chat",
- "pages": [
- {
- "group": "slack",
- "pages": [
- "integrations/udfs/integrations_chat_slack_list_slack_conversations",
- "integrations/udfs/integrations_chat_slack_list_slack_users",
- "integrations/udfs/integrations_chat_slack_post_slack_message",
- "integrations/udfs/integrations_chat_slack_tag_slack_users"
- ]
- }
- ]
- },
- {
- "group": "crowdstrike",
- "pages": [
- "integrations/udfs/integrations_crowdstrike_list_crowdstrike_alerts",
- "integrations/udfs/integrations_crowdstrike_list_crowdstrike_detects",
- "integrations/udfs/integrations_crowdstrike_update_crowdstrike_alert_status",
- "integrations/udfs/integrations_crowdstrike_update_crowdstrike_detect_status"
- ]
- },
- {
- "group": "datadog",
- "pages": [
- "integrations/udfs/integrations_datadog_list_datadog_alerts"
- ]
- },
- {
- "group": "elastic",
- "pages": [
- "integrations/udfs/integrations_elastic_list_elastic_alerts"
- ]
- },
- {
- "group": "email",
- "pages": [
- {
- "group": "resend",
- "pages": [
- "integrations/udfs/integrations_email_resend_send_email_resend"
- ]
- }
- ]
- },
- {
- "group": "ldap",
- "pages": [
- "integrations/udfs/integrations_ldap_disable_ad_user",
- "integrations/udfs/integrations_ldap_enable_ad_user",
- "integrations/udfs/integrations_ldap_find_ldap_users"
- ]
- },
- {
- "group": "microsoft_defender",
- "pages": [
- "integrations/udfs/integrations_microsoft_defender_list_defender_cloud_alerts",
- "integrations/udfs/integrations_microsoft_defender_list_defender_endpoint_alerts"
- ]
- },
- {
- "group": "okta",
- "pages": [
- "integrations/udfs/integrations_okta_expire_okta_sessions",
- "integrations/udfs/integrations_okta_find_okta_users",
- "integrations/udfs/integrations_okta_list_okta_user_events",
- "integrations/udfs/integrations_okta_suspend_okta_user",
- "integrations/udfs/integrations_okta_unsuspend_okta_user"
- ]
- },
- {
- "group": "sentinel_one",
- "pages": [
- "integrations/udfs/integrations_sentinel_one_get_sentinel_one_firewall_rule",
- "integrations/udfs/integrations_sentinel_one_get_sentinelone_agents_by_hostname",
- "integrations/udfs/integrations_sentinel_one_get_sentinelone_agents_by_username",
- "integrations/udfs/integrations_sentinel_one_isolate_sentinelone_agent",
- "integrations/udfs/integrations_sentinel_one_list_sentinelone_alerts",
- "integrations/udfs/integrations_sentinel_one_unisolate_sentinelone_agent",
- "integrations/udfs/integrations_sentinel_one_update_sentinel_one_firewall_rule",
- "integrations/udfs/integrations_sentinel_one_update_sentinelone_alert_status"
- ]
- },
- {
- "group": "sinks",
- "pages": [
- "integrations/udfs/integrations_sinks_write_to_database"
- ]
- },
- {
- "group": "virustotal",
- "pages": [
- "integrations/udfs/integrations_virustotal_analyze_ip_address",
- "integrations/udfs/integrations_virustotal_analyze_malware_sample",
- "integrations/udfs/integrations_virustotal_analyze_url"
- ]
- },
- {
- "group": "wiz",
- "pages": [
- "integrations/udfs/integrations_wiz_list_wiz_alerts"
- ]
- }
- ]
- }
- ]
}
],
"footerSocials": {
diff --git a/docs/platform/actions.mdx b/docs/platform/actions.mdx
new file mode 100644
index 000000000..3bd961ac2
--- /dev/null
+++ b/docs/platform/actions.mdx
@@ -0,0 +1,92 @@
+---
+title: Actions
+description: Building blocks for automations
+---
+
+
+ Check out the [Actions Registry](/tutorials/3-actions-registry) tutorial for a hands-on guide.
+
+
+Actions are steps in your workflows.
+Connect them together to create automations.
+Outputs from upstream actions can be referenced as inputs for downstream actions.
+
+## Success / Error Paths
+
+## Action Results
+
+
+ Actions results are referenced using [JSONPath](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-01.html) syntax.
+
+
+To retrieve the output from an action, use the following expression syntax:
+
+```yaml
+ACTIONS..result.
+```
+
+The action reference is a sluggified version of the action's name.
+You can quickly copy the reference for an action by clicking the icon next to the action's name in the node:
+
+
+
+## Action Types
+
+There are two types of actions:
+
+- **User-Defined Function (UDF)**: A Python function turned into a referencable action.
+- **Action Template**: A YAML template of referencable actions (UDFs and other action templates) that can be used to create new actions.
+
+### Action Templates
+
+Action templates are YAML configuration-as-code templates similar to GitHub Actions workflows.
+We recommend using **Action Templates** over Python UDFswhenever possible.
+
+ - Templates are easier to maintain and update across workflows
+ - Templates, unlike UDFs, can be cloned and editted directly in the UI.
+
+For example, the action template for the **Search URL with VirusTotal** integration is as follows:
+
+```yaml
+type: action
+definition:
+ title: Search URL with VirusTotal
+ description: Get threat intel report for a URL from VirusTotal.
+ display_group: VirusTotal
+ namespace: integrations.virustotal
+ name: search_url
+ secrets:
+ - name: virustotal
+ keys: ["VIRUSTOTAL_API_KEY"]
+ expects:
+ url:
+ type: str
+ description: The URL to search
+ steps:
+ - ref: search_url
+ action: core.http_request
+ args:
+ url: https://www.virustotal.com/api/v3/urls/${{ FN.to_base64(inputs.url) }}
+ method: GET
+ headers:
+ x-apikey: ${{ SECRETS.virustotal.VIRUSTOTAL_API_KEY }}
+ returns: ${{ steps.search_url.result }}
+```
+
+We open sourced action templates for every pre-built integrations.
+Check them out in Tracecat's public repository [here](https://github.com/TracecatHQ/tracecat/tree/main/registry/tracecat_registry/templates).
+
+### User-Defined Functions
+
+User-defined functions (UDFs) are Python functions that are automatically converted into no-code actions.
+Find out how to create your own UDFs in the [Custom Integrations](/tutorials/6-custom-integrations) tutorial.
+
+## Integrations
+
+Tracecat comes with pre-built integrations for many popular security tools.
+A list of supported tools can be found in the [integrations cheatsheet](/cheatsheets/integrations).
+
+
+ Integrations are not automatically updated when you update the Tracecat version.
+ You will need to manually sync the Tracecat registry repository from the **Action Registry** page.
+
diff --git a/docs/platform/expressions.mdx b/docs/platform/expressions.mdx
new file mode 100644
index 000000000..cef97a2e5
--- /dev/null
+++ b/docs/platform/expressions.mdx
@@ -0,0 +1,178 @@
+---
+title: Expressions
+description: Reference action results and workflow metadata in your workflows
+---
+
+Expressions are a way to reference data in your workflows.
+To use an expression, you must wrap an [expression context](/platform/expressions#expression-contexts) around:
+
+```yaml
+${{ }}
+```
+
+Expressions are evaluated into values before the start of each action run.
+Expressions are primarily used within action inputs to reference and manipulate data.
+
+## Expression Contexts
+
+Tracecat comes with five expression context types:
+
+| Prefix | Expression syntax | Description |
+| --------- | ----------------------------------- | --------------------------------------- |
+| `ACTIONS` | `ACTIONS..result.` | Reference the result of an action |
+| `TRIGGER` | `TRIGGER.` | Reference data from the webhook |
+| `SECRETS` | `SECRETS..` | Reference a secret |
+| `FN` | `FN.(, , ...)` | Call a function |
+| `VARS` | `VARS.` | Reference fixed workflow variables |
+
+
+ We use dot notation and JSONPath to access specific data in a particular context.
+ For example, `ACTIONS.my_action.result.data.items` selects the `items` field from a nested JSON object returned by the `my_action` action.
+
+
+### Actions
+
+Use the `ACTIONS` prefix to reference the result of an action.
+
+
+
+Assume an action `welcome_user` returns the following JSON object:
+
+```json
+{"message": "hello world"}
+```
+
+This expression will return the string `hello world`:
+
+```php
+${{ ACTIONS.welcome_user.result.data.message }}
+```
+
+
+### Trigger
+
+Workflows can be triggered via webhook, manual trigger, or the `Execute Child Workflow` action.
+Use the `TRIGGER` prefix to reference the data from the trigger as a JSON object.
+
+```php
+${{ TRIGGER. }}
+```
+
+
+
+Given a workflow with a live webhook, the following curl command will send the JSON payload `{"data": {"name": "John", "age": 30}}` and trigger the workflow:
+
+```bash
+export WEBHOOK_URL=https://tracecat.com/api/webhooks//
+curl -X POST $WEBHOOK_URL \
+ -H "Content-Type: application/json" \
+ -d '{"data": {"name": "John", "age": 30}}'
+```
+
+The following expression will return the string `John`:
+
+```php
+${{ TRIGGER.data.name }}
+```
+
+
+
+### Secrets
+
+Secrets stored in the secrets manager can be accessed using the `SECRETS` prefix:
+
+```php
+${{ SECRETS.. }}
+```
+
+### Functions
+
+
+ Check out the functions [cheatsheet](/cheatsheets/functions) for a list of available functions.
+
+
+Use functions to manipulate data. Functions are called using the `FN` prefix.
+
+
+This expression will return the boolean value `true`:
+
+```php!
+${{ FN.contains("a", ["a", "b", "c"]) }}
+```
+
+
+### Variables
+
+
+ Variables used to be called "static inputs" with the `INPUTS` prefix prior to version 0.14.
+
+
+Variables are accessed using the `VARS` prefix:
+
+```php
+${{ VARS. }}
+```
+
+
+
+Let's say the workflow has a static input defined with the key `api_url` and the value `https://example.com/api`.
+
+This expression will return the string `https://example.com/api`:
+
+```php
+${{ VARS.api_url }}
+```
+
+
+## Operators
+
+
+ Check out the operators [cheatsheet](/cheatsheets/functions#operators) for the full list of supported operators.
+
+
+We support standard operators (`+`, `-`, `*`, `/`) for all Pythonobject types (e.g. `int`, `float`, `str`, `datetime`, `timedelta`, `list`, `dict`).
+
+
+
+This expression will return the integer value 3:
+
+```php
+${{ 1 + 2 }}
+```
+
+And the following expression will return the string `hello world`:
+
+```php
+${{ "hello " + "world" }}
+```
+
+
+## Typecasting
+
+We also support casting expressions into different data types with the following syntax:
+
+
+```php Inline
+${{ int() }}
+```
+
+```php Trailing
+${{ -> int }}
+```
+
+
+Supported typecasts:
+
+| Data Type | Behavior |
+|-----------|----------|
+| int | Python `int` |
+| float | Python `float` |
+| str | Python `str` |
+| datetime | Custom `datetime` - parses ISO 8601 datetime strings |
+| bool | Custom `bool` - true for any truthy value, `1`, or upper/lower case `true` |
+
+
+
+Given an ISO 8601 datetime string, `${{ "2024-01-01T00:00:00Z" -> datetime }}` and `${{ datetime("2024-01-01T00:00:00Z") }}` will both return the datetime object `2024-01-01 00:00:00`.
+
+
diff --git a/docs/platform/secrets.mdx b/docs/platform/secrets.mdx
new file mode 100644
index 000000000..30653f0fe
--- /dev/null
+++ b/docs/platform/secrets.mdx
@@ -0,0 +1,86 @@
+---
+title: Secrets
+description: Store and retrieve sensitive data
+---
+
+Tracecat comes with a build-in secrets manager.
+This allows you to store and retrieve sensitive data without exposing the value in plaintext.
+Secrets are encrypted at rest and stored in the database.
+
+## Storing secrets
+
+Secrets are scoped to a workspace. To add a secret, navigate to the **Credentials** page and click on the **Create Secret** button.
+
+## Retrieving secrets in workflows
+
+To get a secret and use it in an action input, use the `SECRETS..` syntax.
+
+Tracecat will automatically replace the expression with the secret value at runtime.
+Retrieved secrets are deleted from memory after the workflow run completes.
+
+## Integrations and secrets
+
+
+ Check out the [Integrations](/platform/integrations) page for a list of pre-built integrations and their required secrets.
+
+
+Pre-built integrations require a specific secret name and required keys.
+For example, the VirusTotal integration requires a secret with the name `virustotal` and the key `VIRUSTOTAL_API_KEY`.
+
+Different integrations may require different required and optional keys.
+For example, Tracecat's AWS integration is configured with the following secret with optional keys:
+
+```python
+aws_secret = RegistrySecret(
+ name="aws",
+ optional_keys=[
+ # Access key-based authentication
+ "AWS_ACCESS_KEY_ID",
+ "AWS_SECRET_ACCESS_KEY",
+ "AWS_REGION",
+ # Role-based authentication
+ "AWS_ROLE_ARN",
+ "AWS_ROLE_SESSION_NAME",
+ # Profile-based authentication
+ "AWS_PROFILE_NAME",
+ ]
+)
+```
+
+Check out the [Quickstart](/tutorials/1-quickstart) tutorial for a step-by-step example of the concepts discussed above.
+
+## Organization-level secrets
+
+Tracecat also supports organization-level secrets that are accessible to all workspaces within an organization.
+To create an organization-level secret, navigate to the **Organization** page and click on the **Create Secret** button.
+
+## Multi-tenant secrets
+
+A common use case is to have different sets of the same secret for different tenants or environments.
+For example, an MDR provider will likely have different Crowdstrike tenant IDs for each customer.
+
+Use Tracecat's secrets manager and child workflows to create and retrieve multi-tenant secrets.
+
+## Example: Multi-account AWS integration
+
+
+
+ Create a multi-tenant secret for an integration by specifying the environment key.
+ The secret name and keys (e.g. `aws` and `AWS_ROLE_ARN`) remain the same.
+
+ If no environment key is specified, the environment key defaults to `default`.
+
+
+ Let's assume you have a child workflow that retrieves GuardDuty detector IDs for a specific AWS account.
+ You have multiple sets of `AWS_ROLE_ARN`, one for each account:
+
+ `arn:aws:iam::{account_id}:role/ListGuardDutyDetectors`
+
+ Given a list of AWS account IDs configured in the parent workflow's static inputs,
+ select the `Execute Child Workflow` action and configure it with the following inputs:
+
+ ```yaml
+ environment: ${{ STATIC.environment }}
+ ```
+
+
diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx
deleted file mode 100644
index 907fa083c..000000000
--- a/docs/quickstart.mdx
+++ /dev/null
@@ -1,96 +0,0 @@
----
-title: Quickstart
-description: Build and deploy the classic VirusTotal enrichment playbook in 15 minutes.
----
-
-
- If you haven't installed Tracecat yet, please check out our [self-hosting
- docs](/self-hosting/introduction) for step-by-step deployment instructions.
-
-
-## Introduction
-
-By the end of this quickstart, you will:
-
-- Create a new workflow
-- Add a secret credential that allows Tracecat to access the VirusTotal API
-- Use integrations to automate a simple threat enrichment playbook,
- learn to work with Tracecat's built-in case management system,
- and run the workflow live.
-
-
-
-Let's get started!
-
-## Prerequisites
-
-- VirusTotal API key. You can obtain one for free from the [VirusTotal website](https://www.virustotal.com/gui/my-apikey).
-
-## Tutorial
-
-
-
-
- If you are working with a brand new Tracecat deployment, you can find the default admin user's email and password in the [authentication docs](/self-hosting/authentication/introduction).
-
- 
-
-
- 
-
-
- Rename the workflow and save the changes by clicking on the save button.
- 
-
-
- From the trigger action, search and select the VirusTotal **Search URL with VirusTotal** integration.
- 
-
-
-
- Tracecat comes with a powerful templating language called "expressions" to manipulate data directly in action inputs.
- You can find out more [here in our docs](/concepts/expressions).
-
- Use expressions and [JSONPath match syntax](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-01.html) to select data from the webhook trigger.
-
- Fill in inputs with the following:
-
- ```yaml
- url: ${{ FN.to_base64(TRIGGER.url_input) }}
- ```
-
- You'll need to Base64 encode the URL input using a the `to_base64` function.
-
- 
-
- Make sure to save the action inputs by clicking on the **Save** button at the top right of the action panel.
-
-
- Add your VirusTotal API key to workspace secrets.
- For the integration to work, you'll need to name the secret `virustotal` and assign your API token to a `VIRUSTOTAL_API_KEY` secret key.
- 
- 
-
-
- This publishes a live version of your workflow.
- 
-
-
- You can now trigger the workflow with a JSON payload directly from the UI.
- For this demo, we use the following sample payload:
-
- ```json
- {"url_input": "https://crowdstrikebluescreen.com"}
- ```
- 
-
-
- Every workflow run comes with context about every step executed in the workflow.
- You can view this information by switching to the **Runs** tab.
- 
-
-
- 🎉 Congratulations on running your first security workflow in Tracecat!
- Come join us on [Discord](https://discord.gg/n3GF4qxFU8) to discuss new playbook and integration ideas.
-
-
diff --git a/docs/self-hosting/authentication/google.mdx b/docs/self-hosting/authentication/google.mdx
index 81126569f..bc587d00c 100644
--- a/docs/self-hosting/authentication/google.mdx
+++ b/docs/self-hosting/authentication/google.mdx
@@ -1,5 +1,5 @@
---
-title: Google OAuth SSO
+title: Google OAuth
description: Learn how to authenticate into Tracecat using Google OAuth.
---
@@ -27,7 +27,7 @@ TRACECAT__AUTH_TYPES=google_oauth
For the local Docker Compose deployment, it'll be `http://localhost`.
3. Set the **Authorized redirect URIs** to: `/auth/oauth/callback`.
- 
+ 
@@ -35,7 +35,7 @@ TRACECAT__AUTH_TYPES=google_oauth
1. Under the **OAuth 2.0 Client IDs** section, select the app you created in the previous step.
2. You will now see the following **Additional Information** on the right hand side of the screen.
- 
+ 
3. Copy the **Client ID** and **Client secret** in a secure location for storing secrets.
diff --git a/docs/self-hosting/authentication/okta.mdx b/docs/self-hosting/authentication/okta.mdx
new file mode 100644
index 000000000..a9969b4d7
--- /dev/null
+++ b/docs/self-hosting/authentication/okta.mdx
@@ -0,0 +1,43 @@
+---
+title: SAML SSO
+description: Learn how to authenticate into Tracecat with Okta SAML SSO.
+---
+
+
+ Even though this guide uses Okta as an example, you can follow this guide to configure SSO for any identity provider (IdP) that supports the SAML 2.0 protocol.
+
+
+## Configuration
+
+In your `.env` file, make sure you have the following value set.
+
+```bash
+TRACECAT__AUTH_TYPES=sso
+```
+
+## Prerequisites
+
+- Create an Okta account. You can sign up for a 30-day free trial [here](https://www.okta.com/free-trial/).
+
+## Instructions
+
+
+
+ Go to **Applications** and select **Add Application**.
+ Select **SAML 2.0** and click on **Create**.
+
+
+ Set the following environment variables in your `.env` file:
+ - `SAML_IDP_ENTITY_ID`: Okta entity ID
+ - `SAML_IDP_REDIRECT_URL`: Okta redirect URL
+ - `SAML_IDP_CERTIFICATE`: Okta SAML X.509 certificate as text
+ - `SAML_IDP_METADATA_URL`: Okta metadata URL
+
+
+ Restart Tracecat to apply the changes.
+
+
+ Navigate to your Tracecat instance and click on the **Login** button.
+ You should be redirected to Okta for authentication.
+
+
diff --git a/docs/self-hosting/deployment-options/aws-ecs.mdx b/docs/self-hosting/deployment-options/aws-ecs.mdx
index d3923ded4..dfcaab22d 100644
--- a/docs/self-hosting/deployment-options/aws-ecs.mdx
+++ b/docs/self-hosting/deployment-options/aws-ecs.mdx
@@ -29,8 +29,9 @@ please reach out to [founders@tracecat.com](mailto:founders@tracecat.com) for he
Download installation files from the Tracecat GitHub repo: https://github.com/TracecatHQ/tracecat/tree/main/deployments/aws/fargate
- Tracecat relies on three symmetric encryption keys (`TRACECAT__DB_ENCRYPTION_KEY`, `TRACECAT__SERVICE_KEY`, `TRACECAT__SIGNING_SECRET`)
- to sign and encrypt secrets within the application.
+ Tracecat relies on three symmetric encryption keys (`TRACECAT__DB_ENCRYPTION_KEY`, `TRACECAT__SERVICE_KEY`, `TRACECAT__SIGNING_SECRET`) to sign and encrypt secrets within the application.
+
+ 
The service key and signing secret are random 32-byte hexadecial strings generated by the `openssl` CLI tool.
The database encryption key is created using the `cryptography` Python library, which is run in Docker.
@@ -48,7 +49,7 @@ please reach out to [founders@tracecat.com](mailto:founders@tracecat.com) for he
You will need these ARNs to pass into the Terraform stack as variables.
You can find the ARNs in the web console:
- 
+ 
Initialize Terraform and deploy the stack by running the following commands:
diff --git a/docs/self-hosting/external-facing-webhooks.mdx b/docs/self-hosting/external-facing-webhooks.mdx
deleted file mode 100644
index f1472d18f..000000000
--- a/docs/self-hosting/external-facing-webhooks.mdx
+++ /dev/null
@@ -1,14 +0,0 @@
----
-title: External Facing Webhooks
-description: Securely expose webhooks to the internet and receive external events.
----
-
-
-Webhooks in the [docker compose](/self-hosting/deployment-options/docker-compose) deployment are not exposed to the internet by default.
-If you wish to expose your webhooks to the internet, you can use a reverse tunnel like [ngrok](https://ngrok.com/) or [bore](https://github.com/ekzhang/bore).
-
-
-This section is under construction 🚧.
-We recently made changes to Tracecat's networking setup and have yet to update these docs.
-
-In the meantime, if you need help setting up `ngrok` or `bore`, please let us know on [Discord](https://discord.gg/n3GF4qxFU8)!
\ No newline at end of file
diff --git a/docs/tutorials/1-quickstart.mdx b/docs/tutorials/1-quickstart.mdx
new file mode 100644
index 000000000..b0e88c598
--- /dev/null
+++ b/docs/tutorials/1-quickstart.mdx
@@ -0,0 +1,109 @@
+---
+title: Quickstart
+description: Learn Tracecat basics by building the classic VirusTotal enrichment playbook.
+---
+
+
+ If you haven't installed Tracecat yet, please check out our [self-hosting
+ docs](/self-hosting/introduction) for step-by-step deployment instructions.
+
+
+## Goals
+
+By the end of this quickstart, you will learn how to:
+
+- Create a new workflow
+- Add secrets to your workspace
+- Add an action to your workflow (e.g. search a URL with VirusTotal)
+- Manually trigger the workflow
+
+Let's get started!
+
+## Prerequisites
+
+- VirusTotal API key. You can obtain one for free from the [VirusTotal website](https://www.virustotal.com/gui/my-apikey).
+
+## Tutorial
+
+
+
+
+ The default admin user's email and password is configured on initial deployment.
+ You can find out more about authentication in our [self-hosting docs](/self-hosting/authentication/introduction).
+
+ 
+
+
+ 
+
+
+ Click onto the canvas to access workflow settings.
+ Rename the workflow and save the changes by clicking on the save button.
+ 
+
+
+ From the trigger action, search and select the VirusTotal **Search URL with VirusTotal** integration.
+ 
+
+
+
+ Tracecat comes with a powerful templating language called "expressions" and [JSONPath syntax](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-01.html) to reference results from upstream actions.
+
+ Find out more about expressions in our [docs](/platform/expressions).
+
+ Pass data from the trigger into the VirusTotal action by filling in the inputs with the following expression:
+
+ ```yaml
+ url: ${{ TRIGGER.url }}
+ ```
+
+ 
+
+ Make sure to save the action inputs by clicking on the **Save** button at the top right of the action panel.
+
+
+ Add your VirusTotal API key to workspace secrets.
+ For the integration to work, you'll need to name the secret `virustotal` and assign your API token to a `VIRUSTOTAL_API_KEY` secret key.
+ 
+ 
+
+
+ Pre-built integrations in Tracecat come configured with a specific secret name and required keys.
+ Find out how integrations and secrets work in our [docs](/platform/secrets).
+
+
+
+ This saves a live version of your workflow.
+ Workflows cannot be run until they are committed.
+ 
+
+
+ Let's test this workflow with a JSON payload directly from the UI.
+ For this demo, we use the following sample payload:
+ ```json
+ {"url": "https://crowdstrikebluescreen.com"}
+ ```
+ 
+
+
+ You can monitor workflow runs and action outputs by switching to the **Runs** tab.
+ 
+
+
+ 🎉 Congratulations on running your first security workflow in Tracecat!
+
+
+
+## Next Steps
+
+Learn how to use Tracecat's most powerful features in four self-paced tutorials:
+
+- Define **if-conditions** in your workflows. View the [tutorial](/tutorials/2-control-flow).
+- **Actions Registry** to manage integrations. View the [tutorial](/tutorials/3-actions-registry).
+- **Secrets** to manage sensitive data for actions. View the [docs](/platform/secrets).
+
+Check out the following cheatsheets for a list of Tracecat's integrations and utilities:
+
+- **Expressions** to reference data in action inputs. View the [docs](/platform/expressions).
+- **Prebuilt integrations** and their required secrets. View the [cheatsheet](/cheatsheets/integrations).
+- **Functions** to manipulate data. View a list of available functions in the [cheatsheet](/cheatsheets/functions).
diff --git a/docs/tutorials/2-control-flow.mdx b/docs/tutorials/2-control-flow.mdx
new file mode 100644
index 000000000..330c4a8a0
--- /dev/null
+++ b/docs/tutorials/2-control-flow.mdx
@@ -0,0 +1,79 @@
+---
+title: Control Flow
+description: Learn how to use if-conditions in your workflows.
+---
+
+## Goals
+
+By the end of this tutorial, you will learn how to:
+
+- Reference data from previous actions
+- Use the **Reshape** action to organize data
+- Use if-conditions to control the flow of your workflow
+- Configure the output schema of a workflow
+
+## Prerequisites
+
+- Completed the [Quickstart](/tutorials/quickstart) tutorial
+- Basic knowledge of [JSONPath match syntax](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-01.html)
+
+## Tutorial
+
+
+
+ The JSON object returned from the **Search URL with VirusTotal** action can be quite verbose, for example:
+
+ 
+
+ Let's use the **Reshape** action along with JSONPath match to extract then organize the data we need for other actions.
+
+ Rename the **Reshape** action to `Extract VirusTotal report` and configure it's inputs with the following expressions:
+
+ ```yaml
+ value:
+ url: ${{ ACTIONS.search_url_with_virustotal.result.data.data.attributes.url }}
+ stats: ${{ ACTIONS.search_url_with_virustotal.result.data.data.attributes.last_analysis_stats }}
+ ```
+
+
+ The `ACTIONS` expression namespace contains all the results from previous actions.
+ To get the result from a previous action, you call `ACTIONS..result`,
+ where `` is the snake-cased name of the action.
+
+ For example, the action key for an action named "Search URL with VirusTotal" is `search_url_with_virustotal`.
+
+
+
+
+ Add the **List VirusTotal comments on URL** action to your workflow, then configure it's inputs with the following expression:
+
+ ```yaml
+ url: ${{ ACTIONS.extract_virustotal_report.result.url }}
+ ```
+
+
+ As an analyst, you might want to view comments from the VirusTotal community on a potentially malicious URL.
+ To reduce noise, let's list these comments only if the URL has been flagged as malicious more than 10 times.
+
+ You can do this by adding a **Run If** condition to the **List VirusTotal comments on URL** action:
+
+ ```yaml
+ ${{ ACTIONS.extract_virustotal_report.result.stats.malicious > 10 }}
+ ```
+
+
+ Let's configure the workflow to return specific output data on completion.
+ Click on the canvas to view workflow settings, then go to the **Schema** tab.
+
+ ```
+ url: ${{ ACTIONS.extract_virustotal_report.result.url }}
+ comments: ${{ ACTIONS.list_vt_comments.result.comments }}
+ ```
+
+ The ability to normalize a workflow's output data becomes more important when you start using [child workflows](/tutorials/4-child-workflows).
+
+
+
+## Next Steps
+
+Check out the [next tutorial on Actions Registry](/tutorials/3-actions-registry) to learn how to use, edit, and maintain integrations in your workflows.
diff --git a/docs/tutorials/3-actions-registry.mdx b/docs/tutorials/3-actions-registry.mdx
new file mode 100644
index 000000000..2e0a281ec
--- /dev/null
+++ b/docs/tutorials/3-actions-registry.mdx
@@ -0,0 +1,75 @@
+---
+title: Actions Registry
+description: Learn how to use pre-built integrations in your workflows.
+---
+
+## Goals
+
+By the end of this tutorial, you will learn:
+
+- How to create new actions from **Action Templates** in the **Actions Registry**
+- How to use **Action Templates** to create more powerful integrations
+- How to update an existing **Action Template** across all workflows directly in the UI
+
+## Prerequisites
+
+- Completed the [Quickstart](/tutorials/quickstart) tutorial
+- Completed the [Control Flow](/tutorials/control-flow) tutorial
+
+## Tutorial
+
+
+
+ Go to the **Actions Registry** by clicking on the **Registry** tab back in the workflows view.
+ 
+
+ Actions are registered at the organization level and can be used across all workflows and workspaces.
+
+
+ Let's create a new action called `Is URL malicious`.
+ First, clone the existing `Search URL with VirusTotal` action template.
+
+
+ Edit the action to get the VirusTotal report, check if the URL is malicious, and return a single boolean value.
+ Copy the following configuration into the YAML editor:
+
+ ```yaml
+ ```
+
+
+ Replace the `Search URL with VirusTotal` and `Extract VirusTotal report` actions with the new `Is URL malicious` action.
+
+
+ We need to update the `List VirusTotal comments on URL` action to use the new `Is URL malicious` action.
+
+ ```yaml
+ ${{ ACTIONS.is_url_malicious.result }}
+ ```
+
+
+ Click on the **Run** button to execute the workflow.
+ The results will be the same as the previous tutorial.
+
+
+
+## Why use Action Templates?
+
+Action templates allow you to:
+
+- Define explicit input and output schemas for your integrations
+- Combine actions into reusable pieces of tradecraft that aren't just API calls
+- Build integrations that are easier to edit across workflows
+- Declutter your workflows with fewer filler actions
+
+## Best Practices
+
+- **Action templates** should contain logic for only one integration.
+- **Action templates** should be simple and contain at most three actions.
+- **Action templates** should be used to normalize input and output data between actions.
+- **Action templates** are not mini-workflows.
+
+## Next Steps
+
+- Learn how to combine smaller workflows into a single workflow. View the tutorial [here](/tutorials/4-child-workflows).
+- Learn how to receive external events (e.g. from your SIEM) and configure schedules to trigger workflows. View the tutorial [here](/tutorials/5-triggers).
+- Learn how to sync custom Python integrations from GitHub. View the tutorial [here](/tutorials/6-custom-integrations).
diff --git a/docs/tutorials/4-child-workflows.mdx b/docs/tutorials/4-child-workflows.mdx
new file mode 100644
index 000000000..15614a261
--- /dev/null
+++ b/docs/tutorials/4-child-workflows.mdx
@@ -0,0 +1,84 @@
+---
+title: Child Workflows
+description: Learn how to combine smaller workflows into a single workflow.
+---
+
+
+ Tracecat comes with unlimited workflows.
+ Whenever possible, we recommend creating smaller, reusable workflows.
+ Each workflow should contain a single, cohesive piece of logic.
+
+ Then use a "parent" workflow to orchestrate the execution of multiple child workflows.
+ This design is inspired by AWS Step Functions and AWS Lambda.
+
+
+## Goals
+
+By the end of this tutorial, you will learn:
+
+- When to use child workflows
+- How to use the `Execute Child Workflow` action
+- How to use the `Reshape` action and `filter` function to select items from a list
+- How to use the `Reshape` action and `flatten` function to turn a list of lists into a single list
+- How to use loop-iteration to execute child workflows in parallel
+
+
+ This tutorial does not implement the full playbook discussed in the scenario.
+ This is left as an exercise to the reader.
+
+
+## Prerequisites
+
+- Completed the [Control Flow](/tutorials/2-control-flow) tutorial
+- Completed the [Actions Registry](/tutorials/3-actions-registry) tutorial
+
+## Tutorial
+
+
+
+ Let's say you want to automate a playbook that will:
+
+ 1. Receive an alert from your SIEM
+ 2. Check if alert is high-severity
+ 3. Extract all the URLs from the alert
+ 4. Check if each URL is malicious
+ 5. Block the IPs that are associated with the malicious URLs
+
+ You might be tempted to create a single workflow that contains all of these steps.
+ However, each of these steps is a single, cohesive piece of logic.
+ We recommend creating a child workflow for each step.
+
+
+ Create a new workflow called `SIEM alert incident response`.
+
+
+ Let's assume that this workflow recieves a list of alerts (JSON objects) from [Elastic Security](https://www.elastic.co/guide/en/security/current/alert-schema.html) via webhook.
+ We want to filter out any alerts that are not high-severity.
+
+ **This is easily done using the `Reshape` action along with the `filter` function.**
+
+ Rename the `Reshape` action to `Select high-severity alerts`, then configure the action with the following inputs:
+
+ ```yaml
+ value: ${{ FN.filter(TRIGGER, 'x.kibana.alert.severity == "high"') }}
+ ```
+
+
+ We're assuming you've configured the Elastic Security [webhook connector](https://www.elastic.co/guide/en/kibana/current/webhook-action-type.html)to send alerts as ndjson with the MIME content-type set as `application/x-ndjson`.
+
+
+
+ Add the `Execute Child Workflow` action to the workflow.
+ Rename the action to `Trigger VirusTotal workflow`.
+ Copy the workflow ID from the VirusTotal workflow created in the [Quickstart](/tutorials/quickstart) tutorial and paste it into the action inputs.
+
+
+ Every action in Tracecat can be configured with one or more loop-iteration expressions.
+ This allows you to iterate through a list of data and run the same action once per item in the list.
+
+ In this case, under the **Control Flow** tab for the `Trigger VirusTotal workflow` action, we can set the loop-iteration config with the following:
+ ```yaml
+ - ${{ var.alert for alert in ACTIONS.select_high_severity_alerts.result }}
+ ```
+
+
diff --git a/docs/tutorials/5-triggers.mdx b/docs/tutorials/5-triggers.mdx
new file mode 100644
index 000000000..898baeeeb
--- /dev/null
+++ b/docs/tutorials/5-triggers.mdx
@@ -0,0 +1,79 @@
+---
+title: Workflow Triggers
+description: Learn how to trigger workflows via webhooks or schedules.
+---
+
+## Goals
+
+By the end of this tutorial, you will learn how to:
+
+- Trigger workflows from external events (e.g. from your SIEM)
+- Define input schemas for your workflows
+- Schedule workflow runs
+
+## Prerequisites
+
+- Completed the [Quickstart](/tutorials/quickstart) tutorial
+
+## Tutorial
+
+### Webhook
+
+
+
+ Every workflow comes with a webhook URL that can be used to trigger the workflow.
+ To activate the webhook, click on the **Trigger** node and toggle the webhook switch.
+
+
+ In the previous tutorials, we've used the manual trigger UI to run the workflow.
+ To start receiving external events via the webhook URL, you still need to enable the workflow.
+
+ Click on **Enable workflow** to start receiving external events.
+
+
+ To trigger the workflow, send a POST request to the webhook URL with the following JSON payload:
+
+ ```json
+ {
+ "url": "https://example.com"
+ }
+ ```
+
+
+ Let's say you want to the JSON payload to the webhook to fit a specific schema.
+ Even though the input schema is optional, specifying it will allow you to validate the payload of the incoming webhook request.
+ The workflow will fail fast if the incoming payload does not match the schema.
+
+ You can define the input schema by going into the workflow settings and filling out the **Input Schema** config with the following:
+
+ ```yaml
+ url:
+ type: str
+ description: The URL to check if malicious
+ ```
+
+
+ The workflow's input schema must be formatted in the following way:
+
+ ```yaml
+ field:
+ type: str | int | bool | list[type] | dict[str, type]
+ description: The description of the field
+ default: The default value of the field (optional)
+ ```
+
+ Nested schemas are currently not supported.
+
+
+
+
+### Schedule
+
+
+
+ You can schedule a workflow under the **Trigger** node's **Schedules** section.
+
+
+ After creating a schedule, you'll need to click **Enable workflow** to start workflow runs on the schedule.
+
+
diff --git a/docs/tutorials/6-custom-integrations.mdx b/docs/tutorials/6-custom-integrations.mdx
new file mode 100644
index 000000000..2ec04a5cb
--- /dev/null
+++ b/docs/tutorials/6-custom-integrations.mdx
@@ -0,0 +1,29 @@
+---
+title: Custom Integrations
+description: Learn how to add custom integrations to the Actions Registry.
+---
+
+
+ Looking for example Python and YAML-based (Action Template) integrations?
+ Check out Tracecat's public integrations [here](https://github.com/TracecatHQ/tracecat/tree/main/registry/tracecat_registry).
+
+ We recommend writing **Action Templates** over Python **UDFs** when building custom integrations.
+ Find out the difference between the two [here](/platform/actions).
+
+
+## Goals
+
+By the end of this tutorial, you will learn how to:
+
+- Create a custom Python UDF (User Defined Function) integration
+- Create a custom Action Template integration
+- Configure a GitHub repository with your custom integrations
+- Sync custom integrations into Tracecat
+
+## Prerequisites
+
+- Completed the [Actions Registry](/tutorials/3-actions-registry) tutorial
+
+## Tutorial
+
+Coming soon.
diff --git a/docs/self-hosting/updating.mdx b/docs/tutorials/updating.mdx
similarity index 76%
rename from docs/self-hosting/updating.mdx
rename to docs/tutorials/updating.mdx
index b3036b5a4..d9f1ece28 100644
--- a/docs/self-hosting/updating.mdx
+++ b/docs/tutorials/updating.mdx
@@ -47,9 +47,16 @@ description: Learn how to safely update versions and run data migrations.
+## Update Integrations
+
+Integrations are not automatically updated when you update the Tracecat version.
+You will need to manually sync the Tracecat registry repository from the **Action Registry** page:
+
+
+
## Terraform Deployments
-All of Tracecat's Cloud deployments (e.g. AWS EC2, AWS ECS) are configured using Terraform.
+All of Tracecat's Cloud deployments are configured using Terraform.
To update Tracecat, you can download the latest Terraform stack from Tracecat's GitHub repo and run `terraform apply`.
## Data Migration
@@ -59,15 +66,12 @@ Data migrations are, however, non-trivial operations.
We recommend backing up your database before running migrations, especially in a production environment.
-If the API service fails to spin up due to a data migration error, do not worry!
-Your data is still intact. Make sure you first backup the core Tracecat database:
+If the API service fails to spin up due to a data migration error, do not worry.
+Your data is still intact. Make sure you backup the core Tracecat database:
- For Docker Compose and AWS EC2 deployments, this would be the `core-db` volume in Tracecat's Docker stack.
-- For AWS ECS Fargate deployments, backups are created automatically as part of the RDS postgres service.
-
-Then contact us on [Discord](https://discord.gg/n3GF4qxFU8) or email [founders@tracecat.com](mailto:founders@tracecat.com) for live migration support.
+- For AWS ECS Fargate deployments, backups are created automatically as part of the RDS postgres service. Just run `terraform apply` with `var.restore_from_backup` set to `true` to restore the latest RDS snapshot.
-We're releasing a self-serve guide for manual migration in the coming months.
-For the time being, however, we recommend contacting us for one-on-one help!
+If you need live migration support, contact us on [Discord](https://discord.gg/n3GF4qxFU8) or email [founders@tracecat.com](mailto:founders@tracecat.com)!
diff --git a/frontend/src/app/workspaces/[workspaceId]/workflows/[workflowId]/executions/page.tsx b/frontend/src/app/workspaces/[workspaceId]/workflows/[workflowId]/executions/page.tsx
index b5a0ffeba..0875e02ee 100644
--- a/frontend/src/app/workspaces/[workspaceId]/workflows/[workflowId]/executions/page.tsx
+++ b/frontend/src/app/workspaces/[workspaceId]/workflows/[workflowId]/executions/page.tsx
@@ -172,11 +172,9 @@ function WorkflowExecutionsViewLayout({
{selectedEvent ? (
) : (
-
-
- Select an Event.
-
-
+
+ Select an Event.
+
)}
diff --git a/frontend/src/components/workbench/panel/workflow-panel.tsx b/frontend/src/components/workbench/panel/workflow-panel.tsx
index f48c5e346..1c6d3de00 100644
--- a/frontend/src/components/workbench/panel/workflow-panel.tsx
+++ b/frontend/src/components/workbench/panel/workflow-panel.tsx
@@ -564,6 +564,7 @@ my_param:
my_list:
type: list[int]
description: This is a list of integers without a default value
+
my_union:
type: str | int | None
description: This is a union of a string, an integer, and None
diff --git a/tracecat/expressions/functions.py b/tracecat/expressions/functions.py
index 59633e4f8..31a9b1fca 100644
--- a/tracecat/expressions/functions.py
+++ b/tracecat/expressions/functions.py
@@ -299,6 +299,7 @@ def deserialize_ndjson(x: str) -> list[dict[str, Any]]:
"float": float,
"str": str,
"bool": _bool,
+ "datetime": to_datetime,
# TODO: Perhaps support for URLs for files?
}