macOS pgrep/ps can read every managed agent's BUZZ_PRIVATE_KEY (nsec in KERN_PROCARGS2 environ)
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
On macOS, `pgrep -fl` / `ps` can read every managed agent's `BUZZ_PRIVATE_KEY` (nsec) because Desktop injects it into the `buzz-acp` child environment and Darwin `KERN_PROCARGS2` concatenates environ after argv. Grandchildren (`npm`, `node`, `vite preview`, etc.) inherit the key. Any same-UID process on the machine can impersonate any other managed agent.
This is inherited environment, not argv. `argv` does not contain the nsec; `pgrep -fl` still prints it because it dumps the full `KERN_PROCARGS2` buffer.
## Why NIP-GS's current wording is not enough
[NIP-GS "Key Exposure via Environment Variables"](https://github.com/block/buzz/blob/main/docs/nips/NIP-GS.md) documents Linux `/proc//environ` and calls the model acceptable for "agent processes running in a controlled environment (e.g., spawned by a desktop app with process-scoped env vars)."
A Desktop nest with many managed agents on one Mac is not a controlled environment in that sense: every seat runs as the same OS user. One agent (or any npm script, postinstall, or leftover `vite preview`) can `pgrep -fl buzz-acp` and obtain every other seat's signing key.
macOS is not mentioned. `pgrep -fl` is the accidental disclosure path people actually hit — it looks like the secret was passed on the command line even when it was not.
## Reproduction (no secret in the report)
1. Run a managed agent on macOS Desktop.
2. From another same-user shell: `pgrep -fl buzz-acp` (or `pgrep -fl vite` if an agent left a preview server running).
3. Observe `BUZZ_PRIVATE_KEY=nsec1…` in the listed "command" text.
4. Confirm with `KERN_PROCARGS2` that the nsec is in **environ**, not `argv` (`argc` strings do not contain it; the env block after the NUL padding does).
Do not paste the nsec. Redact before sharing `ps` output.
## Expected
- Agent identity should not be readable from the process table of sibling same-UID processes.
- At minimum, long-lived grandchildren should not inherit `BUZZ_PRIVATE_KEY`.
- Docs should name Darwin `KERN_PROCARGS2` / `pgrep -fl` alongside `/proc//environ`.
## Observed spawn site
`desktop/src-tauri/src/managed_agents/runtime.rs` — `command.env("BUZZ_PRIVATE_KEY", &record.private_key_nsec);` on the `buzz-acp` child. Reserved-env stripping correctly blocks *user* env from setting that key; Desktop still injects it itself, which is the leak.
## Suggested direction (not a patch)
- Prefer a fd / unix-socket / one-shot helper for identity so the nsec is not in `environ` of the ACP process or its grandchildren.
- If env injection stays: drop `BUZZ_PRIVATE_KEY` from the environment before the inner agent runtime execs tools, or document a required `env -u BUZZ_PRIVATE_KEY` around long-lived children.
- Treat sibling managed agents on the same UID as the threat model, not only "the process itself and its children."
Contributor guide
Assessment
This issue has not been assessed yet.