{"_id":"@arvoretech/pi-secret-firewall","_rev":"5-c6186749c755182f662bdb8c77cfc59c","name":"@arvoretech/pi-secret-firewall","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@arvoretech/pi-secret-firewall","version":"0.1.0","keywords":["pi-package"],"author":{"name":"Arvore"},"license":"MIT","_id":"@arvoretech/pi-secret-firewall@0.1.0","maintainers":[{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},{"name":"rafsouza","email":"rafasouza@protonmail.com"},{"name":"pedro.adas","email":"pedro.adas@gmail.com"},{"name":"guilhermebs","email":"guilhermebscontact@gmail.com"},{"name":"ricardoraposorfox","email":"ricardorbxx1@gmail.com"},{"name":"jott4","email":"jvgcunha2002@gmail.com"},{"name":"vitor.piovezan","email":"vitor.piovezan@arvore.com.br"}],"homepage":"https://github.com/arvoreeducacao/arvore-pi-extensions#readme","bugs":{"url":"https://github.com/arvoreeducacao/arvore-pi-extensions/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"87d3f8a8346af5a32c7dfefac1f6b93e20d04364","tarball":"https://registry.npmjs.org/@arvoretech/pi-secret-firewall/-/pi-secret-firewall-0.1.0.tgz","fileCount":14,"integrity":"sha512-wsulrOAQJMfYoMTf8asSk3/cRa+Q89OunY4Ur73sbS+vpKm3NXEG5ItUSBGGyz+/Ylb3NOifjTafNyRGRH/CZQ==","signatures":[{"sig":"MEQCICFsJEMncZcPMtOIXi/knloETMwwc+gHjyHpWvidPVX3AiBs1pPKSYqxqfT70ttNzjH5FKzv80TrDSE0Ud7B3gsnig==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27427},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","gitHead":"f0cc81a165c40ab6cc7d2d00a4030a473779a4ed","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"tsc && node --test --experimental-strip-types --disable-warning=ExperimentalWarning test/*.test.ts","build":"tsc"},"_npmUser":{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},"repository":{"url":"git+https://github.com/arvoreeducacao/arvore-pi-extensions.git","type":"git","directory":"packages/secret-firewall"},"_npmVersion":"10.9.4","description":"Redacts secrets (env vars, .env files, token patterns) from the model context and tool outputs, exposing them only as $SECRET_* shell env vars the model can reference but never read","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"typebox":"1.1.38","typescript":"^5.3.0","@types/node":"^20.10.0","@earendil-works/pi-ai":"^0.79.4","@earendil-works/pi-tui":"^0.79.4","@earendil-works/pi-coding-agent":"^0.79.4"},"peerDependencies":{"@earendil-works/pi-coding-agent":">=0.74.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-secret-firewall_0.1.0_1782406204449_0.04938498602767516","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@arvoretech/pi-secret-firewall","version":"0.2.0","keywords":["pi-package"],"author":{"name":"Arvore"},"license":"MIT","_id":"@arvoretech/pi-secret-firewall@0.2.0","maintainers":[{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},{"name":"rafsouza","email":"rafasouza@protonmail.com"},{"name":"pedro.adas","email":"pedro.adas@gmail.com"},{"name":"guilhermebs","email":"guilhermebscontact@gmail.com"},{"name":"ricardoraposorfox","email":"ricardorbxx1@gmail.com"},{"name":"jott4","email":"jvgcunha2002@gmail.com"},{"name":"vitor.piovezan","email":"vitor.piovezan@arvore.com.br"}],"homepage":"https://github.com/arvoreeducacao/arvore-pi-extensions#readme","bugs":{"url":"https://github.com/arvoreeducacao/arvore-pi-extensions/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"a2926c6e8144263e4eaae17cc0e2f3043a61edf8","tarball":"https://registry.npmjs.org/@arvoretech/pi-secret-firewall/-/pi-secret-firewall-0.2.0.tgz","fileCount":14,"integrity":"sha512-4SRHMjekWOb+ctfET6zbjxq/6z+eh2ykCgH6J2bTQL4hcE4ddHW1mixovSR49VOsYMcE+Gqd0iEouoENN4s2DQ==","signatures":[{"sig":"MEUCIQC/0Jh2f/Pv6FKdG8NAFi5vdg92bhPZcu/2ADEnrIVe6AIgIGdzzRorB8MRYuFRW1wzwklvZsqbLgLHOVL47KAKNOI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arvoretech%2fpi-secret-firewall@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":32351},"main":"dist/index.js","type":"module","_from":"file:/tmp/arvoretech-pi-secret-firewall-0.2.0.tgz","types":"dist/index.d.ts","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"tsc && node --test --experimental-strip-types --disable-warning=ExperimentalWarning test/*.test.ts","build":"tsc"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f7c18b14-0555-461a-bb32-1704988d1a1c"}},"_resolved":"/tmp/arvoretech-pi-secret-firewall-0.2.0.tgz","_integrity":"sha512-4SRHMjekWOb+ctfET6zbjxq/6z+eh2ykCgH6J2bTQL4hcE4ddHW1mixovSR49VOsYMcE+Gqd0iEouoENN4s2DQ==","repository":{"url":"git+https://github.com/arvoreeducacao/arvore-pi-extensions.git","type":"git","directory":"packages/secret-firewall"},"_npmVersion":"11.17.0","description":"Redacts secrets (env vars, .env files, token patterns) from the model context and tool outputs, exposing them only as $SECRET_* shell env vars the model can reference but never read","directories":{},"_nodeVersion":"22.23.0","_hasShrinkwrap":false,"devDependencies":{"typebox":"1.1.38","typescript":"^5.3.0","@types/node":"^20.10.0","@earendil-works/pi-ai":"^0.79.4","@earendil-works/pi-tui":"^0.79.4","@earendil-works/pi-coding-agent":"^0.79.4"},"peerDependencies":{"@earendil-works/pi-coding-agent":">=0.74.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-secret-firewall_0.2.0_1782487848626_0.7865236770189377","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@arvoretech/pi-secret-firewall","version":"0.2.1","keywords":["pi-package"],"author":{"name":"Arvore"},"license":"MIT","_id":"@arvoretech/pi-secret-firewall@0.2.1","maintainers":[{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},{"name":"rafsouza","email":"rafasouza@protonmail.com"},{"name":"pedro.adas","email":"pedro.adas@gmail.com"},{"name":"guilhermebs","email":"guilhermebscontact@gmail.com"},{"name":"ricardoraposorfox","email":"ricardorbxx1@gmail.com"},{"name":"jott4","email":"jvgcunha2002@gmail.com"},{"name":"vitor.piovezan","email":"vitor.piovezan@arvore.com.br"}],"homepage":"https://github.com/arvoreeducacao/arvore-pi-extensions#readme","bugs":{"url":"https://github.com/arvoreeducacao/arvore-pi-extensions/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"809fff1266d9a7eedacf622b5b9bbcfc98c2a9cd","tarball":"https://registry.npmjs.org/@arvoretech/pi-secret-firewall/-/pi-secret-firewall-0.2.1.tgz","fileCount":14,"integrity":"sha512-t4MELQOdyZM8kPZST9z/ZoFc6OJUoTI/Xgxgr5b/5oefHR13malhaeWAhbzRSpJlDqYZTNSQksUX8Yecj6m+6A==","signatures":[{"sig":"MEQCIDUpqrxaQvyd/ECxhDH45Eh1w8TxI7qmGRl+yZLP1Jz0AiAcVhHgkZHx+k2HtQ5sVii0tC9wiNiOWJwM676bvJy2EA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arvoretech%2fpi-secret-firewall@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36064},"main":"dist/index.js","type":"module","_from":"file:/tmp/arvoretech-pi-secret-firewall-0.2.1.tgz","types":"dist/index.d.ts","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"tsc && node --test --experimental-strip-types --disable-warning=ExperimentalWarning test/*.test.ts","build":"tsc"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:67568bb9-014d-4a78-9278-da39ef30955f"}},"_resolved":"/tmp/arvoretech-pi-secret-firewall-0.2.1.tgz","_integrity":"sha512-t4MELQOdyZM8kPZST9z/ZoFc6OJUoTI/Xgxgr5b/5oefHR13malhaeWAhbzRSpJlDqYZTNSQksUX8Yecj6m+6A==","repository":{"url":"git+https://github.com/arvoreeducacao/arvore-pi-extensions.git","type":"git","directory":"packages/secret-firewall"},"_npmVersion":"11.18.0","description":"Redacts secrets (env vars, .env files, token patterns) from the model context and tool outputs, exposing them only as $SECRET_* shell env vars the model can reference but never read","directories":{},"_nodeVersion":"22.23.1","_hasShrinkwrap":false,"devDependencies":{"typebox":"1.1.38","typescript":"^5.3.0","@types/node":"^20.10.0","@earendil-works/pi-ai":"^0.79.4","@earendil-works/pi-tui":"^0.79.4","@earendil-works/pi-coding-agent":"^0.79.4"},"peerDependencies":{"@earendil-works/pi-coding-agent":">=0.74.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-secret-firewall_0.2.1_1782840026647_0.3364616863770198","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@arvoretech/pi-secret-firewall","version":"0.3.0","keywords":["pi-package"],"author":{"name":"Arvore"},"license":"MIT","_id":"@arvoretech/pi-secret-firewall@0.3.0","maintainers":[{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},{"name":"rafsouza","email":"rafasouza@protonmail.com"},{"name":"pedro.adas","email":"pedro.adas@gmail.com"},{"name":"guilhermebs","email":"guilhermebscontact@gmail.com"},{"name":"ricardoraposorfox","email":"ricardorbxx1@gmail.com"},{"name":"jott4","email":"jvgcunha2002@gmail.com"},{"name":"vitor.piovezan","email":"vitor.piovezan@arvore.com.br"}],"homepage":"https://github.com/arvoreeducacao/arvore-pi-extensions#readme","bugs":{"url":"https://github.com/arvoreeducacao/arvore-pi-extensions/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"2a489e6b4b1d8bc3897b532859e70ac744e05ac6","tarball":"https://registry.npmjs.org/@arvoretech/pi-secret-firewall/-/pi-secret-firewall-0.3.0.tgz","fileCount":14,"integrity":"sha512-uQZORWW6GFXcvs0jIjLYGKft+RNSJGCKvEk5jXgRLgyh3EdigEMLTA713MXAJjKYxSUYUOmEXF3epNJ5nI0ZFA==","signatures":[{"sig":"MEUCIQCF2zhSr1wN8vRsSfDszHRA9UK7WN7NEkQ5OmenNV4GiwIgS+fvVT1srU927qPlKmIRWmFxAuUlEpgSE1RACjrVVpE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arvoretech%2fpi-secret-firewall@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":37093},"main":"dist/index.js","type":"module","_from":"file:/tmp/arvoretech-pi-secret-firewall-0.3.0.tgz","types":"dist/index.d.ts","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"tsc && node --test --experimental-strip-types --disable-warning=ExperimentalWarning test/*.test.ts","build":"tsc"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:67568bb9-014d-4a78-9278-da39ef30955f"}},"_resolved":"/tmp/arvoretech-pi-secret-firewall-0.3.0.tgz","_integrity":"sha512-uQZORWW6GFXcvs0jIjLYGKft+RNSJGCKvEk5jXgRLgyh3EdigEMLTA713MXAJjKYxSUYUOmEXF3epNJ5nI0ZFA==","repository":{"url":"git+https://github.com/arvoreeducacao/arvore-pi-extensions.git","type":"git","directory":"packages/secret-firewall"},"_npmVersion":"11.18.0","description":"Redacts secrets (env vars, .env files, token patterns) from the model context and tool outputs, exposing them only as $SECRET_* shell env vars the model can reference but never read","directories":{},"_nodeVersion":"22.23.0","_hasShrinkwrap":false,"devDependencies":{"typebox":"1.1.38","typescript":"^5.3.0","@types/node":"^20.10.0","@earendil-works/pi-ai":"^0.79.4","@earendil-works/pi-tui":"^0.79.4","@earendil-works/pi-coding-agent":"^0.79.4"},"peerDependencies":{"@earendil-works/pi-coding-agent":">=0.74.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-secret-firewall_0.3.0_1782847380430_0.16159514347691228","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@arvoretech/pi-secret-firewall","version":"0.4.0","description":"Redacts secrets (env vars, .env files, token patterns) from the model context and tool outputs, exposing them only as $SECRET_* shell env vars the model can reference but never read","main":"dist/index.js","types":"dist/index.d.ts","type":"module","peerDependencies":{"@earendil-works/pi-coding-agent":">=0.74.0"},"devDependencies":{"@earendil-works/pi-coding-agent":"^0.79.4","@earendil-works/pi-ai":"^0.79.4","@earendil-works/pi-tui":"^0.79.4","@types/node":"^20.10.0","typebox":"1.1.38","typescript":"^5.3.0"},"pi":{"extensions":["./dist/index.js"]},"repository":{"type":"git","url":"git+https://github.com/arvoreeducacao/arvore-pi-extensions.git","directory":"packages/secret-firewall"},"author":{"name":"Arvore"},"license":"MIT","keywords":["pi-package"],"scripts":{"build":"tsc","dev":"tsc --watch","lint":"tsc --noEmit","test":"tsc && node --test --experimental-strip-types --disable-warning=ExperimentalWarning test/*.test.ts"},"_id":"@arvoretech/pi-secret-firewall@0.4.0","bugs":{"url":"https://github.com/arvoreeducacao/arvore-pi-extensions/issues"},"homepage":"https://github.com/arvoreeducacao/arvore-pi-extensions#readme","_integrity":"sha512-r1ERY2Kr3B++PBEE9754PYurqy5LnLBgCqrUb6pdoPSqwPejcjH9RdxJzQveMNXXyCe3xg5mEb68Y+HtR5dL2w==","_resolved":"/tmp/arvoretech-pi-secret-firewall-0.4.0.tgz","_from":"file:/tmp/arvoretech-pi-secret-firewall-0.4.0.tgz","_nodeVersion":"22.23.1","_npmVersion":"11.18.0","dist":{"integrity":"sha512-r1ERY2Kr3B++PBEE9754PYurqy5LnLBgCqrUb6pdoPSqwPejcjH9RdxJzQveMNXXyCe3xg5mEb68Y+HtR5dL2w==","shasum":"046f0b383105e7e0b1edd7846ebd8c1ba0f90871","tarball":"https://registry.npmjs.org/@arvoretech/pi-secret-firewall/-/pi-secret-firewall-0.4.0.tgz","fileCount":14,"unpackedSize":43961,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arvoretech%2fpi-secret-firewall@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDaIwzsVRgKnYAmFLs6CPgXK7uXHO7XULOyIZS0/5YKmgIgOJPt4urH5STVzaIC6/qxeORdxf8qxsRt6eOtuPmPz7E="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:67568bb9-014d-4a78-9278-da39ef30955f"}},"directories":{},"maintainers":[{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},{"name":"rafsouza","email":"rafasouza@protonmail.com"},{"name":"pedro.adas","email":"pedro.adas@gmail.com"},{"name":"guilhermebs","email":"guilhermebscontact@gmail.com"},{"name":"ricardoraposorfox","email":"ricardorbxx1@gmail.com"},{"name":"jott4","email":"jvgcunha2002@gmail.com"},{"name":"vitor.piovezan","email":"vitor.piovezan@arvore.com.br"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-secret-firewall_0.4.0_1784731528180_0.5361874851204336"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-25T16:50:04.289Z","modified":"2026-07-22T14:45:28.799Z","0.1.0":"2026-06-25T16:50:04.622Z","0.2.0":"2026-06-26T15:30:48.760Z","0.2.1":"2026-06-30T17:20:26.792Z","0.3.0":"2026-06-30T19:23:00.585Z","0.4.0":"2026-07-22T14:45:28.317Z"},"bugs":{"url":"https://github.com/arvoreeducacao/arvore-pi-extensions/issues"},"author":{"name":"Arvore"},"license":"MIT","homepage":"https://github.com/arvoreeducacao/arvore-pi-extensions#readme","keywords":["pi-package"],"repository":{"type":"git","url":"git+https://github.com/arvoreeducacao/arvore-pi-extensions.git","directory":"packages/secret-firewall"},"description":"Redacts secrets (env vars, .env files, token patterns) from the model context and tool outputs, exposing them only as $SECRET_* shell env vars the model can reference but never read","maintainers":[{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},{"name":"rafsouza","email":"rafasouza@protonmail.com"},{"name":"pedro.adas","email":"pedro.adas@gmail.com"},{"name":"guilhermebs","email":"guilhermebscontact@gmail.com"},{"name":"ricardoraposorfox","email":"ricardorbxx1@gmail.com"},{"name":"jott4","email":"jvgcunha2002@gmail.com"},{"name":"vitor.piovezan","email":"vitor.piovezan@arvore.com.br"}],"readme":"# @arvoretech/pi-secret-firewall\n\nA secret firewall for the Pi/Kiro agent. It keeps secret **values** out of the\nmodel context entirely, exposing them only as shell environment variables that\nthe model can *reference by name* but never *read*. Where a secret value would\nappear, the model instead sees a self-describing placeholder that names the\nexact shell variable to use, e.g.\n`«SECRET DATABASE_URL redacted — ... read it in bash as \"$DATABASE_URL\"»`.\n\n## How it works\n\nOn session start (and on demand) it discovers secrets from two sources:\n\n1. **Real environment variables** whose name looks sensitive\n   (`*_TOKEN`, `*_SECRET`, `*_API_KEY`, `*_PASSWORD`, `DATABASE_URL`, ...) — exact\n   value match, zero false positives.\n2. **`.env` / `.env.local` / `.env.development*`** files in the cwd.\n\nEach secret value gets a stable, self-describing placeholder that tells the\nmodel exactly how to use it. For env/dotenv secrets the shell variable is the\nsecret's **original name**: `MY_API_KEY=xptolksjf` →\n`«SECRET MY_API_KEY redacted — the real value is live in your shell env; read it in bash as \"$MY_API_KEY\"»`.\n\nRedaction happens on three channels:\n\n- **`input` hook** — the user's own message is redacted at the moment it is\n  submitted, before it is stored in the session or shown in the transcript. So a\n  pasted secret never persists in the user's session and the user sees the\n  placeholder too, making it clear the value was redacted.\n- **`context` hook** — every message sent to the model (user text, assistant\n  text, thinking, and tool-call arguments) has secret values swapped for their\n  placeholder.\n- **`tool_result` hook** — output from `bash`, `read`, `grep`, etc. is redacted,\n  so `cat .env` returns placeholders, not values.\n\nA pattern fallback also catches well-known token shapes (AWS keys, JWTs,\n`sk-...`, GitHub/Slack tokens, PEM private keys) that leak into output even when\nthey were never in an env var. When such a token is caught, it is **captured and\nauto-exported** to the shell under a generated name (`SECRET_JWT`,\n`SECRET_JWT_2`, ...), written to `process.env`, and replaced in the context with\nthe same self-describing placeholder. So if you paste a JWT into the chat, the\nmodel sees `... read it in bash as \"$SECRET_JWT\"` and can use it via\n`curl -H \"Authorization: Bearer $SECRET_JWT\"` without ever seeing the value.\nCaptured names show up under `/secret-firewall` status.\n\n### Custom patterns\n\nThe built-in pattern list can be extended with your own regexes via a JSON\nconfig file, so internal or vendor-specific token shapes are also caught and\nauto-exported. Config is read from, in order of precedence (both are merged;\nglobal first, then project):\n\n- `~/.pi/agent/secret-firewall.json` — global, applies to every project.\n- `<cwd>/.pi/secret-firewall.json` — project-local.\n\n```json\n{\n  \"patterns\": [\n    { \"name\": \"ACME\", \"regex\": \"acme-[0-9a-f]{12}\" },\n    { \"name\": \"INTERNAL_TOKEN\", \"regex\": \"int_[A-Za-z0-9]{24}\", \"flags\": \"i\" }\n  ]\n}\n```\n\n- `name` — used to build the exported shell var (`$SECRET_ACME`,\n  `$SECRET_ACME_2` for a second distinct match). Sanitized to `[A-Za-z0-9_]`.\n- `regex` — the pattern to match. The `g` flag is always applied.\n- `flags` — optional extra RegExp flags (e.g. `i`).\n\nInvalid regexes and malformed entries are skipped silently rather than crashing\nthe firewall. Custom patterns behave exactly like the built-in ones: matches are\nmasked, captured, and exported to the shell. Keep patterns specific — a\ntoo-broad regex will redact large chunks of normal output and degrade the agent,\nand a pathological regex runs on every tool result (ReDoS risk).\n\n### Standing guidance in the system prompt\n\nA `before_agent_start` hook appends a short section to the system prompt every\nturn explaining the contract: placeholders are **not** the value and **not** an\nunset variable; the real value is **live in the shell**; reference it by name in\na `bash` command; never echo/print/cat it. It also lists the currently available\nsecret env var names. This is what stops the model from concluding \"the env var\nisn't set\" or treating the placeholder text as the literal value.\n\n## Security model — the model never sees the value\n\nThis extension uses the **shell-env-only** strategy:\n\n- The real value lives in `process.env` (which the `bash` tool inherits).\n- The model references it as a shell variable: `curl -H \"Authorization: Bearer $MY_API_KEY\"`.\n- The shell resolves `$MY_API_KEY` at execution time.\n- The value never returns to the context — any echo of it in tool output is\n  redacted again.\n\nThe extension never re-hydrates placeholders itself. If the model writes the\nliteral *value* instead of the shell reference, that value is redacted on the\nway back, but the model must use the `$NAME` reference for a command to actually\nuse the secret.\n\n### Pasted/leaked tokens are captured and exported\n\nWhen a value is caught by a **pattern rule** (JWT, AWS key, `sk-...`, etc.) it is\nnot only masked — its real value is captured and exported as a `$SECRET_*` shell\nvariable on the fly. This means a token pasted into the chat becomes usable in\nbash (`$SECRET_JWT`) without the model ever seeing the value, and without\nneeding it in `.env` beforehand. Distinct values caught by the same pattern get\nsuffixed names (`$SECRET_JWT_2`).\n\n### Limits / non-goals\n\n- A determined model could still exfiltrate a secret by transforming it before\n  printing (e.g. base64). This raises the bar; it is not a sandbox.\n- Values shorter than 8 chars or matching trivial values (`true`, `3000`, ...)\n  are not protected — they are not secrets and redacting them breaks the agent.\n- Infra/session vars (`PATH`, `HOME`, `SSH_AUTH_SOCK`, `*_SESSION`, ...) are\n  explicitly never treated as secrets.\n\n## Commands\n\n- `/secret-firewall` — show status (protected secrets, redaction count, the\n  shell env var names the model may reference).\n- `/secret-firewall-toggle` — enable/disable redaction.\n- `/secret-firewall-rescan` — re-scan env + `.env` files.\n\n## Develop\n\n```bash\npnpm build   # tsc -> dist/\npnpm test    # node --test against dist/\npnpm lint    # tsc --noEmit\n```\n","readmeFilename":"README.md"}