DevShield is a local guard for dependency installs.
You wrap the install command; it kills hostile lifecycle scripts, requires a pinned lockfile, flags
exposed secrets, and blocks off-allowlist network connections — all on
your machine, zero external dependencies.
i
DevShield is a checkpoint tool: it only protects installs you route through it. A bare
npm ci run alongside is invisible to it. You harden your CI and your blessed
local path — not "install this and you're safe everywhere".
Install
Build it, put it on PATH.
No external dependencies: a stable Rust toolchain is all you need.
# from the Proxia repo
cd devshield
cargo build --release # binary → target/release/devshield
cp target/release/devshield /usr/local/bin/ # optional: onto PATH
The core command
devshield run — wrap an install.
DevShield runs your command, applies the gates you enabled, and (with
--audit-log) writes a local JSONL trail. Every gate defaults to
warn (non-destructive); you escalate to block
or fail when you want to harden.
Each is independent and non-destructive by default. Stacked, they cover the most common install
vectors.
// 1 · execution
Lifecycle scripts
--scripts-mode warn|block|fail
block disables npm install scripts (injects
--ignore-scripts); fail refuses (exit 21)
before spawning. Also gates npx / npm exec /
pnpm dlx as arbitrary code execution. pip: warn-only.
The layer that stops Shai-Hulud / Axios-style payloads.
// 2 · integrity
Lockfile posture
--preflight-lockfile [--lockfile-mode warn|fail]
Flags (or refuses, exit 22) a missing/unhashed npm lockfile, or a command that mutates
the lockfile (npm install) instead of respecting it
(npm ci). Posture, not tamper detection — npm already verifies hashes.
pip: best-effort, warn-only.
// 3 · secrets
Secret preflight
--preflight-secrets [--preflight-mode warn|fail]
Reports secret-bearing env vars and files (.env,
.npmrc, .pypirc…) before the install runs —
without ever printing the values. fail → exit 20.
// 4 · network
Egress proxy
--egress-proxy [--egress-mode warn|enforce]
A local (127.0.0.1) proxy the install is routed through. enforce
blocks (403) any connection to an off-allowlist host. No MITM: blocks by host, never by content.
warn logs everything; a bind failure in enforce → exit 23 (fail-closed).
Exits 21 before spawning if scripts would run. Unrecognized command → refused (fail-closed).
enforce
!
Coverage caveat:block script-disabling is verified for npm. yarn Berry (v2+) ignores npm_config_* and doesn't honor --ignore-scripts; verify before relying on it for pnpm/yarn.
Exit codes
One code per refusal — scriptable in CI.
Code
Meaning
0
Child ran; no gate refused.
child code
Passed through from the wrapped command.
20
--preflight-mode fail: secret risk detected.
21
--scripts-mode fail: lifecycle scripts would run.
22
--lockfile-mode fail: lockfile posture risk.
23
--egress-mode enforce: proxy could not start (fail-closed).
10
check / observe egress: destination blocked by policy.
Other anchors: a shell alias
(alias npm='devshield run … -- npm') for transparent local use; a shared
Makefile / just target for the team; a dev container's
postCreateCommand.
Audit trail
A local, readable JSONL trail.
devshield audit read --audit-log <file> # summary of every eventdevshield audit trace --audit-log <file> --context-id <id> # one command + its egress
Events: command_run, lifecycle_scripts,
secret_preflight, lockfile_preflight,
egress_observation. All local; nothing is transmitted.
Honesty · what DevShield is not
Containment, not a magic wand.
// scope
Routed installs only
No system-wide interception. A bare npm ci is invisible. The shell alias comes closest, but is opt-in and bypassable.
// nature
Containment, not integrity
--scripts-mode stops execution/exfiltration; it won't tell you a package was swapped. npm already verifies integrity on install.
// network
Host, not content
The proxy blocks by host:port, no MITM. It can't tell a download from a publish on an allowlisted host. github.com stays allowed by default.
// destruction
No filesystem defense
A postinstall that wipes files is stopped only if scripts are disabled (block/fail). No network control helps here.
Use DevShield to harden your CI and your blessed local
path, layered with lockfile pinning and package provenance — not as "install this and you're safe
everywhere".