paperclip/packages/adapters/codex-local/src/server
Nicky Leach 9064cfd09e
feat(codex-local): give each Codex account its own home and path secret (#12709)
## Thinking Path

> - Paperclip is the control plane for companies that use AI agents for
work
> - Local adapters connect Paperclip agents to provider command line
tools
> - The Codex adapter stores login data in a shared company home
> - A shared home cannot keep credentials for more than one Codex
account
> - This pull request gives each account a safe home and a matching
company secret
> - The benefit is that one company can use multiple Codex accounts at
the same time

## Linked Issues or Issue Description

**Problem or motivation**

A company can hold only one Codex subscription credential because device
login uses one shared home. A second account cannot log in without
replacing or conflicting with the first credential.

**Proposed solution**

This change validates the vendor account identifier, stores each
credential in its own home, and creates a company secret that points to
that home. Repeat login calls return success when the matching secret
already exists.

**Roadmap alignment**

The change supports the roadmap goal for centrally managed secrets with
scoped access and audited resolution.

**Additional context**

The security review returned approve with no blocking finding. The
branch adds shared account-handle validation and tests for device login
and the Codex local adapter.

## What Changed

- Add strict allowlist validation for Codex account handles.
- Store each Codex account credential in a separate home under the Codex
cache root.
- Verify that the resolved account home stays inside the cache root.
- Create the `CODEX_HOME_<handle>` company secret for each account.
- Keep repeat and concurrent login calls safe and idempotent.
- Add shared helper and route, adapter, and validation tests.

## Verification

- `pnpm --filter @paperclipai/adapter-codex-local test` passes with 343
tests.
- `pnpm --filter @paperclipai/server test
src/__tests__/agent-device-login-routes.test.ts` passes with 25 tests.
- The adapter suite passes with 23 tests.
- The shared package and Codex adapter typechecks pass.
- Continuous integration must pass on every check before merge.

## Risks

The account handle becomes part of a directory path and secret name. The
strict allowlist and root containment check reduce path traversal risk.
Existing single-account homes remain unchanged unless a new device login
creates an account-specific home.

## Model Used

OpenAI GPT-5 (exact runtime model ID: gpt-5), with tool use and code
execution. The runtime context window is not exposed in this run.

## 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
- [ ] 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>
2026-09-02 14:46:53 -07:00
..
__fixtures__ feat(adapter-codex-local): add secure device-login building blocks (#11097) 2026-08-10 16:12:30 -07:00
acp.test.ts refactor(adapter-utils): extract the shared workspace-restore teardown factory (#12196) 2026-08-25 21:38:27 -07:00
acp.ts refactor(adapter-utils): extract the shared workspace-restore teardown factory (#12196) 2026-08-25 21:38:27 -07:00
adapter-auth-promotion.test.ts feat(codex-local): give each Codex account its own home and path secret (#12709) 2026-09-02 14:46:53 -07:00
adapter-auth-promotion.ts feat(codex-local): give each Codex account its own home and path secret (#12709) 2026-09-02 14:46:53 -07:00
auth-check.ts feat(auth): normalize agent login in the sandbox onto one session table and a capability contract (#11730) 2026-08-19 11:51:31 -07:00
auth-precedence.test.ts fix(codex): warn when sandbox auth is shadowed (#9259) 2026-07-15 10:02:28 -07:00
auth-precedence.ts fix(codex): warn when sandbox auth is shadowed (#9259) 2026-07-15 10:02:28 -07:00
codex-args.test.ts fix(codex): do not inject a duplicate --skip-git-repo-check for sandbox runs (#10595) 2026-07-31 20:37:51 -07:00
codex-args.ts fix(codex): do not inject a duplicate --skip-git-repo-check for sandbox runs (#10595) 2026-07-31 20:37:51 -07:00
codex-auth-cache.test.ts feat(codex-local): give each Codex account its own home and path secret (#12709) 2026-09-02 14:46:53 -07:00
codex-auth-cache.ts feat(codex-local): give each Codex account its own home and path secret (#12709) 2026-09-02 14:46:53 -07:00
codex-auth-copyback.test.ts feat(codex): add identity-keyed host credential cache (#10853) 2026-08-04 16:33:54 -07:00
codex-auth-copyback.ts fix(adapter-utils): move the workspace-restore merge lock to an instance-scoped root and surface restore failures on the run (#12187) 2026-08-25 14:32:14 -07:00
codex-auth-merge-decision.cjs feat(codex): add identity-keyed host credential cache (#10853) 2026-08-04 16:33:54 -07:00
codex-auth-merge-decision.test.ts feat(codex): add identity-keyed host credential cache (#10853) 2026-08-04 16:33:54 -07:00
codex-auth-merge-decision.ts Add sandbox device-login for the Codex adapter (#11237) 2026-08-12 08:58:25 -07:00
codex-auth-merge-extract.sh fix(codex): let sandbox runs use the sandbox image's own Codex login (#10582) 2026-07-31 18:36:36 -07:00
codex-auth-merge-scripts.ts feat(sandbox-runtime): route all inbound staging through client.syncIn (Codex home -> native uploadFiles; delete usesCustomProvision gate) (#10354) 2026-07-28 07:22:18 -07:00
codex-auth-merge.test.ts fix(codex): let sandbox runs use the sandbox image's own Codex login (#10582) 2026-07-31 18:36:36 -07:00
codex-auth-seed-write.ts fix(adapter-utils): move the workspace-restore merge lock to an instance-scoped root and surface restore failures on the run (#12187) 2026-08-25 14:32:14 -07:00
codex-home.test.ts fix(codex-local): keep a promoted device-login credential when re-seeding the managed home (#11578) 2026-08-17 20:11:07 -07:00
codex-home.ts fix(codex-local): keep a promoted device-login credential when re-seeding the managed home (#11578) 2026-08-17 20:11:07 -07:00
config-schema.ts Make ACP the default engine for local adapters (#9238) 2026-07-08 19:05:03 -07:00
device-login-export.test.ts feat(adapter-codex-local): add secure device-login building blocks (#11097) 2026-08-10 16:12:30 -07:00
device-login-export.ts fix(adapter-utils): move the workspace-restore merge lock to an instance-scoped root and surface restore failures on the run (#12187) 2026-08-25 14:32:14 -07:00
device-login-parse.test.ts feat: add Grok device login to the sandbox login panel (#12469) 2026-08-28 21:48:34 -07:00
device-login-parse.ts feat: add Grok device login to the sandbox login panel (#12469) 2026-08-28 21:48:34 -07:00
device-login-runner.test.ts feat: add Grok device login to the sandbox login panel (#12469) 2026-08-28 21:48:34 -07:00
device-login-runner.ts feat: add Grok device login to the sandbox login panel (#12469) 2026-08-28 21:48:34 -07:00
execute.acp-fallback.test.ts Make ACP the default engine for local adapters (#9238) 2026-07-08 19:05:03 -07:00
execute.auth-precedence.test.ts refactor(codex-local): stage an allowlist for sandbox CODEX_HOME sync (#9972) 2026-07-21 19:50:21 -07:00
execute.auth.test.ts fix(codex): let sandbox runs use the sandbox image's own Codex login (#10582) 2026-07-31 18:36:36 -07:00
execute.remote.test.ts fix(runtime): support in-place workspace realization (#10230) 2026-07-25 08:29:26 -05:00
execute.stderr-error.test.ts fix(codex-local): skip benign stderr warnings when deriving the fallback run error (#10003) 2026-08-12 16:09:10 -07:00
execute.test.ts feat(codex-local): outbound auth copy-back as home-asset restore contribution (#9788) 2026-07-18 09:13:45 -05:00
execute.ts fix(adapters): restore Paperclip skill for legacy runners (#12225) 2026-08-26 09:45:24 -05:00
index.ts feat(codex-local): give each Codex account its own home and path secret (#12709) 2026-09-02 14:46:53 -07:00
output-inactivity-monitor.integration.test.ts fix(codex): preserve silent active builds (#10153) 2026-07-24 15:27:24 -05:00
output-inactivity-monitor.test.ts fix(codex): preserve silent active builds (#10153) 2026-07-24 15:27:24 -05:00
output-inactivity-monitor.ts fix(codex): preserve silent active builds (#10153) 2026-07-24 15:27:24 -05:00
parse.test.ts fix(codex): classify mid-turn harness crashes structurally as retriable infra (#10210) 2026-07-24 16:40:47 -05:00
parse.ts fix(codex): classify mid-turn harness crashes structurally as retriable infra (#10210) 2026-07-24 16:40:47 -05:00
process-activity-monitor.test.ts fix(codex): preserve silent active builds (#10153) 2026-07-24 15:27:24 -05:00
process-activity-monitor.ts fix(codex): preserve silent active builds (#10153) 2026-07-24 15:27:24 -05:00
quota-spawn-error.test.ts fix(codex): classify refresh auth failures (#9598) 2026-07-14 22:40:38 -07:00
quota.ts fix(codex): classify refresh auth failures (#9598) 2026-07-14 22:40:38 -07:00
runtime-config.test.ts feat(codex-local): env-driven gateway routing via PAPERCLIP_CODEX_PROVIDERS config.toml (#7919) 2026-06-10 21:13:31 -07:00
runtime-config.ts feat(codex-local): env-driven gateway routing via PAPERCLIP_CODEX_PROVIDERS config.toml (#7919) 2026-06-10 21:13:31 -07:00
skills.ts fix(adapters): restore Paperclip skill for legacy runners (#12225) 2026-08-26 09:45:24 -05:00
test.remote.test.ts Add sandbox device-login for the Codex adapter (#11237) 2026-08-12 08:58:25 -07:00
test.ts feat(environments): refer to the managed default environment by name, not the sandbox driver key (#11838) 2026-08-21 12:51:22 -07:00