Skip to content

Workflows

A workflow is a graph of steps that runs without a person at each step. A trigger starts a run. The steps after the trigger wait, ask a decision model, send email, deploy, roll back, or give a task to an agent.

Open the section at Agents > Settings > Workflows. Each organization has its own workflows. The imbi-workflows service runs them.

Setup has four steps:

  1. Prepare the platform: an operator does this one time for each install and organization.
  2. Build the workflow on the canvas, then click Save.
  3. Test it: click Test run. Nothing real happens.
  4. Activate it: set the switch to Active.

How the parts connect

Part What it is
Workflow A name, a slug, an owner team, and its versions
Version One saved graph and its settings. A version never changes after you save it
Active version The one version that triggers start. Saving does not change it
Step A node on the canvas. Its step type sets its parameters and output ports
Trigger A step that starts a run: Manual run, Schedule, or Webhook
Connection An edge from an output port of one step to the input of the next
Run One execution of the active version, with a record for each step

A workflow has one of three statuses:

Status Meaning
Draft No version was activated yet
Active Triggers start runs of the active version
Paused Triggers start no runs

See ADR 0021 for the design.

Build a workflow

  1. Open Agents > Settings > Workflows and click New workflow.
  2. Enter a name in the header. Imbi makes the slug from the name.
  3. Click Choose a trigger on the empty canvas, and select a trigger.
  4. Add the steps that follow. See The canvas.
  5. Click empty canvas to open Workflow settings. Select the Owner team. A workflow must have an owner team.
  6. Click Save.

Each save makes a new version. The header shows Saved ยท v<n>, or Unsaved changes.

The canvas

The editor has three parts: the step palette on the left, the canvas in the middle, and the inspector on the right.

The palette shows the step types in four groups: Triggers, Logic, Actions, and Agents. Use Search steps to find a type.

  • Click a step type to add it after the selected step.
  • Drag a step type onto the canvas to put it at that position.

On the canvas:

  • Drag from an output port to a step to connect them.
  • Drop a connection on empty canvas to open a menu. Select a step type to add it and connect it in one action.
  • Drag the canvas to move it. Use Ctrl + scroll (Cmd + scroll on macOS) to zoom.
  • Use Zoom in, Zoom out, and Fit to view at the bottom.
  • Press Delete or Backspace to remove the selected step or connection. Press Escape to clear the selection.

You cannot connect a step into a trigger, into itself, or twice on the same port.

The inspector

Select a step to see its inspector. It has these fields:

Field What it does
Title The name on the canvas
Key The name that references use. Imbi makes it from the title. Use lower case letters, digits, and _, and start with a letter. Each key must be unique
Run when For a step with more than one input: Any input arrives or All inputs arrive. See Joins
Parameters The form for the step type. See Step types
Output What the step returned in the last test run or run

Use Duplicate and Delete step at the top of the inspector.

Select a connection to see where it starts and ends, and to remove it.

Imbi validates the graph while you edit. A step with a warning shows Needs configuration. An error shows in red. The header counts the steps that need configuration.

Workflow settings

Click empty canvas to see the workflow settings.

Field Values Default
Description Free text Empty
Owner team A team in the organization None. Required
Concurrency Unlimited, One run at a time, One run per key Unlimited
Concurrency key One reference, for One run per key only None
Max run time (minutes) A run that runs longer stops as timed_out 120
When a run fails Notify the owner team, Do nothing Notify the owner team

Only an admin or a member of the current owner team can change the owner team.

Step types

The table shows each step type, its group, and its output ports. A step with one output port has no port name.

Type Label Group Output ports
manual Manual run Triggers One
schedule Schedule Triggers One
webhook Webhook Triggers One
wait Wait Logic One
model_decision Model decision Logic One for each branch
email Send email Actions One
deploy Deploy Actions Succeeded, Failed
rollback Rollback Actions One
agent Agent task Agents Succeeded, Failed

Each step that is not a trigger has a default timeout and a default retry count:

Type Timeout Retries
wait None 0
model_decision 60 seconds 2
email 2 minutes 0
deploy, rollback 1 hour 2
agent None. The max run time limits it 2

The API also accepts timeout_seconds and retries (0 to 10) on a node to replace the defaults. The editor has no field for them.

