apps/cli: use SDK 'auto' permission mode, drop ad-hoc security gating#3242
Merged
youknowriad merged 1 commit intotrunkfrom Apr 27, 2026
Merged
apps/cli: use SDK 'auto' permission mode, drop ad-hoc security gating#3242youknowriad merged 1 commit intotrunkfrom
youknowriad merged 1 commit intotrunkfrom
Conversation
…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>
Collaborator
📊 Performance Test ResultsComparing 1d7c4f6 vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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, theapprovedPermissionsfield oncli.json, theALLOWED_TOOLSlist, the--auto-approve/autoApproveplumbing) is deleted, andpermissionMode: 'auto'is set on the SDKquery()options. The interesting bit is thePreToolUsehook that keepsAskUserQuestionrendering in our chat UI — that's the one piece worth reading carefully.Proposed Changes
@anthropic-ai/claude-agent-sdkresolution to 0.2.117 (already inpackage-lock.json, was stale in node_modules).apps/cli/ai/agent.ts: setpermissionMode: 'auto'. The SDK runs a model classifier to approve/deny each tool call; risky calls (e.g.sudo, destructiverm -rfoutside cwd, sensitive file access) still escalate to a permission prompt. Drop the previouscanUseToolalways-allow callback.AskUserQuestionUI: register aPreToolUsehook scoped tomatcher: 'AskUserQuestion'that forwards questions toonAskUserand injects answers viaupdatedInput, returningpermissionDecision: 'allow'. Every other tool falls through to the classifier.apps/cli/ai/security.ts(TRUSTED_ROOTS, path resolution,ALLOWED_TOOLS,promptForApproval) and its test file.apps/cli/lib/cli-config/permissions.tsand theapprovedPermissionsschema field — old configs strip the unknown key on read, no migration needed.--auto-approve/autoApproveflag 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.securitytest case (agent asks permission before writing outside ~/Studio) and the now-unusedaskUserPolicy/pickAnswer/hasPermissionOptionshelpers inapps/cli/ai/eval-runner.ts.Net: −893 / +63 lines.
Testing Instructions
npm run cli:build && node apps/cli/dist/cli/main.mjs codeand run a normal turn — the agent should execute without prompting on benign tool calls.sudo whoami, orrm -rf ~/Downloads, or read~/.aws/credentials.site-spec) and confirm the questions render in the chat UI and answers are persisted to the session log.studio code sessions resume) and verify it still loads.--no-auto-approve.Pre-merge Checklist
🤖 Generated with Claude Code