feat(permissions): server-side permission rules (ALLOW/DENY/ASK) with session-allow promotion - #239
Open
ikarys wants to merge 4 commits into
Open
feat(permissions): server-side permission rules (ALLOW/DENY/ASK) with session-allow promotion#239ikarys wants to merge 4 commits into
ikarys wants to merge 4 commits into
Conversation
added 4 commits
August 12, 2026 11:24
- Add permission schema, registry, and rules engine (src/server/permissions/) - Add permissions API route (src/server/routes/permissions.ts) - Integrate permission checks into agent loop, orchestrator, and tool execution - Extend path-security with rule-based validation and confirmation flow - Add shared permission types and protocol (src/shared/permissions.ts) - Add PermissionsTab UI with rule editor and shared components - Add permissions store (web/src/stores/permissions.ts) - Wire permission events into MessageList and PathConfirmationButtons - Add .openfox/permissions.json project-level permission config - Add comprehensive tests across server, routes, tools, and web Also fix flaky test timeouts (Markdown cache eviction, inspect-proxy unreachable target)
- Integrate permission checks in agent-loop, orchestrator, execute-tools - Extend path-security with rule-based validation - Add permission events to protocol and event types - Wire PermissionsTab into GlobalSettingsModal - Add permission confirmation flow in PathConfirmationButtons and MessageList - Fix flaky test timeouts (Markdown cache eviction, inspect-proxy)
… session-allow promotion - Rules evaluated deterministically server-side (DENY>ALLOW>ASK precedence) - Scoped global or project; merged per-batch with ephemeral session rules - Cache-safe: rules excluded from system prompt + dynamic context hash - 'Allow for this session' promotes ASK rule to ephemeral ALLOW (pattern-based) - Tool-level DENY gate for non-path tools (web_fetch, call_sub_agent, ...) - Schema validation: non-pattern tools restricted to DENY-only, no pattern - UI: effect/pattern adapt to tool type; hide session-allow for dangerous/git - Removed deprecated path.confirm WS message (REST only) - Clear ephemeral rules on session delete/stop
…ache-safety tests - Gitignore .openfox/permissions.json (machine-specific, not committable) - Replace inline SVG with EditSmallIcon/TrashIcon in permissions-shared.tsx - Rewrite prompts.permissions.test.ts: meaningful cache-safety contract tests - Remove orphaned permissionRules references from test assertions
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.
Summary
Adds deterministic, server-side permission rules (ALLOW/DENY/ASK) for any tool action. Rules are evaluated in Node (not by the LLM), scoped globally or per-project, and merged at runtime with ephemeral session-scoped rules promoted from ASK via "Allow for this session".
Rule engine (
src/server/permissions/)schema.ts— Zod validation: non-pattern tools (web_fetch,call_sub_agent, ...) restricted to DENY-only, no patternrules.ts—evaluateRulesWithMatchreturns matched rule; precedence DENY (3) > ALLOW (2) > ASK (1)registry.ts— load/savepermissions.json(global:~/.config/openfox/, project:.openfox/)Enforcement (
src/server/chat/,src/server/tools/)agent-loop.ts— per-batch merge of disk rules + ephemeral session rules intobatchContext.permissionRulesexecute-tools.ts—evaluateToolGateDENY-only gate for non-path tools (web_fetch,call_sub_agent, ...)path-security.ts— 3-phase evaluation across all targets (command + paths): DENY throws, ALLOW skips sandbox, ASK prompts. Sub-agents fail-closed on ASK. "Allow for this session" promotes ASK → ephemeral ALLOW--no-verifyand dangerous commands always prompt, even with ALLOW ruleCleanup
index.ts—clearAllowedPathson session delete + stop (purge ephemeral rules)path.confirmWS message (REST only).openfox/permissions.jsongitignored (machine-specific, not committable)UI (
web/src/components/settings/,web/src/components/shared/)permissions-shared.tsx—RuleForm,RuleRow,PermissionsListwith effect/pattern adapting to tool typeProjectSettingsModal.tsx— project-scoped Permission Rules sectionPathConfirmationButtons.tsx— "Allow for this session" button; hidden fordangerous_command/git_no_verifyTests — 155 unit + 3 e2e (DENY blocks, ASK prompts, allow-for-session no re-prompt)
AI-Enhanced Development
Cache Impact
buildTopLevelSystemPrompt), the dynamic context hash (computeDynamicContextHash),loadSessionContext, andbuildCachedPrompt. The KV cache remains stable when rules are edited. Rules are enforced deterministically server-side viapath-security.tsandevaluateToolGate— the LLM discovers DENY by receiving a blocked tool result (1 wasted round-trip), not from the prompt.Test plan
npm run typecheck && npm run lint && npm run test:unitcd e2e && npx vitest run permission-rules.test.tsrun_commandpatternrm -rf *, trigger it → blocked withrule_deniedread_filepattern**/.env*→ reads without sensitive-file promptweb_fetch) → effect dropdown forces DENY, pattern disabled