Changelog

Version history and release notes for epack CLI and specification.

v0.6.0 October 2026 Latest

A failed collector is reported with a code that says why, and its exit code reaches the job. A collector that exits 0 without evidence now fails. A new collector project is laid out and checked the way the epack collectors are.

Collector failures

  • epack collect, epack collector run, and epack run report each failed collector with a code: config_invalid when it exited 2, auth_failed for 3, network_error for 4, collector_error for any other exit or a signal, invalid_output when it exited 0 without a result, and timeout when it ran past --timeout. A failure epack finds before the collector runs keeps its own code, such as binary_not_found or digest_mismatch
  • The command's error has the code collect_failed and reads okta: exited with code 3: ... for one collector, or 2 collectors failed: okta, github for several
  • When one collector failed, epack exits with that collector's exit code from 2 to 9, or with epack's own code for a failure it found, such as 13 for a timeout. Several failures exit 1. Earlier releases exited 1 for any collector failure
  • With EPACK_ERROR_FILE set, each failed collector adds a line after the summary, such as collector=okta code=auth_failed exit=3 code_source=exit_code. code_source is exit_code when the code was inferred from the exit code and runner when epack observed the failure itself
  • A failed epack run reports each collector's code, exit, and code_source under metadata.collect.failures. epack remote report-lock --outcome failure lists the same collectors, without their errors, from EPACK_ERROR_FILE when its last error has the code given as --failure-code

Upgrade notes

  • A collector that exits 0 must print a result. Empty stdout, JSON null, text that is not JSON, and an envelope whose artifacts list is empty or null now fail the collector with invalid_output. Earlier releases packed text that was not JSON as a JSON string
  • A script that reads EPACK_ERROR_FILE by sourcing it should read the ^code=, ^exit=, and ^summary= lines instead, since a collector= line would also set code and exit

Collector SDK

  • ConfigError, AuthError, and NetworkError keep their exit codes when returned as a pointer or wrapped with %w, and an error that reaches context.DeadlineExceeded without one of them exits 4
  • epack sdk new collector lays a project out as the epack collectors are: its entrypoint in cmd/epack-collector-<name>/main.go, collection logic and its test in internal/collector, a Makefile, and testdata/conformance.json. --module sets the Go module path, and the project needs Go 1.26
  • A new project's CI runs conformance at the epack version go.mod pins. A collector's runs make conformance, which passes testdata/conformance.json and the variables in CONFORMANCE_SECRETS
  • epack sdk mock collector writes config.json and run-collector.sh, a script that runs the collector as epack does

Conformance

  • epack sdk test and epack-conformance take --config, a collector config to collect with, and --secret, a variable the collector reads a credential from. Every run sets each secret to a canary value. The checks fail when a canary shows up in output, files, or error messages, and when a collector reports a rejected credential without exiting 3
  • epack sdk test builds cmd/<directory name>, or the only package under cmd/, and passes a collector project's testdata/conformance.json unless --config names another. epack-conformance -v lists every result, including passes

Releases

  • A tag with a prerelease suffix, such as v0.7.0-rc.1, publishes a GitHub prerelease. Homebrew and the latest image tags stay on the newest stable release
v0.5.3 October 2026 Stable

epack says when a newer release is out, at most once a day. CI mode is detected on more CI systems, and epack secret set says when a folder may be behind its configuration.

New

  • At a terminal, a command checks at most once a day for a newer epack release. When one is out, the command ends with epack X.Y.Z is available (you have A.B.C) and how to upgrade: brew upgrade with the formula when Homebrew installed epack, or else the releases page
  • The check asks GitHub without credentials, never sends GITHUB_TOKEN, gives up after two seconds, and never fails a command. Prereleases are not offered
  • There is no check in CI mode, with --quiet, when stderr is not a terminal, for a local or prerelease build, or for bare epack, help, version, completion, hooks, and context. Set EPACK_NO_UPDATE_NOTIFIER to turn it off
  • When the last check ran and the release it found are kept in ~/.epack/update-check.json, readable only by you. The check is in the full build only