GET /organizations/{org}/workflow-step-types/ returns each type with its parameter schema, output schema, and sample output.

Manual run

A person starts a run with the Run button.

Parameter What to enter Default
inputs The inputs that the person must enter. Each has a name (a key) and a type: string, number, or boolean None
who Who can start and cancel runs: owner_team, admins, or anyone owner_team

The inspector shows inputs as JSON, for example:

[{"name": "service", "type": "string"}, {"name": "dry_run", "type": "boolean"}]

Every input is required. Imbi refuses an input that is not declared, and a value of the wrong type.

Output: the inputs, by name. Use {{ trigger.<name> }}.

admins means Imbi administrators. An administrator can always start and cancel a run.

Schedule

imbi-scheduler starts a run on a cron schedule.

Parameter What to enter Default
cron A cron expression. imbi-scheduler checks it Required
timezone An IANA time zone, for example America/New_York UTC

Output: fired_at, the time of the firing. Use {{ trigger.fired_at }}.

Webhook

A delivery to a gateway Webhook starts a run.

Parameter What to enter Default
webhook_id A Webhook of the organization. It must be a literal id Required
filter A CEL expression. A delivery starts a run only when it is true None (every delivery)

Output: payload, the body of the delivery. Use {{ trigger.payload.<field> }}, for example {{ trigger.payload.repository.name }}.

Create the Webhook first at Admin > \ Admin > Webhooks.

Wait

Holds the run for a fixed time.

Parameter What to enter
duration A number and a unit: s, m, h, or d. Example: 10m

Output: waited_seconds.

Model decision

A decision model selects one branch.

Parameter What to enter Default
model_id A decision model from the AI Model catalog Required
prompt The question for the model Required
context The text that the model decides on. Without it, the model gets the prompt None
min_confidence 0 to 1 0.7
branches Two or more unique names. Each name is one output port Required

When the probability of the choice is less than min_confidence, the step takes the last branch. Put the safe branch last, for example ["yes", "no"].

The model must be enabled, its provider must be enabled, its type must be decision, its driver must be typesafe, and it must have credentials. Otherwise the step fails with model_unavailable or model_credentials_missing. See AI Models.

Output: choice, probability, and reasoning.

Send email

Sends an email to users and teams of the organization.

Parameter What to enter
to One or more recipients. Each has a kind (user or team) and an id
subject The subject. Templates are allowed
body The body. Templates are allowed

Enter a user by user id. Select a team from the list. Imbi sends only to active members of the organization. It never sends to an address outside Imbi.

If the send fails for one or more recipients, the step fails with email_failed and the addresses. Imbi does not retry it, because the other recipients already have the message.

Output: recipients, the addresses that got the message.

Deploy

Deploys a version of a project to an environment, then waits for the deployment to finish.

Parameter What to enter
project_id A project id, or one reference such as {{ trigger.project }}
environment An environment slug
version A tag or a commit

The step takes Succeeded when the deployment succeeds. It takes Failed when the deployment fails or is cancelled, or when the step fails after its retries.

The imbi-workflows service account does the deployment. See Operator prerequisites for what it needs.

Output: deployment_id and status.

Rollback

Deploys an earlier version of a project again.

Parameter What to enter Default
project_id A project id, or one reference Required
environment An environment slug Required
target last_healthy, previous, or version last_healthy
version The tag or commit. Required when target is version None
  • last_healthy: the newest successful release that is not the release of the newest attempt.
  • previous: the successful release before the one that serves now.

If Imbi finds no release, the step fails with no_release_to_roll_back_to. A rollback has one output port, so a failed rollback fails the run.

Output: deployment_id and status.

Agent task

Gives an agent a task and waits for its outcome. See Agent tasks.

Parameter What to enter Default
agent_id An agent of the organization. It must be a literal id Required
instruction What the agent must do. Templates are allowed Required
project_id The primary project of the task. It must be a literal id None
budget A limit in USD. It cannot be more than the task budget of the agent The task budget of the agent

The step takes Succeeded when the outcome is done_acted, done_nothing_to_act_on, or no_reason_to_run. Every other outcome takes Failed. The engine checks the task every 30 seconds.

The person who activated the workflow owns the task. That person must still be able to make agent tasks when the step runs.

