feat(policy): gate credential-bearing file writes and .env as protected metadata - #4
Open
AtropinolTT wants to merge 1 commit into
Open
Conversation
…ed metadata containsSecretMaterial() matches strong credential/private-key patterns (AKIA/ASIA, ghp_/gho_/ghu_/ghs_/github_pat_, sk-(proj-)?, and BEGIN RSA|OPENSSH|EC|ECDSA|DSA|ENCRYPTED PRIVATE KEY blocks) in file-mutation payloads - write/edit content fields and str_replace_editor old_str/new_str/file_text. Hits route to ask instead of the fast-path allow: classifier-eligible for write/edit (their content fields are redacted by the classifier sanitizer), direct ask for str_replace_editor (its payload fields are not covered by the sanitizer's content-key redaction, so the credential would otherwise reach the classifier in cleartext). .env and .env.* (multi-segment included) join isProtectedProjectPath, so env-file writes require explicit authorization. The str_replace_editor secret check runs before the protected-path check so credential writes to .env can never be routed to the classifier in cleartext. Weak patterns (password = "...") are deliberately excluded - they are routine in fixtures/templates. Credential hits are ask rather than hard deny, consistent with the DESIGN.md principle that blanket rules should not block targets the user explicitly authorized. Tests: table-driven policy tests covering every regex branch across write/edit and str_replace_editor (credential -> ask; ordinary fixture write -> allow; .env* -> ask; multi-segment .env.development.local -> ask). Full suite: 68/68 passing; tsc --noEmit clean (host + client).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why: DESIGN.md lists "credentials, tokens, private keys" as protected material, but the workspace-local file-mutation fast path currently allows any content without classification. An agent (or prompt-injected repo) can write
AKIA.../ghp_.../sk-.../BEGIN PRIVATE KEY material into a project file with no review.What:
containsSecretMaterial()matches strong credential/private-key patterns in file-mutation payloads (write/editcontent fields andstr_replace_editorold_str/new_str/file_text). Hits route toaskinstead of the fast-path allow: classifier-eligible forwrite/edit(their content fields are redacted by the classifier sanitizer), direct ask forstr_replace_editor(its payload fields are not covered by the sanitizer's content-key redaction, so the credential would otherwise reach the classifier in cleartext)..envand.env.*(multi-segment included) joinisProtectedProjectPath, so env-file writes require explicit authorization.Design notes: Weak patterns (
password = "...") are deliberately excluded — they are routine in fixtures/templates, and classifier payloads already redact content fields. Credential hits areaskrather than hard deny, consistent with the DESIGN.md principle that blanket rules should not block targets the user explicitly authorized;str_replace_editoris the one exception (direct ask) purely because its payload fields are outside the sanitizer's redaction coverage.Tests: table-driven policy tests covering every regex branch across write/edit and str_replace_editor (credential → ask; ordinary fixture write → allow;
.env*→ ask; multi-segment.env.development.local→ ask). Full suite: 68/68 passing;tsc --noEmitclean (host + client).Appendix — Known gaps and follow-up intent (PR-B)
This guard covers the file-mutation tools (
write/edit/str_replace_editor). Two write paths remain outside its scope by design: shell redirection (echo "AKIA..." > .env) and patch-style tools (apply_patch). The shell-redirect path is the subject of a planned follow-up (PR-B): evaluate shell command segments for credential material in redirect targets (reusingcontainsSecretMaterial, no new patterns), submitted as a separate PR after this one lands and maintainer feedback is heard.