Gate all built-in tools through PermissionFilter; confine read tools in trigger sessions #192

Merged
lucas merged 1 commit from agent/issue-189-permission-gate into main 2026-11-02 14:31:47 +01:00
Collaborator

Closes: #189

  • New permissionGate tool_call extension (bridge/permission-gate.ts) runs PermissionFilter.evaluatePermission for every tool that is neither a ClientBridge tool (bash/edit/delete/move) nor a deck custom tool. It is installed in normal sessions via extensions and in trigger sessions via preloadedPreparedExtensions (restricted sessions ignore extensions).
  • PARAM_FIELD_MAP now uses current tool names (grep/find/glob: path, no search). Multi-path calls are split on ;, with a missing path treated as .. Allow rules must match every path; deny and ask rules match on any path.
  • bridge/path-confinement.ts confines read/grep/find/glob to the checkout in conversation, pull-request and CI-watchdog sessions. Paths are resolved with realpath (so symlinks are followed) and file:N-M / archive:member selectors are handled. http(s), local:// and artifact:// are allowed; every other URI scheme is denied. The implementer stays unconfined.
  • extensionHandlers.toolCallTimeoutMs is raised to 24 h in DECK_SESSION_OVERRIDES. A throwaway script confirmed the isolated settings return 86400000.

Verification: bun test src/bridge src/forgejo/dispatcher.test.ts passes (661 tests, 0 failures), and bun run typecheck is clean. New tests are in permission-gate.test.ts, path-confinement.test.ts and permission-filter.test.ts (multi-path). The manual UI check from the plan (deny .env read, ask on glob waiting more than 30 s) has not been run, because this session is unattended.

Closes: #189 - New `permissionGate` `tool_call` extension (`bridge/permission-gate.ts`) runs `PermissionFilter.evaluatePermission` for every tool that is neither a ClientBridge tool (bash/edit/delete/move) nor a deck custom tool. It is installed in normal sessions via `extensions` and in trigger sessions via `preloadedPreparedExtensions` (restricted sessions ignore `extensions`). - `PARAM_FIELD_MAP` now uses current tool names (`grep`/`find`/`glob: path`, no `search`). Multi-path calls are split on `;`, with a missing path treated as `.`. Allow rules must match every path; deny and ask rules match on any path. - `bridge/path-confinement.ts` confines `read`/`grep`/`find`/`glob` to the checkout in conversation, pull-request and CI-watchdog sessions. Paths are resolved with realpath (so symlinks are followed) and `file:N-M` / `archive:member` selectors are handled. http(s), `local://` and `artifact://` are allowed; every other URI scheme is denied. The implementer stays unconfined. - `extensionHandlers.toolCallTimeoutMs` is raised to 24 h in `DECK_SESSION_OVERRIDES`. A throwaway script confirmed the isolated settings return `86400000`. Verification: `bun test src/bridge src/forgejo/dispatcher.test.ts` passes (661 tests, 0 failures), and `bun run typecheck` is clean. New tests are in `permission-gate.test.ts`, `path-confinement.test.ts` and `permission-filter.test.ts` (multi-path). The manual UI check from the plan (deny `.env` read, ask on `glob` waiting more than 30 s) has not been run, because this session is unattended.
The SDK only routes bash/edit/delete/move through the ClientBridge, so
permission rules and trigger policies never saw read, grep, find, glob,
write, eval, etc. A deck `tool_call` extension (permissionGate) now sends
every other non-custom tool through PermissionFilter, in normal sessions
and (via preloadedPreparedExtensions) in restricted trigger sessions.

- Rule matching uses current tool names and checks each path of a
  multi-path grep/find/glob call: allow needs all, deny/ask any.
- Conversation, pull-request and CI-watchdog sessions confine read tools
  to the checkout (realpath-checked), allowing http(s), local:// and
  artifact:// only.
- Raise extensionHandlers.toolCallTimeoutMs so a pending permission
  prompt does not fail closed after 30 s.

Co-Authored-By: Claude Opus 5.5 via omp-deck
lucas merged commit 2bd9265c34 into main 2026-11-02 14:31:47 +01:00
lucas deleted branch agent/issue-189-permission-gate 2026-11-02 14:31:47 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
lucas/omp-deck!192
No description provided.