Overview
Workflows enable automation of actions based on triggers. A workflow consists of:- Trigger: What starts the workflow (e.g., an API request, a new log event, or a new autodiscovered resource)
- Actions: What the workflow does when triggered (e.g., send a Slack message, call the Formal API)
Triggers vs Actions
A workflow has exactly one trigger and one or more actions. Actions can be chained together using
depends_on and conditionally executed using if.
Workflow Structure
depends_on - Action Chaining
The depends_on field controls the execution order of actions. Actions with empty depends_on run immediately after the trigger. Subsequent actions run after their dependencies complete.
Referencing Previous Trigger and Action Outputs
Actions can reference previous triggers and actions outputs via the following syntax in CEL expressions:trigger.<output_field>: reference any output field of the triggeractions.<action_name>.<output_field>: reference any output field of an action by its name
if or the api-request allow argument, take CEL expressions by default. For arguments that take strings
instead, embed CEL expressions via the ${{}} syntax.
if - Conditional Execution
The if field is a CEL expression that determines whether a subsequent action should execute based on the previous actions or trigger.
Trigger Types
api-request
Triggered when a user calls the CreateWorkflowTrigger API endpoint. Useful for manually triggered workflows or integrations.
Args:
Outputs (available in actions):
When the caller authenticates with an OIDC integration,
user.oidc is also available:
Example:
payload:
new-log
Triggered when a new log event matches a specified condition. Useful for reacting to specific database queries, policy violations, or access patterns.
Args:
Outputs (available in actions):
Example:
new-autodiscovered-resource
Triggered when a new resource is autodiscovered via cloud integration (AWS, GCP, etc.). Useful for automatically onboarding new databases.
Args: None
Outputs (available in actions):
Example:
updated-autodiscovered-resource
Triggered when an existing autodiscovered resource is updated.
Args: None
Outputs (available in actions):
Example:
deleted-autodiscovered-resource
Triggered when an autodiscovered resource is deleted because it no longer exists in the cloud provider.
Args: None
Outputs (available in actions):
Example:
cron-schedule
Triggered on a recurring schedule defined by a standard 5-field cron expression (minute hour day-of-month month day-of-week). All times are evaluated in UTC. Useful for periodic checks, scheduled reports, and recurring maintenance tasks.
Args:
Outputs (available in actions):
Example:
recovery has no effect. It only matters in the unlikely event of a Formal platform outage where the workflow engine is temporarily unable to process scheduled triggers. When the platform recovers, any missed ticks are handled according to the recovery policy. If omitted, defaults to none. Missed triggers are capped at a 24-hour lookback window.
Cron schedules are always evaluated in UTC. To schedule at a local time, convert manually (e.g., 9am US Eastern =
"0 14 * * *" during EDT or "0 13 * * *" during EST).form-submission
Triggered when a user submits a Formal form via Slack. Useful for approval workflows, access requests, and other structured data collection scenarios.
Args:
Outputs (available in actions via
trigger.form_submission):
Example:
See the Forms documentation for details on creating forms and the full Slack integration.
Action Types
send-slack-message
Sends a direct message to a Slack user or channel. Requires a Slack integration to be configured.
Args:
Outputs:
Example:
ask-in-chat
Sends an interactive message with Yes/No buttons. The workflow pauses until the user responds.
Args:
Outputs:
The user’s response triggers a webhook that continues the workflow with
action-response.
Example:
formal-app-command
Calls a Formal API endpoint using a machine user’s credentials.
Args:
Outputs:
Example:
Terraform Examples
Next Steps
Policies
Learn about Formal policies for access control
Terraform Provider
Full Terraform provider documentation