fix: redact secrets from every tool and resource response - #9
Merged
Merged
Conversation
cloudsync_list passed the TrueNAS response through as-is, so each task's provider block put the B2 application key and S3 secret access key into the model transcript. Certificate and SSH private keys, API key and password hashes, bind passwords and alert tokens had the same problem, and truenas_api_call could reach all of them. All tool results, error messages and resources now pass through one redaction step in src/redact.ts on the way out. Matching is by key name, case-insensitive and separator-blind, plus a string scrub for private key blocks, URL passwords and secret query parameters. Identifiers, provider type, bucket, region and public keys stay visible. Handlers and the client still see real values, so no update can write "[redacted]" back to the NAS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
cloudsync_listreturned each task'scredentials.providerblock unredacted, so listing cloud sync tasks put the B2 application key and the S3 secret access key into the model transcript. The same was true of certificate and SSH private keys, API key and password hashes, bind passwords, CHAP secrets and alert service tokens.truenas_api_callcould reach all of them.What changed
src/redact.ts: one redaction pass. Values under secret-named keys become"[redacted]"at any depth. The match is case-insensitive and ignores separators (api_key,API-KeyandapiKeyare one name). Every string also gets a scrub for private key blocks, URL passwords and secret query parameters. Non-JSON text, such as error messages, gets the same scrub plus"name": "value"pair matching.src/run-tool.ts: the dispatch logic moved out ofindex.tsso it can be tested. Every path out is redacted: handler results, the raw-result fallback and error messages.src/index.ts: usesrunTooland registers resources through a redacting wrapper, so new tools and resources are covered by default. The tool description tells the model values are redacted.api_key_createandkeychaincredential_generate_ssh_keydescriptions now say the secret they create is not returned.Redaction is output-only. Handlers and the client still see real values, so no update can write
[redacted]back to the NAS.Deliberate choices
id,name, providertype, bucket, folder, endpoint, region, public keys, certificates,*_path,key_type. Null, booleans, numbers and empty strings are never redacted, because they show whether something is set and leak nothing.accountis redacted. TrueNAS labels it "Key ID". It is the same half of the pair as S3access_key_id, which is also redacted.accounton other providers is kept.urlor a password typed into a cloud syncargsstring, is not caught.Full rationale is in
DECISIONS.md.Verification
npm run buildclean,npm test78/78, including 29 new redaction tests. The fixtures mirror real TrueNAS 26 response shapes: cloud sync tasks with nested B2 and S3credentials.provider, the credentials list, cloud backup, keychain SSH keypair and SSH credentials, a certificate, the general config's nestedui_certificate, API keys, users, alert services, iSCSI auth, LDAP, keytabs, VMs and proxies. Every secret value is an obvious fake, and one test proves no fake survives any fixture.cloudsync_list,cloudsync_get,cloudsync_credentials_list,cloud_backup_list,keychaincredential_listandkeychaincredential_generate_ssh_keyhandlers through the real registry andrunTool.dist/smoke test: a real MCP client talked to the built server, backed by a mock TrueNAS WebSocket. There were 0 leaks oncloudsync_list,truenas_api_call GET /cloudsync, the error path and thetruenas://vmsresource.🤖 Generated with Claude Code