---
id: workflows
title: Workflows and steps
sidebar_label: Workflows
---

A **step** is a reusable script with declared inputs, outputs and secret
references. A **workflow** composes steps in order and targets a set of servers.
Running one dispatches the steps to each target's agent and streams the output
back live.

## Steps

A step has:

| Field                 | Meaning                                         |
| --------------------- | ----------------------------------------------- |
| `name`, `description` | Library identity                                |
| `interpreter`         | `bash` or `powershell`                          |
| `script`              | The body                                        |
| `declared_inputs`     | Named parameters with defaults and descriptions |
| `declared_outputs`    | Names this step promises to export              |
| `secret_refs`         | Vault entries injected as environment variables |

### Passing values between steps

Each step runs with `WORKFLOW_ENV` set to a file path. Anything written there as
`KEY=value` becomes an environment variable for the **later steps of the same
run on the same server**.

```bash
HOSTNAME=$(hostname)
echo "$HOSTNAME"
echo "HOSTNAME=$HOSTNAME" >> $WORKFLOW_ENV
```

That is the whole mechanism. `declared_outputs` documents what a step exports so
the designer can show it; the file is what actually carries the value.

### Secrets

List a vault group in `secret_refs` and its key/value pairs are injected as
environment variables when the step runs. They are not written to the run log
unless your own script echoes them. See [Secrets](./secrets.md).

### The workspace

Every run gets a per-run working directory on each target. Steps share it, so
one step can leave a file for the next. The agent removes it at the end of the
run (`CleanupWorkspaceCmd`).

Do not use it for anything that must outlive the run.

## Default steps

A small library is seeded into every organisation at boot from the image, so a
new install is not staring at an empty page.

:::warning Default steps are read-only
Editing or deleting one is refused with `409`. Seeding rewrites them on every
boot, so an edit would silently revert and a delete would come back at the next
restart refusing is the honest answer.

To customise one, use the per-step **script override** in the workflow designer,
which belongs to that workflow and is not touched by seeding. To add to the
shared library permanently, a file has to be committed to the repository and the
server image rebuilt.
:::

The UI mirrors this the step modal opens read-only and Delete is hidden but
the API is the boundary; the UI is the courtesy.

## Building a workflow

1. **Workflows → New**.
2. Add steps in order from the library.
3. Set inputs per step.
4. Set failure behaviour per step.
5. Choose target servers.

### Failure behaviour

| `on_failure` | Effect                                                          |
| ------------ | --------------------------------------------------------------- |
| `stop`       | Abort this server's run. Other servers continue                 |
| `continue`   | Record the failure, run the next step anyway                    |
| `retry`      | Re-run the step up to `max_retries`, then treat it as a failure |

### Per-step overrides

A workflow can override a step's script or its secret references without
touching the library entry. This is how you adapt a default step, and it is
scoped to that workflow.

## Running

**Run** snapshots the resolved steps into the run record and dispatches each step
to the target's agent over the command stream no waiting for the next poll.

:::info Runs freeze their steps
The snapshot is why editing a step tomorrow never rewrites what happened today.
A run shows the script that actually executed, not the current library version.
:::

Targets run **in parallel**; steps within one server run **in order**.

## Watching a run

Step stdout and stderr stream back as chunks, are appended to a log file on the
server, and the UI follows them live. Each step records status, attempts, exit
code and its exported environment.

**Cancel** stops a run in progress. Steps already running on an agent finish;
nothing further is dispatched.

## Log retention

Run logs are swept on a schedule set by `workflow_log_retention_days` in
Settings:

| Value    | Meaning        |
| -------- | -------------- |
| unset    | 30 days        |
| a number | that many days |
| `0`      | keep forever   |

## Import and export

Steps export to a JSON file (`vantage.step/v1`) and import back, which is how
you move a step between instances or keep one in version control. There is also
a parse endpoint that turns a pasted script into a draft step by reading its
declared inputs and outputs.

## Practical notes

- A step is a script. It runs as root, on the target, with no sandbox. Review
  what you import.
- Keep steps small and single-purpose; compose them in the workflow. That is
  what makes the library reusable rather than a folder of near-duplicates.
- PowerShell steps only make sense on Windows targets and bash steps on Linux
  ones. Nothing stops you targeting the wrong one; the step simply fails.
