Skip to content

Releases: AperionAI/shield

shield-v0.8.0

27 May 20:31

Choose a tag to compare

Aperion Shield v0.8.0 — closes the non-git command bypass

v0.7 closed the agent-reaches-around-MCP-and-commits-something-destructive bypass with git hooks.
v0.8 closes the parallel agent-reaches-around-MCP-and-runs-something-destructive-from-the-shell bypass with shell shims — plus ships first-class decision transparency via --explain.

$ aws s3 rm --recursive s3://prod-bucket
[aperion-shield/check-cmd] APPROVAL-REQUIRED -- `aws s3 rm --recursive s3://prod-bucket`
  rule    : cloud.aws_s3_recursive_delete  (severity=High)
  reason  : Bulk S3 delete -- irreversible if versioning is off.
  suggest : Enable versioning, then use lifecycle rules to expire -- never `--recursive --force`.

What shipped

1. Shell shims (--install-shims)

aperion-shield --install-shims --for aws,kubectl,terraform
  • Writes tiny /bin/sh wrappers to ~/.aperion-shield/bin/ (or --shim-dir PATH) for 10 high-blast-radius CLIs out of the box: aws, gcloud, az, kubectl, helm, terraform, psql, mongosh, redis-cli, rm.
  • User puts that dir first on $PATH; every invocation goes through Shield's engine before reaching the real binary.
  • Same engine, same YAML rules, same audit JSONL stream — the shim path reuses the shell tool-call scope that MCP + --check-staged already use, so a rule you add for one surface automatically covers all three.
  • Foreign-file collision protection: Shield never overwrites a wrapper it didn't write. --install-shims exits non-zero, file untouched, operator told what was found.
  • Bypass: SHIELD_SHIMS_DISABLE=1 <cmd> (env override, parity with --no-verify for hooks).
  • Fail-open posture: if aperion-shield isn't on $PATH, the shim execs the real binary directly (teammates without Shield aren't broken).
  • Companion commands: --uninstall-shims, --list-shims, --check-cmd (runtime entry point each shim calls into; also debug-invokable).

2. --explain (decision transparency)

echo '{"name":"shell","arguments":{"command":"rm -rf /"}}' \
    | aperion-shield --explain --input -
  • Takes any tool-call descriptor (MCP {"name":..., "arguments":...} or legacy {"tool":..., "params":...}) and prints a complete decision walkthrough.
  • Three output formats: text (terminals), markdown (PR review comments), json (stable schema for piping into tooling).
  • Shows every rule that matched (sorted severity desc, points desc), every adjustment signal applied, the full severity ladder (raw → composite + points → final), the decision, the safer alternative.
  • What-if exploration via --explain-force-prod, --explain-force-burst, --explain-force-repeatedly-approved, --explain-force-recently-denied — see how the same call would decide in a different context without rebuilding the environment.
  • Exit codes mirror --check-cmd: 0 allow/warn, 1 block, 2 approval/identity.

Tests: 243 passing (was 192 in v0.7)

  • +22 in-module + +7 e2e for shims — install / uninstall / refresh round-trips, foreign-file refusal, missing-upstream skip, --for parsing + dedup + path-reject; full /bin/sh integration tests against a fake real binary covering allowed pass-through, blocked refusal (real binary never runs), SHIELD_SHIMS_DISABLE=1 bypass, fall-through when Shield isn't on $PATH.
  • +15 in-module + +7 e2e for --explain — descriptor parsing for both MCP and legacy shapes, allow/block/approval emission, format aliases, text/markdown/JSON render contracts, JSON parseable with stable schema, --explain-force-* flags honoured, missing tool-name refused.

Heads up: HTTP/SSE MCP transport is the v0.9 headline

The Streamable HTTP transport (POST + SSE relay with backpressure) is a multi-day implementation that deserves to be the headline of its own release, not a half-shipped breadth bump here. v0.8 is the bypass-closing release; v0.9 will be the any-transport release.

Install

brew install AperionAI/tap/aperion-shield
# OR
docker pull ghcr.io/aperionai/shield:shield-v0.8.0
# OR grab a platform tarball from the Assets list below

After install:

# v0.7 (still recommended): git-hook coverage for code landing in commits
cd your-repo
aperion-shield --install-hooks

# v0.8 (NEW): shell-shim coverage for commands run directly
aperion-shield --install-shims --for aws,kubectl,terraform,rm

# v0.8 (NEW): explain a gating decision
echo '{"name":"shell","arguments":{"command":"rm -rf /"}}' \
    | aperion-shield --explain --input -

Platforms

Platform Tarball
Linux x86_64 (glibc) shield-v0.8.0-x86_64-unknown-linux-gnu.tar.gz
Linux aarch64 (glibc) shield-v0.8.0-aarch64-unknown-linux-gnu.tar.gz
macOS x86_64 shield-v0.8.0-x86_64-apple-darwin.tar.gz
macOS aarch64 (Apple Silicon) shield-v0.8.0-aarch64-apple-darwin.tar.gz
Windows x86_64 shield-v0.8.0-x86_64-pc-windows-msvc.zip

