Skip to content

apps/cli: use SDK 'auto' permission mode, drop ad-hoc security gating#3242

Merged
youknowriad merged 1 commit intotrunkfrom
claude/interesting-almeida-8f09d8
Apr 27, 2026
Merged

apps/cli: use SDK 'auto' permission mode, drop ad-hoc security gating#3242
youknowriad merged 1 commit intotrunkfrom
claude/interesting-almeida-8f09d8

Conversation

@youknowriad
Copy link
Copy Markdown
Contributor

@youknowriad youknowriad commented Apr 25, 2026

The idea is that our native permissions handling is probably useless and "auto" mode does a better job. "auto" mode was not available on previous versions but now it's there.

How AI was used in this PR

Built with Claude Code in auto mode. The change is small enough to review by reading the diff: the in-house path-gated permission gate (apps/cli/ai/security.ts, apps/cli/lib/cli-config/permissions.ts, the approvedPermissions field on cli.json, the ALLOWED_TOOLS list, the --auto-approve / autoApprove plumbing) is deleted, and permissionMode: 'auto' is set on the SDK query() options. The interesting bit is the PreToolUse hook that keeps AskUserQuestion rendering in our chat UI — that's the one piece worth reading carefully.

Proposed Changes

  • Bump effective @anthropic-ai/claude-agent-sdk resolution to 0.2.117 (already in package-lock.json, was stale in node_modules).
  • apps/cli/ai/agent.ts: set permissionMode: 'auto'. The SDK runs a model classifier to approve/deny each tool call; risky calls (e.g. sudo, destructive rm -rf outside cwd, sensitive file access) still escalate to a permission prompt. Drop the previous canUseTool always-allow callback.
  • AskUserQuestion UI: register a PreToolUse hook scoped to matcher: 'AskUserQuestion' that forwards questions to onAskUser and injects answers via updatedInput, returning permissionDecision: 'allow'. Every other tool falls through to the classifier.
  • Delete apps/cli/ai/security.ts (TRUSTED_ROOTS, path resolution, ALLOWED_TOOLS, promptForApproval) and its test file.
  • Delete apps/cli/lib/cli-config/permissions.ts and the approvedPermissions schema field — old configs strip the unknown key on read, no migration needed.
  • Drop the --auto-approve / autoApprove flag throughout: apps/cli/commands/ai/index.ts, apps/cli/commands/ai/sessions/resume.ts, apps/studio/src/modules/studio-code/studio-code-process.ts, apps/studio/src/modules/ai-agent/run-manager.ts. Auto-approval is now the SDK's job.
  • Eval: remove the security test case (agent asks permission before writing outside ~/Studio) and the now-unused askUserPolicy / pickAnswer / hasPermissionOptions helpers in apps/cli/ai/eval-runner.ts.

Net: −893 / +63 lines.

Testing Instructions

  • npm run cli:build && node apps/cli/dist/cli/main.mjs code and run a normal turn — the agent should execute without prompting on benign tool calls.
  • Trigger a permission prompt to confirm the classifier still gates risky operations: ask the agent to run sudo whoami, or rm -rf ~/Downloads, or read ~/.aws/credentials.
  • Trigger an AskUserQuestion (e.g. ask the agent to invoke a skill that asks clarifying questions like site-spec) and confirm the questions render in the chat UI and answers are persisted to the session log.
  • Resume a session (studio code sessions resume) and verify it still loads.
  • Desktop app: spawn a turn from the studio-code panel and confirm subprocess args no longer include --no-auto-approve.

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?
  • Have you run the linter and tests?
  • Have you tested the new behavior on macOS / Windows / Linux?

🤖 Generated with Claude Code

…ity gating

The Claude Agent SDK 0.2.117 added an 'auto' permission mode that uses a
model classifier to approve/deny tool calls. Switch to it and remove the
in-house path-gated approval flow (TRUSTED_ROOTS, approvedPermissions in
cli.json, ALLOWED_TOOLS list, autoApprove flag) — the classifier
supersedes them.

AskUserQuestion still needs to render in our chat UI rather than the
SDK's default prompt, so route it through a PreToolUse hook scoped with
matcher: 'AskUserQuestion' that injects answers via updatedInput. Every
other tool falls through to the classifier.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@youknowriad youknowriad requested review from epeicher and sejas April 25, 2026 10:40
@youknowriad youknowriad self-assigned this Apr 25, 2026
@wpmobilebot
Copy link
Copy Markdown
Collaborator