Changes

  • CI mode is also detected from GITLAB_CI, CODEBUILD_BUILD_ID, JENKINS_URL, BUILDKITE, and TF_BUILD, besides CI and GITHUB_ACTIONS. A job on a system that sets only one of these now runs in CI mode: no spinners, timestamps on output, and no keychain
  • When epack secret set refuses a name no component lists, in a folder a clone created, it names the revision the folder holds and says to run epack remote clone to update the folder before passing --unlisted
v0.5.2 October 2026 Stable

When the revision a run fetches needs something the runner lacks, the run names what is missing and runs the newest earlier revision that works here, or stops and reports it. A job with no folder can run a configuration by name, signed in for that configuration.

Runs

  • epack run <name> checks the revision it fetched before installing anything: each variable or keychain secret it reads, approval for stored secrets, trust in each publisher it installs from, and the epack release the remote says it needs
  • When something is missing, the run lists it with where to add it, as the remote says or as epack knows, and asks the remote for the newest earlier revision that runs without it. That revision is fetched into .epack/fallback inside the folder and runs instead, and the run names both revisions. The fetched revision stays in the folder for you to finish
  • With no earlier revision that runs here, the run stops before installing anything, prints the remote's reason, reports what is missing to the remote with the code requirements_missing, and exits with revision N needs ..., and no earlier revision runs here without it
  • epack run --check reports an epack release older than the revision needs, with the release to upgrade to
  • After a fetch, epack prints what the remote says changed since the revision this runner last ran

Jobs

  • A job can run a configuration by name with no folder. With EPACK_PIPELINE_ID set and the job's GitLab ID token or the runner's key, epack run <name> and its check sign in for that configuration at the credential broker and fetch through the adapter installed for the user
  • That adapter must come from a publisher the job trusts, named with --trust-publisher or EPACK_TRUSTED_PUBLISHERS, and the check happens before the adapter is installed or run
  • When a run by name needs the adapter a folder pins and it is not installed yet, a run with nobody at the terminal installs it without asking if its publisher is trusted, and verifies it before it runs. Earlier releases installed it only after a prompt

Security

  • Trust in a new publisher is offered only for the revision you fetched. Earlier revisions a run falls back to are checked without prompting
  • EPACK_INSECURE_REMOTE_ENDPOINT and EPACK_INSECURE_REMOTE_AUTH_ENDPOINT point an adapter installed for the user at another instance of its remote, as insecure_endpoint does for a project's adapter. epack warns about each use and records it, and strict production builds refuse it

Remote Protocol

  • config.pull requests carry config.purpose: run, check, or clone. A remote can count a run or a check as contact from the runner; a clone sets up a folder and is never a run
  • A run that lacks what a revision needs sends config.fallback with that revision and what it lacks, by kind and name and never by value: variable, secret_approval, publisher, or epack. The answer is the newest earlier revision that runs without it, or no_fallback with a reason
  • A config.pull.result can carry requirements, the oldest epack that runs the revision and where a runner adds each variable, and changes with changes_since, what changed since the revision this runner last ran
  • Adapter commands run with EPACK_WRAPPER_VERSION set to the running epack release

Fixes

  • Choosing the newest release in a version range, and epack remote update, order prereleases by semver precedence: a release sorts after its prereleases, and rc.10 after rc.9
v0.5.1 October 2026 Stable

The lock drops what the configuration no longer lists, and epack lock --keep-pins resolves only what changed. Inside a folder a clone created, epack remote clone needs no name.

Lockfile

  • epack lock, epack install, and epack run remove lockfile entries for collectors, tools, remotes, profiles, overlays, and mappings the configuration no longer lists. epack lock and epack install print each one, as in removed okta@v0.2.0 (not in config). Earlier releases kept the entry, and a locked sync refused it with LOCK_STALE
  • epack lock --keep-pins keeps each pinned version its range still allows from the same source, and resolves only components that are new, out of range, or from another source. A pin it keeps prints as kept. Without the flag, every range resolves to its newest release as before

