mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-07 16:11:46 +02:00
## Thinking Path > - Paperclip is the open-source control plane people use to manage AI agents for work. > - Routines are the subsystem that schedules recurring work and returns routine detail to authorized company actors. > - Routine detail embedded the complete assignee database row even though its shared contract requires only assignee identity. > - That full row can contain protected adapter and runtime configuration, including environment bindings. > - The service boundary should project only the fields the routine contract actually needs. > - This pull request replaces the full-row query with a company-scoped identity projection and adds sentinel-based regression coverage. > - The benefit is useful routine detail without exposing protected assignee configuration. ## Linked Issues or Issue Description No public issue exactly tracks this service-level exposure. - Related prior PR: Refs #4967, an older route-level redaction approach with broader changes and no focused routine serialization test. - Related closed PR: Refs #5144, an unmerged prior implementation of the same identity-projection approach. - Related agent-route hardening: Refs #8779; that work covers direct agent responses, while this PR removes protected fields from the routine embed itself. Bug details: - Actual behavior: `GET /api/routines/{routineId}` could serialize the complete assignee row, including protected adapter/runtime configuration. - Expected behavior: routine detail exposes only the assignee identity required by `RoutineDetail`, including its derived `urlKey`. - Reproduction: assign an agent with sentinel-only protected configuration to a routine, retrieve routine detail, and inspect key presence or serialize the response; no production value is needed or recorded. - Version/commit reproduced: upstream `master` immediately before this PR. - Deployment mode: service-level embedded Postgres test; the vulnerable serializer is shared by supported deployments. ## What Changed - Added a company-scoped assignee summary query in `server/src/services/routines.ts` that selects only `id`, `name`, `role`, and `title`, then derives the non-sensitive `urlKey` from the name. - Updated `getDetail()` to use that projection instead of selecting the complete agent row. - Added focused negative and positive identity assertions, including the derived `urlKey`, in `server/src/__tests__/routines-service.test.ts`. - Audited routine list/detail serialization and broader embedded-agent query sites; routine list exposes only `assigneeAgentId`, while other agent embeds use explicit projections or authorized agent endpoints. ## Verification - `pnpm exec vitest run server/src/__tests__/routines-service.test.ts` — 57/57 passed. - Focused sentinel regression test — passed. - `pnpm -r typecheck` — passed. - Server, UI, and CLI builds — passed; UI gzip-size completion used a 4096 MB Node heap. - `git diff --check` — passed. - Full `pnpm test:run` — 2,699 passed, 1 skipped, 9 failed in untouched tests. The failures reproduce outside this change and are limited to local-adapter `nohup`/PTY behavior, macOS `/tmp` versus `/private/tmp` normalization, and one workspace-runtime auto-port fixture. ## Risks - Low compatibility risk: the returned shape now matches the existing shared `RoutineDetail` contract. - A consumer relying on undocumented protected agent fields inside routine detail will stop receiving them. - No schema, migration, deployment, credential, or production-secret changes are included. - Rollback is a single commit revert, but reverting would restore the exposure. > This is security hardening for the already-shipped routines subsystem; `ROADMAP.md` marks Scheduled Routines complete, and this PR does not add or duplicate roadmap feature work. ## Model Used - OpenAI GPT-5 via Codex, with repository search, local code execution, tests, TypeScript typechecking, builds, Git, and GitHub API use. The runtime does not expose a more granular snapshot ID or context-window size. ## 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 relevant tests pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes (no documentation change is required for this contract-preserving security fix) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green 5 with no open P2s, recommendations, or follow-ups/- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: ClawdeBot <clawdebot@Mac-mini-de-ClawdeBot.local> Co-authored-by: Paperclip <noreply@paperclip.ing>