mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-27 19:35:13 +01:00
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - The `pi_local` adapter spawns the Pi CLI as a child process for
agent runs, environment tests, and model discovery
> - Each of these three paths builds the child env with `{
...process.env, ...env }`, so the child inherits the full server
environment
> - The server environment can hold server-only `PAPERCLIP_*` secrets
and config paths, such as `PAPERCLIP_AGENT_JWT_SECRET`,
`PAPERCLIP_TOOL_ACTION_SIGNING_SECRET`, and
`PAPERCLIP_SECRETS_MASTER_KEY_FILE`
> - `@paperclipai/adapter-utils` already has
`sanitizeInheritedPaperclipEnv`, and the shared `runChildProcess` path
uses it for its base env. `pi_local` passes its pre-merged env as
`opts.env`, which `runChildProcess` spreads over that sanitized base, so
the inherited server values come back
> - This pull request routes the three `pi_local` merges through
`sanitizeInheritedPaperclipEnv`
> - The benefit is that `pi_local` agent processes no longer receive
server secrets. This is a security hardening change.
## Linked Issues or Issue Description
No issue exists. This is a bug report in the in-PR format.
**What happened?**
A `pi_local` agent process receives the inherited `PAPERCLIP_*`
variables of the Paperclip server process. An env dump from inside a
`pi_local` run showed `PAPERCLIP_AGENT_JWT_SECRET`,
`PAPERCLIP_TOOL_ACTION_SIGNING_SECRET`,
`PAPERCLIP_SECRETS_MASTER_KEY_FILE`, and server config path variables.
The agent process can read these values.
**Expected behavior**
The `pi_local` child env drops inherited server `PAPERCLIP_*` variables,
the same as the shared `runChildProcess` path. Only
`PAPERCLIP_RUNTIME_API_URL`, `PAPERCLIP_LISTEN_HOST`, and
`PAPERCLIP_LISTEN_PORT` stay inherited. The run-scoped variables that
the adapter sets (for example `PAPERCLIP_AGENT_ID` and
`PAPERCLIP_API_KEY`) and the adapter-configured env still reach the
child.
**Steps to reproduce**
1. Start the Paperclip server with `PAPERCLIP_AGENT_JWT_SECRET` set in
its environment.
2. Run a `pi_local` agent whose command writes `process.env` to a file.
3. Read the file. `PAPERCLIP_AGENT_JWT_SECRET` is present.
**Agent adapter(s) involved**
`pi_local` only.
**Additional context**
Other CLI adapters appear to merge `process.env` into the child env in a
similar way (for example in some `execute.ts` and `test.ts` files). This
pull request does not change them. It keeps the scope to `pi_local`.
Related: #3030 and #12870 also touch inherited agent env. This pull
request is independent of #14479.
## What Changed
- `packages/adapters/pi-local/src/server/execute.ts`: the run env and
the runtime env that the adapter logs now start from
`sanitizeInheritedPaperclipEnv(process.env)` instead of `process.env`.
- `packages/adapters/pi-local/src/server/test.ts`: the environment test
env now starts from `sanitizeInheritedPaperclipEnv(process.env)`.
- `packages/adapters/pi-local/src/server/models.ts`: the model discovery
env (`pi --list-models`) now starts from
`sanitizeInheritedPaperclipEnv(process.env)`.
- `server/src/__tests__/pi-local-execute.test.ts`: add a regression
test. The test sets three server secrets on `process.env`, runs
`execute` with a fake Pi command that dumps its env, and checks that the
secrets are absent. It also checks that the adapter-configured env and
the run-scoped `PAPERCLIP_AGENT_ID` and `PAPERCLIP_API_KEY` are present.
## Verification
- `cd server && npx vitest run src/__tests__/pi-local-execute.test.ts
src/__tests__/pi-local-adapter-environment.test.ts
src/__tests__/pi-local-skill-sync.test.ts`: 7 tests pass.
- The new test fails without the source change (the secret assertion
fails) and passes with it.
- `npx vitest run packages/adapters/pi-local`: 42 tests pass.
- `pnpm --filter @paperclipai/adapter-pi-local typecheck`: pass.
- `cd server && tsc --noEmit` (after `pnpm --filter
@paperclipai/plugin-sdk ensure-build-deps`): pass.
- Follow-up coverage observes real child environments from direct model
discovery, agent execution, and `testEnvironment`. Each path omits
inherited secrets and retains the permitted runtime/listen variables and
configured env. Removing either the model-discovery or environment-probe
sanitizer independently makes the regression fail. All 49 scoped tests
and both direct typechecks pass.
## Risks
- Low risk. A `pi_local` setup that relied on an inherited server
`PAPERCLIP_*` variable (other than the three kept keys) no longer gets
it. Such a value can still be set in the adapter `env` config. This is
the same behavior as the shared `runChildProcess` path.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI GPT-6.1 Sol, exact runtime model ID
`gpt6sol-cliproxy/gpt-6.1-sol`, with tool use and code execution.
Context-window and thinking-level metadata are not exposed. The prior
model and human-review disclosure was not substantiated by available
runtime metadata.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: mdc2122 <259970464+mdc2122@users.noreply.github.com>