Docs / Action packs

Action packs

An action pack is a versioned, content-addressed directory of YAML action declarations. The runner loads the pack at boot, advertises every action to the control plane, and refuses anything not in this catalog. This is the contract between your ops team and the LLM.

Layout

my-pack/
  pack.yaml              # pack-level metadata
  actions/
    disk_usage.yaml      # one declared action per file
    nodetool_repair.yaml

pack.yaml

schema_version: 1
id: cassandra
name: Cassandra operations
version: 0.4.0
description: Cassandra triage + scoped repair
vendor: acme
homepage: https://github.com/acme/cassandra-pack
allow_symlinks: false
actions:
  - actions/nodetool_status.yaml
  - actions/nodetool_repair.yaml

allow_symlinks defaults to false: the loader rejects symlinked action YAMLs and scripts unless you opt in. Together with the pack hash (computed from every file's bytes), this prevents a tampered pack from being silently accepted.

An action YAML

schema_version: 1
id: linux.grep_log
title: Grep a log file
kind: exec
risk: low

description: >
  Greps an extended regex against a log file under /var/log.
  Read-only. Returns matching lines with line numbers.
side_effects:
  - Reads a log file under /var/log.

args:
  - name: file
    type: path
    required: true
    validation:
      allowed_prefixes: ["/var/log/"]
  - name: pattern
    type: string
    required: true
    validation:
      pattern: "^.{1,512}$"

execution:
  command:
    binary: grep        # bare name — resolved via PATH on the host
    argv: ["-E", "-n", "{{ args.pattern }}", "{{ args.file }}"]
  timeout: 30s
  user: syslog        # optional — run as this lower-privilege local user

output:
  parser: text
  max_stdout_bytes: 524288
  max_stderr_bytes: 8192

# Optional. Rendered on the dispatch form so operators (and LLMs)
# see realistic invocations before they fill the args themselves.
examples:
  - title: Search syslog for sshd auth failures
    args:
      file: /var/log/syslog
      pattern: "sshd.*Failed password"
  - title: Tail nginx access for 5xx
    args:
      file: /var/log/nginx/access.log
      pattern: " 5\\d\\d "

Field reference

  • kindexec (run a binary with an explicit argv) or script (run a script packaged in the pack, its bytes SHA-256-verified at load). There is no shell kind: actions are argv arrays, never shell strings, so there is nothing to inject.
  • risklow | medium | high | critical. The policy engine assigns a default decision per tier; higher tiers must be at least as restrictive as lower tiers. The runner declares risk in the pack; the caller can't override it.
  • args — every argument is declared. Types: string, integer, number, boolean, duration, path, string_array, integer_array. Validation tightens the type: enum, regex pattern, allowed_prefixes / denied_prefixes for paths, max_items for arrays, min/max for numbers, max_duration for durations.
  • execution.user — Linux-only. Drops the child process to that local user's uid and primary gid before exec, so a runner under a privileged service account still runs the action as the declared, lower-privilege user.
  • output.parsertext (default), json, or json (parser_required: true) to force the run to fail if stdout isn't valid JSON.
  • output.max_*_bytes — stdout/stderr ceilings. The cloud can lower these per-call via opts; it can't raise them past the declared maximum.
  • redact — per-action rules layered on top of 20+ built-in patterns (AWS keys, GitHub/GitLab/Slack tokens, JWTs, bearer/basic auth, secret assignments). Redaction runs on the runner before output leaves the host; the control plane never sees the raw bytes, and per-rule hit counts are recorded.
  • examples — optional list of {title, args} entries. Each one renders as a clickable hint on the dispatch form, so operators and LLMs see realistic invocations before they type. Examples don't validate any tighter than the declared argument schema — they're documentation, not policy.

Pack trust

Every pack is content-addressed by a SHA-256 over all its files. The control plane pins the hash an admin trusted; the runner recomputes it and refuses to run a pack whose on-disk bytes don't match. A new, changed, or custom pack blocks dispatch until an admin trusts its hash — a tampered mirror is rejected, not silently run. This is content integrity, not publisher signing: the runner trusts the exact bytes you approved.

Drift detection

Once a pack is installed on at least one runner, the in-app Packs page groups every observed (pack_id, version, hash) in your account. Two runners on the same pack version with different hashes means somebody hand-edited a pack on a host — the page flags it as drift. Re-deploy from the canonical source to clear it.

Browse 50+ working packs in the public registry (linux-core, postgres, docker, kubernetes, nginx, redis, the AWS suite, vault, and more) — each shows every action it declares and a hash-pinned install snippet you can paste on a runner host. Want one of your own? Author your own pack .