Step Handler Catalog
Scope: this catalog documents the handler set shipped with the demo/e2e plugin wheels. Handlers are pluggable and installed per instance — your instance lists its live handler set under Settings → Installed Plugins, and the flow editor's step palette shows the same configuration forms rendered from these schemas. In the app, the Help drawer's Installed Handlers topic (on the flow editor) shows the live catalog instead of this pinned one, including each handler's own documentation page when its plugin ships one.
Handlers are grouped into namespaces by their id prefix (for example netcli.* for network-CLI steps). Configuration tables list top-level fields; nested objects are edited structurally in the flow editor.
ansible.playbook
Ansible Playbook · category: Actions · kinds: ACTION, CHECK, EXECUTE
Run an Ansible playbook against the step's target devices, with the inventory and credentials generated from Hegemony's inventory.
| Key | Type | Default | Description |
|---|---|---|---|
timeout_seconds | integer | 600 | Timeout (seconds) — Maximum run time of the container, including the image pull. |
memory | string | "" | Memory Limit — Container memory limit, e.g. 512m or 2g. Defaults to 1g. |
cpus | string | "" | CPU Limit — Container CPU limit, e.g. 0.5 or 2.0. Defaults to 1.0. |
env | object | Environment Variables — KEY=VALUE format, one per line. Keys starting with HEGEMONY_ are reserved and ignored. Prefer Secrets for sensitive values: environment variables are visible in the sandbox's container metadata. | |
egress_mode | string | "" | Egress policy mode — Outbound firewall for this step's container: 'open' allows everything except Deny rules, 'allow-listed' allows only Allow rules (minus Deny), 'deny-all' blocks all network access. Leave empty to inherit the flow's network policy. |
egress_allow | array of string | Egress allow rules — One rule per line, used with allow-listed mode: CIDR[:port[-port]][/tcp|udp] or service:port. | |
egress_deny | array of string | Egress deny rules — One rule per line, same format as Allow rules. Deny always wins. | |
mounted_files | object | null | Attachments — Which flow attachments are copied into the container under /attachments. Leave at All to copy every attachment; a selector ending in / includes that folder recursively. |
playbook | string | Playbook — Path of the playbook among the flow attachments, e.g. site.yml or ansible/site.yml. It runs from its own folder, so roles/, group_vars/ and ansible.cfg next to it are picked up. (required) | |
limit | string | "" | Limit — Optional host pattern passed to --limit, e.g. a group name or host name. |
check_mode | boolean | false | Check mode (dry run) — Run with --check: report what would change without changing anything. Combine with Show differences to review changes before approving a real run. |
diff | boolean | false | Show differences — Run with --diff so changed files and configuration show before/after. |
tags | array of string | Tags — Only run tasks with these tags (--tags), one per line. | |
skip_tags | array of string | Skip tags — Skip tasks with these tags (--skip-tags), one per line. | |
extra_vars | object | Extra variables — NAME=value, one per line, passed as extra variables (highest precedence). Values may use templates such as {{ inputs.service }}. | |
secrets | object | Secrets — NAME=secret reference, one per line: a {{ secret('...') }} template or a bare reference such as vault://orgs/acme/secrets/db/password. Each becomes the Ansible variable NAME, passed from a file (never an environment variable or argument) and redacted from output. | |
group_secrets | object | Group secrets — GROUP:NAME=secret reference, one per line: the variable NAME for hosts in inventory group GROUP only, e.g. site_emea:api_key=vault://… | |
vault_password | string | "" | Ansible Vault password — Secret reference holding the password for files encrypted with ansible-vault, so existing repositories run unchanged. |
vault_ids | object | Ansible Vault IDs — LABEL=secret reference, one per line, for playbooks that use several vault IDs (--vault-id LABEL@…). | |
inventory_scope | enum: step, run | "step" | Inventory scope — 'step' puts the step's target devices in the inventory; 'run' puts every device the run targets, grouped by role, so plays can reach other roles. |
group_by | array of string | Inventory groups — Which groups to derive: role (the flow's role names), platform (platform_ios_xe), site (site_emea, site_emea_nl, …), tag (tag_env_prod), provider (provider_netbox_main). | |
extra_inventory | array of string | Extra inventory files — Attachment paths of further inventory sources layered on the generated one (-i), one per line. | |
device_credentials | boolean | true | Use device credentials — Give Ansible each device's login from its access configuration. Turn off when the playbook brings its own credentials. |
host_key_checking | enum: accept_new, strict, off | "accept_new" | Host key checking — accept_new trusts a host's key on first contact within the run and rejects a change; strict needs the keys in the image's known_hosts; off disables checking. |
requirements_file | string | "" | Requirements file — Attachment path of a requirements.yml to install with ansible-galaxy before the play (roles and collections). Needs network access to the Galaxy server. |
forks | object | null | Forks — How many hosts Ansible works on in parallel (--forks). Unset, the playbook's ansible.cfg decides (Ansible's default is 5). |
verbosity | integer | 0 | Verbosity — Ansible verbosity: 0 is normal, 1-4 add -v to -vvvv. |
image | string | "ghcr.io/hegemony-sh/ansible-runner:0.9" | Execution image — Container image with ansible-playbook and the collections the playbook needs. Any Ansible execution environment image works. |
cache_image | boolean | true | Cache image — Keep a copy of the pulled image in the platform registry, under this organization, and use it on later runs. A tag is still checked against the image's registry by digest, and the copy serves when that registry is unreachable. Turn off for an image that must come straight from its registry every time. No effect when the platform runs no registry. |
cisco.iosxe.upgrade.cleanup
Upgrade: Cleanup · category: Upgrade · kinds: ACTION
Remove inactive packages/old images after a successful upgrade.
| Key | Type | Default | Description |
|---|---|---|---|
upgrade_mode | enum: install, bundle | "install" | Upgrade Mode — Which cleanup workflow to run: install mode uses "install remove inactive", while bundle mode deletes old .bin images from flash that the boot configuration no longer references. Defaults to install mode. |
remove_inactive | boolean | true | Remove inactive packages/old images — For install mode: runs "install remove inactive" |
keep_versions | integer | 1 | Versions to Keep — Number of old versions to keep (for bundle mode) |
max_parallel_devices | integer | 1 | Max Parallel Devices — Devices cleaned concurrently (1 = sequential) |
cisco.iosxe.upgrade.install
Upgrade: Install · category: Upgrade · kinds: ACTION, EXECUTE
Install and activate the staged image (may reload the device).
| Key | Type | Default | Description |
|---|---|---|---|
upgrade_mode | enum: install, bundle | "install" | Upgrade Mode — Which activation workflow to run: install mode uses the "install add file ... activate commit" command, while bundle mode points the boot system at the .bin image, saves the configuration, and reloads. Defaults to install mode; it must match how the device boots. |
image_name | string | Image Filename — Image filename on device flash (required) | |
dest_fs | string | "flash:" | Destination Filesystem — Device filesystem holding the staged image; combined with the image filename to build the full image path. Defaults to "flash:"; a trailing colon is added automatically if omitted. |
activate | boolean | true | Activate (trigger reload immediately) — If unchecked, upgrade is staged but not activated |
commit | boolean | true | Commit (prevent rollback) — For install mode: commit to prevent automatic rollback |
max_parallel_devices | integer | 1 | Max Parallel Devices — Devices upgraded concurrently (1 = sequential) |
cisco.iosxe.upgrade.preflight
Upgrade: Preflight · category: Upgrade · kinds: CHECK
Validate devices are ready for upgrade (space, image, install mode).
| Key | Type | Default | Description |
|---|---|---|---|
upgrade_mode | enum: install, bundle | "install" | Upgrade Mode — Which IOS-XE upgrade workflow to validate: install mode (modern devices using the "install" command) or bundle mode (legacy devices booting a monolithic .bin image). Install mode also verifies that the device actually supports the install command. Defaults to install mode. |
image_name | string | "" | Image Filename (optional) — Check if image is already staged |
target_version | string | "" | Target Version (optional) — Expected version after upgrade |
dest_fs | string | "flash:" | Destination Filesystem — Device filesystem checked for free space and for an already staged image. Defaults to "flash:"; a trailing colon is added automatically if omitted. |
min_free_bytes | integer | 1073741824 | Min Free Space (bytes) — Minimum free disk space required (default: 1GB) |
max_parallel_devices | integer | 1 | Max Parallel Devices — Devices checked concurrently (1 = sequential) |
cisco.iosxe.upgrade.stage
Upgrade: Stage · category: Upgrade · kinds: ACTION, TRANSFER
Transfer the upgrade image to device flash and verify integrity.
| Key | Type | Default | Description |
|---|---|---|---|
upgrade_mode | enum: install, bundle | "install" | Upgrade Mode — Which IOS-XE upgrade workflow the staged image is intended for: install mode (modern devices) or bundle mode (legacy devices). The transfer itself behaves the same in both modes; keep this consistent with the install step that follows. Defaults to install mode. |
transfer_method | enum: auto, http, https | "auto" | Transfer Method — How the image reaches the device. Auto (the default) prefers a device-side HTTPS/HTTP pull when the source is an HTTP(S) URL - the only transfer implemented. Legacy stored values such as scp or tftp fail with an explanatory error. |
file_ids | array of string | File Repository File — Browse files in the file repository and select one. Use either this or Source URL (not both). | |
source_url | string | "" | Source URL — Manual URL fallback (http/https). Do not combine with File Repository File. |
dest_filename | string | "" | Destination Filename — Optional when selecting File Repository File (defaults to selected filename) |
dest_fs | string | "flash:" | Destination Filesystem — Device filesystem the image is copied to. Defaults to "flash:"; a trailing colon is added automatically if omitted. |
expected_md5 | string | "" | MD5 Checksum (optional) — MD5 hash verified on the device with verify /md5 after a transfer - and before one: a file already staged under the destination name that passes this check is not transferred again. |
overwrite | boolean | false | Force re-transfer even if file exists — Transfer the image again even when a file with the same name is already on the device. When off (the default), an existing file that passes the MD5 check is reused and the transfer is skipped; with no checksum configured the image is transferred again, unless the step's raw definition carries an expected_size that matches the existing file. |
max_parallel_devices | integer | 1 | Max Parallel Devices — Devices staged concurrently (1 = sequential) |
cisco.iosxe.upgrade.verify
Upgrade: Verify · category: Upgrade · kinds: CHECK
Wait for the device to return and verify the running version.
| Key | Type | Default | Description |
|---|---|---|---|
upgrade_mode | enum: install, bundle | "install" | Upgrade Mode — Which verification workflow to run: install mode additionally checks commit status with "show install summary" and can auto-commit, while bundle mode checks the running version and boot configuration only. Defaults to install mode. |
target_version | string | "" | Target Version — Expected version after upgrade |
max_wait_seconds | integer | 600 | Max Wait (sec) — Max time to wait for device to come back online |
retry_interval | integer | 30 | Retry Interval (sec) — Seconds between reconnect attempts |
auto_commit | boolean | true | Auto-commit if not committed — For install mode: run "install commit" if needed |
max_parallel_devices | integer | 1 | Max Parallel Devices — Devices verified concurrently (1 = sequential) |
container.run
Run Container · category: Actions · kinds: ACTION, EXECUTE
Run a command inside a Docker container on the Docker-in-Docker sandbox.
| Key | Type | Default | Description |
|---|---|---|---|
image | string | Docker Image — Full image reference including tag (e.g., registry.example.com/tools:v1) (required) | |
cache_image | boolean | true | Cache image — Keep a copy of the pulled image in the platform registry, under this organization, and use it on later runs. A tag is still checked against the image's registry by digest, and the copy serves when that registry is unreachable. Turn off for an image that must come straight from its registry every time. No effect when the platform runs no registry. |
command | array of string | Command — Shell script lines joined with newlines under set -e. With no entrypoint override, the handler appends sh -c <script>; with entrypoint /bin/sh, it passes -c <script> to that shell. Leave empty to add no script. | |
entrypoint | object | null | Entrypoint override — Optional Docker --entrypoint. Leave empty to use the image entrypoint. Set /bin/sh for tool images such as hashicorp/terraform so Command runs as a shell script. Advanced YAML may use list form, e.g. ["/usr/bin/env", "bash", "-lc"]. |
working_dir | string | "/workspace" | Working Directory — Working directory inside the container (default: /workspace) |
timeout_seconds | integer | 300 | Timeout (seconds) — Max execution time in seconds |
memory | string | "" | Memory Limit — e.g., 256m, 1g |
cpus | string | "" | CPU Limit — e.g., 0.5, 2.0 |
network_disabled | boolean | false | Disable network access — Off by default to preserve Docker networking. Turn on only when this step should run with --network=none. |
network_mode | string | "" | Network mode — Optional. Use to attach to a specific Docker network (e.g. clab-mylab) or share another container's namespace (host shares the Docker-in-Docker sandbox's, not the machine's). Disabled when network access is disabled; leave empty for default Docker networking. |
attach_docker_socket | boolean | false | Attach sandbox Docker socket — Mounts the Docker-in-Docker sandbox daemon's /var/run/docker.sock into the container, giving it full control of the sandbox daemon (not the host's). Required by tools that start their own containers, like containerlab. Off by default. |
privileged | boolean | false | Run as privileged — Runs the container with --privileged, granting all capabilities and access to /proc/sys inside the Docker-in-Docker sandbox (needed by containerlab to adjust rp_filter, etc.). The sandbox itself runs privileged, so the step becomes a sandbox admin. Off by default. |
pid_mode | string | "" | PID namespace — Optional. Share the PID namespace of the Docker-in-Docker sandbox (host) or of another container (container:<name>). Required by containerlab-in-Docker so it can resolve sibling container PIDs. Leave empty for default isolation. |
extra_mounts | array of string | Extra bind mounts — One per line, format <abs-src>:<abs-dst>[:opts]. Sources resolve inside the Docker-in-Docker sandbox, not on the host. Bypasses workspace isolation; use sparingly (e.g. containerlab needs /var/run/netns shared). | |
egress_mode | string | "" | Egress policy mode — Outbound firewall for this step's container, enforced on the sandbox daemon: 'open' allows everything except Deny rules, 'allow-listed' allows only Allow rules (minus Deny), 'deny-all' blocks all network access. Leave empty to inherit the flow's network policy. Cannot be combined with host-access options or 'Disable network access'. |
egress_allow | array of string | Egress allow rules — One rule per line, used with allow-listed mode: CIDR[:port[-port]][/tcp|udp] or service:port (e.g. 172.20.30.0/24, 0.0.0.0/0:443/tcp, dind:3000). | |
egress_deny | array of string | Egress deny rules — One rule per line, same format as Allow rules. Deny always wins over Allow and is unioned with the flow policy's Deny rules. | |
env | object | Environment Variables — KEY=VALUE format, one per line. Keys starting with HEGEMONY_ are reserved and will be ignored. | |
secrets | object | Secret files — NAME=secret reference, one per line (a {{ secret('...') }} template or a bare reference such as vault://orgs/acme/secrets/db/password). Each value is written to /run/secrets/NAME inside the container and redacted from output; unlike environment variables, it never appears in the sandbox's container metadata. | |
mounted_artifacts | object | null | Artifacts — Select which upstream step artifacts are copied into the container. Leave at All to make every upstream step artifact available by default. |
mounted_step_outputs | object | null | Step Outputs — Select which upstream step output snapshots are copied into the container. Leave at All to make every upstream predecessor step output available by default. |
mounted_files | object | null | Attachments — Select which flow attachments are copied into the container under the attachments mount path. Leave at All to copy every flow attachment; a selector ending in / includes that folder recursively. |
artifacts_path | string | "" | Artifacts mount path — Absolute path inside the container where upstream step artifacts are copied. Defaults to /artifacts. |
new_artifacts_path | string | "" | New artifacts upload path — Absolute path inside the container where newly created files are harvested after the container exits: UTF-8 text files become step artifacts, and every other file is uploaded as a downloadable artifact up to the worker's per-file cap (50 MiB by default). Files the harvest drops are listed in the step's skipped-artifacts report. Defaults to /artifacts/new, or <artifacts_path>/new when you change the artifacts root. |
attachments_path | string | "" | Attachments mount path — Absolute path inside the container where attachments are copied. Defaults to /attachments. |
step_outputs_path | string | "" | Step outputs mount path — Absolute path inside the container where completed step output snapshots are copied. Defaults to /step_outputs. |
shared_path | string | "" | Shared workspace mount path — Absolute path inside the container where the shared run workspace is mounted when this step uses shared or explicit execution affinity. Defaults to /shared. |
evidence.assert
Assert · category: Checks · kinds: CHECK
Assert an expected value against evidence collected by another step.
| Key | Type | Default | Description |
|---|---|---|---|
artifact_step_id | string | Evidence Step — Only netcli.collect_evidence steps shown (required) | |
operator | enum: contains, not_contains, matches, not_matches, eq, ne, gt, lt, ge, le | "contains" | Operator — How the artifact content is compared with the expected value. Regex operators treat the expected value as a regular expression; ordering operators compare numerically when both sides parse as numbers, and as text otherwise. Defaults to Contains. |
match_scope | enum: output, lines | "output" | Match Scope — 'Whole output' asserts once against the entire artifact; 'Every line' asserts the operator against each selected line (e.g. every OSPF neighbor row must contain 'Full'). |
line_filter | string | "" | Line Filter (regex) — With 'Every line' scope: only lines matching this regex are asserted, so headers and blanks don't count. Empty selects every non-empty line. |
min_lines | integer | 1 | Minimum Lines — With 'Every line' scope: fail unless at least this many lines were selected — an empty selection must not pass vacuously. |
target_role | string | "" | Evidence Output — Choose a target and command from the selected evidence step. |
command | string | "" | Evidence Command — The command whose collected output is asserted; the editor's evidence-output picker sets it together with the Evidence Output target. Each device bound to the target is checked against the artifact the evidence step stored for that device and this command. |
expected | string | "" | Expected Value / Pattern — The value compared against the artifact content: literal text for the contains and equality operators, a regular expression for the regex operators, or a number for the ordering operators. |
message | string | "" | Custom Message (optional) — Shown verbatim as the step summary when the assertion passes and as the error when it fails, replacing the generated messages. Leave empty to get an auto-generated message that names the operator and expected value. |
evidence.compare
Compare Evidence · category: Checks · kinds: CHECK
Diff evidence artifacts between two steps (precheck vs postcheck).
| Key | Type | Default | Description |
|---|---|---|---|
precheck_step_id | string | "" | Precheck Step — Select the step that collected pre-change evidence |
postcheck_step_id | string | "" | Postcheck Step — Select the step that collected post-change evidence |
comparison_type | enum: exact, changed, subset, superset, json_diff | "exact" | Comparison mode — What a difference between the pre- and post-check evidence means. 'exact': pass only when they are identical — a difference FAILS the step (drift / no-change checks). 'changed': pass only when they differ — a difference SUCCEEDS the step (confirm an intended change actually took effect). 'subset' / 'superset' / 'json_diff' compare structured (dict/list) evidence. |
artifact_name | string | "" | Only this artifact — Compare a single artifact by its exact name (e.g. 'dc1-core-01:show running-config'). Leave blank to compare every artifact the two steps share. |
artifact_name_pattern | string | "" | Only artifacts matching — Glob over artifact names (e.g. '*show running-config') so volatile outputs — routing tables, neighbor tables — can be left out of the comparison. Ignored when a single artifact name is set. |
ignore_patterns | array of string | Mask text matching — Regular expressions; every match is removed from BOTH sides before a text comparison, so volatile output — uptimes, timers, packet/byte counters — does not register as a difference while the rest of the line is kept. Matched per line (^ and $ anchor to line boundaries), e.g. ', \d\d:\d\d:\d\d,' to mask route uptimes. | |
ignore_fields | array of string | Ignore fields — Structured (dict) evidence only: keys removed from both sides before comparing. |
flow.notify
Send Notification · category: Notifications · kinds: ACTION
Send an on-demand notification to a configured destination.
| Key | Type | Default | Description |
|---|---|---|---|
destination_id | string | Notification Destination — Where to send the notification (Slack, Teams, etc.) (required) | |
title | string | "" | Title — Notification title template, rendered by the notification renderer with the full notification context (run values, step outputs, secret()/env() helpers). Leave empty to use the shared default title template. |
message | string | "" | Message — Notification body template, rendered by the notification renderer with the full notification context (run values, step outputs, secret()/env() helpers). Leave empty to use the shared default body template. |
flow.run
Run Flow · category: Actions · kinds: ACTION, EXECUTE
Launch another committed flow as a child run.
| Key | Type | Default | Description |
|---|---|---|---|
flow_id | string | "" | Flow — UUID of the committed child flow to launch. Provide exactly one of flow_id / flow_name; leave this empty when selecting the child flow by name. |
flow_name | string | "" | Flow name — Child flow name, resolved to the newest flow at launch time — the portable alternative to flow_id for imported bundles. Provide exactly one of flow_id / flow_name. |
version | object | null | Version — Committed version number of the child flow to run, starting at 1. Omit to launch the newest committed version at start time. |
wait_for_completion | boolean | true | Wait for completion — When enabled (the default), the step polls the child run until it finishes and mirrors its result, exposing the child flow's outputs. Disable to succeed as soon as the child run is created. |
run_name | object | null | Child run name — Name given to the child run. Leave empty to derive one from the parent run's name plus a short random suffix. |
field_mappings | object | Field mappings — Values for the child flow's input fields: one entry per field id with mode default (keep the child's default), literal, or template, plus the value to pass. Managed by the run-flow editor widget. | |
target_mappings | object | Target mappings — Device binding for each child target role: mode child_default, parent_role (forwarding the devices this run bound to the given parent_role_id), or none. Managed by the run-flow editor widget. | |
poll_interval_seconds | number | 5 | Poll interval (sec) — Seconds between status checks of the child run while waiting for completion; values are clamped to 1-60 and default to 5. Ignored when the step does not wait. |
general.sleep
Sleep · category: Actions · kinds: ACTION, WAIT
Pause the flow for a fixed duration.
| Key | Type | Default | Description |
|---|---|---|---|
seconds | integer | 30 | Duration (seconds) — How many seconds the flow pauses at this step before moving on. Must be at least 1; defaults to 30. |
message | string | "" | Message (optional) — Note recorded as the step summary and in the sleep evidence, e.g. why the flow is waiting. When omitted, a generated 'Sleeping for N seconds' text is used. |
monitor.connectivity
Connectivity Monitor · category: Checks · kinds: CHECK
Continuously probe targets in the background during a flow run.
| Key | Type | Default | Description |
|---|---|---|---|
check_type | enum: dns_resolve, http_health, icmp_ping, tcp_connect | "tcp_connect" | Check Type — The kind of probe sent to each target on every sample, such as a TCP connection attempt, an ICMP echo, an HTTP health request, or a DNS lookup. Options come from the host's monitor check registry and the value is validated when the step runs. Defaults to a plain TCP connect check. |
port | integer | 22 | Port — TCP port probed on each target by the port-based checks such as TCP Connect and HTTP Health. Ignored by checks that do not connect to a port, such as ICMP Ping and DNS Resolve. Defaults to 22 (SSH); must be between 1 and 65535. |
interval_ms | integer | 5000 | Interval (ms) — Time between successive samples, in milliseconds. Defaults to 5000 (one sample every five seconds); minimum 100. |
schedule_mode | enum: count, duration, until_join | "count" | Schedule Mode — How the monitor decides when to stop sampling: after a fixed number of samples, after a fixed duration, or - with Until Join - when the flow engine stops it at the branch's join point. Defaults to a fixed count. |
count | integer | 10 | Count — Number of samples to take before the monitor stops on its own. Only used when Schedule Mode is Fixed Count. Defaults to 10; minimum 1. |
duration_sec | integer | 60 | Duration (sec) — How long the monitor keeps sampling, in seconds, before it stops on its own. Only used when Schedule Mode is Duration. Defaults to 60; minimum 1. |
timeout_sec | integer | 10 | Timeout (sec) — Per-sample time limit in seconds: how long each probe waits for an answer before giving up on that sample. Defaults to 10; minimum 1. |
url_path | string | "" | URL Path — Request path for the HTTP Health check, e.g. /health. Used only when Check Type is HTTP Health; when omitted, /health is probed. |
socks_proxy | string | "" | SOCKS Proxy — Optional authenticated SOCKS5 proxy for the TCP-based checks (tcp_connect, http_health), so a monitor can reach targets only accessible through a bastion (e.g. a lab management subnet behind dind:1080). socks5[h]😕/[user:pass@]host:port. Not usable by icmp_ping or dns_resolve — neither ICMP nor DNS traverses a SOCKS5 CONNECT tunnel, so those checks reject a configured proxy rather than probe the wrong path. |
netcli.collect_evidence
Collect Evidence · category: Checks · kinds: CHECK
Capture CLI command outputs from devices as evidence.
| Key | Type | Default | Description |
|---|---|---|---|
commands | array of string | Commands (one per line) — Device CLI commands whose outputs are captured as evidence, one artifact per command per device. Use {{ variable }} syntax for flow inputs. Leave empty to collect nothing (the step still succeeds). | |
max_parallel_devices | integer | 1 | Max Parallel Devices — Devices processed concurrently (1 = sequential) |
netcli.execute
Execute CLI · category: Actions · kinds: ACTION
Run CLI commands on target devices.
| Key | Type | Default | Description |
|---|---|---|---|
commands | array of string | Commands (one per line) — Use {{ variable }} syntax for flow inputs | |
max_parallel_devices | integer | 1 | Max Parallel Devices — Devices processed concurrently (1 = sequential) |
netcli.poll_until
Poll Until · category: Checks · kinds: CHECK, WAIT
Poll a device command until its output matches a condition.
| Key | Type | Default | Description |
|---|---|---|---|
command | string | "" | Command to Poll — Device CLI command run on every poll attempt; its output is tested against the match condition. Required — the step fails without it. Use {{ variable }} syntax for flow inputs. |
match_regex | string | "" | Match Regex (optional) — Regex pattern to match in command output |
match_string | string | "" | Match String (optional) — Literal string to find (case-insensitive) |
interval_seconds | integer | 5 | Interval (sec) — Seconds to wait between poll attempts (default 5, minimum 1). No extra wait is added after the final attempt. |
max_attempts | integer | 12 | Max Attempts — Maximum times the command is run per device before the step gives up and fails (default 12, minimum 1). Polling stops early on the first attempt that satisfies the condition. |
invert_match | boolean | false | Invert Match — Succeed when pattern does NOT match |
max_parallel_devices | integer | 1 | Max Parallel Devices — Devices polled concurrently (1 = sequential) |
probe.connectivity
Connectivity Check · category: Checks · kinds: CHECK
One-shot connectivity probes (TCP/ICMP/HTTP/DNS) against targets.
| Key | Type | Default | Description |
|---|---|---|---|
check_type | enum: dns_resolve, http_health, icmp_ping, tcp_connect | "tcp_connect" | Check Type — Which probe to run against each target; the list comes from the checks registered on the worker. Defaults to a TCP connection attempt (tcp_connect) on the configured port. |
port | integer | 22 | Port — For TCP/TLS/SSH checks |
timeout_sec | integer | 10 | Timeout (sec) — Time limit for each probe attempt, in seconds. An attempt that does not complete in time counts as failed. Defaults to 10. |
attempts | integer | 1 | Attempts — Number of attempts (1-10) |
url_path | string | "" | URL Path — URL path requested by the HTTP Health check; when omitted the check requests /health. Ignored by every other check type. |
hostname | string | "" | Hostname to Resolve — DNS name the DNS Resolve check looks up against each target. Ignored by every other check type. |
socks_proxy | string | "" | SOCKS5 Proxy — Route TCP-based checks through an authenticated SOCKS5 proxy (socks5[h]😕/user:pass@host:port), e.g. the lab bastion. icmp_ping rejects it — use tcp_connect for tunneled targets. |
probe.dns
DNS Check · category: Checks · kinds: CHECK
Resolve a DNS name (or each target's hostname) and assert the answers.
| Key | Type | Default | Description |
|---|---|---|---|
query_name | string | "" | Name to Resolve — Leave empty to resolve each target device's hostname |
record_type | enum: A, AAAA, CNAME, MX, NS, TXT | "A" | Record Type — Which kind of DNS record to query for. Defaults to A records. |
resolver | string | "" | Resolver (optional) — Nameserver IP; empty uses the system resolver |
expected_values | array of string | Expected Values (optional) — One per line; every listed value must appear in the answers | |
timeout_sec | integer | 5 | Timeout (sec) — Overall time budget for each resolution attempt, in seconds. A lookup that has not answered in time counts as a failed attempt. Defaults to 5. |
attempts | integer | 1 | Attempts — Number of attempts (1-10) |
probe.http
HTTP Check · category: Checks · kinds: CHECK
Request an HTTP(S) endpoint on each target and assert status/body.
| Key | Type | Default | Description |
|---|---|---|---|
scheme | enum: http, https | "http" | Scheme — Whether the request uses plain HTTP or TLS-protected HTTPS. Also selects the default port (80 or 443) when Port is left empty. |
port | object | null | Port — Defaults to 80/443 by scheme |
path | string | "/" | Path — Request path on the target, such as /health. A missing leading slash is added automatically, and an empty value requests the root path /. |
method | enum: GET, HEAD, POST | "GET" | Method — HTTP request method to send. Defaults to GET; note that a HEAD response has no body for the Body Contains assertion to match. |
expected_status | string | "200-399" | Expected Status — Comma-separated status codes and ranges, e.g. 200-299,301 |
body_contains | string | "" | Body Contains (optional) — Fail unless the response body contains this text |
verify_tls | boolean | true | Verify TLS certificate — Validate the server's TLS certificate on HTTPS checks; turn off for devices with self-signed certificates. Enabled by default and ignored by plain HTTP checks. |
follow_redirects | boolean | true | Follow redirects — Follow HTTP redirects and assert the final response. When disabled, the redirect response itself is what Expected Status and Body Contains see. Enabled by default. |
timeout_sec | integer | 10 | Timeout (sec) — Time limit for each request attempt, in seconds, covering connection setup and the response. Defaults to 10. |
attempts | integer | 1 | Attempts — Number of attempts (1-10) |
probe.wait_reachable
Wait Reachable (Stable) · category: Checks · kinds: WAIT
Wait until targets stay reachable for a stability window.
| Key | Type | Default | Description |
|---|---|---|---|
max_wait_seconds | integer | 300 | Max Wait (sec) — Overall deadline for the wait, in seconds. The step fails once this much time passes without every target completing its stability window. Defaults to 300. |
stable_seconds | integer | 30 | Stable (sec) — How long every target must remain continuously reachable before the step succeeds, in seconds. A target that goes unreachable restarts its window from zero. Defaults to 30. |
poll_interval | integer | 5 | Poll Interval (sec) — Seconds to wait between reachability polls. Defaults to 5. |
shell.execute
Execute Shell · category: Actions · kinds: ACTION, EXECUTE
Run shell commands on Linux/Unix hosts (exit codes, stdout/stderr).
| Key | Type | Default | Description |
|---|---|---|---|
commands | array of string | Commands (one per line) — Each line runs as its own exec-channel command with its own exit code | |
shell | enum: default, sh, bash, pwsh | "default" | Interpreter — How commands are wrapped on the remote host |
env | object | Environment Variables — KEY=VALUE per line; prefixed via env(1). Not supported with pwsh. | |
fail_fast | boolean | true | Stop on first failure — Skip remaining commands on a device after a non-zero exit code |
command_timeout_sec | integer | 60 | Per-command timeout (sec) — Maximum time in seconds each command may run. The limit applies to every command individually, not to the step as a whole; a command that exceeds it fails the device and its remaining commands are skipped. Defaults to 60 seconds. |
max_parallel_devices | integer | 1 | Max Parallel Devices — Hosts processed concurrently (1 = sequential) |
tf.apply
OpenTofu/Terraform Apply · category: Actions · kinds: ACTION, EXECUTE
Apply exactly the plan a tf.plan step saved earlier in the run.
| Key | Type | Default | Description |
|---|---|---|---|
timeout_seconds | integer | 600 | Timeout (seconds) — Maximum run time of the container, including the image pull. |
memory | string | "" | Memory Limit — Container memory limit, e.g. 512m or 2g. Defaults to 1g. |
cpus | string | "" | CPU Limit — Container CPU limit, e.g. 0.5 or 2.0. Defaults to 1.0. |
env | object | Environment Variables — KEY=VALUE format, one per line. Keys starting with HEGEMONY_ are reserved and ignored. Prefer Secrets for sensitive values: environment variables are visible in the sandbox's container metadata. | |
egress_mode | string | "" | Egress policy mode — Outbound firewall for this step's container: 'open' allows everything except Deny rules, 'allow-listed' allows only Allow rules (minus Deny), 'deny-all' blocks all network access. Leave empty to inherit the flow's network policy. |
egress_allow | array of string | Egress allow rules — One rule per line, used with allow-listed mode: CIDR[:port[-port]][/tcp|udp] or service:port. | |
egress_deny | array of string | Egress deny rules — One rule per line, same format as Allow rules. Deny always wins. | |
mounted_files | object | null | Attachments — Which flow attachments are copied into the container under /attachments. Leave at All to copy every attachment; a selector ending in / includes that folder recursively. |
stop_grace_seconds | integer | 120 | Stop grace period (seconds) — How long the tool gets to stop cleanly when the step is cancelled or reaches its timeout: it receives SIGTERM, lets the changes in progress finish, saves the state and releases the lock, and is killed only after this time. At a timeout the time comes out of the step's timeout (at most half of it). 0 stops the tool at once. |
secret_env | object | Secret environment — NAME=secret reference, one per line, exported to the tool's process only (provider credentials such as AWS_SECRET_ACCESS_KEY). A reference is a {{ secret('...') }} template or a bare reference such as vault://orgs/acme/secrets/aws/key. Values are redacted from output and never appear in the container's metadata. | |
plan_step | string | Plan step — The tf.plan step whose saved plan to apply. It must have run in this run. (required) | |
state_encryption_key | string | "" | State encryption key — OpenTofu only: the same secret reference the plan step used, needed to read the encrypted plan and write encrypted state. |
lock_timeout | string | "300s" | Lock timeout — How long to wait for the state lock (-lock-timeout), e.g. 300s or 5m. |
tf.plan
OpenTofu/Terraform Plan · category: Actions · kinds: ACTION, CHECK, EXECUTE
Plan an OpenTofu or Terraform configuration from the flow's attachments and report what would change; tf.apply applies the saved plan.
| Key | Type | Default | Description |
|---|---|---|---|
timeout_seconds | integer | 600 | Timeout (seconds) — Maximum run time of the container, including the image pull. |
memory | string | "" | Memory Limit — Container memory limit, e.g. 512m or 2g. Defaults to 1g. |
cpus | string | "" | CPU Limit — Container CPU limit, e.g. 0.5 or 2.0. Defaults to 1.0. |
env | object | Environment Variables — KEY=VALUE format, one per line. Keys starting with HEGEMONY_ are reserved and ignored. Prefer Secrets for sensitive values: environment variables are visible in the sandbox's container metadata. | |
egress_mode | string | "" | Egress policy mode — Outbound firewall for this step's container: 'open' allows everything except Deny rules, 'allow-listed' allows only Allow rules (minus Deny), 'deny-all' blocks all network access. Leave empty to inherit the flow's network policy. |
egress_allow | array of string | Egress allow rules — One rule per line, used with allow-listed mode: CIDR[:port[-port]][/tcp|udp] or service:port. | |
egress_deny | array of string | Egress deny rules — One rule per line, same format as Allow rules. Deny always wins. | |
mounted_files | object | null | Attachments — Which flow attachments are copied into the container under /attachments. Leave at All to copy every attachment; a selector ending in / includes that folder recursively. |
stop_grace_seconds | integer | 120 | Stop grace period (seconds) — How long the tool gets to stop cleanly when the step is cancelled or reaches its timeout: it receives SIGTERM, lets the changes in progress finish, saves the state and releases the lock, and is killed only after this time. At a timeout the time comes out of the step's timeout (at most half of it). 0 stops the tool at once. |
secret_env | object | Secret environment — NAME=secret reference, one per line, exported to the tool's process only (provider credentials such as AWS_SECRET_ACCESS_KEY). A reference is a {{ secret('...') }} template or a bare reference such as vault://orgs/acme/secrets/aws/key. Values are redacted from output and never appear in the container's metadata. | |
engine | enum: opentofu, terraform | "opentofu" | Engine — opentofu (default) or terraform. The apply step uses the same one. |
source_dir | string | "" | Configuration folder — Folder among the flow attachments holding the .tf files, e.g. terraform/network. Leave empty for the attachments root. Commit its .terraform.lock.hcl. |
state | enum: managed, backend, ephemeral | "managed" | State — managed: Hegemony stores the state (encrypted, locked, versioned) under the state name; any backend block in the configuration is replaced. backend: the configuration's own backend block (S3, Azure, GCS, Consul, PostgreSQL, …), required. ephemeral: local state that lives only for this run, for tests and demos. |
state_name | string | "" | State name — Name of the managed state in this organization, e.g. network-core. Every flow and laptop using the same name shares one state (and its lock). |
hold_until_apply | boolean | false | Hold the state until apply — Keep the managed state for this run from this plan until the run applies or ends: meanwhile other runs and people cannot lock or change it, so the plan stays valid while the run waits (for an approval, say). Every other flow using the state waits that long. |
backend_config | object | Backend settings — KEY=value, one per line, for a partial backend block (for example bucket=…, key=…). Values may use {{ secret('...') }}; they are passed from a file, not the command line. Only for backend state. | |
vars | object | Variables — NAME=value, one per line. Values may use templates such as {{ inputs.service_name }}; a JSON list or object (["r1","r2"]) is passed as that type. | |
secret_vars | object | Secret variables — NAME=secret reference, one per line, for sensitive variables. Always passed as strings (decode a JSON secret with jsondecode() in the configuration), from a file, and redacted from output; like every variable they are stored in the saved plan, which lives only in the run's workspace. | |
var_files | array of string | Variable files — Attachment paths of .tfvars or .tfvars.json files, one per line. | |
destroy | boolean | false | Plan a destroy — Plan the destruction of every resource the state holds (-destroy). |
refresh_only | boolean | false | Refresh only — Only reconcile state with the real infrastructure (-refresh-only). |
targets | array of string | Targets — Resource addresses to limit the plan to (-target), one per line, e.g. aws_vpc.main or aws_instance.web["blue"]. | |
replace | array of string | Replace — Resource addresses to force-replace (-replace), one per line, e.g. aws_instance.web["blue"]. | |
lock_timeout | string | "300s" | Lock timeout — How long to wait for the state lock (-lock-timeout), e.g. 300s or 5m. |
state_encryption_key | string | "" | State encryption key — OpenTofu only: secret reference of a passphrase (16+ characters). State and saved plans are then encrypted by OpenTofu before they are written anywhere. |
image | string | "" | Image — Container image with the tool, run as root with a POSIX sh. Leave empty for the engine's default: ghcr.io/hegemony-sh/opentofu-runner:0.9 for OpenTofu, hashicorp/terraform at a pinned version for Terraform. |
cache_image | boolean | true | Cache image — Keep a copy of the pulled image in the platform registry, under this organization, and use it on later runs. A tag is still checked against the image's registry by digest, and the copy serves when that registry is unreachable. Turn off for an image that must come straight from its registry every time. No effect when the platform runs no registry. |
Internal handlers
These handlers are registered but hidden from the step palette; flows use them indirectly (for example through notification or monitor nodes).
| Handler | Description |
|---|---|
flow.git_sync | Trigger a repo-wide pull sync of flow definitions (scheduled flows). |
general.noop | Does nothing; placeholder/testing step. |
monitor.start | Internal: start a background connectivity monitor. |
monitor.stop | Internal: stop a background connectivity monitor. |