Aperion Shield · v0.2.0

Adaptive guardrails for AI coding agents

v0.2 turns Shield from a regex filter into a thinking guardrail. 45 rules across 8 destructive surfaces, composite scoring across every matching rule, a workspace context probe, local decision memory, and an in-process burst detector — all running offline on your machine. Drop-in for Cursor and Claude Code. Apache 2.0.

Apache 2.0 45 rules · 8 surfaces macOS · Linux · Windows 87 tests, all green
  Release
github.com/AperionAI/shield · v0.2.0
  Homebrew
brew install AperionAI/tap/aperion-shield
  Docker
ghcr.io/aperionai/shield:shield-v0.2.0
Headline changes
01
45 rules across 8 destructive surfaces (up from 13)
Security
v0.2 quadruples coverage. The bundled ruleset now spans:
  • SQL (9) — DROP DATABASE / TABLE / SCHEMA, TRUNCATE, ALTER DROP COLUMN, unscoped UPDATE/DELETE, GRANT/REVOKE ALL, REVOKE FROM PUBLIC, Postgres COPY FROM PROGRAM (RCE), MySQL LOAD DATA INFILE.
  • Git (5) — force-push to protected branches, filter-branch / filter-repo / reflog expire, push --mirror --force, branch -D, checkout . / git clean -fxd.
  • Filesystem (5) — rm -rf at filesystem root, sensitive paths under /etc / ~/.ssh / ~/.aws, dd to block device, find … -delete sweeps, world-writable chmod, recursive chown root.
  • Secrets exfil (3) — compound predicate catching read-secret + post-to-network in one command, raw SSH/AWS key reads, bulk cloud secrets dumps.
  • Supply chain (2) — curl | sh, bash <(curl …), untrusted npm/pip/yarn/gem/cargo registries.
  • Reverse shells (1) — 10 incantations across bash, nc, python, perl, ruby, openssl, socat, PowerShell.
  • Privilege (2) — sudo-prefixed destructive verbs, setuid grants.
  • Cloud / k8s / Docker (11) — aws s3 rm --recursive, rds delete --skip-final-snapshot, terraform destroy -auto-approve, gcloud sql delete, az group delete --yes, kubectl delete namespace / --all / drain, helm uninstall, docker system prune -a --volumes, docker rm -fv.
  • LLM-response (5) — assistant plan text mentioning DROP DATABASE / force-push / rm -rf / curl|sh / secret-exfil — second pair of eyes before a destructive call is attempted.
  • Anomaly (1) — destructive-burst marker.
Every shipping rule has at least one positive integration test plus a negative test proving it doesn't over-fire on benign inputs. 51 integration tests + 36 unit tests = 87 tests, all green.
02
Composite scoring — stack weak signals into a strong one
Engine
Every rule now contributes a points score (defaulting to severity rank). When multiple rules fire on the same call, Shield sums their points and maps the total to its own severity tier: 2 → Medium, 5 → High, 9 → Critical. The final severity is whichever is higher — top single match or composite total.

Why this matters: an isolated git branch -D feature/legacy is a Medium warning. The same call inside a script that also reads ~/.aws/credentials and runs chmod 777 /var/data stacks four matches at 2 + 4 + 3 + 3 = 12 points and gets promoted to Critical. Composite scoring catches the shape of a destructive session even when no single command crosses the line.
03
Workspace context probe — production-aware
Engine
At startup, Shield checks the working directory for production-management signals — .env.production, kubeconfig, prod/, terraform state, a Procfile. When any of them match, Shield logs a banner and bumps the severity of every subsequent match one tier. The probe takes under 1 ms and never recurses outside cwd. Disable per-run with --no-workspace-probe.
04
Decision memory — learns from your approvals
Adaptive
Approvals and denials are journaled to .aperion-shield/decisions.jsonl in your project root, fingerprinted by sha256(rule_id + canonical-JSON(params)). The log is append-only and never leaves your machine. Two adaptive behaviours derive from it:
  • Demote-after-approvals: three approvals of the same fingerprint with no denial since demotes one tier.
  • Escalate-on-recent-deny: any denial within the last 7 days bumps the next match one tier.
So after the third time you approve the same legitimate UPDATE users SET email_verified=true WHERE id IN (…), Shield stops prompting. But if you ever deny one, the next attempt is treated harder. Disable per-run with --no-memory.
05
Burst detector — escalates during destructive waves
Anomaly
An in-process sliding window. Five or more destructive matches within five minutes bumps every subsequent match one tier until the burst quiets. Useful when an agent has gone off the rails and is running ten rms and a git push --force back-to-back — exactly the moment you want the brakes to tighten, not stay constant. Configurable threshold and window under policy.burst_detector; disable with --no-burst.
06
Six new structured predicates
Engine
Some patterns can't be expressed as a single regex — they require parsing a pipeline or normalising a path. v0.2 ships six new predicates beyond the SQL pair:
  • curl_pipe_sh — sees through sudo -u root bash and env FOO=bar python wrapper prefixes.
  • network_fetch_to_interpreter — process-substitution form (bash <(curl …)).
  • env_to_network — compound: secret source + network sink in the same command line.
  • reverse_shell — 10 classic incantations.
  • world_writable_chmod — numeric AND symbolic forms.
  • untrusted_pkg_registry — allowlist-based detection of non-default npm/pip/yarn registries (since Rust regex has no negative lookahead).
