DamonKoy/dsh-plugins

dsh-secret-redactor

工具结果敏感信息自动脱敏:模型看到前掩码 API key / token / JWT / 私钥与配置密钥。

安全与权限

dsh-secret-redactor

Sensitive-information redaction plugin for DeepSeek Harness. Inspired by Codex 0.147's "redact secrets from displayed commands and replayed conversation history".

English | 中文

What it does

  • Auto-redaction of tool results: hooks the tools/post-execute waterfall and masks secrets in every text block the model sees — verified live in a real harness session (sk-abc123... becomes sk-***).
  • 25 built-in rules (see Rule catalog) covering vendor API keys, PEM private keys, bearer tokens, JWTs, connection-string and URL passwords, key = value pairs, data URIs, and generic high-entropy tokens — engineered to avoid false positives (tool names, file names, git hashes, UUIDs, credential-free URLs and plain long words are never masked).
  • Environment secret collection: any env var whose name matches TOKEN / KEY / SECRET / PASSWORD / PASSWD / CREDENTIAL / AUTH / SIGNING (value length >= 8) is collected and masked when it appears in output.
  • SSH password collection: passwords stored in ~/.dsh/dsh-ssh.json are masked (opt-out via config).
  • redact_text model tool: mask arbitrary text or JSON before it is logged, persisted, or echoed.
  • redact_secret_status model tool: report active rule names and collected secret counts (never the values) to verify the redactor.
  • Package-private RPC (harness.handle, sandbox realm only; skipped when loaded via CLI): secret-redactor/redact and secret-redactor/status for client halves and other plugins.

Install

dsh plugin --profile web add github:DamonKoy/dsh-plugins#path:/packages/dsh-secret-redactor

Restart dsh web. The redactor is active by default.

Config

Optional file ~/.dsh/dsh-secret-redactor.json:

{
  "enabled": true,
  "mask": "***",
  "disablePatterns": ["generic-mixed"],
  "patterns": ["CUSTOM-\\d{8}"],
  "extraSecrets": ["literal-secret-1"],
  "collectEnv": true,
  "collectSshPasswords": true
}
FieldDefaultMeaning
enabledtrueMaster switch
mask"***"Replacement text for user-supplied secrets/patterns
disablePatterns[]Disable built-in rules by name (see catalog)
patterns[]Extra regexes applied with g flag
extraSecrets[]Literal strings to mask (length >= 4)
collectEnvtrueCollect matching env var values
collectSshPasswordstrueCollect ~/.dsh/dsh-ssh.json passwords

Config is re-read on every hook, so edits apply without a restart.

Rule catalog

Rule nameWhat it masksExample
sk-openaisk- prefixed keys (OpenAI/DeepSeek)sk-abc… → sk-***
gh-tokensGitHub tokensghp_… → gh***
aws-akidAWS access key idsAKIA… → AKIA***
slackSlack tokensxoxb-… → xox***
google-apiGoogle API keysAIza… → AIza***
huggingfaceHF tokenshf_… → hf***
gitlabGitLab PATsglpat-… → glpat-***
bitbucketBitbucket tokensATBB… → ATBB***
aliyunAlibaba Cloud AKLTAI… → LTAI***
tencentTencent Cloud AKAKID… → AKID***
stripeStripe keyssk_live_… → sk_***
npmnpm tokensnpm_… → npm***
telegramTelegram bot tokens123456:AA… → 1234567890***
sendgridSendGrid API keysSG.… → SG.***
digitaloceanDO PATsdop_v1_… → dop_v1***
shopifyShopify tokensshpat_… → shpat_***
pem-private-keyPEM private key blocks (RSA/EC/OpenSSH/PGP/encrypted)whole block
bearerBearer <token> headersBearer ***
jwtJWTs***JWT***
data-uribase64 payloads of data:…;base64,… URIsdata:image/png;base64,***
url-credentialsscheme://user:password@ credentialsmongodb://***@host
key-valueapiKey/password/secret/token-style pairs (quoted or not)"password": "***"
hex-mixed32+ hex with mixed case + digits***
base64-mixed64+ base64-looking text, mixed case + digits***
generic-mixed40+ identifier-shaped text, mixed case + digits***

False-positive protection is baked into the generic rules: plain tool names (hindsight_search_knowledge_pages), lowercase-only words (even 45 chars), git commit hashes, UUIDs, https://user@host URLs, git SSH URLs and git@… forms are never masked. Run node --test test/ for the 13-case bidirectional suite (positives and negatives).

Security notes

  • Redaction applies to the model-facing content of tool results (the main leak surface). The durable log still stores the raw canonical result value; full log-level redaction is on the roadmap.
  • Collected secrets live only in memory; nothing is persisted or uploaded.
  • Counts reported by redact_secret_status never include the values.

License

MIT