mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-28 20:21:50 +01:00
7eea9d8214fec00dfde32bda7fcf9b20a428e330
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2568bdecc4 |
fix(adapter-utils): keep sandbox proxy sockets within Linux path limit (#10221)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents for work > - Local process adapters can enforce network allowlists through a Unix-socket proxy inside the Linux sandbox > - The proxy socket was created under `os.tmpdir()`, which can be a deeply nested run-specific directory > - Linux Unix-domain socket paths are limited to 107 usable bytes, so deep temporary paths can be silently truncated during bind > - A truncated proxy socket resets every confined outbound connection, including the model provider API, before the agent can do work > - This pull request creates proxy sockets under the short `/tmp` path when possible and validates the path length before bind > - The benefit is reliable sandboxed egress under deep `TMPDIR` values and an explicit error instead of an opaque connection-reset storm ## Linked Issues or Issue Description ### Pre-submission checklist - [x] I searched existing open and closed issues and this is not a duplicate. - [x] I can reproduce this on upstream `master`. - [x] I confirmed the error originates in Paperclip's local-process sandbox proxy. ### What happened? Sandboxed local-process agents using `networkScope: "allowlist"` could lose all proxied egress when `TMPDIR` was deeply nested because `proxy.sock` exceeded Linux's Unix socket path limit. The truncated bind surfaced as repeated connection resets, including for provider API traffic. ### Expected behavior Proxy creation should use a Linux-safe short path and fail explicitly if no safe socket path can be created. ### Steps to reproduce 1. Set `TMPDIR` to a path long enough that `<TMPDIR>/paperclip-network-sandbox-XXXXXX/proxy.sock` exceeds 107 bytes. 2. Build or run a local-process sandbox with `networkScope: "allowlist"`. 3. Make an HTTP or HTTPS request through the generated sandbox proxy. 4. Observe connection resets from the overlong Unix socket path on affected code. ### Paperclip version or commit Upstream `master` before this change. ### Deployment mode Other — Linux local-process adapters using Bubblewrap network allowlisting. ### Installation method Built from source. ### Agent adapter(s) involved Codex and any other local-process adapter using the shared sandbox utility. ### Operating system Linux. ### Additional context GitHub search found no duplicate public issue or pull request for this defect. ## What Changed - Add a Linux Unix-socket byte-length guard that reports the unsafe path before binding. - Create network proxy temporary directories under `/tmp` first, with `os.tmpdir()` as a validated fallback. - Use the safe temporary-directory helper at both allowlist proxy creation sites while preserving trusted URL handling. - Add regression coverage that sets a deliberately deep `TMPDIR` and verifies the working socket remains within 107 bytes under `/tmp`. ## Verification - `node /srv/paperclip/home/paperclipai/paperclip/node_modules/vitest/vitest.mjs run packages/adapter-utils/src/local-process-sandbox.test.ts` — 8 passed, 4 environment-gated tests skipped. - `git diff --check origin/master...HEAD` — passed. - Greptile Review — passed after reviewing 2 files with 0 comments and no unresolved threads; this repository integration did not emit a separate numeric confidence score. - Full GitHub CI matrix — passed after one rerun of an unrelated ACPX `ENOTEMPTY` cleanup flake. - Package typecheck was attempted, but the existing shared install cannot resolve `acpx/runtime`; the failure is outside the changed files and is expected to be covered by CI's clean dependency install. ## Risks - Low risk: the change is limited to Linux sandbox proxy temporary-directory selection and validation. - Systems without a writable `/tmp` fall back to `os.tmpdir()` only when the resulting socket path is safe; otherwise startup now fails loudly instead of producing connection resets. - No schema, API, UI, migration, or documentation behavior changes. > 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 Codex, `gpt-5.3-codex`, tool-enabled coding agent with managed reasoning and code execution; context-window size is not exposed by the runtime. ## 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 - [x] All Paperclip CI gates are green - [x] 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: Paperclip <noreply@paperclip.ing> |
||
|
|
4e00818574 |
fix(runtime): support in-place workspace realization (#10230)
## Thinking Path > - Paperclip is the control plane people use to coordinate AI agents and their execution environments. > - Environment realization decides where an agent runs and which filesystem and toolchain are authoritative. > - Copy-based realization is unsafe for container-anchored tasks because absolute paths such as `/app` can point outside the synchronized tree and task-specific binaries may be absent. > - That mismatch can let an agent successfully verify work in a phantom writable path while sync-back silently discards the result. > - Existing task environments already provide the authoritative filesystem and toolchain, so they should be executed in place rather than copied. > - Copy mode still needs explicit confinement rules so aliases target the synchronized workspace and unsynchronized writable paths fail visibly. > - This pull request adds typed realization metadata, propagates the authoritative root through orchestration, and teaches Codex to honor it. > - The benefit is that container-anchored tasks operate on verifier-visible state with the intended tools, while copy mode remains safe and backward compatible. ## Linked Issues or Issue Description No public GitHub issue exists for this defect. GitHub duplicate searches for in-place execution, workspace realization, and authoritative workspace roots found no related pull request to link. ### What happened? Environment-backed agent runs were always realized through a copied workspace. Tasks anchored to absolute container paths could therefore write outside the synchronized tree, and task-provided toolchains were unavailable in the copy. A run could report success even though sync-back discarded its output. ### Expected behavior Existing task environments should run against their real authoritative root and toolchain. Copy-mode runs should map declared absolute aliases into the synchronized tree and reject writable paths that cannot be restored. ### Steps to reproduce 1. Run a Codex task environment whose required files live under `/app` or `/workspace` and whose required binary exists only in the task container. 2. Observe that copy realization changes the effective filesystem/toolchain or permits writes outside the synchronized root. 3. Complete and verify the task inside the agent sandbox. 4. Observe that the verifier cannot see out-of-tree artifacts or that task-specific commands were unavailable. ### Reproduction context - Paperclip commit: `3a16b91217483d2c233926de5b7f7bc3a1077924` - Deployment: built from source in a task-container execution environment - Adapter: Codex local - Database: not database-related - Access context: agent execution ## What Changed - Added typed `copy | in_place` workspace-realization metadata, authoritative roots, confined aliases, and outbound restore paths to shared execution-target contracts. - Selected in-place realization for existing task environments and skipped archive prepare/restore when the authoritative environment is used directly. - Propagated the authoritative root into adapter context so Codex uses it for cwd and `PAPERCLIP_WORKSPACE_*` semantics, including ACP execution. - Bound copy-mode aliases such as `/app` to the synchronized workspace and rejected writable out-of-tree paths without explicit restore mappings. - Added focused regression coverage while preserving existing copy-mode archive restore behavior. ## Verification - `pnpm --filter @paperclipai/shared typecheck` — passed. - `pnpm exec vitest run packages/adapter-utils/src/local-process-sandbox.test.ts packages/adapters/codex-local/src/server/acp.test.ts packages/adapters/codex-local/src/server/execute.remote.test.ts server/src/__tests__/environment-run-orchestrator.test.ts` — 48 passed, 4 skipped. - `pnpm -r typecheck` — passed. - `env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN pnpm test:run` — passed across all general and serialized Vitest shards. - `pnpm build` — passed. - Codex `k=1` acceptance run completed July 24, 2026 at 23:54:30 UTC with 4 completed, 0 exceptions, and mean reward 1.0: `build-cython-ext`, `openssl-selfsigned-cert`, `prove-plus-comm`, and `sqlite-db-truncate` each received terminal grade 1.0 against real task-environment paths and toolchains. ## Risks - In-place mode deliberately exposes the authoritative task root to the adapter; incorrect environment metadata could point execution at the wrong root. Typed metadata and focused orchestration tests cover selection and propagation. - Copy-mode writable-path validation is stricter and may reject previously accepted unsafe configurations. The rejection is intentional and produces a visible error instead of silently losing output. - The acceptance run is focused on four Codex task-environment workloads, not a broad cross-adapter benchmark. Existing copy-mode archive tests and the full repository suite remain green. > 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 Codex CLI coding agent; exact model ID and context-window size were not exposed to this runtime. Capabilities used: extended reasoning, repository editing, shell execution, test/build execution, Git, GitHub CLI, and Paperclip API tool use. ## 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 - [x] All Paperclip CI gates are green - [x] 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: Paperclip <noreply@paperclip.ing> |
||
|
|
e4662b1f9d |
fix: preserve control plane access in Codex sandbox (#10152)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents for work > - Local coding adapters can be confined with filesystem and network sandbox policies > - Codex confinement proxied only user-allowlisted hosts, so it denied Paperclip's own run API and managed MCP endpoints > - The same proxy returned untyped plaintext denials, which MCP clients could treat as a fatal unexpected content type > - Host-only `PAPERCLIPAI_CMD` values could also leak into agents even when the referenced checkout module did not exist > - This pull request gives the sandbox an explicit trusted-URL channel for Paperclip endpoints, returns structured JSON errors, and removes the inherited host CLI pointer > - The benefit is confined Codex agents retain control-plane access without broadening the operator's external network allowlist or crashing on policy denials ## Linked Issues or Issue Description Refs #3802 Related foundation: #9504 ### What happened? A `codex_local` agent configured with `networkScope: "allowlist"` and an external-only allowlist could not reach its own Paperclip API or Paperclip-managed MCP endpoints. The sandbox proxy returned a `403` plaintext response without `Content-Type`, and an inherited `PAPERCLIPAI_CMD` could point at a missing checkout-local CLI module. ### Expected behavior Paperclip's run-scoped API and managed MCP endpoints remain reachable regardless of the user external allowlist. Policy denials are valid structured JSON responses with an explicit media type, and host-only CLI pointers are not inherited by agent processes. ### Steps to reproduce 1. Configure a `codex_local` agent with `networkScope: "allowlist"` and `networkAllowlist: ["api.openai.com"]`. 2. Run the agent and request its Paperclip issue API or a Paperclip-managed MCP endpoint. 3. Observe the sandbox proxy deny the request with an untyped plaintext `403` response. ### Environment - Paperclip commit: `f49a3f99` originally exhibited the defect; fix is based on current `master`. - Deployment: local source build on Linux. - Adapter: Codex. - Database: not database-related. - Access context: agent bearer/run-scoped credentials. ## What Changed - Added internal trusted URL rules to the local network allowlist proxy and supplied the Codex run API plus managed MCP endpoints. - Returned JSON error envelopes with `Content-Type` and `Content-Length` for HTTP and CONNECT policy denials. - Removed inherited `PAPERCLIPAI_CMD` from child process environments while preserving explicitly constructed runtime variables. - Added focused proxy and environment sanitizer regression tests. ## Verification - `pnpm exec vitest run packages/adapter-utils/src/local-process-sandbox.test.ts packages/adapter-utils/src/server-utils-env.test.ts --reporter=verbose` - 2 test files passed; 8 tests passed; 4 platform-dependent tests skipped. - `git diff --check` - Package typecheck was attempted; it reaches unrelated current-`master` type drift in untouched files (`spawnCwd` in `adapter-utils`, and staged-runtime ACP types in `codex-local`). ## Risks - Low risk: trusted access is restricted to exact HTTP(S) hostname and port pairs derived from Paperclip-provided URLs. - Invalid or non-HTTP trusted URL values are ignored rather than broadening access. - Denial response bodies change from plaintext to structured JSON; status codes remain unchanged. > 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 Codex coding agent (exact model ID and context window are not exposed to this runtime), reasoning and terminal/tool execution enabled. ## 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 - [x] All Paperclip CI gates are green - [x] 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: Paperclip <noreply@paperclip.ing> |
||
|
|
98d9360658 |
feat(adapters): confine local coding processes (#9504)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents for work. > - Local coding adapters currently spawn their CLI processes directly on the Paperclip host. > - CLI-native approval and sandbox flags do not provide a reliable host filesystem or network boundary. > - An agent can therefore inspect unrelated host files or fetch external material when an operator needs stronger isolation. > - The confinement must stay opt-in so existing local adapter behavior does not change unexpectedly. > - This pull request adds a shared Linux Bubblewrap spawn layer for workspace filesystem and deny/allowlist network scopes. > - The benefit is enforceable defense in depth around Codex and Claude local runs while preserving explicit provider connectivity. ## Linked Issues or Issue Description ### What happened? `codex_local` and `claude_local` processes could read arbitrary host paths and make unrestricted outbound network requests because Paperclip did not impose a spawn-level boundary. ### Expected behavior Operators can opt into a workspace-only filesystem view and either deny network egress or allow exact provider/API hosts, independently of CLI approval flags. ### Steps to reproduce 1. Run current `master` on Linux and configure a Codex or Claude local adapter. 2. Ask the agent to read a canary file outside its active workspace. 3. Ask the agent to `curl` a public host. 4. Observe that both operations succeed without a Paperclip-level confinement option. ### Environment - Paperclip commit: `c36f1a4af` / current `master` base. - Deployment mode: Linux local dev or self-hosted server. - Installation: built from source. - Adapters: Codex and Claude Code. - Database: not related. ## What Changed - Added a shared Bubblewrap process wrapper with opt-in `filesystemScope: "workspace"`, managed/extra path mounts, private `/tmp`, and Linux-only validation. - Added `networkScope: "deny" | "allowlist"`; both use a private network namespace, while allowlist mode exposes an exact-host HTTP(S) proxy over a Unix-socket bridge. - Wired Codex and Claude local CLI execution through the wrapper and forced scoped auto runs onto the CLI lane because ACP processes are not covered. - Added unit and gated Bubblewrap canaries for outside-file denial, workspace writes, direct network denial, allowlisted forwarding, and rejected destinations. - Documented both scopes, provider allowlist examples, Bubblewrap requirements, and default-off behavior. ## Verification - `pnpm exec vitest run packages/adapter-utils/src/local-process-sandbox.test.ts packages/adapters/codex-local/src/server/acp.test.ts packages/adapters/claude-local/src/server/acp.test.ts` — 34 passed, 4 gated Bubblewrap tests skipped by default. - `pnpm --filter @paperclipai/adapter-utils typecheck` - `pnpm --filter @paperclipai/adapter-codex-local typecheck` - `pnpm --filter @paperclipai/adapter-claude-local typecheck` - `pnpm --filter @paperclipai/adapter-utils build` - `pnpm --filter @paperclipai/adapter-codex-local build` - `pnpm --filter @paperclipai/adapter-claude-local build` - Attempted the gated tests with a vendored Bubblewrap binary; this container blocks unprivileged namespace setup (`setting up uid map: Permission denied` / loopback `RTM_NEWADDR: Operation not permitted`), so kernel-level execution remains for CI or a namespace-enabled Linux host. ## Risks - Bubblewrap must be installed and unprivileged user/mount/network namespaces must be enabled on the host; scoped runs fail clearly if the prerequisite is missing. - Allowlist mode depends on the coding CLI honoring standard `HTTP_PROXY` / `HTTPS_PROXY` variables; custom providers must list every required exact hostname and port. - Exact-host allowlists intentionally reject wildcards, which is safer but may require operators to enumerate multi-host provider setups. - No behavior changes unless an operator enables `filesystemScope` or `networkScope`. > This aligns with the ROADMAP direction toward safer remote and sandboxed agent environments and does not duplicate an open PR or issue found in the repository search. ## Model Used - OpenAI GPT-5.5 (`gpt-5.5`) via Codex CLI, with reasoning, repository tool use, shell execution, code editing, and test execution. The serving context-window size is not exposed to the agent. ## 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: Paperclip <noreply@paperclip.ing> |