Each tarball is paired with a .sha256 sidecar; verify before installing in CI.

Docker:

docker pull ghcr.io/aperionai/shield:shield-v0.8.0
docker pull ghcr.io/aperionai/shield:latest
# multi-arch: linux/amd64 + linux/arm64

Security

  • No new advisories. cargo audit clean against the v0.8.0 Cargo.lock.
  • No new network endpoints or on-disk persistence outside ~/.aperion-shield/bin/ (shims, 0755 inside 0700 dir).
  • v0.7.x dropped to security-only support; see SECURITY.md.

Full changelog

b65c33a chore(v0.8): release prep -- version 0.8.0, README, SECURITY, env-race fix
237f5f3 feat(v0.8): aperion-shield --explain renders decision walkthroughs
fcf51c9 feat(v0.8): shell shims close the non-git command-bypass surface

Compare to v0.7.0: shield-v0.7.0...shield-v0.8.0

shield-v0.7.0

20 May 20:36

Choose a tag to compare

aperion-shield v0.7.0 — git hooks close the MCP-bypass gap

The release that closes the most-cited objection to MCP-only enforcement: "the agent just opens a shell and reaches around your guardrail." v0.7 runs the same engine on the way to git, regardless of how the destructive change got there.

v0.7 git hooks demo — real repo, real GitHub remote, 8 scenarios in 28 seconds

Headline features

1. aperion-shield --install-hooks (git pre-commit + pre-push)

Writes a managed pre-commit and pre-push hook into .git/hooks/. Same engine, same shieldset.yaml, same severity tiers — now enforced on every git commit and git push. Idempotent (re-runnable). Coexists with husky / pre-commit / lefthook via --chain-existing. Honours git --no-verify and SHIELD_HOOKS_DISABLE=1 for the rare legitimate bypass.

$ aperion-shield --install-hooks
[aperion-shield] writing pre-commit  -> .git/hooks/pre-commit
[aperion-shield] writing pre-push    -> .git/hooks/pre-push
[aperion-shield] both hooks installed (managed by APERION-SHIELD-HOOK v1)

2. aperion-shield --suggest-rules (audit-log → rule tuning)

Reads your local shield_eval JSON-Lines audit log and emits text / markdown / yaml-patch suggestions across three classes — rules that never fire, rules that get consistently demoted by decision memory, and noisy Warn rules that should probably be Info. --suggest-format yaml-patch produces splice-ready snippets for shieldset.yaml with # rationale: comments. Stays local — never reads from a network source, never writes anywhere except the file you ask it to.

$ aperion-shield --suggest-rules \
    --audit-log ~/.aperion-shield/audit.jsonl \
    --suggest-window-days 14 \
    --suggest-format yaml-patch

3. Four new IDE quickstarts: Cline, Continue, Windsurf, Zed

Joining Cursor + Claude Code. Per-IDE schema notes in the README (notably Zed uses context_servers, not mcpServers).

What's under the hood

  • New CLI surface: --install-hooks, --uninstall-hooks, --repo <PATH>, --chain-existing, --check-staged, --check-pushed-refs, --suggest-rules, --audit-log <PATH>, --suggest-window-days <N>, --suggest-min-occurrences <N>, --suggest-format <FMT>.
  • --check-staged parses git diff --cached --unified=0, classifies files by kind (.sql / shell / Dockerfile / Makefile / source-code), evaluates each line through the engine, and exits 0 clean / 1 block / 2 approval-required / 3 operational-error.
  • --check-pushed-refs reads git's pre-push stdin protocol (<local-ref> <local-sha> <remote-ref> <remote-sha> per line), recognises protected-branch deletions (remote-sha is zero) and force-pushes (via git merge-base --is-ancestor). Override protected branches with SHIELD_PROTECTED_BRANCHES=trunk,deploy/*.
  • Hooks are written with an APERION-SHIELD-HOOK v1 banner so --install-hooks is idempotent and never clobbers a foreign hook silently. --chain-existing renames the foreign hook to .aperion-backup and chains Shield in front of it.
  • --suggest-rules aggregates per-rule statistics across the analysis window, then evaluates three emit conditions: RULE_NEVER_FIRES (zero matches with rule present in shieldset), CONSISTENTLY_DEMOTED (≥ N matches with > 70% Allow/AllowWithWarn after the adaptive layer demoted), NOISY_WARN (high-frequency Warn with no human intervention recorded).

Tests

192 total tests, all green (was 148 in v0.6.0):

  • 26 new unit tests covering hooks install round-trips, diff parser fixtures, protected-branch glob matching, env-var override, audit JSONL parsing, RuleStats aggregator, and YAML-patch shape.
  • 18 new end-to-end integration tests against real tempdir git repos: install/uninstall idempotency, DROP DATABASE in a migration blocked, rm -rf / in a shell script blocked, force-push to main blocked, fast-forward to main allowed, branch-delete of main blocked, audit-derived suggestion correctness, and YAML splice shape.