Plus a sensitive_paths matcher with ~ expansion and .. traversal normalisation, closing a class of evasion tricks (cat /etc/../etc/shadow and cat /etc/shadow resolve identically).
07
Teach-as-you-go: every block ships a safer_alternative
UX
Every blocked or approval-required decision now includes a safer_alternative field in the JSON-RPC error payload, surfaced to the user in the IDE's tool-call panel. Examples:
  • fs.recursive_delete_root: “Scope to a specific subdirectory, e.g. rm -rf ./build/.”
  • git.history_rewrite: “If you need to remove a commit, git revert it; rewrites strand collaborators.”
  • supply.curl_pipe_sh: “curl -fSLo install.sh URL && shasum -a 256 install.sh && bash install.sh.”
  • secret.env_to_network: “Never let an agent share a secret with an outside service. Copy manually and rotate afterwards.”
Aperion Shield is also a teaching tool. Every block is a small lesson.
08
Hybrid lib+bin crate — embeddable engine
Engine
The Rust crate is now [lib] + [bin]. The library at aperion_shield::engine exposes Engine, Adjustments, Evaluation, and decide() so embedders can drop the engine into non-MCP contexts: custom proxies, lint tools, pre-commit hooks, CI step that scans pending shell commands. Same YAML format, same predicates, no MCP plumbing required.
09
Still offline by default — no new network surface
Privacy
Every new feature lives entirely on your machine. Decision memory writes to a local JSONL. The workspace probe reads cwd. The burst detector is in-process. The --telemetry flag remains reserved and stubbed — setting it today still prints the privacy-review notice and exits without sending anything. Nothing is phoning home in v0.2.
How to install
Homebrew (macOS / Linux)
$ brew install AperionAI/tap/aperion-shield
Docker
$ docker run --rm -i ghcr.io/aperionai/shield:shield-v0.2.0 --help
Binary download
# Linux / macOS / Windows · x86_64 + aarch64 $ curl -L -o aperion-shield.tar.gz \     https://github.com/AperionAI/shield/releases/download/shield-v0.2.0/aperion-shield-shield-v0.2.0-aarch64-apple-darwin.tar.gz $ tar -xzf aperion-shield.tar.gz $ ./aperion-shield --version
Attach to your IDE
A
Cursor — ~/.cursor/mcp.json
{   "mcpServers": {     "postgres-shielded": {       "command": "aperion-shield",       "args": ["--shadow", "--",            "npx", "-y", "@modelcontextprotocol/server-postgres",            "postgresql://localhost/mydb"]     }   } }
B
Claude Code — ~/.claude/config.json or claude mcp add
$ claude mcp add github-shielded -- \     aperion-shield -- npx -y @modelcontextprotocol/server-github
Upgrading from 0.1.x
U1
No config changes required
The schema is fully backward compatible. Existing v1 shield.yaml documents load unchanged in v0.2. Rules without an explicit points field default to their severity rank (Low = 1 … Critical = 4), so composite scoring “just works” on your existing ruleset without edits.
U2
First-run banner tells you which adaptive layers are active
On startup, Shield logs a line like [shield] composite_scoring=true workspace_probe=true decision_memory=true burst_detector=true. If the workspace probe matches a prod signal, a second line names which signals fired. So you always know what's running.
U3
New CLI flags to opt out of any adaptive layer
Three new flags — --no-workspace-probe, --no-memory, --no-burst — disable the corresponding adaptive layer per-run. The old behaviour (single-rule, regex-only, no memory) is one flag away if you want it.
Roadmap
R1
v0.3 — SSE & HTTP MCP transports
v0.2 still covers only the dominant stdio transport. Adding SSE and streaming HTTP MCP transports lifts coverage to every flavour of MCP server in the wild — including remote ones that aren't subprocesses.
R2
v0.4 — Pluggable predicates (WASM)
Today predicates ship in the binary. WASM-loaded predicates would let teams bake their own structured matchers (custom SQL dialects, internal tooling, in-house policy DSLs) without forking Shield. The engine API surface from v0.2's lib split was designed with this in mind.
R3
v0.5 — Optional public block ticker
Reserved for an anonymised, opt-in, once-per-minute aggregate of (rule_id, severity) tuples that power a community dashboard (think CVE tracker for AI-agent destructive operations). Gated on legal/DPO review; will never enable without explicit opt-in via --telemetry.
At-a-glance summary
#ChangeTagNotes
0145 rules · 8 destructive surfacesSecuritySQL · git · fs · secrets exfil · supply chain · reverse shells · privilege · cloud / k8s / docker
02Composite scoringEngineSum points across matches; 2 / 5 / 9 thresholds
03Workspace context probeAdaptiveBumps one tier in prod-looking repos
04Decision memoryAdaptive.aperion-shield/decisions.jsonl; demote-after-3, deny-resets-streak
05Burst detectorAdaptive5 destructives in 5 min escalates subsequent matches
06Six new structured predicatesEnginecurl_pipe_sh · env_to_network · reverse_shell · world_writable_chmod · sudo_prefix · untrusted_pkg_registry
07safer_alternative on every blockUXTeach as you go — never just “denied.”
08Hybrid lib+bin crateEngineEmbed the engine in non-MCP contexts
0987 tests, all greenQA36 unit + 51 integration; positive + negative per rule
10Still offline by defaultPrivacyNothing phones home. --telemetry remains stubbed.