Docs navigation
Get started
AI agents
Connect
Operate
Day to day
When it breaks
Govern access
Team & account
Access
Identity concepts
Provider guides
Account
Pack reference
An action pack is a versioned, content-addressed directory of YAML action declarations. The runner loads the pack, advertises every action to the control plane, and refuses anything outside this catalog. This is the contract between your ops team and the LLM.
Pack and action schemas are v1 compatibility surfaces. Read Compatibility and deprecation before you depend on a schema version.
Layout#
my-pack/
pack.yaml # pack-level metadata
actions/
nodetool_status.yaml # one declared action per file
nodetool_repair.yaml
scripts/ # optional — packaged scripts for kind: script actions
repair_report.sh
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
requires:
os: [linux]
binaries: [nodetool]
setup:
summary: >
How the pack reaches its target and authenticates.
env:
- name: CQLSH_PASSWORD
description: Password for cqlsh-backed actions.
verify: cassandra.nodetool_status
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.
requires
lists what the pack's host needs — OS and binaries. They are advertised as host
readiness, and a missing binary fails at run time, not at load. The setup
block powers emisar pack info, pack verify, and the
install probe: a summary, the env names the tool reads, and one low-risk
verify
action.
When an action needs protected host access, add a host_access
group. It names the exact actions, the resource they need, complete persistent grant
and verification commands, and the authority the grant gives the runner identity.
Emisar displays these commands; it never runs them.
setup:
host_access:
- actions: [my.journal_tail]
requirement: Read the system journal.
recipes:
- name: systemd Linux — default emisar service user
commands:
- sudo usermod -aG systemd-journal emisar
- sudo systemctl restart emisar
verify:
- sudo -u emisar journalctl -n 1 --no-pager
impact: The emisar service identity can read the complete system journal.
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.
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#
-
kind—exec(run a binary with an explicit argv) orscript(run a script packaged in the pack, its contents SHA-256-verified at load). There is no shell kind. Both run as argv arrays throughexecve. An exec action can invoke/bin/sh -cfor a fixed, pack-authored program. Open-ended strings and paths must reach that program through environment variables or whole positional arguments. Only finite choices and two-sided bounded numbers can be substituted into its text. Thecritical, default-deniedshellpack is the break-glass exception where the operator supplies the program itself. -
risk—low | medium | high | critical. The policy engine assigns a default decision per tier, and a higher tier must be at least as restrictive as a lower one. Risk is declared in the pack — the caller cannot 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. -
side_effects— the plain-language list of what the action touches. The LLM reads it verbatim when it decides what to call, so an honest list is a safety control, not documentation polish. -
execution.user— Linux-only. Drops the child process to that local user's uid and primary gid before exec. A runner under a privileged service account still runs the action as the declared, lower-privilege user. -
output.parser—text(default),json, orjson (parser_required: true)to force the run to fail if stdout is not valid JSON. -
output.max_*_bytes— stdout/stderr ceilings. The control plane can lower these per call, and it cannot raise them past the declared maximum. -
redact— per-action rules layered on top of 20 built-in patterns (GitHub, GitLab, Slack tokens, JWTs, authentication, and secret assignments). Redaction runs before output leaves the host, so the control plane receives the redacted stream. The local journal records each rule's hit count, and the terminal result sends rule names, types, and counts to the control plane. -
examples— optional list of{title, args}entries. Each one renders as a clickable hint on the dispatch form, so operators and LLMs see a realistic invocation before they type. Examples do not validate anything — they are documentation, not policy.
Pack trust#
Every pack is content-addressed: a SHA-256 hash over all its files. The control plane pins the exact hash the account trusts, and the runner recomputes it and refuses to load files that do not match. A hash carried by the published catalog is trusted automatically — any other, like a pack you wrote or a hand-edited tree, waits for an administrator before dispatch. This protects content integrity, not publisher identity.
Drift detection#
Once a pack is installed on at least one runner, the console's
Packs
page groups every observed (pack_id, version, hash)
in your account.
Two runners on the same pack version with different hashes mean somebody hand-edited
a pack on a host — the page flags it as drift, and re-deploying from the canonical
source clears it.
Browse the public registry — each pack's page lists its declared actions and a hash-pinned install command. Examples include linux-core, postgres, docker, kubernetes, nginx, redis, AWS, and Vault. To publish your own, read Author your own pack.