Remotes

  • Inside a folder a clone created, epack remote clone with no name refreshes the folder from the configuration and remote it was cloned from
  • A configuration renamed since it was cloned still refreshes in place: from inside its folder, epack run or epack remote clone with the new name matches the folder by the configuration's ID instead of nesting a copy
  • A folder cloned from another configuration is refused unless you pass --force
  • When a revision carries a lock, it replaces an epack.lock.yaml that a run wrote in the folder, and the fetch says so. The JSON result gains replaced. Earlier releases refused the fetch as a local change unless you passed --force
  • After a clone of a configuration with a CI job file that arrives locked, the next step reads commit the folder, without epack lock --all-platforms first
v0.5.0 October 2026 Stable

The variables a configuration lists under secrets can live in your keychain, scoped to one configuration on one remote and approved for the components that read them. A run reports each stage to a remote that can show it, and a failed run names the collector that failed.

New

  • epack secret keeps a configuration's secrets in the operating system keychain: setup walks through every missing and unapproved secret, set stores one value (hidden at a prompt, from a pipe with --stdin, or from a file with --from-file), approve reviews what changed and records approval, list shows names, readers, and approval state without values, and remove erases one. Run them in the folder epack remote clone created
  • Each stored secret is approved for the components that read it as they are now. A revision that changes a reader's entry in epack.yaml, or adds a reader, is shown and must be approved before the value is used again. Storing or approving one secret never approves another
  • The environment always wins: a variable set in the shell reaches its readers as before, and the keychain is read only for the rest. CI never reads the keychain
  • Remote adapters can take run.progress events, one as each stage and each collector or tool starts, finishes, or fails, so the remote can show the run while it is going. Adapters opt in with the run_progress feature; epack sends nothing to one that does not

Running

  • epack run --check reports variables as N of M ready and lists each one with where its value comes from: the environment, your keychain, stored but awaiting approval, or not set. A variable that is not ready comes with the command that resolves it. The JSON report gains variables and secret_store
  • epack run stops before collecting when a required variable is not ready, naming each one and the epack secret command to run. Runs and checks never prompt; only the epack secret commands do
  • The summary printed after a fetch counts a variable as set when your keychain holds it for that configuration
  • epack run <name> and epack remote clone <name> from inside the folder a clone created refresh that folder instead of nesting a second copy
  • A failure report from the collect stage names the failed collector and its error, or counts and names several, in place of a bare failure count
  • Every run has an id, carried in its progress events, on the release it pushes, and on the failure it reports, so a remote can join them

Security

  • What the keychain protects is encryption at rest and isolation from other user accounts, not isolation from code running as the same user. Every platform lets a same-user process read what epack stored, as it can read an exported variable
  • What epack records about stored secrets, their names, readers, and times but never values, lives in ~/.epack/secrets.yaml, readable only by you
  • The keychain is consulted only after the publisher trust gate, and the lookup behind a fetch summary never prompts

Upgrade notes

  • The epack secret commands are in the full build only; epack-core says so and exits
  • On Linux the keychain is the Secret Service over D-Bus, so a desktop session with gnome-keyring or kwallet is needed. Without one, the check reports the store as unavailable and the environment still works
v0.4.9 October 2026 Stable

After cloning a configuration that runs in CI, epack says to lock and commit rather than run.

Changes

  • When the configuration epack remote clone fetched carries a CI job file, a .gitlab-ci.yml or a workflow under .github/workflows/, the next step reads epack lock --all-platforms and commit the folder with epack.lock.yaml, since CI runs from a committed lock
  • A configuration that runs where it was cloned keeps the epack run hint
v0.4.8 October 2026 Stable

A fetched configuration can carry the profile and mapping files the validate tool reads, so a pipeline with profile validation runs from a laptop or a GitLab job.

Fixes

  • epack remote clone and epack run <name> write .epack/profiles/<name>.yaml and .epack/mappings/<name>.yaml from a pulled configuration. Earlier releases refused them as hidden paths, so a configuration with the validate tool failed with "is not a path epack writes"
  • Every other hidden path is still refused, including .epack/collectors/, .epack/remotes/, and .git/
v0.4.7 October 2026 Stable

A secrets entry can be optional: a variable the run may hold, passed through when set and never required. Reported collector output no longer carries the values of passed secrets, and a timed-out collector takes its background processes with it.

Configuration

  • A secrets entry is a bare name or {name: AWS_PROFILE, optional: true}. A bare name is required, and epack run --check reports it when unset. An optional entry is passed through when set and is neither counted nor reported
  • The summary printed after a fetch marks optional entries as (optional) or (optional, set), and the check's report lists them under env_optional
  • Earlier releases parse the list strictly and refuse a configuration with an optional entry, so upgrade before fetching one

Security

  • Collector and adapter stderr in error messages and streamed output has every passed secret value replaced with [REDACTED], before truncation and pattern redaction. Values shorter than six characters are not matched
  • On Unix, collectors and remote adapters run in their own process group, and a timeout kills the whole group, so a process a collector started cannot outlive the run with its environment
  • A collector that exits but leaves a process holding its output open no longer hangs the run; after five seconds the run fails with an error naming the cause
v0.4.6 October 2026 Stable

Toolchain and dependency refresh. No behavior changes.

Changes

  • Built with Go 1.26.9, with the golang.org/x modules and gRPC updated to their current releases, so the binaries carry those projects' latest fixes
v0.4.5 October 2026 Stable

Installing from a lock no longer calls the GitHub API, so runs on shared runners without a GitHub token stop failing with a 403.

Fixes

  • When the lock records a component's release asset, epack run, epack run --check, and epack sync download it and its Sigstore bundle from the release's download link instead of looking the release up through the GitHub API. Unauthenticated runners on shared addresses, such as AWS CodeBuild and hosted CI runners, often had no API quota left and failed with "unexpected status 403 fetching release"
  • The download is verified the same way: it must match the lock's digest and its Sigstore signature
  • A lock that doesn't record asset names still looks each release up
v0.4.4 October 2026 Stable

epack run --check now offers to register this machine's signing key for a configuration that does not hold it yet, as a run does.

Runs

  • In a terminal, epack run --check asks to register this machine's key when the remote does not hold it for the configuration, then waits for the approval the remote asks for and reports the key as usable or waiting. Previously the check only reported the key as not registered, and registering it took a run or epack key create
  • Without a terminal, or with --yes, the check still reports the unregistered key, and the finding now also names --browser, which signs in the browser instead
v0.4.3 October 2026 Stable

A run on a laptop now gets its collectors' managed credentials with your epack remote login sign-in, and a failed run prints its output cleanly.

Runs

  • A run or epack run --check with no CI identity, such as one on a laptop, resolves managed collector credentials through the remote's sign-in when the remote's adapter supports it. Previously a collector with managed credentials failed there with "locktivity-managed credentials require a runtime identity"
  • That error now lists a sign-in with epack remote login among the identities a run can use

Remote Protocol

  • Added credentials.resolve and the credentials_resolve capability. An adapter resolves a configuration's managed credentials with the sign-in it holds, so the person's token stays in the adapter and only the resolved credentials reach epack

Fixes

  • After a failed collect, the spinner no longer keeps running into the post-collect hook's output. The failed stage closes with its failure line first
  • A stage's result clears the rest of the line, so a shorter message no longer keeps the end of the spinner text it replaced
  • The line saying a failure was reported to the remote ends with a newline, so the next output starts on its own line
  • Collector errors no longer end with an escaped newline from the collector's stderr
v0.4.2 October 2026 Stable

epack run --check now installs the locked components before it signs in, so it works on a fresh machine or CI runner.

Fixes

  • epack run --check installs the locked collectors, tools, and remote adapter the way a run does before collecting. Previously, on a machine where they were not installed yet, a check with a current lock stopped at "verifying adapter binary: opening binary: no such file or directory"
  • This affected the first check of a configuration fetched from a remote and checks in CI on fresh runners, including GitLab jobs run with EPACK_CHECK=1
v0.4.1 October 2026 Stable

epack run --check now works before the first run of a configuration fetched from a remote.

Fixes

  • In a folder fetched from a remote, epack run --check locks the configuration the way the first run does. Previously it stopped at "no epack.lock.yaml", and without a lock it could not verify the remote's adapter or sign in
  • In your own project, such as a folder committed for CI, a missing or stale lock is still reported with the epack lock command to run and commit