When you cancel the run, or the run passes its max run time, Imbi cancels the task. A step timeout does not cancel the task.

You cannot delete an agent that a workflow uses. The delete returns 409 with "used in N workflow(s)".

Output: task_id, outcome, reason, and summary (the last message of the agent). Run detail shows reason and summary only to people with agent_task:read.

References

A parameter can use the output of an earlier step with {{ }}. The syntax is the sandboxed Jinja of Prompts.

Reference Value
{{ trigger.<name> }} A manual input, fired_at of a schedule, or payload of a webhook
{{ <key>.<field> }} An output field of a step before this one, by its key

Examples:

  • Deploy {{ trigger.service }} to production
  • {{ decide.reasoning }}
  • {{ trigger.payload.release.tag_name }}

Rules:

  • A reference can name only a step that comes before this step on a path from a trigger. Otherwise validation shows unknown_reference.
  • When the whole value is one reference, the step gets the typed value. Otherwise the step gets text.
  • A reference to a skipped step is empty.
  • If a template fails when the step starts, the step fails with invalid_params.

Some ids have more rules, so that run input cannot select a resource in a different organization:

Parameter Allowed
webhook_id, and agent_id and project_id of an agent step A literal id only
project_id of deploy and rollback, email recipient ids A literal id, or one plain reference such as {{ trigger.project }}

A literal id must exist in the organization. Otherwise validation shows resource_not_in_organization.

Joins

A step with more than one input has a join. Set it in Run when:

  • Any input arrives (any): the step runs one time, at the first input. It ignores the other inputs.
  • All inputs arrive (all): the step runs when every input arrived or will not arrive, and at least one arrived.

A branching step (model decision, deploy, agent task) takes one port. The steps on its other ports are skipped. A step whose inputs are all from skipped paths is skipped too.

Validation warns when an Any input arrives step can get two inputs in one run.

Concurrency

Mode What it does
Unlimited Runs start at once
One run at a time One run of the workflow at a time. Other runs wait in queued
One run per key One run at a time for each key value. Runs with other keys start at once

Runs that wait start in the order that Imbi made them.

For One run per key, the Concurrency key must be one reference to a trigger value:

  • {{ trigger.service }}
  • {{ trigger.payload.repository.name }}

More rules for One run per key:

  • Each Manual run trigger must declare the input that the key uses.
  • You cannot use it with a Schedule trigger.
  • When a run has no value for the key, Imbi refuses it with 422 concurrency_key_missing and makes no run.

Validation

Imbi validates the graph while you edit, when you save, and when you activate. A save always stores the version with its issues, except when the graph is too large.

Check Issue code
At most 100 steps, 200 connections, and 64 KiB of graph JSON. A save is refused too_many_nodes, too_many_edges, graph_too_large
At least one trigger no_trigger
Each step type exists unknown_type
Parameters are valid. A missing required parameter is a warning invalid_param, missing_param (warning)
Keys and ids are unique duplicate_key, duplicate_node_id, duplicate_edge
No connection into a trigger, and each port exists edge_into_trigger, port_out_of_range, unknown_node
No cycles cycle
Each step can be reached from a trigger unreachable
Templates are valid, and references name earlier steps invalid_template, unknown_reference
Ids are literal where required, and exist in the organization invalid_reference, resource_not_in_organization
Concurrency key rules missing_concurrency_key (warning), invalid_concurrency_key, concurrency_key_with_schedule, concurrency_key_input_missing
An Any input arrives step can get two inputs any_join_overlap (warning)

Activate a workflow

  1. Save the workflow. The switch is off while there are unsaved changes.
  2. Set the switch in the header to Active.

Activation makes the latest version the active version. Runs that already started keep the version that they started with.

Activation fails in these cases:

Response Cause Fix
422 validation_failed The version has issues. Warnings count Fix every issue, save, and activate again
403 missing_permissions You do not hold a permission that a step needs. The message lists them Ask an admin to activate it, or to give you the permissions

Imbi checks the permissions of your role in the workflow's organization only. The permissions that steps need:

Step Permission
Schedule scheduled_task:create
Webhook webhook:update
Deploy, Rollback project:deployment:write
Agent task agent_task:create

