When a compromised dependency tries to phone home, Guard severs the line. Daemon-backed denials stay in a local audit trail.
Protect yourself// outbound denied
Build scripts, test fixtures, deploy helpers, and vendored CLIs can all try to reach the network. Guard wraps the command, denies unreviewed outbound calls, and leaves a local audit trail.
~ $ stt-guard wrap cargo build --release Compiling proc-macro2 v1.0.82 Compiling syn v2.0.66 Compiling fast-helper-sys v0.6.3 Running build script for fast-helper-sysnetwork denied build-script-build → 178.62.45.211:9001 error: failed to run custom build command for `fast-helper-sys v0.6.3`error: build script exited with status 1 ~ $ stt-guard status denials 9f3b... 178.62.45.211 (port 9001) source_kind=confirmed-deny~ $
~ $ stt-guard wrap npm test> my-app@1.0.0 test> jest --runInBand PASS src/util.test.ts (3 tests) RUNS src/integration.test.tsnetwork denied node → c2.tinyurl-shop.xyz:443 FAIL src/integration.test.ts ● dependency network call denied — see stt-guard status denialsTest Suites: 1 failed, 1 passed, 2 total ~ $ stt-guard status denials 17aa... c2.tinyurl-shop.xyz (port 443) source_kind=suspect-deny~ $
~ $ stt-guard wrap python ./scripts/deploy.py --env prodloading config from ./deploy.ymlresolving image digests...network denied python → 91.107.236.18:8443 Traceback (most recent call last): File "deploy.py", line 7, in <module> import requesstsConnectionError: blocked by stt-guard ~ $ stt-guard status denials a81c... 91.107.236.18 (port 8443) source_kind=raw-ip-no-dns~ $
~ $ stt-guard wrap ./vendor/repo-cli sync --allrepo-cli 2.4.0 — syncing 14 repositories ✓ resolved 14 remotes ✓ fetched 12 of 14network denied repo-cli → telemetry.repo-cli.io:443 ✓ fetched 14 of 14✓ sync complete in 6.3s ~ $ stt-guard status denials bd42... telemetry.repo-cli.io (port 443) source_kind=default-deny~ $
Guard allows reviewed destinations, blocks confirmed threats, and treats missing or invalid enforcement state as a reason to deny.
OSV.dev malicious-package advisories are pulled nightly, reviewed, and baked into the Guard binary alongside hand-curated abuse-pattern rules.
Repeated decisions stay in-process with no IPC. Cache hits are held to a 100µs hot-path budget; misses can use the daemon for more context.
// under the hood
Guard stays in user space, but not on one check. The CLI, daemon, signed snapshots, hook, and exec classification share the boundary.
Registers the root before user code starts.
stt-guard wrap <cmd>Owns state, verifies clients, and records daemon-backed decisions.
Freezes policy, threat intel, and fail-closed state.
stt-guard-hook.dylibDNS, connect, exec, and persistence calls pass through here.
Runtime choke point for the wrapped process tree.
Hard rules first; allow and deny tiers after.
Repeated decisions stay in-process with no IPC.
Coverage gaps and bypass patterns fail closed.
Denials, prompts, exec gaps, and persistence events stay local.
// security architecture
Guard assumes wrapped code may try to tamper, spoof, bypass libc, or race the daemon. Enforcement is split across signed snapshots, authenticated IPC, exec-tier checks, and fail-closed paths.
Setup deploys root-owned binaries under /usr/local/libexec/stt-guard/, creates the _stt_guard service user, and starts a root-managed LaunchDaemon.
The daemon owns state, snapshots, and logs as _stt_guard. A reachable socket is not enough; peers are checked with audit tokens, codesign identity, and message policy.
A non-exportable Secure Enclave P-256 key signs trusted policy artifacts. The daemon can verify signatures, but does not hold a private key malware could steal or forge with.
Before exec, Guard classifies the target. Reviewed runtimes and clean scripts continue; hardened runtime, privilege escalation, unsupported formats, and raw-syscall patterns are blocked.
The injected dylib verifies its signed per-run snapshot and enforces locally on cache hits. Invalid snapshots, untrusted signatures, IPC timeouts, and coverage gaps become denies.
The watchdog checks daemon liveness. Denials, prompt outcomes, exec gaps, and persistence events are written to service-owned logs that wrapped user processes cannot casually rewrite.
// what it isn't
Loud about quality means honest about scope. Here's what Guard does not do.
Guard is user-space interposition for wrapped process trees. It fails closed on known coverage gaps, but it is not a VM, kernel sandbox, or hermetic build environment.
Guard enforces inside stt-guard wrap subtrees. Processes launched outside that tree are outside the current enforcement scope.
Guard does not decide whether code is safe. It denies outbound access by policy, threat intel, and default-deny rules.
Keep lockfiles, audit tools, Dependabot/SCA, code review, and EDR. Guard adds a local egress boundary when code runs.
// support the work
If Guard blocks something you did not want, sponsorship helps pay for the release, review, and testing work behind that moment.
A monthly coffee is enough - if Guard blocks one install you would rather not explain later, that is a pretty good return on a coffee.If you'd rather not, starring the repo and spreading the word helps too; sponsorship does not change what the tool does or who it protects.
// before you install
Yes, for the supported install. The installer uses sudo once to deploy root-owned binaries, create the _stt_guard service user, enroll a Secure Enclave rule-signing key, and run the daemon as a LaunchDaemon. wrap and status refuse to run if that hardened install is unhealthy.
Cache-hit network decisions stay under the 100µs hot-path budget, and most calls aren't network calls. Misses can pay IPC, DNS, or prompt latency.
Hardened-runtime binaries reject DYLD_INSERT_LIBRARIES by design. Guard treats that as a coverage gap and fails closed by blocking exec into unsupported hardened children from wrapped subtrees.
Nothing at runtime. Guard ships with reviewed OSV.dev malicious-package advisories and hand-curated abuse-pattern rules baked into the release artifact. Release automation refreshes those sources; the installed daemon does not pull feeds.
No. Guard has no analytics path, no cloud tier, and no runtime telemetry. Status and forensic data stay on the machine.
npm audit?Audit and SCA tools match known vulnerable or malicious packages in dependency metadata. Guard adds a runtime egress boundary: when an install script, dependency, CLI, or wrapped installer tries to connect out, policy decides before the connection leaves the machine. Keep audit and Dependabot; Guard covers a different moment.
macOS is the supported target. Linux exists for development work only; Windows is not planned.
MIT or Apache-2.0, your pick. Standard Rust dual-license.
// install
One command. Wrap your next install — and let the next dependency that tries to dial out hit a wall instead.
curl -fsSL https://stentorian.io/guard/install.sh | sh