v0.4.0 October 2026 Stable

Run a configuration a remote generated in one command, sign in with your browser, and sign runs with a key registered for the machine.

Runs

  • Added epack run: install the locked components, run the hooks, collect, run tools, sign, and push in one command. Given a configuration name, it fetches the configuration from the remote first. When a stage fails, the failure is reported to the remote with a stable code
  • Added epack run --check (or EPACK_CHECK=1): sign in and verify the lock, secrets, credentials, and publishers, report the result, and collect nothing
  • A configuration fetched from a remote may only run collectors, tools, and remote adapters from trusted publishers. epack asks once in a terminal and records the answer in ~/.epack/config.yaml; a job names publishers with --trust-publisher or EPACK_TRUSTED_PUBLISHERS

Remotes

  • Added epack remote login: sign in with your browser, which returns to epack at 127.0.0.1. --no-browser and --port support sign-in over SSH
  • Added epack remote clone: fetch a named configuration into a folder, and pick up newer revisions without overwriting files you edited
  • Added epack remote update: move the adapter installed for you, pinned in ~/.epack/remotes.lock, to its newest release
  • The remote adapter protocol gains auth.complete, config.pull, and key.register, key.list, key.retire, and key.revoke

Signing keys

  • Added epack key create, epack key list, and epack key rotate: make a key for the machine, register it with the remote, and wait for approval when the remote asks for it. Runs from the machine sign with the key once it is approved
  • A runner without its own identity signs in to the credential broker with its key, using EPACK_SIGNING_KEY and EPACK_PIPELINE_ID. A GitHub Actions OIDC token or a GitLab ID token is used first when present
  • Added epack verify --public-key to verify packs signed with a key, and verify.WithPublicKeys in the SDK

Upgrade notes

  • Sign-in moved from a device code to the browser. epack remote login needs an adapter that supports browser sign-in, such as epack-remote-locktivity v0.2.0
  • Adapters report a browser auth mode where they reported device_code
v0.3.3 September 2026 Stable

Version updates now re-lock every platform in the lockfile, so a lockfile updated on one OS works in CI on another.

Fixes

  • When epack update, epack lock, or epack install moves a component to a new version, every platform already in epack.lock.yaml is downloaded, Sigstore-verified, and re-digested from the new release. Previously only the current platform was re-locked, and other platforms kept the previous release's digests, which failed sync on those platforms
  • A previously locked platform that the new release does not publish is now a lock error instead of a stale entry
v0.3.2 September 2026 Stable

Control mappings seal publisher-authored links from evidence to profile requirements into packs, plus toolchain and dependency security updates.

Control mappings

  • A mappings: section in epack.yaml declares local mapping files (evidencepack/control-mapping@v1) recording which evidence supports which profile requirement
  • Each mapping file is locked by digest in epack.lock.yaml, drift-checked, and verified under --frozen
  • epack collect and epack run seal each mapping into the pack as artifacts/<name>.json, and epack build accepts a repeatable --mapping flag
  • Malformed entries, citations of artifacts the pack does not carry, and profile digests matching no locked profile are build warnings, never failures. Mappings never affect verification or validation results
  • epack inspect shows a Control Mappings section, the collect summary reports sealed entries, and lock provenance summaries gain a mappings section

Security

  • Release binaries are built with Go 1.26.8, picking up the standard library fix for CVE-2026-39821
  • google.golang.org/grpc updated to 1.83.1 for GHSA-vp52-pcj8-j9qc
v0.3.1 August 2026 Stable

Windows support for pack operations, catalog search across all component kinds, and dependency security updates.

Windows

  • New epack-core-windows-amd64.exe and epack-core-windows-arm64.exe release binaries carry the same SLSA Level 3 provenance as every other platform
  • Windows covers pack operations: build, sign, verify, inspect, list, extract, merge, and diff. Collector and tool execution stays on macOS and Linux and fails closed on Windows
  • Merge, filtered listing and extraction, and recursive result globbing handle Windows paths correctly