Imbi records who activated the workflow. A workflow cannot do more than that person can do. When a run starts, the engine checks the person again. If the person is no longer an active member of the organization, or no longer holds the permissions, the run fails with activator_lacks_permission and the workflow pauses. A person with the permissions must activate it again.

To pause a workflow, set the switch to Inactive. Its triggers start no runs. Runs that already started continue.

Triggers

Activation, pause, and delete write a trigger binding for each schedule and webhook trigger. imbi-workflows syncs each binding when imbi-api tells it, and every 5 minutes (IMBI_WORKFLOWS_RECONCILE_INTERVAL).

  • Schedule: imbi-workflows makes the imbi-scheduler task workflow-<binding id>. The task runs as the imbi-scheduler service account. A pause disables the task. Do not edit this task: imbi-workflows changes it back.
  • Webhook: imbi-workflows adds a gateway-actions#start_workflow rule to the Webhook. The rule stays when you pause the workflow. The gateway then gets 409 and records the delivery as no effect.

Only the imbi-workflows service account can add, change, or remove a start_workflow rule. Other changes get 403 workflow_rule_forbidden. You can still edit the other rules of the Webhook.

The workflow from GET /organizations/{org}/workflows/{slug} has a bindings list. Each binding has a sync_state:

sync_state Meaning
pending imbi-workflows did not sync it yet
synced The task or the rule exists. The trigger starts runs
failed The sync failed. error has the cause. The next pass tries again

A trigger whose binding is not synced starts no runs. A bad cron expression gives a failed binding with the error from imbi-scheduler.

A schedule firing or a webhook delivery starts at most one run, also when it is sent again.

Runs

Test run

Click Test run to walk the saved latest version. Each step returns its sample output. Nothing is sent, deployed, or written.

  • Save first. The button is off while there are unsaved changes.
  • A branching step takes its first port.
  • Errors stop the test run with 422 validation_failed. Warnings do not.

The Test log tab of the bottom panel shows each step, its port, and its output.

Run

Click Run to start a run of the active version. The workflow must be active and have a Manual run trigger. If the trigger declares inputs, enter them, then click Run workflow.

Schedule and webhook triggers start runs without a person.

Run history

The Runs tab of the bottom panel lists the runs of the workflow, newest first. Click a run to see each step: status, duration, branch, error, input, and output. Open runs refresh every 2 seconds.

The workflow list shows Runs 30d and Last run for each workflow.

Run status Meaning
queued Waiting for the engine, or for another run with the same concurrency key
running The engine works on it
succeeded No step is left to run
failed A step failed and no connection handles the failure
cancelled A person cancelled it
timed_out It ran longer than the max run time

The engine keeps the run log in Postgres until ClickHouse has every event of a closed run. Then run detail reads from ClickHouse. If ClickHouse is not available, run detail of an old run returns 503, and Runs 30d and Last run are empty.

Cancel a run

Open the run and click Cancel run. The engine stops the run before its next step. Steps that did not finish become cancelled. Imbi cancels the task of an agent step. Imbi does not stop a deployment that already started.

To cancel, you need workflow:run and the same who as the trigger that started the run. A schedule or webhook run allows the owner team.

Runs that need attention

Admins see Runs that need attention on the workflow list:

  • Failed: a run that failed or timed out in the last 7 days.
  • Stuck: no engine has picked it up: an open run that no engine works on.

The list comes from GET /organizations/{org}/workflow-runs/attention.

Failures, timeouts, and retries

  • Retries. An error (a timeout, a 5xx, a connection error, a model error) uses the retries of the step. The first retry waits 5 seconds. Each retry after that waits two times longer.
  • No retry. A 4xx from imbi-api, a 403, and a failure that the step reports (a failed deployment, a failed agent outcome) are not retried.
  • Failed port. After the retries, a failed step takes its Failed port when its type has one and a connection starts there.
  • Run fails. Otherwise the run fails at once. Steps that did not start become cancelled. Then the failure policy runs.
  • Failure policy. Notify the owner team sends an email to the members of the owner team. Do nothing sends nothing.
  • Step timeout. A step that runs longer than its timeout fails with timeout, and its retries apply.
  • Max run time. The engine counts it from when Imbi made the run. A run that passes it closes as timed_out.

