# Flows

## Overview

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FpK8c34EPQX4IcrIBroWQ%2F1.png?alt=media&#x26;token=f6fa2b04-1607-49d9-baa1-6abad9c8802d" alt=""><figcaption></figcaption></figure>

Flows is a comprehensive, end-to-end workflow automation engine powered by [AFScript](https://support.attackforge.com/attackforge-enterprise/afscript).

Flows can help you to automate AttackForge with *nearly unlimited systems*. You can streamline processes across your organization to save time and focus on what's important.

Some examples you can do with Flows:

* Create bespoke workflows - QA, risk management, reporting, bi-directional integrations, and more.
* Prioritize vulnerabilities with full context, including threat-intelligence like [VulnDB](https://flashpoint.io/ignite/vulnerability-intelligence/)
* Integrate your vulnerability data with ticketing tools like [Atlassian JIRA](https://www.atlassian.com/software/jira), [ServiceNow](https://www.servicenow.com/), [Azure DevOps](https://azure.microsoft.com/en-us/products/devops), [BMC Helix](https://www.bmc.com/it-solutions/bmc-helix.html) and others.
* Visualize your pentesting data in powerful tools like [Power BI](https://www.microsoft.com/en-us/power-platform/products/power-bi) and [Tableau](https://www.tableau.com/)
* Integrate your Bug Bounty and VDP data from platforms like [HackerOne](https://hackerone.com/) and [BugCrowd](https://www.bugcrowd.com/)
* Help make better risk decisions by sending your vulnerability data to GRC platforms like [RSA Archer](https://www.archerirm.com/), [MetricStream](https://www.metricstream.com/), [OneTrust](https://www.onetrust.com/) and [LogicGate](https://www.logicgate.com/).
* Create workflow automations by chaining together [AttackForge Self-Service APIs](https://support.attackforge.com/attackforge-enterprise/modules/self-service-restful-api)
* Trigger automated scanning activities in your security toolset like [Rapid7](https://www.rapid7.com/), [Tenable](https://www.tenable.com/) and [Qualys](https://www.qualys.com/).
* Create messages on collaboration platforms like [Slack](https://slack.com/intl/en-au/) and [Teams](https://www.microsoft.com/en-au/microsoft-teams/group-chat-software).
* Create custom webhooks.
* Send custom email notifications on events.

{% embed url="<https://youtu.be/tTbq4Dbh-A8>" %}

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FDQYiJrDsVNjzstzeGxVF%2FScreenshot%202025-06-23%20at%209.52.03%E2%80%AFpm.png?alt=media&#x26;token=bdd33547-b97c-4336-9dc2-1b9a5ef79372" alt=""><figcaption></figcaption></figure>

## Getting Access to Flows

Flows is included in all AttackForge Enterprise plans, and in the AttackForge Core SME plan. For all others plans, Flows can be add-on from the `Administration -> Subscriptions` page.&#x20;

To get started with building a Flow:

* You must have **Create** access to [Event Triggers](#internal-events), [HTTP Triggers](#external-events), [Schedule Triggers](#scheduled-events) or [Action Triggers](#action-events)

As an Administrator, go to `Users > (Select User) > Access > Flows`  and enable access to the desired triggers.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FPtrHaxdepVWmDXU0hKxg%2FScreenshot%202026-02-28%20at%208.44.27%E2%80%AFpm.png?alt=media&#x26;token=4c92aeb1-b999-4017-a9af-7644b369cd67" alt=""><figcaption></figcaption></figure>

### Event Trigger Access Level

* **None** - user is unable to create or import flows with the [Event Trigger](#internal-events) type. Any existing Event Trigger flows for which they are the owner of will also not run.
* **Run** - user is able to trigger flows with the [Event Trigger](#internal-events) type they are the owner of, so long as the flow is enabled and they have access to the matching [event type](#internal-events).
* **Create** - user is able to create or import flows with the [Event Trigger](#internal-events) type. Any existing Event Trigger flows for which they are the owner of will run so long as the flow is enabled and the user has access to the matching [event type](#internal-events).

### HTTP Trigger - Authentication (None) Access Level

HTTP Triggers can be [configured with no authentication](#http-trigger-authentication). This means that the flow will not check for authentication before the flow runs.

* **None** - user is unable to create or import flows with the non-authenticated [HTTP Trigger](#external-events) type. Any existing non-authenticated HTTP Trigger flows for which they are the owner of will also not run.
* **Run** - user is able to trigger flows with the non-authenticated [HTTP Trigger](#external-events) type they are the owner of, so long as the flow is enabled.
* **Create** - user is able to create or import flows with the non-authenticated [HTTP Trigger](#external-events) type. Any existing non-authenticated HTTP Trigger flows for which they are the owner of will run so long as the flow is enabled.

### HTTP Trigger - Authentication (User API Key) Access Level

HTTP Triggers can be [configured with authentication](#http-trigger-authentication). This means that the flow will check for authentication before the flow runs.

* **None** - user is unable to create or import flows with the authenticated [HTTP Trigger](#external-events) type. Any existing authenticated HTTP Trigger flows for which they are the owner of will also not run.
* **Run** - user is able to trigger flows with the authenticated [HTTP Trigger](#external-events) type they are the owner of, so long as the flow is enabled and an authorized [User Key](https://support.attackforge.com/attackforge-enterprise/getting-started/manage-user#user-api-key) is supplied in the nominated header.
* **Create** - user is able to create or import flows with the authenticated [HTTP Trigger](#external-events) type. Any existing authenticated HTTP Trigger flows for which they are the owner of will run so long as the flow is enabled and an authorized [User Key](https://support.attackforge.com/attackforge-enterprise/getting-started/manage-user#user-api-key) is supplied in the nominated header.

### Schedule Trigger

* **None** - user is unable to create or import flows with the [Schedule Trigger](#scheduled-events) type. Any existing Schedule Trigger flows for which they are the owner of will also not run.
* **Run** - user is able to trigger flows with the [Schedule Trigger](#scheduled-events) type they are the owner of, so long as the flow is enabled.
* **Create** - user is able to create or import flows with the [Schedule Trigger](#scheduled-events) type. Any existing Schedule Trigger flows for which they are the owner of will run so long as the flow is enabled.

### Action Trigger

* **None** - user is unable to create or import flows with the [Action Trigger](#action-events) type. Any existing Action Trigger flows for which they are the owner of will also not run.
* **Run** - user is able to trigger flows with the [Action Trigger](#action-events) type they are the owner of, so long as the flow is enabled.
* **Create** - user is able to create or import flows with the [Action Trigger](#action-events) type. Any existing Action Trigger flows for which they are the owner of will run so long as the flow is enabled.

## Flow Overview

A Flow is comprised of the following:

* **Name** - the name of the Flow.
* [**Trigger**](#triggers) - the trigger which initiates a [Run](#run-overview).
* [**Actions**](#actions) - a sequence of steps which are executed in order during a [Run](#run-overview).
* [**Secrets**](#secrets) - any piece of sensitive information that needs to be kept confidential, such as passwords and API keys.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FKB9VKU24T0JXaNzAE34s%2FScreenshot%202025-06-23%20at%2010.24.50%E2%80%AFpm.png?alt=media&#x26;token=74214d5b-aa49-49bf-bb4f-75a05b38a686" alt=""><figcaption></figcaption></figure>

## Run Overview

A Run refers to a single execution of a Flow, meaning when a set of actions defined in your Flow is triggered and carried out from start to finish, that is considered one "Run" of the flow; essentially, it's a single instance of your Flow being executed.&#x20;

Key points about a Run:

* **Triggered by a Trigger -** A Run is initiated by a [Trigger](#triggers), like a new vulnerability or an update to a project, or a manual action.
* **Trackable status -** You can monitor the status of a Run, including whether it succeeded, failed, or is currently running.
* **Provides details -** Each Run has details like start time, duration, and the specific [Actions](#actions) taken within the Flow.

> **IMPORTANT:** A normal Run will only be executed in the context of the [Flow Owner](#sharing-flows-with-teams) and related [Trigger](#triggers). For example, if the [Trigger](#triggers) was "vulnerability-created" - the Run will only initiate for the vulnerability for which the [Flow Owner](#sharing-flows-with-teams) has access to the vulnerability. Test runs can be manually executed with test data at any time.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FCuY4HpBG44GLA2M2OGEV%2FScreenshot%202025-06-23%20at%2010.27.52%E2%80%AFpm.png?alt=media&#x26;token=6d56e1ed-9fa5-43e2-8743-af39b5caab13" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2F8W716QADMWuEyJVTHnLI%2FScreenshot%202025-06-23%20at%2010.27.42%E2%80%AFpm.png?alt=media&#x26;token=c0f291c3-aa4f-4315-b9f6-d8f6ce9b04f6" alt=""><figcaption></figcaption></figure>

## Sharing Flows with Teams

When a Flow is created, it belongs to the user who created the Flow (the Flow Owner). Flow Owners can be [transferred](#transferring-flows) however a Flow can only ever run under the context of a single user.

Only Flow Owners are allowed to share their Flows with other users.

To share your Flow:

* Open your Flow and click on the `Settings` button

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fp2or13G7KBau1h5GorXq%2FScreenshot%202025-06-23%20at%2010.27.52%E2%80%AFpm.png?alt=media&#x26;token=773216de-33a2-4484-bbb1-f6a014b24429" alt=""><figcaption></figcaption></figure>

* Click on `Add Access`

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FPbuojGYUovFIdpLz5wPy%2FScreenshot%202025-06-23%20at%2010.31.09%E2%80%AFpm.png?alt=media&#x26;token=4fdd844f-4dc3-4a91-8de7-410ae0ba336d" alt=""><figcaption></figcaption></figure>

* Insert the user's email address, or if permitted, look up and select the user. Assign an access level to the flow.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Ft93Zncse84tfVVixl2mt%2FScreenshot%202025-06-23%20at%2010.54.56%E2%80%AFpm.png?alt=media&#x26;token=fabc5233-b14e-4f1e-a57d-074a2dd1c413" alt=""><figcaption></figcaption></figure>

### Access Levels

* **None** - the user explicitly does not have access to the flow.
* **Info** - the user is able to view basic information about the flow, including:
  * Name of the flow
  * Current status, last run, trigger, enabled/disabled
  * Flow owner
  * Readme
  * If [HTTP Trigger](#external-events) - HTTP Method, Trigger URL, Trigger Id&#x20;
* **View** - the user is able to access read-only information for the flow, including:
  * Name of the flow
  * Current status, last run, trigger, enabled/disabled
  * Flow owner
  * Readme
  * If [HTTP Trigger](#external-events) - HTTP Method, Trigger URL, Trigger Id
  * View all [Runs](#runs)
  * View all [Actions](#actions)
  * View [Run details](#run-logs) and logs
  * [Export](#importing-exporting-flows) the flow
* **Edit** - the user is able to modify the flow, including:
  * Name of the flow
  * Current status, last run, trigger, enabled/disabled
  * Flow owner
  * Readme
  * If [HTTP Trigger](#external-events) - HTTP Method, Trigger URL, Trigger Id
  * View all [Runs](#runs)
  * View all [Actions](#actions)
  * View [Run details](#run-logs) and logs
  * Edit the flow
  * Save and Run the flow
  * [Export](#importing-exporting-flows) the flow
  * Disable the flow

### Trigger Access

Trigger access is used for controlling authentication to triggering a [Flow Run](#runs) using authenticated [HTTP Triggers](#external-events) based on the [User Key](https://support.attackforge.com/attackforge-enterprise/getting-started/manage-user#user-api-key) supplied in the nominated header.

* **No** - user is not able to trigger the flow.
* **Yes** - user is able to trigger the flow provided they enter their valid [User Key](https://support.attackforge.com/attackforge-enterprise/getting-started/manage-user#user-api-key) into the flows' nominated authentication header.

> **IMPORTANT:** Administrators have implicit permissions to view access for all flows.

## Triggers

A Trigger is an action which initiates a [Run](#run-overview). Triggers can be initiated from [Events](https://support.attackforge.com/attackforge-enterprise/modules/self-service-events-api) or manually initiated.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FfAcYjqcDixVjKZPTTJBu%2FFlow%20Use%20Cases.png?alt=media&#x26;token=a72499ed-bf24-48fb-a49d-5ba98741e274" alt=""><figcaption></figcaption></figure>

### Internal Events

Internal Events (or Event Triggers) are events which occur when something *inside* AttackForge changes.

The following Internal Events are currently supported:

* Project Created
* Project Updated
* Project Request Created
* Project Request Updated
* Project Retest Requested
* Project Retest Completed
* Project Retest Cancelled
* Project Reporting Updated
* Project Reporting File Uploaded
* Project Summary Updated
* Project Summary File Uploaded
* Project Test Case Updated
* Project Workspace File Uploaded
* Vulnerability Created&#x20;
* Vulnerability Updated
* Vulnerability Remediation Note Created
* Vulnerability Remediation Note Updated
* Vulnerability Evidence Created
* Vulnerability Evidence Updated
* Writeup Created
* Writeup Updated

Access to events can be granted by Administrators in [`Users > (Select User) > Access > Events (Flows / Self Service API)`](https://support.attackforge.com/attackforge-enterprise/modules/users#self-service-events-api)&#x20;

### External Events

External Events (or HTTP Triggers) are events which occur when something *outside* of AttackForge changes.

For example, if an update happens in an external system - that system can use [Webhooks](https://hookdeck.com/webhooks/guides/what-are-webhooks-how-they-work) to send the message to AttackForge in *real-time*.

External Events can also be called from within any other Flow, creating possibilities for modularisation of your flows.

### Scheduled Events

Time-Based Events are events which occur at a specified time for example each day at 9am, or on a specified frequency for example every hour. Time-Based Events are particularly useful when something needs to happen on a automated time basis.

For example, *each day - find all vulnerabilities which have just exceeded their risk-acceptance date, change their status to open, create a ticket in an external system and notify the vulnerability owner(s) and security team by email and by chat message.*

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fmztg679mYzY8bJU7Ipa0%2FScreenshot%202025-08-14%20at%206.22.37%E2%80%AFam.png?alt=media&#x26;token=67eb3844-05fa-4475-96c3-173c7722b257" alt=""><figcaption></figcaption></figure>

### Action Events

Action Events are triggered when [Actions](#actions) are clicked by a user within the application user interface.

Action Events can be restricted to `Entities` which helps to scope where Action Events can be accessed from within the application user interface by Actions. This helps to avoid Action Events getting linked to Actions which are not related to the Action Event.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FCj52hIYIsI3tFFl0q2T5%2FScreenshot%202026-02-28%20at%208.59.57%E2%80%AFpm.png?alt=media&#x26;token=dc087cbf-6f1d-463b-8c26-3775be8cff23" alt=""><figcaption></figcaption></figure>

### Assigning Events

A Flow can be assigned to only one Trigger.&#x20;

Triggers can be assigned to a Flow when either creating or editing the Flow.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FKcwdo5bNn9Ekyd0jBBvh%2FScreenshot%202026-02-28%20at%209.16.28%E2%80%AFpm.png?alt=media&#x26;token=80c76215-9c46-4aaa-b0e4-734434592404" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FQOMJhdVLTOQuhzQWqYu1%2FScreenshot%202025-06-24%20at%209.30.17%E2%80%AFam.png?alt=media&#x26;token=1b2d3e88-8186-4799-8416-cd800168b277" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FWgykJEBT06BmrtxjWb6p%2FScreenshot%202025-06-24%20at%209.30.47%E2%80%AFam.png?alt=media&#x26;token=16e42dd3-ab9d-4fa8-9f18-b71a616a77bd" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fmztg679mYzY8bJU7Ipa0%2FScreenshot%202025-08-14%20at%206.22.37%E2%80%AFam.png?alt=media&#x26;token=67eb3844-05fa-4475-96c3-173c7722b257" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FOxt2G3bbM3XpNZxp7IAI%2FScreenshot%202026-02-28%20at%209.16.37%E2%80%AFpm.png?alt=media&#x26;token=a2358703-ee8e-4e76-88a2-34c61011fdac" alt=""><figcaption></figcaption></figure>

### HTTP Trigger - Authentication

[External Events](#external-events) (HTTP Triggers) can be either authenticated or non-authenticated.

Authentication is a way to protect the flow by ensuring that the user who is sending data to the [Trigger URL](#http-trigger-url) is authorized to do so. Authentication is recommended where it is practical to implement on the system sending data to AttackForge, via custom headers.

An authenticated HTTP Trigger flow will check for authentication before the flow runs.

A non-authenticated HTTP Trigger flow will not check for authentication before the flow runs.

Authentication is configured as a custom header. You have control over what the header name should be.

A user interacting with an authenticated HTTP Trigger flow must include their [User Key](https://support.attackforge.com/attackforge-enterprise/getting-started/manage-user#user-api-key) in the specified header. They must also be [granted access to the Flow with Trigger access](#trigger-access), unless they are the [Flow Owner](#sharing-flows-with-teams) whom has implicit access to trigger their flows.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fn93EGFVwt1EsOMP8vU8n%2FScreenshot%202025-06-24%20at%209.50.18%E2%80%AFam.png?alt=media&#x26;token=7f4e0d11-a202-4fd9-b5b0-58830fd10d5a" alt=""><figcaption></figcaption></figure>

### HTTP Trigger URL

After creating a HTTP Trigger flow, you will receive the Trigger URL and Trigger Id. The Trigger URL is the URL which your external systems and scripts will use to interact and send data to your flow.

The Trigger URL and Trigger ID are unique for every flow.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2F3uj3VUUcmCwA2hMEemNK%2FScreenshot%202025-06-24%20at%209.57.03%E2%80%AFam.png?alt=media&#x26;token=4120ad1b-9484-400c-ac31-17e33ad5e3b7" alt=""><figcaption></figcaption></figure>

> **IMPORTANT**: For non-authenticated HTTP Trigger flows, protect your Trigger URL and Trigger ID as if it was a secret. Without authentication, anybody who knows the URL and HTTP Method can attempt to trigger your flow.

You can rotate your Trigger URL and Trigger ID by clicking on the regenerate button:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2F1YPlKIEtvzzbUZjCbXNf%2FScreenshot%202025-06-24%20at%2010.01.48%E2%80%AFam.png?alt=media&#x26;token=be66de78-df29-4144-8bad-b636d50ce5b7" alt=""><figcaption></figcaption></figure>

### Trigger Configuration

Triggers have different configuration options which are supported.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FXRwMcQD32OZlvYmngNZr%2FScreenshot%202025-06-24%20at%2010.03.29%E2%80%AFam.png?alt=media&#x26;token=ece61fde-cf8e-42fc-bd7f-9eb2ea5e7441" alt=""><figcaption></figcaption></figure>

* **Redact user API Key** - this option can be used to prevent anybody working on an authenticated HTTP Trigger flow from gaining access to the [User Key](https://support.attackforge.com/attackforge-enterprise/getting-started/manage-user#user-api-key) supplied in the authentication header, such as through logging.
* **Redact all headers except specified** - this option can be used to specify a [*whitelist*](https://en.wikipedia.org/wiki/Whitelist) of headers which are allowed to be passed into the flow. This option is useful to prevent anybody working on an authenticated HTTP Trigger flow from gaining access to headers which they should not have access to, for example session tokens from external systems.
* **Redact specified headers** - this option can be used to specify a [*blacklist*](https://en.wikipedia.org/wiki/Blacklist_\(computing\)) of headers which will not be passed into the flow. This option is useful to prevent anybody working on an authenticated HTTP Trigger flow from gaining access to headers which they should not have access to, for example session tokens from external systems.

## Secrets

Secrets are any piece of sensitive information that needs to be kept confidential, such as passwords and API keys.

You can create Secrets which belong to the Flow. Only users with access to the Flow would be able to view the associated Secrets.

You can also reference [Secrets which belong to users](https://support.attackforge.com/attackforge-enterprise/getting-started/manage-user#secrets). User Secrets make it easy to rotate passwords and credentials without having to update flows.

To create a Secret, start by clicking on the `Secrets` button when creating or editing a Flow.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FCMiYhACizWsBiyePSsMI%2FScreenshot%202025-06-24%20at%2010.13.27%E2%80%AFam.png?alt=media&#x26;token=23d76e22-ecf5-4a76-84a1-e023366bfb44" alt=""><figcaption></figcaption></figure>

From here, you can see and manage all of the existing Secrets associated to the Flow.

Click on `Add Secret` to create a new Secret.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FnvA4iQjG6XgC5elQHwRd%2FScreenshot%202025-06-24%20at%2010.14.46%E2%80%AFam.png?alt=media&#x26;token=b7f8794f-9968-441f-b5ea-23f8d65c2888" alt=""><figcaption></figcaption></figure>

Note the Key must be letters, numbers and underscores only.

You can create a Local Secret:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FJfW1MrkZVHcLDSkrRmTr%2FScreenshot%202025-06-24%20at%2010.21.32%E2%80%AFam.png?alt=media&#x26;token=eba8ff42-ef81-41e3-b7ca-2487f0aee347" alt=""><figcaption></figcaption></figure>

Or select from one of your [User Secrets](https://support.attackforge.com/attackforge-enterprise/getting-started/manage-user#secrets):

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FntqkcWjAUlBpcwX8Fljc%2FScreenshot%202025-06-24%20at%2010.21.44%E2%80%AFam.png?alt=media&#x26;token=0fb1fa35-e89e-47af-9cd8-3d858447f763" alt=""><figcaption></figcaption></figure>

You can also view, manage and create secrets in the [Request Script](#request-script) and in the [Response Script](#response-script):

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FGVqbnl2LG71VrFI2UcSi%2FScreenshot%202025-02-20%20at%209.24.32%E2%80%AFpm.png?alt=media&#x26;token=af2a82d3-8f68-4334-a4fb-f02f048d505d" alt=""><figcaption></figcaption></figure>

> **NOTE:** Secrets are stored encrypted in the database.

There are two (2) ways in which you can refer to your Secrets in your Flow:

1. Select the Secret directly in the [Headers](#headers)
2. Refer to the Secret in the [Request Script](#request-script) or [Response Script](#response-script)

### Secrets in Headers

When creating or modifying [Headers](#headers) within the [Action](#actions), you can select 'Secret' for the header type. This will then allow you to select from an existing Secret, or create a new Secret.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FVK7sTRAz7NblM8w2oHDS%2FScreenshot%202025-02-20%20at%209.26.00%E2%80%AFpm.png?alt=media&#x26;token=3b096cf8-a273-4469-a2e2-7678685e20a3" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FxX59PO8a1lhabf26vT9w%2FScreenshot%202025-02-20%20at%209.26.07%E2%80%AFpm.png?alt=media&#x26;token=6d1928f1-a0fe-4a73-a218-2bce215bbd4c" alt=""><figcaption></figcaption></figure>

### **Secrets in Request/Response Scripts**

When creating or modifying the [Request Script](#request-script) or the [Response Script](#response-script), you can refer to secrets using the following syntax:

```javascript
secrets.<KEY>
```

Where `<KEY>` is replaced with the Key associated with the Secret.

> **IMPORTANT**: Make sure to select `Use Secrets` to ensure your secrets are used in your script.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FQUEPbtJQ8ZdIhqFo2AKw%2FScreenshot%202025-02-20%20at%209.27.02%E2%80%AFpm.png?alt=media&#x26;token=18a42302-e33a-4883-86d1-443d2e5f74c6" alt=""><figcaption></figcaption></figure>

## Actions

Actions are either one activity, or a sequence of activities, which are executed in order during a [Run](#run-overview).

For example, if the use case for your Flow is:

* *to create a JIRA Issue every time a Vulnerability is created*

You may choose to include two (2) Actions in your Flow:

* **Action 1 - Create JIRA Issue**
  * This involves formatting the vulnerability into the necessary [JIRA Create Issue API](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-post) format, and making a HTTPS request to the JIRA API to create the issue.
* **Action 2 - Update Vulnerability with JIRA Issue Key**
  * This involves making a HTTPS request to the [Update Vulnerability Self-Service API](https://support.attackforge.com/attackforge-enterprise/modules/self-service-restful-api/updatevulnerability) to set the JIRA Issue Key custom field.

### Action Types

The following Action Types are supported:

* [**HTTP Action**](#http-action)
  * The primary purpose of a HTTP Action is to make a HTTP request. The HTTP request can be against the AttackForge [Self-Service APIs](https://support.attackforge.com/attackforge-enterprise/modules/self-service-restful-api) or any external system or endpoint outside of AttackForge.
* [**Script Action**](#script-action)
  * The primary purpose of a Script Action is to execute user-defined logic.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fyw3OeL57ocLDLfVOODp2%2FScreenshot%202025-10-21%20at%204.00.01%E2%80%AFpm.png?alt=media&#x26;token=b689c833-e114-4d79-91ca-3cc0be72447c" alt=""><figcaption></figcaption></figure>

### Script Action

Script Actions can be leveraged to execute user-defined logic.

Script Actions can receive input from [Data](#data) and output [Data](#data) into the proceeding Action.

In the example below:

* **Action 1 (HTTP)**: Retrieves vulnerabilities from the AttackForge Self-Serviced APIs.
* **Action 2 (Script)**: Takes the vulnerabilities from Action 1; groups them into the required format, then passes them into Action 3.
* **Action 3 (HTTP)**: Sends the formatted vulnerabilities to an external security platform.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FBTRN5uDHeQwhHCNrukAm%2FScreenshot%202025-10-21%20at%204.19.46%E2%80%AFpm.png?alt=media&#x26;token=14a4d45a-3888-4397-bf39-bbf6f5b94004" alt=""><figcaption></figcaption></figure>

The Script Action contains a single code editor where the script can be input.&#x20;

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FKfKsuxOFVd1Nrom3tzWi%2FScreenshot%202025-10-21%20at%204.34.47%E2%80%AFpm.png?alt=media&#x26;token=51de95d2-7173-4891-8929-20f05ff1cb8f" alt=""><figcaption></figcaption></figure>

### HTTP Action

Every HTTP Action is made up of a [**Request**](#request) and a [**Response**](#response).

* The [Request](#request) is the HTTP request which is made by the Action.
* The [Response](#response) is the HTTP response from the server which received the HTTP request.

Every HTTP Action is made up of the following components:

* [**Method**](#methods) - this is the HTTP method i.e. GET, POST, PUT, etc. that will be used for the [Request](#request)
* [**URL**](#url) - this is the URL that will be used for the [Request](#request).
* **Verify Certificate** - this determines whether to verify if the TLS certificate is valid for the URL.
* [**Headers**](#headers) - these are the headers that will be sent when the [Request](#request) is made.
* [**Request Script**](#request-script) - this is the script which will execute *before* the [Request](#request) is made.
* [**Response Script**](#response-script) - this is the script which will execute *after* the [Response](#response) is returned.

> **IMPORTANT:** When more than one Action is included in a Flow, the *output* of an Action will become the *input* into the next Action.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FFgolsILtmKX3GuMe3Lkl%2FScreenshot%202025-02-20%20at%209.29.24%E2%80%AFpm.png?alt=media&#x26;token=cc94d64c-ca05-4729-aef7-1107e7fc9f88" alt=""><figcaption></figcaption></figure>

### Methods

Methods are the HTTP methods/verbs that will be used for the [Request](#request) i.e. GET, POST, PUT, etc.

The following methods are supported:

* GET
* POST
* PUT
* PATCH
* DELETE

Methods can be selected when editing the HTTP [Action](#actions):

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FTQ7AbF84EPubJGj0xFhG%2FScreenshot%202025-02-20%20at%209.30.51%E2%80%AFpm.png?alt=media&#x26;token=b6b9534a-4550-4aa5-8182-f37ca98b2f48" alt=""><figcaption></figcaption></figure>

Methods can also be programatically set in your [Request Script](#request-script) in the [Return Statement](#the-return-statement):

```javascript
return {
    decision: { 
        status: 'continue'
    },
    request: {
        url: url,
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            'Authorization': secrets.jira_auth
        },
        body: {
            fields: {
                summary: summary,
                description: description,
                priority: {
                    name: priority
                },
                issuetype: {
                    name: 'Bug'
                },
                labels: labels
            }
        }
    }
};
```

### URL

The URL is the web address that will be used for the [Request](#request), for example `https://acmecorp.atlassian.net/rest/api/2/issue`

The URL can be entered in when editing the HTTP [Action](#actions):

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2F2RITgwzZSXKyVkcZkdpr%2FScreenshot%202025-02-20%20at%209.31.47%E2%80%AFpm.png?alt=media&#x26;token=35fa0371-2dd8-47f8-84a3-44d4fef7adb3" alt=""><figcaption></figcaption></figure>

The URL can also be programatically set in your [Request Script](#request-script) in the [Return Statement](#the-return-statement). This is useful if your URL has a dynamic component which needs to be computed:

```javascript
const url = 'https://demo.attackforge.com/api/ss/vulnerability/' + data.vulnerability_id;

return {
    decision: { 
        status: 'continue'
    },
    request: {
        url: url,
        method: 'PUT',
        headers: {
            'Content-Type': 'application/json',
            'x-ssapi-key': secrets.af_auth
        },
        body: {
            project_id: project_id,
            custom_fields: [
                {
                    key: 'jira_issue_key',
                    value: jira_issue_key
                }
            ]
        }
    }
};
```

### Headers

The Headers are the HTTP headers that will be sent when the [Request](#request) is made.

The Headers can be manually entered in when editing the HTTP [Action](#actions):

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Ftfozrkx0ezm84Q0aypnm%2FScreenshot%202025-02-20%20at%209.32.52%E2%80%AFpm.png?alt=media&#x26;token=f606ffd3-dce6-4ae0-b758-56b583367891" alt=""><figcaption></figcaption></figure>

The Headers can also be programatically set in your [Request Script](#request-script) in the [Return Statement](#the-return-statement). This is useful if your Headers have a dynamic component which needs to be computed:

```javascript
const customHeaderName = 'X_CUSTOM_HEADER_' + customHeader;
const customHeaderValue = customValue;

return {
    decision: { 
        status: 'continue'
    },
    request: {
        url: url,
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            customHeaderName: customHeaderValue,
            'Authorization': secrets.custom_auth
        },
        body: {
            super_secret_something: "..."
        }
    }
};
```

### Request

The Request is a HTTP/HTTPS request to a web address.&#x20;

The Request is made up of the following components:

* [URL](#url)
* [Method](#methods)
* [Headers](#headers)
* Body - an optional HTTP body. This is typically required for POST, PUT and PATCH HTTP requests.
* [Request Script](#request-script)

> **IMPORTANT:** Requests can be made over both HTTP and HTTPS.

### Response

The Response is the HTTP server response to a [Request](#request).

The Response is made of the of the following components:

* [Response Object](#the-response-object)
* [Response Script](#response-script)

### Request Script

The Request Script is the script which will execute *before* the [Request](#request) is made.

The Request Script is made up of the following components:

* [Code](#code)
* [Data](#data)
* [Return Statement](#the-return-statement)

### Response Script

The Response Script is the script which will execute *after* the [Response](#response) is returned.

The Request Script is made up of the following components:

* [Code](#code)
* [Data](#data)
* [Return Statement](#the-return-statement)

### Code

Flows support [AFScript](https://support.attackforge.com/attackforge-enterprise/afscript) - a powerful interpreted programming language created by AttackForge.

This makes it possible to write logic to help you handle all various use cases for how you want your Flows to work.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FVWVE0inxU8eAayiFBkqQ%2FScreenshot%202025-02-20%20at%209.34.32%E2%80%AFpm.png?alt=media&#x26;token=b0d0cab7-847f-4fae-8099-239e9d68a090" alt=""><figcaption></figcaption></figure>

You can take advantage of [Logging](https://support.attackforge.com/attackforge-enterprise/afscript#logging) in [AFScript](https://support.attackforge.com/attackforge-enterprise/afscript) to help you to debug and test your code.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FM8RoHQFG4dMag4rvITzF%2FScreenshot%202025-02-20%20at%209.37.45%E2%80%AFpm.png?alt=media&#x26;token=91c9fd9d-8fd2-4fff-b24c-fc30dde5af2e" alt=""><figcaption></figcaption></figure>

You can test and debug your code using the `Run` option:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2F6vy33kQLTmrwbPSgBT1z%2FScreenshot%202025-02-20%20at%209.35.34%E2%80%AFpm.png?alt=media&#x26;token=389c6f58-1049-4125-b79f-3e18e52ac4e1" alt=""><figcaption></figcaption></figure>

If your code fails after running it, you will see an error message with the relevant stack trace:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FKWJN0vX8FlCuT8ns4KBI%2FScreenshot%202025-02-20%20at%209.38.59%E2%80%AFpm.png?alt=media&#x26;token=fbccb405-c5de-454f-82bd-d5ebe8910a4f" alt=""><figcaption></figcaption></figure>

### Data

Data is contextually relevent information for your [Request Script](#request-script) and [Response Script](#response-script).

You can reference the information included within Data as follows:

```javascript
data.<KEY>
```

Where `<KEY>` is replaced with the associated key on the [Data Object](#the-data-object).

For more information on Data, please see [Data Object](#the-data-object).

### The Data Object

[Data](#data) is contextually relevant information for your [Request Script](#request-script) and [Response Script](#response-script).

The Data Object is an [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) that holds the [Data](#data).

The first [Action](#actions) in your Flow will contain [Data](#data) in the [Request Script](#request-script) which is relevent to your [Trigger Event](#triggers). For example, if your Flow was assigned to the "vulnerability-created" Event, then your Data Object will contain all of the information relating to the vulnerability.

However from this point forward, you can control how you would like your Data Object to look for the [Response Script](#response-script) and any subsequent [Actions ](#actions)going forward.

In the following example, we can see that Data Object has vulnerability-related information due to the "vulnerability-created" Event.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FKvSdXO1g1C1VxJfqFocN%2F2.png?alt=media&#x26;token=7255b6e1-4a15-4275-a370-f74959e3a7f7" alt=""><figcaption></figcaption></figure>

You can refer to keys on the Data Object using the following syntax:

```javascript
data.<KEY>
```

Using the example above, if you wanted to store the vulnerability Id in a constant, you could do the following:

```javascript
const vuln_id = data.vulnerability_id;
```

Keeping with the example above, if you wanted to extract the project Id for the vulnerability, you could do the following:

```javascript
let project_id = undefined;

if (data.vulnerability_projects) {
    for (let x = 0; x < data.vulnerability_projects.length; x++) {
        if (data.vulnerability_projects[x].id) {
            project_id = data.vulnerability_projects[x].id;
        }
    }
}
```

If you needed to pass this information to the next step of this Flow, which using the example above will be the [Response Script](#response-script) on the first [Action](#actions) - you can include the "data" key in your [Response Object](#the-response-object) and pass in an [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) with key/value pairs as follows:

```javascript
return {
    decision: { 
        status: 'continue'
    },
    data: {
        af_project_id: project_id,
        af_vuln_id: vuln_id,
        af_vuln: data
    }
}
   
```

Continuing with this example, the [Response Script](#response-script) will now have the following Data Object:

```javascript
data = {
    af_project_id: "...",
    af_vuln_id: "...",
    af_vuln: {
        "vulnerability_title": "...",
        ...
    }
}
```

When viewing the details of a [Run](#run-overview) - you can see what [Data](#data) was passed as input and output into an [Action.](#actions)

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fq0dXkcCPaW7rcOAXj3ML%2FScreenshot%202025-02-20%20at%202.53.17%E2%80%AFpm.png?alt=media&#x26;token=9fd954fc-eb55-4b59-ad67-9f9b57bdad4c" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FJDAMFMSrZy5k8M2uECmo%2FScreenshot%202025-02-20%20at%202.53.24%E2%80%AFpm.png?alt=media&#x26;token=71b34f42-fe9a-4dd1-bd81-111b812b4e96" alt=""><figcaption></figcaption></figure>

If you would need to log the Data Object for visibility or debugging during execution of a [Run](#run-overview) you can do the following:

```javascript
Logger.debug('Data:');
Logger.debug(JSON.stringify(data));
```

You can then view the details in the [Run Logs](#runlogs)

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2F9pgoXVuI7i8oU2zs6qEw%2FScreenshot%202025-02-20%20at%202.59.45%E2%80%AFpm.png?alt=media&#x26;token=877bda54-eca8-4c94-9019-ceb72b5502e0" alt=""><figcaption></figcaption></figure>

When working on [Action Events](#action-events) - you can select which test context(s) you would like to access for the purposes of building and testing your flows.

For example, if your Action Event was restricted to `Project` and `Projects` entities - you can load a test context for either entity:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FBCq9bU2kfJ4XFbeBXgEv%2FScreenshot%202026-02-28%20at%209.12.01%E2%80%AFpm.png?alt=media&#x26;token=a17eecbd-6b64-430a-8cc0-1283b4b6e7ff" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FY7hIviu1pn0VOPBkzvpn%2FScreenshot%202026-02-28%20at%209.12.17%E2%80%AFpm.png?alt=media&#x26;token=033f2b26-501b-4028-9781-05d5002bd501" alt=""><figcaption></figcaption></figure>

### The Response Object

The Response Object is the HTTP information which is sent back from the server during the [Response](#response).

The Response Object is available in the [Response Script](#response-script).

The Response Object is made up of the following:

* [HTTP Response Status Code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
* [HTTP Response Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)
* [HTTP Response Body](https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages)

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FOcmgapJkZSw5TklFIG2e%2FScreenshot%202025-02-20%20at%203.32.39%E2%80%AFpm.png?alt=media&#x26;token=b29d2cd4-43fc-443d-9c0e-26b839e49f97" alt=""><figcaption></figcaption></figure>

You can refer to keys on the Response Object using the following syntax:

```javascript
response.<KEY>
```

An example of the Response Object:

```json
response = {
    "statusCode": 200,
    "headers": {},
    "body": ""
}
```

* The **statusCode** will be accessible as a [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number).
* The **headers** will be accessible as a [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object).
* The **body** will be accessible as a [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String).

If you are expecting the body to be returned as a [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) payload (which is common for [RESTful APIs](https://developer.mozilla.org/en-US/docs/Glossary/REST)) - you must first parse the body into JSON format before you can access it using [dot or bracket notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors), see example below:

```javascript
const body = JSON.parse(response.body);
```

When viewing the details of a [Run](#run-overview) - you can see the [Response](#response) [Status Code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) and Response Headers and Response Body:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FcWCj9wpc6I1xqx0jEPyB%2FScreenshot%202025-02-28%20at%201.05.22%E2%80%AFpm.png?alt=media&#x26;token=13d28081-5114-440c-9da4-25754a49e0df" alt=""><figcaption></figcaption></figure>

If you would need to log the Response Object for visibility or debugging during execution of a [Run](#run-overview) you can do the following:

```javascript
Logger.debug('Response:');
Logger.debug(JSON.stringify(response));
```

You can then view the details in the [Run Logs](#runlogs)

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FgsKHB9PSXdmLKc3UvWtF%2FScreenshot%202025-02-20%20at%203.43.26%E2%80%AFpm.png?alt=media&#x26;token=03a3f534-b96e-43e4-8a3b-7c46df2e2ea0" alt=""><figcaption></figcaption></figure>

### The Return Statement

The Return Statement is the action to take for your [Request Script](#request-script) and [Response Script](#response-script).

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FQXTAGLJwMqNFvcxNmuHh%2FScreenshot%202025-02-23%20at%209.11.05%E2%80%AFam.png?alt=media&#x26;token=ff9d08ff-1e87-4d5c-802b-6dde77b23883" alt=""><figcaption></figcaption></figure>

The Return Statement is made up of the following components:

* [Decision](#decision)
* [Request](#request)
* [Data](#data-1)

```javascript
return {
   decision: { 
     status: 'continue', 
     message: 'Payload is valid, proceed to submit request', 
   }, 
   request: { 
     url: 'https://www.attackforge.com/api',
     body: {}, 
     headers: {}, 
     method: 'GET', 
   }, 
   data: {} 
};
```

#### Decision

The following Flow Return Decisions are supported:

* Continue
* Finish
* Abort
* Next
* Repeat

```javascript
return {
   decision: { 
     status: 'continue', 
     message: 'Payload is valid, proceed to submit request', 
   }
};
```

The decision is the action that your script will take. A decision is made up of the following components:

* status - a supported status (see below)
* message - an optional message to display in the logs
* delay - an optional number in milliseconds to wait until proceeding with the [Request](#request) or the next [Action](#actions). The minimum delay is 0. The maximum delay is 86400000 (24 hours).

```javascript
return {
   decision: { 
     status: 'continue', 
     message: 'Payload is valid, wait 5 seconds then proceed to submit request',
     delay: 5000 
   }
};
```

You can also include the decision as a string if you do not need to include a message:

```javascript
return {
   decision: "continue" //also supports "next", "abort", "finish"
};
```

The following statuses are supported:

**CONTINUE**

Continue will instruct your script to continue with normal execution. For example, continuing in the [Request Script](#request-script) will result in the [Request](#request) being made. Continuing in the [Response Script](#response-script) will result in executing the next [Action](#actions).

Example using Continue:

```javascript
return {
   decision: { 
     status: 'continue', 
     message: 'Payload is valid, proceed to submit request', 
   }
};
```

**NEXT**

Next will instruct your [Request Script](#request-script) or [Response Script](#response-script) to move to the next [Action](#actions). This is useful if a [Request](#request) in your Flow is conditional i.e. it may or may not need to be made.

Example using Next:

```javascript
return {
   decision: { 
     status: 'next', 
     message: 'Asset already exists. Move to create vulnerability', 
   }
};
```

**REPEAT**

Repeat will instruct your [Action](#actions) to repeat. This is useful for the following use cases:

* Create a 'for loop' Action over a list of data - for example create a new vulnerability for each record in a long list.
* Interact with paginated endpoints to retrieve the full list of results.
* Request failed; update the payload and try again.

When you repeat an action, you can also modify its [Data](#the-data-object). This means you can pass in new data and context to the Action.

**Example Action using Repeat**&#x20;

***Request Script***

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FGlpmYf2mtY8a3TFlsPNP%2Frepeat-action-2.png?alt=media&#x26;token=6f0909c5-b6d7-44d7-bb01-c8444954326d" alt=""><figcaption></figcaption></figure>

***Response Script***

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FO8G6kJKoAbTZWAbBd1Dd%2Frepeat-action-1.png?alt=media&#x26;token=993afe5a-8677-408c-8292-f0ecdc31359a" alt=""><figcaption></figcaption></figure>

***Example 1: Process list of data***

Say you have 100 vulnerabilities in a list. The purpose of your Action is to create a new vulnerability.

On the *first iteration* of the Action, you create vulnerability `1 out of 100` - leaving 99 more to go.

You can then repeat the Action, updating the list to remove the vulnerability which was just created.

On the *second iteration* of the Action, you create vulnerability `2 out of 100` - leaving 98 more to go.

This process repeats until you have 0 vulnerabilities left in the list to process, then you call *next* to move on to the next Action in your Flow, or *finish* to gracefully end your Flow.

***Example 2: Interact with paginated endpoints***

Say you have 1000 vulnerabilities you need to access, however the page length of the API endpoint only returns 50 at a time. The purpose of your Action is to fetch a page of vulnerabilities.

On the *first iteration* of the Action, you fetch vulnerabilities `1 to 50 out of 1000` - leaving 950 more to go.

You can then repeat the Action, updating the page marker to fetch the next page.

On the *second iteration* of the Action, you fetch vulnerabilities `51 to 100 out of 1000` - leaving 900 more to go.

This process repeats until you have 0 pages left to fetch, then you call *next* to move to the next Action in your Flow, or *finish* to gracefully end your Flow.

When an Action repeats, the logs for each iteration will be visible to you in the [Flow Run](https://support.attackforge.com/attackforge-enterprise/modules/flows#run-overview) logs.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FM7gNRoU7Ql8lgHVXtrJz%2Frepeat-action-3.png?alt=media&#x26;token=2a323509-8029-49c4-a961-dc29dfc9e960" alt=""><figcaption></figcaption></figure>

**ABORT**

Abort will terminate your Flow as an error condition. This is useful in cases where your Flow can no longer proceed due to various reasons.

Example using Abort:

```javascript
return {
   decision: { 
     status: 'abort', 
     message: 'Auth token not generated. Check if credentials are valid?', 
   }
};
```

**FINISH**

Finish will terminate your Flow as an success condition. This is how you would normally terminate a Flow.

Example using Finish:

```javascript
return {
   decision: { 
     status: 'finish', 
     message: 'Vulnerability created!', 
   }
};
```

#### Request

The Request is the HTTP Request information that your [Request Script](#request-script) will use. Request is made up of the following components:

* url
* body
* headers
* method

```javascript
return {
   decision: { 
     status: 'continue', 
     message: 'Payload is valid, proceed to submit request', 
   }, 
   request: { 
     url: 'https://www.attackforge.com/api',
     body: {}, 
     headers: {}, 
     method: 'GET', 
   }
};
```

**URL**

The URL is the URL that the [Request](#request) will be sent to. This field is optional. If it is not specified, the [URL](#url) set in the [Action](#actions) will prevail. If it is specified, it will take precedence over the [URL](#url) set in the [Action](#actions).

**BODY**

The Body is the payload body that will be sent in the [Request](#request). This field is optional. If it is not specified, no body will be sent in the [Request](https://support.attackforge.com/attackforge-enterprise/self-service-restful-api/getprojectrequest#request).

Example with a JSON Body:

```javascript
return {
    decision: { 
        status: 'continue'
    },
    request: {
        body: {
            fields: {
                project: {
                    key: jiraProjectKey
                },
                summary: summary,
                description: description,
                priority: {
                    name: priority
                },
                issuetype: {
                    name: 'Bug'
                },
                labels: labels
            }
        }
    }
};
```

**HEADERS**

The Headers are the HTTPS Headers that the [Request](#request) will use. This field is optional. If it is not specified, the [Headers](#headers) set in the [Action](#actions) will prevail. If it is specified, it will take precedence over the [Headers](#headers) set in the [Action](#actions).

Example Headers:

```javascript
return {
    decision: { 
        status: 'continue',
    },
    request: {
        headers: {
            'Content-Type': 'application/json',
            'x-ssapi-key': secrets.af_auth,
        }
    }
};
```

**METHOD**

The Method is the HTTPS Method that the [Request](#request) will be sent to. This field is optional. If it is not specified, the [Method](#methods) set in the [Action](#actions) will prevail. If it is specified, it will take precedence over the [Method](#methods) set in the [Action](#actions).

Example Headers:

```javascript
return {
    decision: { 
        status: 'continue',
    },
    request: {
        method: 'GET' //supports GET, POST, PUT, PATCH, DELETE
    }
};
```

#### Data

Data is an object that can be used to pass information between [Request Script](#request-script) to [Response Script](#response-script), and from [Response Script](#response-script) to the next [Action](#actions).

The Data in the [Request Script](#request-script) for the first [Action](#actions) of the Flow will be the Event information, for example "vulnerability-created" fields. From then onwards, you can override what the data will be in the [Response Script](#response-script) and beyond.

Example with Data in the [Request Script](#request-script) of the first [Action](#actions) in the Flow:

```javascript
return {
    decision: { 
        status: 'continue',
    },
    data: {
        af_project_id: afProjectId,
        af_vuln: data
    }
};
```

Example with Data in the [Response Script](#response-script) of the first [Action](#actions) in the Flow. This example will pass on the "af\_project\_id" and "af\_vuln" that was passed in the Data from the [Request Script](#request-script) on to the next [Action](#actions) in the Flow.

```javascript
return {
    decision: { 
        status: 'continue',
    },
    data: {
        af_project_id: data.af_project_id,
        af_vuln: data.af_vuln
    }
};
```

### Downloading Files using Flows

Flows can be used to download [HTTP Response](#response) data as a file.

To download data from a HTTP Response, open the [Action](#actions) - click on **Options** then select **Download Response**.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FdagTgZHUVFl2yCBqEltu%2FScreenshot%202025-12-15%20at%207.57.05%E2%80%AFam.png?alt=media&#x26;token=e8b7e1c9-b005-4faa-9276-eae325ccb89c" alt=""><figcaption></figcaption></figure>

Then inside the HTTP Response, the response will contain a **fileId** which is the reference to the file after Flows has automatically downloaded the file. You can then refer to this fileId in subsequent Actions to use the file, for example upload it to some place.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2F2cDFQDPwsRPUEleDFeFz%2FScreenshot%202025-12-15%20at%207.59.31%E2%80%AFam.png?alt=media&#x26;token=e3fcc15f-f4af-4be8-b8db-24216bd8c841" alt=""><figcaption></figcaption></figure>

### Uploading Files using Flows

Flows can be used to upload [previously downloaded files](#downloading-files-using-flows).

To upload a file, you must have first downloaded the file and stored the **fileId** - see [Downloading Files using Flows](#downloading-files-using-flows).

Once you have the **fileId**, you can upload it using a **multipart/form-data** [HTTP Request](#request).

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2F7iDCsRMA3e1Y3VWvs9xJ%2FScreenshot%202025-12-15%20at%208.05.53%E2%80%AFam.png?alt=media&#x26;token=0b717f9b-3740-4b90-98b0-deecc0471e6a" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FEnuiWI3VZa23BibK9Pau%2FScreenshot%202025-12-15%20at%208.06.06%E2%80%AFam.png?alt=media&#x26;token=20588739-fb7d-4c19-86b2-01f994ef1a85" alt=""><figcaption></figcaption></figure>

## Runs

Flow Runs is where you can view the history of each [Run](#run-overview) you have access to, across all of your Flows. It is a consolidated view for every [Run](#run-overview). You can access this page from the Flows module.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FqRzgg9uCcHSKb7N2pxFa%2FScreenshot%202025-06-24%20at%2010.43.28%E2%80%AFam.png?alt=media&#x26;token=a128cc97-0594-4499-b6d9-6dcfb363f4b3" alt=""><figcaption></figcaption></figure>

You can also view [Runs](#run-overview) for a specific Flow by clicking on Flows and then clicking on the name of a Flow.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fp39ICK28hwC9jVYXK3ZJ%2FScreenshot%202025-06-24%20at%2010.44.38%E2%80%AFam.png?alt=media&#x26;token=897bdcc5-551f-4a5a-8d0a-ba1e763b6be2" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FUzcTXXnTf7A5zN9gUWHI%2FScreenshot%202025-06-24%20at%2010.48.39%E2%80%AFam.png?alt=media&#x26;token=db1974d2-c239-454d-bdb2-3e14ba6a0343" alt=""><figcaption></figcaption></figure>

### Run Logs

When clicking on a [Run](#run-overview), you will see an overview of the history for that [Run](#run-overview), including the following information:

* **Run Status -** Whether the [Run](#run-overview) was Completed or Failed.
* **Event -** the related Event which triggered the Flow.
* **Started -** the timestamp of when the [Run](#run-overview) started execution.
* **Duration -** the duration (in milliseconds) for execution of the [Run](#run-overview) until completion or failure.
* **Actions -** the [Actions](#actions) in-scope during the [Run](#run-overview).
* **Data -** the input and output of each [Action](#actions).
* **HTTP -** the [URL](#url), [Method](#methods), [Headers](#headers), [Request Body](#request-script), Response Status Code and [Response Body](#response-script) for each [Action](#actions) in the Flow.
* **Logs -** the logs for each [Action](#actions).

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fkyyltid8syJW9B1Xe9yh%2FScreenshot%202025-02-28%20at%201.09.24%E2%80%AFpm.png?alt=media&#x26;token=a9235946-6729-4805-9de7-0d96929585ea" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FmcXP5taQQiGw8MrFBjRx%2FScreenshot%202025-02-28%20at%201.10.02%E2%80%AFpm.png?alt=media&#x26;token=4c5ce544-10ac-4bd6-959e-caddcd1bb781" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FIhlomHYD5RwmXcKjuAIP%2FScreenshot%202025-02-28%20at%201.10.08%E2%80%AFpm.png?alt=media&#x26;token=6539f3b5-13ad-496b-bdcd-3e0442558f66" alt=""><figcaption></figcaption></figure>

If you include [Logging](https://support.attackforge.com/attackforge-enterprise/afscript#logging) in your [Request Script](#request-script) or [Response Script](#response-script), you will be able to see the logs here during execution of a Flow.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FYKUVYFssgev00yFBLXcY%2FScreenshot%202025-02-23%20at%207.52.16%E2%80%AFpm.png?alt=media&#x26;token=24ae73a9-08b8-417b-9db1-7217169ff732" alt=""><figcaption></figcaption></figure>

### Manually Run Flow

You can manually run a Flow at any time. This is useful for testing your Flow. When you manually run a Flow, the input into the first [Action](#actions) will be test data. You can modify the test data to match your testing needs.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FD7ARbRFKDIh0JIgZrhCr%2FScreenshot%202025-02-23%20at%208.04.17%E2%80%AFpm.png?alt=media&#x26;token=9d06186b-6873-4dc8-aeb8-23b330fc1aa4" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FQUmyhmwwblB35ylEkZey%2FScreenshot%202025-02-23%20at%208.04.29%E2%80%AFpm.png?alt=media&#x26;token=ed9af120-d3ec-4829-b68d-3562377e8991" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fvybh3wERPrkUmCTImPj1%2FScreenshot%202025-02-23%20at%208.04.59%E2%80%AFpm.png?alt=media&#x26;token=627353e9-c72c-4036-b73a-46293edac839" alt=""><figcaption></figcaption></figure>

### Re-Run

You can manually re-run a Flow at any time. When you Re-Run a Flow, it will execute with exactly the same input data into the first [Action](#actions).&#x20;

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FMvwntChUE1rqOFaOwl1B%2FScreenshot%202025-02-23%20at%207.54.33%E2%80%AFpm.png?alt=media&#x26;token=3772a6d5-604e-4102-a093-bc3bf54fcea3" alt=""><figcaption></figcaption></figure>

After a Flow has Re-Run, you will notice the [Event Trigger](#triggers) will show that it was Re-Run.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fz0WhbeRkd2H3qh1jfaMs%2FScreenshot%202025-02-23%20at%208.01.25%E2%80%AFpm.png?alt=media&#x26;token=724ce59d-e009-4e1e-9084-7c2bd386d162" alt=""><figcaption></figcaption></figure>

### Accessing Previous Runs

When a HTTP Triggered Flow is invoked, the Flow will Run asynchronously.

Due to the asynchronous nature of the [Flow Run](#runs), will you immediately receive a **Flow Run Id** in the response:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FYUzbWI6mYpPjvAPCD6Qe%2FScreenshot%202025-11-12%20at%204.19.19%E2%80%AFpm.png?alt=media&#x26;token=e91fe734-d557-4525-8463-043b3f640522" alt=""><figcaption></figcaption></figure>

The Flow Run Id can then be used to poll and fetch the results of the Flow Run once it has reached its terminal state.

To fetch the results of the Flow Run, you would need to make the following API request:

```bash
curl --request GET \
	--url 'https://{{tenant}}/api/flows/runs/{{flowRunId}}' \
	--header 'content-type: application/json' \
	--header 'x-user-key: {{api-key}}'
```

The result of the Flow Run will then be returned:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FAp0YF1kiMrxfeSGOIvaX%2FScreenshot%202025-11-14%20at%204.31.06%E2%80%AFpm.png?alt=media&#x26;token=b6503bfd-af1c-4663-992a-e60f6912a22c" alt=""><figcaption></figcaption></figure>

And we can confirm that this is what should have been returned based on a successful Flow Run:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FkE2NAME94MtqY07nEONw%2FScreenshot%202025-11-12%20at%204.31.13%E2%80%AFpm.png?alt=media&#x26;token=774dd89d-dcc6-4738-86f0-0aa9139209ad" alt=""><figcaption></figcaption></figure>

If accessing the Flow through the browser, for example if the Flow is a GET request and attached to a button in an email - you can set a user friendly response page by appending `?format=html` to the URL:

```bash
curl --request GET \
	--url 'https://{{tenant}}/api/flows/runs/{{flowRunId}}?format=html' \
	--header 'content-type: application/json' \
```

A `successful` response will appear as follows:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FizOI4NBDSXZjZAXMWNtG%2Fsuccess.png?alt=media&#x26;token=56343e1c-ad9d-4d8a-bc8e-c82365aeb347" alt=""><figcaption></figcaption></figure>

A `failed` response will appear as follows:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FWtyTRmUAK1MLHqKk3yaQ%2Ffailed.png?alt=media&#x26;token=b39b42ca-f423-4d47-b52e-85b690b7674a" alt=""><figcaption></figcaption></figure>

### Flow Run Statuses

The following Flow Run Statuses are available:

* **Running -** the Flow is currently running.
* **Completed -** the Flow Run has completed.
* **Failed** - the Flow Run has failed. This happens when a Flow Return decision is set to Abort; or when there is a runtime error in the script.
* **Dropped** - the Flow Run was detected as a duplicate and dropped.
* **Missed** - the Flow Run was scheduled, however did not run as per schedule, for example if the AttackForge server was restarted.
* **Terminated** - the Flow Run was manually terminated.

## Flow Readme

Every flow can have a readme which helps to detail key information such as:

* How the flow works
* How to operate the flow
* Links to external documentation
* Contact information for key persons

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FaUNLT4lQcSPUZF85nRQv%2FScreenshot%202025-06-24%20at%2012.31.17%E2%80%AFpm.png?alt=media&#x26;token=db0927a6-28d2-4e07-99d8-342096f56c3d" alt=""><figcaption></figcaption></figure>

You can create and edit the readme when creating or editing the flow:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FZxlnDRNp9hKrSNWfKnCA%2FScreenshot%202025-06-24%20at%2012.24.39%E2%80%AFpm.png?alt=media&#x26;token=84aae8b0-b3f8-452f-abf1-5100dae1266f" alt=""><figcaption></figcaption></figure>

## Importing/Exporting Flows

You can export your existing Flows and import Flows at any time. This utility can help to:

* Share Flows with others, without giving them access to your Flows
* Create a backup of your Flows
* Bootstrap a new Flow based on a template

To export a Flow, click on the `Export Flow` button. The Flow will be exported with a `.flow` extension format.

> **IMPORTANT**: Exported Flows do not contain the values of [Secrets](#secrets). However for compatibility and convenience, the [Secret](#secrets) key/name will be included in the export.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FG5j8Ejt6QsxcTfam2uVQ%2FScreenshot%202025-02-23%20at%208.39.50%E2%80%AFpm.png?alt=media&#x26;token=efa40bcb-ace2-4511-9552-aaee00600855" alt=""><figcaption></figcaption></figure>

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FJM7oAgAOmYc6WOfGAts8%2FScreenshot%202025-02-23%20at%208.40.34%E2%80%AFpm.png?alt=media&#x26;token=2961c508-3871-4d1e-880d-e55f0ccc6463" alt=""><figcaption></figcaption></figure>

To import a Flow, click on `Import Flow`:

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fsh0yJn50NGsvpKd5B50e%2FScreenshot%202025-02-23%20at%208.47.40%E2%80%AFpm.png?alt=media&#x26;token=21fcf91e-f75a-4f67-bd22-a2bee7d6c4dd" alt=""><figcaption></figcaption></figure>

Select the Flow you would like to import (.flow file):

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FQTphkEaTiQNVb8zBxezF%2FScreenshot%202025-02-23%20at%208.46.46%E2%80%AFpm.png?alt=media&#x26;token=4e0f7f6d-f926-476b-a186-b952bfd3e1e1" alt=""><figcaption></figcaption></figure>

You will have an opportunity to review and adjust the Flow prior to saving.

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FJTaBZodjDz84DJPg6VQU%2FScreenshot%202025-02-23%20at%208.57.43%E2%80%AFpm.png?alt=media&#x26;token=ae25692b-d37a-4b00-9975-007d1742d3bc" alt=""><figcaption></figcaption></figure>

## Transferring Flows

Flows run under the context of an Owner. That means, when the event happens for the Owner, the Flow will trigger.

You can transfer ownership of Flows when required, so that the Flow can operate under the context of another user.

To transfer ownership of your Flow - open the Flow settings page and click on `Transfer`

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FjtEybznvxTzdEfkzvKN6%2FScreenshot%202025-05-28%20at%2010.52.17%E2%80%AFam.png?alt=media&#x26;token=ce7bd2f9-89ba-41f8-b35b-43e3b074ca81" alt=""><figcaption></figcaption></figure>

Select the user or enter in their email address and click `Transfer`

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2Fl1FwX8iGR9RYn8k0uyl7%2FScreenshot%202025-05-28%20at%2010.54.27%E2%80%AFam.png?alt=media&#x26;token=e7ca510f-ea19-4d24-87d9-68f82a33d7b3" alt=""><figcaption></figcaption></figure>

The user will immediately receive ownership of the Flow, however it will be disabled until they review the Flow and chose to enable it.