Catalog and utilities

  • epack catalog search searches collectors, tools, remotes, and utilities with an optional --kind filter, and epack catalog refresh fetches the latest registry catalog with caching
  • The new epack utility command installs, lists, and removes user-scoped utilities with Sigstore verification, tracked in a global utilities lock

Security

  • Dependency updates for published advisories in sigstore-go and grpc-go
  • Path validation rejects rooted paths on every platform
v0.3.0 July 2026 Stable

Lockfile verification metadata: every locked component records whether its signature was checked at lock time.

Lockfile

  • Locked collectors, tools, and remotes gain a verification block recording the outcome of lock-time signature verification
  • Components locked from GitHub releases record status: verified with a verified_at timestamp after their Sigstore bundles are checked against the pinned digests
  • External binaries record status: skipped: they run from a local path and have no bundle to verify
  • Lockfiles written by earlier versions carry no verification block, so consumers can tell verified and skipped entries apart from locks that predate verification recording
v0.2.2 July 2026 Stable

Committed-lockfile CI: strict locked installs, lockfile provenance reporting, and machine-readable errors.

CLI

  • Added epack sync --locked: clean-machine CI install that fetches exactly the locked versions with full signature and digest verification, fails on any drift, and never rewrites the lockfile
  • Added epack remote report-lock: report the current epack.lock.yaml to a remote without pushing a pack, for CI bootstrap and refresh flows
  • Sync and frozen paths now validate range satisfaction: a pinned version outside its configured range fails with lock_config_mismatch instead of silently keeping the old pin
  • Added EPACK_ERROR_FILE: failed commands append stable code=, exit=, and summary= lines for log-free CI error handling
  • Runner context gains head_sha via EPACK_HEAD_SHA, the branch head on pull_request workflows where GITHUB_SHA is the merge commit

Remote Protocol

  • Added the lock.report command and lock_report capability for lockfile provenance reports (conformance rule REM-090)
  • push.prepare and push.finalize carry a structured lock_provenance envelope alongside the existing string build context, so releases record the exact lock that produced the pack

Errors

  • New stable codes for frozen and locked failures: lock_config_mismatch, lock_stale, and lock_missing_pinned_artifact replace generic lockfile errors at the affected call sites
v0.2.1 July 2026 Stable

Richer artifact metadata for generated collector evidence.

Protocol

  • Collector artifacts can carry display_name, description, and controls manifest metadata

Go SDK

  • Added JSONArtifact, FileArtifact, and ArtifactMeta helpers for metadata-bearing collector artifacts
v0.2.0 July 2026 Stable

Collector file artifacts for binary evidence such as PDFs, screenshots, and archives.

Protocol

  • Added EPACK_COLLECTOR_OUTPUT_DIR, a per-collector staging directory for raw file artifacts
  • Collectors can emit file artifact entries whose bytes are packaged at the declared path
  • Staged file paths reject traversal, absolute paths, symlinks, and non-regular files before packaging
  • Staged bytes count toward artifact and pack budgets without counting against stdout limits

Go SDK

  • Added componentsdk.Staging(ctx) for optional file-artifact staging helpers
  • Added WriteStagedFile and StageFile helpers for buffered and streaming collector output
v0.1.34 May 2026 Stable

Security fixes for transitive dependencies.

Dependencies

  • Bumped go-jose to v4.1.4 to fix a JWE decryption panic (GHSA-78h2-9frx-2jm8)
  • Bumped sigstore/timestamp-authority to v2.0.6 for improper certificate validation in the verifier (GHSA-xm5m-wgh2-rrg3)
  • Bumped go.opentelemetry.io/otel to v1.42.0 to fix a baggage-header allocation amplification (GHSA-mh2q-q3fh-2475)
v0.1.32 May 2026 Stable

Collection levels for graduated evidence gathering.

Protocol

  • Reserved a top-level level config key with values trust, audit, internal; defaults to trust when absent
  • Levels are cumulative: audit is a superset of trust; internal is a superset of audit
  • Unknown values downgrade to trust with a stderr warning so collectors never gather more than was asked for
  • Collectors honoring the field stamp collected_at_level on their top-level artifact for downstream interpretation