Deploy, rollback, and email send the idempotency key <run_id>:<node_key> to imbi-api. After a crash, imbi-api returns the first result, so the step does not deploy or send two times. If the first call did not finish, imbi-api returns 409 outcome_unknown, and the step fails without a retry.

Permissions

Permission Allows
workflow:read View workflows, their versions, and their runs
workflow:create Create workflows
workflow:write Edit, activate, and pause workflows
workflow:delete Delete workflows
workflow:run Start manual and test runs, and cancel runs

The default roles get these permissions:

Role Permissions
admin All
developer workflow:read, workflow:create, workflow:write, workflow:run
default, readonly workflow:read

The editor has no delete button. To delete a workflow, call DELETE /organizations/{org}/workflows/{slug}. Imbi refuses it with 409 while a run is queued or running.

See Roles and Permissions.

Operator prerequisites

Do these steps one time for each install.

  1. Run imbi-api setup-permissions. This adds the workflow:* permissions, workflow:run to the imbi-scheduler and imbi-gateway roles, and scheduled_task:* to the imbi-workflows role.
  2. Run imbi-api setup-clickhouse. This makes the workflow_runs and workflow_run_events tables.
  3. Restart iggy-connect after the first deploy, so that it reads the two new streams.
  4. Run imbi-workflows. It runs in Helm service.mode: all, or as its own release with service.mode: workflows (port 8006).
  5. Give imbi-workflows its service account credential. See Helm values.

Each organization that uses workflows needs three service accounts as members: imbi-workflows, imbi-scheduler (for schedule triggers), and imbi-gateway (for webhook triggers). Each account has the role of the same name in the organization.

imbi-api setup does this for the organization that it creates. For each other organization, run this command:

imbi-api setup-service-accounts --organization <organization slug>

Run imbi-api setup-permissions first, because the command assigns the seeded roles by name. When only one organization exists, you can omit --organization. The command does not change an account or a credential that already exists.

You can also add the accounts in the Admin UI:

  1. Open Admin > Global Admin > Service Accounts.
  2. Open imbi-workflows. Under Organization Memberships, click Add to Organization.
  3. Select the organization and the imbi-workflows role.
  4. Do steps 2 and 3 again for imbi-scheduler with the imbi-scheduler role, and for imbi-gateway with the imbi-gateway role.

For deploy and rollback steps, the imbi-workflows account also needs the bounds of ADR 0017:

  1. Grant integration:act-as-service to the imbi-workflows role at Admin > Global Admin > Roles. Imbi does not grant it by default.
  2. Select Allow Autonomous Deployments on each target environment at Admin > \ Admin > Environments.

The imbi-workflows account also needs organization membership for agent steps.

Helm values

Value Purpose
workflows.serviceAccount.clientId Client id of the imbi-workflows service account
workflows.serviceAccount.clientSecret Client secret of that account
workflows.schedulerUrl imbi-scheduler's task API with its route prefix, for example http://imbi-scheduler.<namespace>.svc.cluster.local:8005/api. Set it when imbi-workflows runs as its own release. Empty works in all mode only

imbi-api setup seeds the account to match the client id and secret. Set both or neither. With neither, setup makes a pair and prints it one time. With existingSecret, the chart reads the workflows-sa-client-id and workflows-sa-client-secret keys. In service.mode: workflows, the pod does not start without them.

A release with service.mode: workflows also needs service.internalApiUrl and service.publicApiUrl, as for the scheduler. See Kubernetes.

Engine settings

Variable Purpose Default
IMBI_WORKFLOWS_WORKERS Runs that one process works on at the same time 10
IMBI_WORKFLOWS_POLL_INTERVAL Most seconds between polls for runs 10
IMBI_WORKFLOWS_LEASE_SECONDS How long a claim of a run lasts. More than 30 300
IMBI_WORKFLOWS_DEPLOY_POLL_SECONDS Seconds between deployment checks 15
IMBI_WORKFLOWS_AGENT_POLL_SECONDS Seconds between agent task checks 30
IMBI_WORKFLOWS_SCHEDULER_URL imbi-scheduler's task API. Helm sets it from workflows.schedulerUrl http://localhost:8005/api
IMBI_WORKFLOWS_RECONCILE_INTERVAL Seconds between trigger binding syncs 300

See also Agents, Agent tasks, and Agent runners.