fix(security): migrate MCP private-key handoff to keyfile pattern - #3478
Closed
jewoos2921 wants to merge 1 commit into
Closed
fix(security): migrate MCP private-key handoff to keyfile pattern#3478jewoos2921 wants to merge 1 commit into
jewoos2921 wants to merge 1 commit into
Conversation
Previously, BUZZ_PRIVATE_KEY and NOSTR_PRIVATE_KEY were passed to MCP subprocesses via environment variables (PASSTHROUGH_ENV allowlist in buzz-agent). Any configured MCP server could read the user's identity key from its own environment — a known trust-boundary tradeoff documented in commit fbce606. This migrates to a keyfile pattern so raw private keys never appear in subprocess environments: 1. buzz-dev-mcp shim.rs: writes BUZZ_PRIVATE_KEY to a 0600 keyfile (same pattern already used for NOSTR_PRIVATE_KEY), exposes the path via BUZZ_KEYFILE, then removes the raw key from the process env. Shell children receive BUZZ_KEYFILE (a path, not a secret) instead. 2. buzz-cli: adds --keyfile flag / BUZZ_KEYFILE env var that reads the private key from a file. Takes precedence over --private-key / BUZZ_PRIVATE_KEY (backward compatible — existing env-var usage still works for standalone CLI invocations). 3. buzz-dev-mcp view_image.rs: relay media auth now reads from BUZZ_KEYFILE first, falling back to BUZZ_PRIVATE_KEY for backward compatibility. 4. buzz-agent mcp.rs: removes BUZZ_PRIVATE_KEY and NOSTR_PRIVATE_KEY from PASSTHROUGH_ENV. Adds BUZZ_KEYFILE (non-secret path). MCP subprocesses can no longer read identity keys from their environment. The keyfile is written inside the shim's 0700 tempdir (cleaned up on drop), with 0600 permissions set at creation time — the same proven pattern used for the NOSTR_PRIVATE_KEY keyfile since it was introduced.
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.
Summary
Previously,
BUZZ_PRIVATE_KEYandNOSTR_PRIVATE_KEYwere passed to MCP subprocesses via environment variables (PASSTHROUGH_ENVallowlist inbuzz-agent). Any configured MCP server could read the user's identity key from its own environment — a known trust-boundary tradeoff documented in commitfbce606fe.This PR migrates to a keyfile pattern so raw private keys never appear in subprocess environments.
Changes
buzz-dev-mcp/src/shim.rs— core fixBUZZ_PRIVATE_KEYto a 0600 keyfile inside the shim's 0700 tempdir (same proven pattern already used forNOSTR_PRIVATE_KEY)BUZZ_KEYFILEenv var to shell childrenBUZZ_PRIVATE_KEYfrom the process env immediately after writing the keyfileShim.buzz_envfield carriesBUZZ_KEYFILE+BUZZ_RELAY_URL(relay URL is non-secret)buzz-cli/src/lib.rs— keyfile support--keyfileflag /BUZZ_KEYFILEenv var that reads the private key from a file--private-key/BUZZ_PRIVATE_KEYbuzz-dev-mcp/src/view_image.rs— media autht=getauth now reads fromBUZZ_KEYFILEfirst, falling back toBUZZ_PRIVATE_KEYfor backward compatibilitybuzz-dev-mcp/src/shell.rsbuzz_env(BUZZ_KEYFILE,BUZZ_RELAY_URL) to shell children alongsidegit_envBUZZ_KEYFILEinstead ofBUZZ_PRIVATE_KEYbuzz-agent/src/mcp.rs— allowlist lockdownBUZZ_PRIVATE_KEYandNOSTR_PRIVATE_KEYfromPASSTHROUGH_ENVBUZZ_KEYFILE(a filesystem path, not a secret)Security impact
BUZZ_PRIVATE_KEYfrom its envBUZZ_KEYFILE(a path)/proc/self/environ,env, etc.NOSTR_PRIVATE_KEYalready keyfile-isolatedBUZZ_PRIVATE_KEYnow also keyfile-isolatedVerification
cargo check— all 3 crates compilecargo clippy -- -D warnings— cleancargo fmt --check— cleancargo test -p buzz-cli -p buzz-dev-mcp -p buzz-agent --lib— 286 passed (2 pre-existing failures on main, unrelated to this change)