v0.3.0 - Secret egress guard and stroq attack
Stroq 0.3.0 ships the two remaining parts of the killer-feature research: the secret egress guard and stroq attack.
Secret egress guard (#9)
- Values of known secrets — the project's
.env*files,~/.aws/credentials,~/.npmrc,~/.netrc,~/.docker/config.json, and credential-shaped environment variables (hashed live, never stored) — are indexed as salted hashes in~/.stroq/secrets.json. - An outbound action (network command, web fetch, MCP call, external push, encoded exec) whose arguments contain one of those values is denied by the new first default rule
deny-secret-egress(action classsecret.egress). The reason names the secret and its file, never the value; the value is redacted from the audit summary in raw, decoded and URL-encoded forms. stroq canary [--name <NAME>]prints a decoy secret to plant; any outbound use of it is a certain positive that also marks the session suspect.stroq doctorreports the index and fails when a source could not be read,.env*files were dropped, or the index was corrupt;stroq whyexplains secret-egress denials; WebFetch now fails closed on engine errors.- Hardened after review: candidate extraction is bounded by input bytes (not by a candidate count an attacker could pad past), URL/hostname/
_URL-style values are not indexed, at most 32 project.env*files are read. Limits and the false-positive recovery path are documented in the README. - Upgrade note: a custom
~/.stroq/policy.yamlreplaces the default policy, so adddeny-secret-egress(first) to be protected.
stroq attack (#10)
- Replays twelve recorded, incident-backed attack scenarios — a protestware README, Sentry agentjacking, Comment-and-Control, s1ngularity, RoguePilot's
$schematoken fetch, anenv | curlexfiltration, a hooks-removal write, therm -rf ~anddrizzle-kit push --forceincidents, a ToxicSkills base64 installer, a fetched page asking for~/.ssh/id_rsa, and a parent-directory wipe — through the engine with your policy, in throwaway directories, and printsblocked/asked/passedper scenario with totals. Exit code 1 when any scenario misbehaves, so a weakened policy fails CI;--jsonfor badges;--only <id>for one scenario. Each scenario cites the public incident it models. - Classifier coverage the suite exposed:
rm -rof any~…target,terraform/tofu destroy,terraform apply -destroy,pulumi destroy,drizzle-kit push --force,prisma migrate reset,prisma db push --force-reset/--accept-data-loss,supabase db reset --linked,gh repo deleteareshell.destructive;gh repo create … --pushisgit.push_external.
Verification
- 660+ tests, coverage ≈ 96 / 87 / 99 / 97 (statements / branches / functions / lines), CI on Node 22 and 24 including the demo and the attack suite.
stroq attackwith the default policy:12 scenarios: 8 blocked, 4 asked, 0 passed through — every attack was stopped.
Install: npm install -g @stroq/cli then stroq init, or npx @stroq/cli init.