Install

# macOS / Linux (Homebrew)
brew install AperionAI/tap/aperion-shield

# Docker (multi-arch distroless ~12 MB)
docker pull ghcr.io/aperionai/shield:shield-v0.7.0

# Direct download
# https://github.com/AperionAI/shield/releases/tag/shield-v0.7.0

Then enable git hooks in any repo where you want commit-time enforcement:

cd /your/repo
aperion-shield --install-hooks

Supported platforms

  • macOS: aarch64-apple-darwin · x86_64-apple-darwin
  • Linux: aarch64-unknown-linux-gnu · x86_64-unknown-linux-gnu
  • Windows: x86_64-pc-windows-msvc

Security

No new advisories. Feature-only release. cargo audit clean against Cargo.lock at this commit. New surfaces (--install-hooks, --check-staged, --check-pushed-refs, --suggest-rules) all stay within the standalone process model — no new network endpoints, no new on-disk persistence beyond .git/hooks/ (Shield itself) and the operator-redirected audit log. See SECURITY.md.

Docs

Full changelog

shield-v0.6.0...shield-v0.7.0

shield-v0.6.0

18 May 16:17

Choose a tag to compare

What's in v0.6.0

The security-hygiene + behavior-diff release. Two themes:

1. Closes the three open Dependabot advisories from v0.5.x

rustls-webpki 0.101.7 (vulnerable transitive) → rustls-webpki 0.103.13, achieved by upgrading the connected dep cluster:

Dependency v0.5.x v0.6.0
reqwest 0.11.27 0.12.28
rustls 0.21.12 0.23.40
rustls-webpki 0.101.7 0.103.13 (closes RUSTSEC-2026-0098, -0099, -0104)
hyper-rustls 0.24.2 0.27.9
hyper 0.14.32 1.9.0
tokio-rustls 0.24.1 0.26.4
webpki-roots 0.25.4 1.0.7

None of the three advisories was practically exploitable in Shield's actual usage (see SECURITY.md §4 for the analysis), but cargo audit now passes cleanly against an empty ignore list. GitHub Dependabot auto-closed all three open alerts on push.

The hyper 0.14 → 1.x bump required a refactor of the OIDC callback server in src/identity/server.rs to the new http1::Builder + per-connection serve_connection model and the http_body_util::Full<Bytes> body type. The refactor is contained to that one file; the rest of the binary saw no API surface change. 7 end-to-end identity tests against a mock OIDC provider still pass post-refactor.

2. Native aperion-shield --diff mode

Native Rust port of scripts/shield-diff.py, the pre-merge behavior-diff explainer for shieldset changes. Run the engine over the same corpus under two different shieldsets and get a per-rule attribution of which lines flipped:

aperion-shield --diff \
    --rules-before main-shieldset.yaml \
    --rules-after  pr-shieldset.yaml \
    --corpus       tests/corpus/team-cursor-history.jsonl \
    --format       markdown

Outputs text / markdown (PR-comment friendly) / json (machine-readable, schema-stable with the Python prototype). CI gates:

  • --fail-if-flipped — exit 1 if any line's decision changed
  • --fail-if-loosened — exit 1 if any line moved toward a more permissive decision (the gate most teams want)
  • --fail-if-allows-loosened N — exit 1 if more than N lines flipped to allow

Runs in-process (no subprocess, no PATH dependency), reusing the same engine the proxy uses, so the decisions in the diff are exactly what a live wrapped agent would see. Existing CI workflows wired against scripts/shield-diff.py continue to work — the script is now a thin compatibility wrapper that delegates to aperion-shield --diff.

Full PR-review pattern: docs/shieldset-as-code.md Layer 4.

Verification

  • cargo build --release --locked: clean
  • cargo test --release: 148 tests passing (was 133 in v0.5.0 — +15 covering the new diff mode)
  • cargo audit against an empty ignore list: 0 advisories on 249 deps
  • Identity callback server end-to-end against the mock OIDC provider: 7/7 still pass

Install

Homebrew (macOS + Linux):

brew install AperionAI/tap/aperion-shield

Docker:

docker pull ghcr.io/aperionai/shield:shield-v0.6.0
# or for the latest tag:
docker pull ghcr.io/aperionai/shield:latest

Direct download: see the assets attached to this release for each platform (Linux x86/arm64, macOS x86/arm64, Windows x86). Each binary archive ships with a .sha256 sidecar.

Public-trust commitment

This release satisfies the hard public commitment in SECURITY.md §4.5 (pushed 2026-05-15): three open Dependabot advisories would close when v0.6.0 lands on Monday 2026-05-18. They closed.

Full Changelog: shield-v0.5.0...shield-v0.6.0

shield-v0.5.0

15 May 18:01

Choose a tag to compare

shield-v0.3.0

13 May 15:14

Choose a tag to compare

shield-v0.2.1

13 May 14:26

Choose a tag to compare

shield-v0.2.0

12 May 18:46

Choose a tag to compare

shield-v0.1.0

12 May 17:37

Choose a tag to compare