Releases: AperionAI/shield
shield-v0.8.0
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/shwrappers 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
shelltool-call scope that MCP +--check-stagedalready 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-shimsexits non-zero, file untouched, operator told what was found. - Bypass:
SHIELD_SHIMS_DISABLE=1 <cmd>(env override, parity with--no-verifyfor hooks). - Fail-open posture: if
aperion-shieldisn'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,
--forparsing + dedup + path-reject; full/bin/shintegration tests against a fake real binary covering allowed pass-through, blocked refusal (real binary never runs),SHIELD_SHIMS_DISABLE=1bypass, 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 belowAfter 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/arm64Security
- No new advisories.
cargo auditclean against the v0.8.0Cargo.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
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.
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-patch3. 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-stagedparsesgit diff --cached --unified=0, classifies files by kind (.sql/ shell / Dockerfile / Makefile / source-code), evaluates each line through the engine, and exits0clean /1block /2approval-required /3operational-error.--check-pushed-refsreads 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 (viagit merge-base --is-ancestor). Override protected branches withSHIELD_PROTECTED_BRANCHES=trunk,deploy/*.- Hooks are written with an
APERION-SHIELD-HOOK v1banner so--install-hooksis idempotent and never clobbers a foreign hook silently.--chain-existingrenames the foreign hook to.aperion-backupand chains Shield in front of it. --suggest-rulesaggregates 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/AllowWithWarnafter the adaptive layer demoted),NOISY_WARN(high-frequencyWarnwith 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 DATABASEin a migration blocked,rm -rf /in a shell script blocked, force-push tomainblocked, fast-forward tomainallowed, branch-delete ofmainblocked, 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.0Then enable git hooks in any repo where you want commit-time enforcement:
cd /your/repo
aperion-shield --install-hooksSupported 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
- README: https://github.com/AperionAI/shield#readme
- Full docs: https://docs.aperion.ai/aperion-shield.html
Full changelog
shield-v0.6.0
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 markdownOutputs 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 toallow
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: cleancargo test --release: 148 tests passing (was 133 in v0.5.0 — +15 covering the new diff mode)cargo auditagainst 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-shieldDocker:
docker pull ghcr.io/aperionai/shield:shield-v0.6.0
# or for the latest tag:
docker pull ghcr.io/aperionai/shield:latestDirect 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
Full Changelog: shield-v0.3.0...shield-v0.5.0
shield-v0.3.0
Full Changelog: shield-v0.2.1...shield-v0.3.0
shield-v0.2.1
Full Changelog: shield-v0.2.0...shield-v0.2.1
shield-v0.2.0
Full Changelog: shield-v0.1.0...shield-v0.2.0