📊 Performance Test Results

Comparing 1d7c4f6 vs trunk

app-size

Metric trunk 1d7c4f6 Diff Change
App Size (Mac) 1441.77 MB 1441.76 MB 0.01 MB ⚪ 0.0%

site-editor

Metric trunk 1d7c4f6 Diff Change
load 1810 ms 1763 ms 47 ms ⚪ 0.0%

site-startup

Metric trunk 1d7c4f6 Diff Change
siteCreation 8088 ms 8084 ms 4 ms ⚪ 0.0%
siteStartup 4943 ms 4951 ms +8 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

Copy link
Copy Markdown
Member

@borkweb borkweb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great change!

@youknowriad youknowriad merged commit 05a20ca into trunk Apr 27, 2026
11 checks passed
@youknowriad youknowriad deleted the claude/interesting-almeida-8f09d8 branch April 27, 2026 15:08
youknowriad added a commit that referenced this pull request Apr 27, 2026
Brings in #3242 (SDK 'auto' permission mode, drop ad-hoc security gating)
plus a few smaller trunk PRs. Conflict resolution:

- `apps/cli/ai/agent.ts`: kept the dual-runtime dispatch this branch
  introduced; absorbed trunk's runtime-agnostic additions — `AskUserHandler`
  type alias and `allowFreeForm` field on `AskUserQuestion`. Switched the
  Studio root mkdir from `STUDIO_ROOT` (deleted) to `STUDIO_SITES_ROOT`.
  Moved `AskUserQuestion` / `AskUserHandler` into agent.ts since their
  prior home (`cli/ai/security`) was removed in #3242.
- `apps/cli/ai/runtimes/anthropic/index.ts`: ported #3242's improvements
  inside the runtime layer — `permissionMode: 'auto'`, PreToolUse hook for
  `AskUserQuestion`, dropped the `canUseTool`-based ad-hoc approval and
  the `ALLOWED_TOOLS` allowlist that lived in the now-deleted security
  module. Anthropic turns now go through the SDK's classifier the same way
  trunk does it inline.
- `apps/cli/ai/runtimes/openai/index.ts`: re-pointed `STUDIO_ROOT` →
  `STUDIO_SITES_ROOT` from `cli/lib/site-paths`. Pi tools (`Read`/`Write`/
  `Edit`/etc.) and the agent cwd both swap over.
- `apps/cli/ai/runtimes/types.ts`, `apps/cli/ai/tools/ask-user-question.ts`:
  re-pointed `AskUserQuestion` import from `cli/ai/security` to
  `cli/ai/agent`.

Verified: typecheck clean, 1376 tests pass (down 20 from trunk's deleted
security.test.ts), lint clean, CLI builds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
youknowriad added a commit that referenced this pull request Apr 27, 2026
Reconciles the unified pi runtime with trunk's `permissionMode: 'auto'` /
ad-hoc-gating-removal change (#3242). pi-agent-core ships no equivalent to
the SDK's auto classifier, so this merge takes the middle path:

- Drops the allow-once / allow-always / deny prompt machinery from
  `apps/cli/ai/security.ts` (matches trunk's "drop ad-hoc gating" intent
  while keeping a stable trust-root contract on the pi side).
- Keeps a minimal static path allowlist — `STUDIO_ROOT`, `os.tmpdir()`,
  `/tmp` — enforced via pi's `beforeToolCall` hook in `runtimes/pi/`.
  Tool calls whose path arguments land outside the allowlist are blocked
  silently with `ACCESS_DENIED_MESSAGE`. Bash is intentionally not gated
  (its `command` arg isn't a structured path).
- Removes `autoApprove` from `AgentRuntimeConfig` and `AiAgentConfig`
  (no consumers; the new gate has no escape hatch by design).
- Rewrites `tests/security.test.ts` for the trimmed surface
  (`isPathGatedTool`, `resolveToolPath`, `isPathWithinTrustedRoot`,
  `findFirstPathOutsideTrustedRoots`).
- Resolves `tests/agent.test.ts` to keep the pi-runtime dispatch tests
  (Claude → anthropic-messages, GPT → openai-completions).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants