Reference

CLI Reference

Complete reference for the epack command-line interface. Build, sign, verify, and inspect evidence packs from your terminal.

Quick Reference

Build & Sign

# Build a pack
epack build out.epack ./files --stream org/stream

# Sign with keyless (opens browser)
epack sign out.epack

# Sign in CI/CD
EPACK_OIDC_TOKEN=$TOKEN epack sign out.epack

Verify & Inspect

# Verify with identity check
epack verify evidence.epack \
  --issuer "https://accounts.google.com" \
  --subject "security@company.com"

# Inspect pack contents
epack inspect evidence.epack

Run from a Remote

# Sign in once with your browser
epack remote login locktivity

# Fetch a configuration and run it
epack run northwind-production

# Keep its secrets in your keychain
cd northwind-production && epack secret setup

# Check the setup; collect nothing
epack run --check

Common Workflows

These are the most common command sequences for working with evidence packs.

๐Ÿ“ฆ

Build โ†’ Sign โ†’ Verify

The standard evidence pack lifecycle for creating trusted artifacts.

๐Ÿ”ง

Project Setup

Initialize a new epack project with collectors and tools.

๐Ÿ”

Audit & Compare

Review pack contents and compare against previous versions.

Global Flags

These flags can be used with any command.

Flag Description Default
-q, --quiet Suppress non-essential output. Only errors and primary results are shown. false
--json Output in JSON format for machine consumption. Supported by most commands. false
--no-color Disable colored output. Also respects NO_COLOR env var. false
-v, --verbose Verbose output with additional details for debugging. false
--no-redact Disable secret redaction in error messages. Use with caution false
--ci CI mode: disable spinners, add timestamps. Auto-detected from CI, GITHUB_ACTIONS, GITLAB_CI, CODEBUILD_BUILD_ID, JENKINS_URL, BUILDKITE, or TF_BUILD env vars. false

Environment Variables

Configure epack behavior through environment variables. Command-line flags take precedence.

Variable Description Used By
EPACK_OIDC_TOKEN Optional OIDC identity token for keyless signing outside GitHub Actions ambient OIDC. sign
EPACK_SIGNING_KEY Path to a PEM private key a run signs in to the credential broker with when the runner has no identity of its own. --key sets it. run
EPACK_PIPELINE_ID The configuration a run belongs to, for a run that signs in with a key and for the scope of stored secrets. A folder made with epack remote clone sets it. A job with no folder that runs a configuration by name signs in for it with the job's GitLab ID token or the key. run
EPACK_CHECK Set to 1 to make a run a check that collects nothing, like --check. run
EPACK_TRUSTED_PUBLISHERS Comma-separated GitHub owners a fetched configuration may run components from, like --trust-publisher. run
EPACK_NO_REDACT Set to any value to disable secret redaction in error messages. All commands
NO_COLOR Standard variable to disable colored output (any value). All commands
EPACK_NO_UPDATE_NOTIFIER Set to any value to turn off the daily check for a newer epack release. The check runs only at a terminal and never in CI mode. All commands
EPACK_ERROR_FILE Path of a file every failed command appends machine-readable code=, exit=, and summary= lines to, plus a collector= line for each collector that failed. Lets CI read stable error codes without scraping logs. See machine-readable errors. All commands
EPACK_HEAD_SHA Branch head commit reported as head_sha in runner context. Set it on pull_request workflows, where GITHUB_SHA is the ephemeral merge commit rather than the head. remote report-lock, push

Configuration Precedence

  1. Command-line flags (highest priority)
  2. Environment variables
  3. Project config (epack.yaml)
  4. User config (~/.epack/config.yaml)

Exit Codes

Use these exit codes in scripts and CI/CD pipelines to handle different outcomes.

Code Name Description
0 Success Command completed successfully.
1 General Error Generic failure (invalid input, runtime error, etc.).
2 Malformed Pack Pack file cannot be opened or parsed.
2-9 Collector Exit From collect, collector run, and run: the exit code of the one collector that failed. See collector run failures.
10 Lock Invalid Lockfile missing, invalid, or mismatched.
11 Digest Mismatch Binary or artifact digest doesn't match expected value.
12 Signature Mismatch Sigstore signature verification failed.
13 Timeout Operation timed out.
14 Missing Binary Required binary not found or installed.
15 Network Error Network error during fetch operation.
Example: CI/CD error handling
#!/bin/bash
epack verify evidence.epack --issuer "https://token.actions.githubusercontent.com"
case $? in
  0) echo "Verification passed" ;;
  2) echo "Pack is corrupted or invalid"; exit 1 ;;
  11) echo "Digest mismatch"; exit 1 ;;
  12) echo "Signature verification failed"; exit 1 ;;
  *) echo "Other error: $?"; exit 1 ;;
esac

Output Formats

Most commands support multiple output formats for different use cases.

Default human-readable format with colors and formatting:

epack inspect evidence.epack
Pack:        evidence.epack
Stream:      myorg/prod
Created:     2025-02-21T10:30:00Z
Artifacts:   3 files (1.2 MB)
Signed:      โœ“ keyless (security@company.com)
Digest:      sha256:a1b2c3d4...

Machine-readable JSON with --json flag:

{
  "pack": "evidence.epack",
  "stream": "myorg/prod",
  "created": "2025-02-21T10:30:00Z",
  "artifacts": 3,
  "size_bytes": 1258291,
  "signed": true,
  "signer": {
    "subject": "security@company.com",
    "issuer": "https://accounts.google.com"
  },
  "digest": "sha256:a1b2c3d4..."
}

Minimal output with -q flag for scripting:

sha256:a1b2c3d4e5f6...
Commands

build

Core

Create an Evidence Pack from artifacts. Bundles files with metadata into a verifiable package.

epack build <output.epack> [files...] --stream <stream>
# Build from files
epack build evidence.epack ./reports/*.pdf --stream myorg/prod

# Include multiple directories
epack build evidence.epack ./configs ./logs --stream myorg/prod
# Explicit file mapping (src:dest)
epack build evidence.epack --stream myorg/prod \
  --file ./local/report.pdf:artifacts/soc2.pdf \
  --file ./local/config.json:artifacts/config.json

Use src:dest format to control artifact paths inside the pack.

# Read artifact from stdin
curl -s https://api.example.com/data | \
  epack build evidence.epack --stream myorg/prod \
  --stdin artifacts/api-response.json

# Combine stdin with files
cat config.yaml | epack build out.epack ./logs --stream myorg/prod \
  --stdin artifacts/config.yaml
.github/workflows/build-pack.yml
- name: Build Evidence Pack
  run: |
    epack build evidence.epack ./artifacts --stream ${{ github.repository }} \
      --source "github-collector:1.0.0"
Flags 8
-s, --stream required Stream identifier (e.g., myorg/prod). Uniquely identifies this evidence stream.
-f, --file File mapping (src:dest or src). Can be repeated.
--stdin Read artifact from stdin with given path inside pack.
--content-type Default MIME type for artifacts (auto-detected if omitted).
-o, --output Output path (alternative to positional argument).
--force Overwrite existing output file.
--source Source collector metadata (name:version). Can be repeated.
--mapping Seal a control mapping file (evidencepack/control-mapping@v1) into the pack. Can be repeated.

sign

Core Sigstore

Sign a pack with Sigstore. Creates a cryptographic attestation binding your identity to the pack contents.

epack sign <pack.epack> [flags]
# Keyless signing (opens browser for OIDC auth)
epack sign evidence.epack

# Preview what would be signed
epack sign evidence.epack --dry-run

Opens your browser to authenticate with Google, GitHub, or Microsoft. No keys to manage!

GitHub Actions
permissions:
  id-token: write

- name: Sign Evidence Pack
  run: epack sign evidence.epack -y  # Skip confirmation
GitHub Actions: Grant id-token: write. epack automatically mints the Sigstore OIDC token from the ambient GitHub Actions endpoint.
# Sign with private key (PEM format)
epack sign evidence.epack --key ./private.pem

# Skip transparency log (private signing)
epack sign evidence.epack --key ./private.pem --no-tlog
Note: Key-based signing requires you to manage and secure your private keys. Keyless signing is recommended for most use cases.
Flags 7
--oidc-token OIDC token for keyless signing. Also reads from EPACK_OIDC_TOKEN. GitHub Actions uses ambient OIDC automatically when available.
--key Path to private key (PEM format) for key-based signing.
-y, --yes Skip confirmation prompt.
--dry-run safe Show what would be signed without signing.
--no-tlog Skip transparency log (Rekor). Reduces verifiability
--tsa Timestamp authority URL(s) for timestamping.
--insecure-allow-custom-endpoints Use with caution Allow custom Sigstore endpoints (TSA, Fulcio, Rekor).

verify

Core

Verify pack integrity and signatures. Confirms the pack hasn't been tampered with and validates signer identity.

epack verify <pack.epack> [flags]
# Basic verification (requires identity flags in production)
epack verify evidence.epack

# Integrity only (no signature required)
epack verify --integrity-only evidence.epack
# Require specific signer identity
epack verify evidence.epack \
  --issuer "https://accounts.google.com" \
  --subject "security@vendor.com"

# Pattern matching for organizations
epack verify evidence.epack \
  --issuer "https://accounts.google.com" \
  --subject-regexp ".*@vendor\\.com$"
Security: Always verify signer identity in production. Without --issuer and --subject, you're only checking that someone signed it.
GitHub Actions
# Verify packs came from trusted CI/CD
epack verify evidence.epack \
  --issuer "https://token.actions.githubusercontent.com" \
  --subject-regexp "https://github.com/myorg/.*"
# Offline verification (skip transparency log check)
epack verify --offline evidence.epack \
  --issuer "https://accounts.google.com" \
  --subject "security@vendor.com"

# With custom trust root
epack verify evidence.epack --trust-root ./sigstore-root.json
# A pack signed with a key carries no certificate; check it against the signer's public key
epack verify evidence.epack --public-key signer.pem

# Accept any of several keys; the one that verifies names the signer
epack verify evidence.epack --public-key runner-a.pem --public-key runner-b.pem
Flags 11
--issuer Required OIDC issuer (exact match). The identity provider that authenticated the signer.
--issuer-regexp Required OIDC issuer (regexp pattern).
--subject Required certificate subject (exact match). The email or identity of the signer.
--subject-regexp Required certificate subject (regexp pattern).
--offline Use embedded Rekor/TSA timestamps only; requires --trust-root.
--integrity-only Only verify digests, skip attestation verification.
--require-attestation Fail if no attestations present (default for production).
--insecure-skip-identity-check INSECURE Accept any valid signer. Only use for testing.
--insecure-skip-embedded-verify INSECURE Skip verification of embedded attestations.
--public-key PEM public key a signer used instead of a certificate. Repeatable; the key that verifies names the signer.
--trust-root Path to custom Sigstore trust root JSON.

inspect

Core

Display pack metadata. Shows stream, artifacts, signatures, control mappings, and other details.

epack inspect <pack.epack> [flags]
epack inspect evidence.epack
epack inspect --digest evidence.epack      # Just the pack digest
epack inspect --json evidence.epack        # JSON format
epack inspect --raw evidence.epack         # Raw manifest.json
epack inspect --summary evidence.epack     # Condensed output
Flags 3
--digest Show only pack_digest (useful for scripting).
--raw Output raw manifest.json without formatting.
--summary Condensed single-line summary output.
See also: list verify

list

Core

List pack contents. Shows artifacts, attestations, or source collectors.

epack list [pack.epack]
epack list <subcommand> <pack.epack> [flags]

Subcommands

artifacts

List artifacts in the pack

attestations

List attestations (signatures)

sources

List source collectors

epack list artifacts evidence.epack
epack list artifacts -l evidence.epack          # Detailed view
epack list artifacts --filter "*.json" evidence.epack
epack list attestations evidence.epack
epack list sources evidence.epack
Flags 2
-l, --long Detailed information including size and digest.
--filter Filter by path pattern (glob syntax).
See also: inspect extract

extract

Core

Extract artifacts from a pack. Writes files to disk while preserving directory structure.

epack extract <pack.epack> [path...] [flags]
# Extract specific artifact
epack extract evidence.epack artifacts/config.json

# Extract all artifacts
epack extract --all evidence.epack

# Extract to specific directory
epack extract --all -o ./extracted evidence.epack

# Filter and preview
epack extract --all --filter "*.json" --dry-run evidence.epack
Flags 5
-o, --output Output directory (default: current directory).
--all Extract all artifacts.
--filter Filter by path pattern (glob syntax).
--force Overwrite existing files.
--dry-run safe Show what would be extracted without writing files.
See also: list

diff

Core

Compare two packs. Shows added, removed, and changed artifacts between versions.

epack diff <old.epack> <new.epack> [flags]
epack diff last-year.epack this-year.epack
epack diff --artifact artifacts/config.json old.epack new.epack
epack diff --json old.epack new.epack
epack diff -C 5 old.epack new.epack   # 5 lines context
Flags 2
-a, --artifact Compare specific artifact by path.
-C, --context Lines of context for text diffs (default: 3).
See also: inspect merge

merge

Core

Combine multiple packs into one. Useful for aggregating vendor evidence or combining collector outputs.

epack merge <output.epack> <pack1.epack> <pack2.epack> ... --stream <stream>
# Basic merge
epack merge combined.epack vendor-a.epack vendor-b.epack \
  --stream myorg/all-vendors

# Glob patterns
epack merge combined.epack vendor-*.epack --stream myorg/all-vendors

# Preview merge
epack merge combined.epack vendor-*.epack --stream myorg/all-vendors --dry-run
# Verify source packs during merge
epack merge combined.epack vendor-*.epack \
  --stream myorg/all-vendors \
  --include-attestations \
  --issuer "https://accounts.google.com" \
  --subject-regex ".*@trusted-vendor\\.com$" \
  --merged-by "security-team"

Using --include-attestations embeds the original signatures, creating an audit trail.

Flags 11
-s, --stream required Stream identifier for merged pack.
--merged-by Identifier of who performed the merge.
--include-attestations Embed source pack attestations in merged pack.
--force Overwrite existing output file.
--dry-run safe Show what would be merged without creating output.
--issuer Required OIDC issuer for source attestations.
--subject Required exact subject identity.
--subject-regex Required subject pattern (regex).
--insecure-skip-identity-check INSECURE Accept source attestations from any signer.
--insecure-skip-attestation-verify INSECURE Skip attestation verification on source packs.
--trust-root Path to Sigstore trust root JSON.
See also: build verify

version

Core

Show version information including build details.

At a terminal, the full build also checks at most once a day for a newer release while a command runs, and when one is out, says so after the command finishes with how to upgrade. It asks GitHub without credentials and gives up after two seconds. There is no check in CI mode or with --quiet, and EPACK_NO_UPDATE_NOTIFIER turns it off.

epack version [flags]
epack version
epack version --json
epack version -v    # Verbose: commit, date, Go version
Full Edition Commands below require -tags components build

new

Full Edition

Create a new epack project. Scaffolds a complete project structure with config, sample pack, and git setup.

epack new <directory> [flags]
epack new my-pipeline
epack new .                          # Initialize current directory
epack new my-pipeline --force       # Allow non-empty directory
epack new my-pipeline --skip-sample --skip-git

Created Files

  • epack.yaml - Project configuration
  • packs/ - Output directory for packs
  • sample.epack - Example pack
  • README.md - Project documentation
  • .gitignore - Ignores runtime .epack/ state while keeping .epack/hooks/ tracked

This keeps caches and downloaded runtime state out of git while reserving .epack/hooks/ for committed project-level customization.

Flags 3
--force Allow non-empty directory.
--skip-sample Don't create sample pack.
--skip-git Don't create .gitignore.

new vs init

new init
Creates directory โœ“ โœ—
Works in existing project โœ— โœ“
Creates sample pack โœ“ (optional) โœ“ (optional)
See also: init install

init

Full Edition

Initialize epack in existing directory. Adds configuration without creating a new project and updates the managed .gitignore block to keep .epack/hooks/ tracked.

epack init [flags]
epack init
epack init --skip-sample
Flags 2
--skip-sample Don't create sample pack.
-f, --force Overwrite existing epack.yaml.
See also: new

collect

Full Edition Recommended

One-command workflow: lock โ†’ sync โ†’ run โ†’ build. This is the primary command for generating evidence packs. When collectors fail, no pack is built, and each failed collector is reported with a code such as auth_failed; see collector run failures.

epack collect [flags]
epack collect
epack collect --frozen              # CI mode: strict verification
epack collect -c epack.yaml        # Specific config file
epack collect -o output.epack       # Custom output file
epack collect --timeout 2m         # Collector timeout
Tip: Use --frozen in CI/CD to fail on any dependency mismatch. This ensures reproducible builds.
Flags 6
-c, --config Path to epack config file (default: epack.yaml).
--frozen Fail on any mismatch (CI mode). Requires lockfile to be up-to-date.
-o, --output Output pack file path.
--timeout Timeout per collector execution (default: 10m).
--progress Progress display mode: auto|tty|plain|json|quiet.
--parallel Max parallel collector executions (0=auto).

run

Full Edition

Run the workflow a project describes, start to finish: install the locked collectors, tools, and remote adapters, run the pre-collect hook, collect, run the post-collect hook, run each tool on the pack, sign, and push. With a configuration name, the configuration is fetched from the remote you last signed in to (or --remote) into a folder named after it, refreshed when the folder exists, and the run happens there. Without a name, the run uses the project in the current directory. From inside a folder a clone created, a run by that name refreshes the folder in place. When a stage fails, the failure is reported to the remote with a stable code, and a collect failure names the collector. A remote whose adapter takes progress is told as each stage, collector, and tool starts, finishes, or fails.

epack run [<name>] [flags]
# Fetch a configuration from the remote you signed in to and run it
epack run northwind-production

# Run the project in the current directory
epack run

# Check sign-in, the lock, variables, credentials, and publishers; collect nothing
epack run --check

# In CI: no prompts, sign with a key
epack run --yes --key "$EPACK_SIGNING_KEY"

In a folder fetched from a remote, --check locks the configuration as the first run would. In your own project, it reports a missing or stale lock instead. With a current lock, it installs the locked collectors, tools, and remote adapter as a run does before it signs in. In a terminal, it also offers to register this machine's key for the configuration when the remote does not hold it, as a run does. Variables are reported as N of M ready, one line each with where the value comes from: the environment, your keychain, stored but awaiting approval, or not set. A variable that is not ready comes with the epack secret command that resolves it. Variables the configuration lists as optional are reported with the rest but not counted.

The variables a configuration lists under secrets come from the environment first and from your keychain second, for the folder's configuration on its remote. A stored value is used only once it is approved for the components that read it as they are now; a revision that changes a reader stops the run before collecting until epack secret approve. Runs and checks never prompt, and a CI job never reads the keychain.

A run from a terminal signs in your browser, as you. Its collectors get their managed credentials through that sign-in when the remote's adapter supports it. A machine with a key from epack key create signs with it once the remote approves the key. A configuration fetched from a remote may only run collectors, tools, and remote adapters from publishers you trust: in a terminal, epack asks once for each new publisher, and a job names them with --trust-publisher or EPACK_TRUSTED_PUBLISHERS.

A run by name checks the revision it fetched before installing anything: the variables and keychain secrets it reads, approval for stored secrets, trust in its publishers, and the epack release the remote says it needs. When something is missing, the run lists it with where to add it and asks the remote for the newest earlier revision that runs without it. That revision runs from .epack/fallback inside the folder, and the fetched revision stays in the folder for you to finish. With no earlier revision that runs here, the run stops, reports what is missing to the remote, and exits. A job with no folder signs in for the configuration with EPACK_PIPELINE_ID and the job's GitLab ID token or the runner's key, through the adapter installed for the user, which must come from a publisher the job trusts.

Flags 10
--check Sign in, verify the lock, variables, credentials, and publishers, report the result, and collect nothing. Or set EPACK_CHECK=1.
-y, --yes Skip prompts.
--key Sign with a private key (PEM) instead of keyless signing. A runner without its own identity also signs in to the credential broker with it.
--browser Sign in your browser even when this machine has a key from epack key create.
--oidc-token OIDC token for keyless signing (or EPACK_OIDC_TOKEN).
--remote With a name, the remote to fetch it from (default: the last one you signed in to). Otherwise, the remote to push to (default: the only one configured).
--trust-publisher Trust a publisher (GitHub owner) for this run only. Repeatable. EPACK_TRUSTED_PUBLISHERS does the same in a job.
-o, --output Pack file to build (default: evidence.epack in the project).
--force When fetching, replace files you have edited, or a folder cloned from another configuration.
--insecure-allow-unpinned Allow components and adapters not pinned in the lockfile (not recommended).

secret

Full Edition

Keep the variables a configuration lists under secrets in your operating system keychain, scoped to this configuration on its remote, so a run finds them in any terminal. The environment always wins: a variable set in the shell reaches the components that list it as before, and the keychain is read only for the rest. A stored value is approved for the components that read it as they are now. When a later revision changes one of them, or adds one, the secret needs approval again before a run uses it. Run these commands in the folder epack remote clone created. Runs and checks never prompt; only these commands do.

epack secret <subcommand> [<NAME>] [flags]

Subcommands

setup

Walk through every missing and unapproved secret

set

Store one value and approve it for its readers

approve

Review what changed for a stored secret and approve it

list

Show stored secrets, their readers, and approval state

remove

Erase one stored secret and forget its approval

# Walk every missing and unapproved secret; each value is read hidden
epack secret setup

# Paste one value, hidden
epack secret set AZURE_CLIENT_SECRET

# Store a key or a JSON credential from a file
epack secret set OKTA_PRIVATE_KEY --from-file ~/Downloads/okta.pem

# Pipe a value in from a password manager
op read op://Vault/item/field | epack secret set SENTRY_AUTH_TOKEN --stdin

# Review what changed and approve
epack secret approve

# Names, readers, and approval state; never values
epack secret list

epack secret remove AZURE_CLIENT_SECRET

# Clean up after a pipeline is gone
epack secret list --all
epack secret remove AZURE_CLIENT_SECRET --scope locktivity:cfg_abc123

setup is the one command meant to be interactive: each secret the keychain lacks is asked for, hidden, and stored, and each one that needs approval again is shown with what changed and approved on a yes. Enter skips a value. It ends with what was skipped or left unapproved and the next step, epack run --check. set refuses a value given as an argument, since it would land in shell history; in a terminal the value is read hidden, --stdin reads a pipe to the end, and --from-file reads a file. Exactly one trailing newline is stripped. approve prints each change to a reader since the approval and what it means before asking; without a name it walks every secret that needs approval. list never shows a value.

The keychain is /usr/bin/security on macOS, the Secret Service over D-Bus on Linux, and Credential Manager on Windows. A value too large for one item is split across items that a header item describes, so an interrupted write keeps the old value. What epack records about stored secrets, names, readers, approvals, and times but never values, lives in ~/.epack/secrets.yaml, readable only by you. The keychain protects a value at rest and from other user accounts, not from code running as you; see Stored secrets.

Flags 6
--stdin Read the value from standard input, to the end. Refused when standard input is a terminal. set only.
--from-file Read the value from a file, for a key or a JSON credential. set only.
--unlisted Store a name no component in the configuration lists yet. set only.
-y, --yes Never prompt. On approve, approve without asking; meant for someone who has read the check's findings.
--all List every configuration on this machine with stored secrets. list only.
--scope The configuration to erase from, as remote:configuration, the way list --all prints it. remove only.

key

Full Edition

Signing keys for runs from this machine. A run from a terminal signs its pack in your browser, as you. A key signs it with nobody at the keyboard, which a scheduled run needs, and keeps your email out of the signature. epack key create keeps the private half in ~/.epack/keys/<remote>.pem, readable only by you, and registers the public half with the remote. Once the remote accepts it, runs from this machine sign with it. Requires an adapter that manages keys.

epack key <subcommand> [remote] [flags]

Subcommands

create

Make a signing key for this machine and register it

list

Show the keys a configuration accepts, and which is this machine's

rotate

Replace this machine's key and retire the old one

# Make a key for this machine and register it
epack key create

# Register a key for a configuration by name
epack key create locktivity --for northwind-production

# Write a key for a runner you manage instead of this machine
epack key create --for northwind-production --out ./epack-signing-key.pem

# Show the keys a configuration accepts
epack key list --for northwind-production

# Replace this machine's key; the old one is retired once the new one is accepted
epack key rotate

The remote may hold a new key until someone approves it. The command then shows a code, opens the approval page in your browser, and waits for the code to be entered there. Running the command again registers the same key, so it is safe to repeat. rotate registers the new key first and retires the old one only once the new one is accepted, so a failed rotation leaves the old key working. A retired key signs nothing new, and packs it already signed stay trusted.

Flags 6
--for The configuration the key is for (default: the fetched configuration in this folder).
--name How the key is listed (default: this machine's name). create and rotate.
--expires-days Days until the key stops being accepted; 0 for no expiry (default 365). create and rotate.
--out Write the key to this path for a runner you manage, instead of this machine's key. create only.
--no-browser Print the approval link instead of opening a browser. create and rotate.
--insecure-allow-unpinned Allow adapters not pinned in the lockfile (not recommended).

install

Full Edition

Lock if needed and download binaries. Combines lock and sync in one command.

epack install [flags]
epack install
epack install --all-platforms      # Lock and sync all platforms
Flags 4
-c, --config Path to epack config file (default: epack.yaml).
--frozen Fail on any mismatch (CI mode).
--all-platforms Lock and sync all available platforms.
--platform Platforms to lock (comma-separated).
See also: lock sync

lock

Full Edition

Resolve dependencies and write lockfile. Creates epack.lock with pinned versions, checksums, and per-component verification status. Each component resolves to the newest release its version range allows, and entries for components and files the config no longer lists are removed. With --keep-pins, a pinned version stays while its range allows it, and only components that are new, out of range, or from another source are resolved.

epack lock [flags]
epack lock
epack lock --all-platforms
epack lock --platform linux/amd64,darwin/arm64
epack lock --keep-pins       # Resolve only new or out-of-range components
Flags 4
-c, --config Path to epack config file.
--all-platforms Lock all available platforms.
--platform Platforms to lock (comma-separated).
--keep-pins Keep each pinned version its range still allows, and resolve only new or out-of-range components.
See also: sync update

sync

Full Edition

Download binaries from lockfile. Fetches and verifies collectors/tools specified in epack.lock. Use --locked on clean CI machines to install exactly the locked versions and fail on any drift; use --frozen to verify an existing install without downloading anything.

epack sync [flags]
epack sync
epack sync --locked  # CI install: exact locked versions, fail on drift
epack sync --frozen  # CI verify: no downloads, fail on mismatch
Flags 4
-c, --config Path to epack config file.
--locked Clean-machine CI install: install exactly the locked versions with full signature and digest verification, fail on any drift (modified binaries, unpinned externals, a pin outside its configured range), and never rewrite the lockfile. Mutually exclusive with --frozen.
--frozen Verify-only CI mode: fail on any mismatch or missing platform. Never downloads, so it always fails on a fresh machine; use --locked there instead.
--insecure-skip-verify Skip signature verification (not recommended; rejected together with --locked or --frozen).
See also: lock install

update

Full Edition

Update collector/tool versions and re-lock. Checks for newer versions and updates the lockfile. When a component moves to a new version, every platform already in the lockfile is re-locked against the new release.

epack update [flags]
epack update                # Update all collectors
epack update github aws     # Update specific collectors
Flags 1
-c, --config Path to epack config file.
See also: lock

collector

Full Edition

Collector management commands. Run collectors directly without the full collect workflow.

epack collector <subcommand> [flags]

Subcommands

run

Run collectors and build pack

epack collector run
epack collector run -o output.epack
epack collector run --timeout 5m

For managed credential development flows, set EPACK_INSECURE_CREDENTIAL_BROKER_URL to use a custom broker.

See also: collect

tool

Full Edition

Tool discovery and execution. Run analysis tools on evidence packs.

epack tool <subcommand> [flags]

Subcommands

<name>

Execute a configured tool

list

List available tools

info <name>

Show tool details

source <name>

Show tool provenance

catalog search

Search tool catalog

catalog refresh

Update tool catalog

verify <name>

Verify tool binary

# Execute configured tools
epack tool ask --pack vendor.epack "What MFA policies exist?"
epack tool policy --pack vendor.epack

# Discovery
epack tool list
epack tool info ask
epack tool catalog search "policy"
See also: Building Tools

utility

Full Edition

Manage and run globally installed epack utilities. Unlike project-specific collectors and tools, utilities are installed globally for the current user in ~/.epack/.

epack utility <name> [args]
epack utility <subcommand> [flags]

Subcommands

<name> [args]

Run an installed utility

install <name>[@version]

Install a utility from the catalog

list

List installed utilities

remove <name>

Remove an installed utility

# Install a utility from the catalog
epack utility install viewer

	# Install a specific version
	epack utility install viewer@v1.2.3

# Run an installed utility
epack utility viewer pack.epack
epack utility exporter evidence.epack --format xlsx

# List installed utilities
epack utility list

# Remove a utility
epack utility remove viewer
Install Flags 4
--refresh Refresh the catalog before lookup.
--dry-run Show what would be installed without making changes.
--insecure-skip-verify Skip Sigstore signature verification (NOT RECOMMENDED).
--insecure-trust-on-first Trust digest without Sigstore verification (NOT RECOMMENDED).
Root Flags 1
--insecure-allow-unpinned Skip digest verification for installed utilities (NOT RECOMMENDED).
Security: Utility binaries are verified against their lockfile digest before execution (TOCTOU-safe). The binary is copied while hashing to ensure you execute exactly the bytes you verified.
Utilities vs Tools: Utilities are globally installed helper applications (stored in ~/.epack/). Tools are project-specific plugins configured in epack.yaml and run via epack tool.

catalog

Full Edition

Search and manage the unified component catalog. Searches across collectors, tools, remotes, and utilities.

epack catalog <subcommand> [flags]
search [query]

Search the catalog for components

refresh

Update the local catalog cache

# Search for components matching "github"
epack catalog search "github"

# Search for tools only
epack catalog search "policy" --kind tool

# Search for collectors
epack catalog search --kind collector

# List all available remotes
epack catalog search --kind remote

# Refresh the catalog cache
epack catalog refresh
search Flags 2
--kind Filter by component type: collector, tool, remote, or utility.
--refresh Refresh the catalog before searching.
Note: The epack tool catalog command is deprecated. Use epack catalog instead for a unified view of all component types.
See also: collector tool utility

remote login

Full Edition

Sign in to a remote with your browser. epack opens the remote's sign-in page, and once you allow epack there, the browser returns to epack at 127.0.0.1 on this machine and the adapter finishes the sign-in. The adapter keeps the session, so later commands need no token. The remote you sign in to becomes the default for configuration names in run and remote clone, and its adapter's publisher is trusted for configurations fetched from it. Outside a project, the adapter is installed for your user from the catalog and verified before it runs; inside a project that names the remote, the project's pinned adapter is used.

epack remote login <remote> [flags]
epack remote login locktivity

# Over SSH: forward a fixed port when you connect, then open the printed link on your own computer
ssh -L 8400:127.0.0.1:8400 host
epack remote login locktivity --port 8400 --no-browser
Flags 3
--no-browser Print the link instead of opening a browser.
--port Port on 127.0.0.1 the browser returns to (0 picks a free one).
--insecure-allow-unpinned Allow adapters not pinned in the lockfile (not recommended).

remote clone

Full Edition

Fetch a named configuration from a remote and write it into a folder: epack.yaml, the hooks, any profile files, and the lock when the remote has one. The remote is the one you last signed in to, or --remote. The folder defaults to the configuration's name, or to the current folder when it is the one an earlier clone of that configuration created, even if the configuration was renamed since. Run it again to pick up a newer revision. Inside a folder a clone created, the name can be left out: the folder is refreshed from the configuration and remote it was cloned from. Files you have edited are left alone unless you pass --force, and hook scripts are never overwritten. When the revision carries a lock, it replaces a lock that a run wrote in the folder. A folder cloned from another configuration is refused unless you pass --force. After a fetch that changed something, epack prints what the configuration will run and read, counting a variable as set when the environment or your keychain holds it.

epack remote clone [<name>] [dir] [flags]
epack remote clone northwind-production
epack remote clone northwind-production ./compliance
epack remote clone northwind-production --remote locktivity

# Inside a folder a clone created, pick up a newer revision
epack remote clone

# Replace files you have edited with the remote's
epack remote clone northwind-production --force
Flags 3
--remote Remote to fetch from (default: the last one you signed in to).
--force Replace files you have edited, and write into folders no clone created or another configuration was cloned into.
--insecure-allow-unpinned Allow adapters not pinned in the lockfile (not recommended).

remote update

Full Edition

Update the adapter installed for you to the newest release the catalog lists. The adapter you signed in with is pinned in ~/.epack/remotes.lock and never moves on its own. This command moves it to the newest release of the same repository, verified the same way as the first install. The new release is installed and started before the pin moves, so a release that fails leaves the old one in place. A project that names the remote pins its own adapter in epack.lock.yaml; this command does not change that pin.

epack remote update [remote]
epack remote update
epack remote update locktivity
See also: remote login update

pull

Full Edition

Pull an evidence pack from a remote registry. Downloads and optionally verifies the pack.

epack pull <remote> [ref] [flags]
# Pull latest pack
epack pull locktivity

# Pull to specific output path
epack pull locktivity -o ./packs/evidence.epack

# Preview what would be pulled (dry-run)
epack pull locktivity --dry-run
# Pull specific version
epack pull locktivity --version v1.2.3

# Pull by release ID
epack pull locktivity --release rel_abc123

# Using positional ref argument
epack pull locktivity v1.2.3
# Pull by digest (immutable, for reproducibility)
epack pull locktivity --digest sha256:abc123...

# Overwrite existing file
epack pull locktivity --force

# Skip verification (not recommended)
epack pull locktivity --verify=false
# Pull from staging environment
epack pull locktivity --env staging

# Override workspace target
epack pull locktivity --workspace acme-prod

# Pull in background (returns immediately)
epack pull locktivity --detach
Flags 11
-o, --output Output path (default: ./<stream>.epack).
--version Pull specific version.
--release Pull specific release by ID.
--digest Pull specific pack by digest (immutable).
--env Environment to use (applies config from environments.<env>).
--workspace Override target workspace.
--force Overwrite existing file.
--verify Verify pack integrity after download (default: true).
--dry-run Show what would be pulled without downloading.
-d, --detach Run in background and return immediately.
--insecure-allow-unpinned Allow using adapters not pinned in lockfile (NOT RECOMMENDED).
Exit codes: 0 = Pack pulled successfully, 1 = Pull failed (auth/network error), 2 = Pack verification failed

push

Full Edition

Push a pack to a remote registry. Uploads the pack, creates a release, and syncs run records.

epack push <remote> <pack.epack> [flags]
# Push to Locktivity remote
epack push locktivity packs/evidence.epack

# Non-interactive mode (skip prompts)
epack push locktivity packs/evidence.epack -y
# Push with release labels
epack push locktivity packs/evidence.epack \
  --label monthly \
  --label soc2

# Push with release notes
epack push locktivity packs/evidence.epack \
  --notes "February 2025 compliance release"
# Push to staging environment (uses staging config overrides)
epack push locktivity packs/evidence.epack --env staging

# Override workspace target
epack push locktivity packs/evidence.epack --workspace acme-prod

Environment configs are defined in epack.yaml under environments:

GitHub Actions
- name: Push to Locktivity
  run: |
    epack push locktivity packs/evidence.epack \
      -y \
      --label automated \
      --notes "Build ${{ github.run_number }}"
Flags 10
--env Environment to use (applies config from environments.<env>).
--workspace Override target workspace.
--label Release label (can be repeated).
--notes Release notes.
--runs-path Additional path to search for run results (can be repeated).
--no-runs Skip run syncing after push.
-y, --yes Non-interactive mode (skip prompts).
--dry-run Show what would be pushed without uploading.
-d, --detach Run in background and return immediately.
--insecure-allow-unpinned Allow using adapters not pinned in lockfile (NOT RECOMMENDED).
Exit codes: 0 = Pack pushed successfully, 1 = Push failed (auth/network error), 2 = Pack malformed

remote report-lock

Full Edition

Report the current epack.lock.yaml to a remote without pushing a pack. Sends the raw lockfile, its SHA-256, a normalized component summary, and runner context. Built for CI bootstrap and refresh flows where the platform needs the resolved lock before any evidence exists. Requires an adapter that advertises the lock_report capability. A failure report also lists the collectors that failed, with each one's failure code and exit code, when the last error in EPACK_ERROR_FILE has the code given as --failure-code.

epack remote report-lock <remote> [flags]
# Report a freshly resolved lock during setup bootstrap
epack remote report-lock locktivity --reason bootstrap

# Report a refreshed lock from a config-change branch
epack remote report-lock locktivity --reason refresh

# Report a frozen-run failure with a stable error code
epack remote report-lock locktivity --reason frozen_check \
  --outcome failure --failure-code lock_config_mismatch
Flags 7
--reason Why the report exists: bootstrap, refresh, or frozen_check (default).
--outcome success (default) or failure. Failure reports omit the raw lockfile.
--failure-code Stable error code for failed reports (required with --outcome failure). Read it from EPACK_ERROR_FILE rather than scraping logs.
--failure-message Human-readable summary for failed reports.
--env Environment to use (applies config from environments.<env>).
--workspace Override target workspace.
--insecure-allow-unpinned Allow adapters not pinned in the lockfile (not recommended).
See also: push sync

completion

Core

Generate shell completion scripts. Enables tab completion for commands, flags, and arguments.

epack completion <shell>
# Add to ~/.bashrc
source <(epack completion bash)

# Or install system-wide
epack completion bash > /etc/bash_completion.d/epack
# Add to ~/.zshrc
source <(epack completion zsh)

# Or install to fpath
epack completion zsh > "${fpath[1]}/_epack"
epack completion fish > ~/.config/fish/completions/epack.fish
# Add to your PowerShell profile
epack completion powershell | Out-String | Invoke-Expression