Go SDK

  • Added componentsdk.Level with LevelTrust / LevelAudit / LevelInternal constants
  • Added ctx.Level() reader and Level.AtLeast(other) comparator for gating field collection
v0.1.31 March 2026 Stable

Locktivity-managed credentials, portable hooks, build-context emission, and smoother GitHub Actions signing.

Managed Workflows

  • Added top-level credential_sets for Locktivity-managed workflow integrations
  • Collectors, tools, and remotes can request managed credentials by logical ref
  • Locktivity remote auth docs now reflect access_token, device_code, and client_credentials

Runner UX

  • Added epack hooks run for portable project hooks under .epack/hooks/
  • Added epack context build to emit build metadata for runners
  • Project scaffolding now keeps .epack/hooks/ tracked while ignoring other runtime state

CI/CD Signing

  • epack sign now uses ambient GitHub Actions OIDC automatically when id-token: write is granted
  • Other CI systems can continue to provide EPACK_OIDC_TOKEN explicitly
v0.1.29 March 2025 Stable

Profile and overlay support, multiple collector artifacts, and new top-level commands.

Profiles & Overlays

  • Added profiles and overlays configuration sections in epack.yaml
  • Support for registry-sourced profiles with version locking
  • Profile/overlay digests tracked in manifest for reproducibility

Collector SDK

  • Breaking: Emit() now accepts []CollectedArtifact for multiple artifacts per collection
  • New CollectedArtifact struct with Schema and Path metadata
  • Collectors can emit multiple artifacts in a single call

New Commands

  • epack catalog search — unified search across collectors, tools, remotes, and utilities
  • epack catalog refresh — update local catalog cache
  • epack utility install/list/remove — manage global utilities

Remote Protocol

  • Added runs.sync and auth.whoami feature capabilities
  • Consistent sync behavior across collector, tool, and remote adapters

Bug Fixes

  • Fixed offline verification mode to properly use embedded timestamps
  • Fixed JSON output returning null instead of [] for empty arrays
v0.1.27 March 2025

Verification improvements and remote protocol enhancements.

Verification

  • Improved error messages for attestation verification failures
  • Added support for sigstore-js provenance bundles

Remote Protocol

  • Added sidecar push support for parallel attestation uploads
  • Improved push workflow reliability
v0.1.24 February 2025

Initial public release of the Evidence Pack specification and epack CLI.

Specification

  • Evidence Pack format specification v1.0
  • Manifest schema with SHA-256 digests for all artifacts
  • Sigstore attestation bundle format
  • Pack digest and manifest digest algorithms

CLI (epack-core)

  • build — create packs from artifacts
  • sign — keyless signing via Sigstore
  • verify — integrity and signature verification
  • inspect — view pack contents and metadata
  • diff — compare two packs
  • merge — combine multiple packs
  • list — list artifacts in a pack
  • extract — extract artifacts from a pack

CLI (Full)

  • new — scaffold a new epack project
  • init — initialize epack in existing directory
  • collect — run collectors and build pack
  • push / pull — remote registry operations
  • lock / sync / install / update — dependency management
  • collector / tool — plugin management

Go SDK

  • pack — core pack types and operations
  • pack/builder — fluent API for building packs
  • pack/verify — verification with policy options
  • sign — Sigstore signing integration

Stay Updated

Watch the repository for new releases and subscribe to release notifications.

View Releases

Versioning Policy

epack follows Semantic Versioning:

  • Major versions (1.0, 2.0) may include breaking changes to the specification or CLI
  • Minor versions (0.2, 0.3) add new features in a backwards-compatible manner
  • Patch versions (0.1.1, 0.1.2) include backwards-compatible bug fixes

Specification vs CLI versions

The Evidence Pack specification version is independent of the CLI version. The specification is versioned in the manifest ("spec_version": "1.0") and changes less frequently than the CLI.

Backwards compatibility

The CLI will always be able to read packs created by older versions. New features that require pack format changes will use new specification versions, and the CLI will indicate when a pack requires a newer version.