Execution Plans & Permissions
Relevant source files
The following files were used as context for generating this wiki page:
The Execution Plan and Permissions system in OpenWork serves as a critical safety and transparency layer for agentic workflows. It bridges the gap between an agent's intended actions (the "Execution Plan") and the user's control over those actions through structured permission requests. This system ensures that high-risk operations—such as executing shell commands or modifying files—are audited and approved by the user before execution.
Sources: README.md:46-47, apps/orchestrator/src/cli.ts:1095-1096
Permission Lifecycle and Architecture
OpenWork employs a client-server architecture to manage permissions. When an agent (OpenCode) identifies a task requiring privileged access, it generates a PendingPermission request. This request is managed by the OpenWork server and surfaced to the UI (desktop app) or CLI (orchestrator) for user intervention.
Permission Request Flow
The following sequence diagram illustrates the lifecycle of a permission request from generation to resolution:
The flow ensures that agents cannot bypass user consent for restricted tools.
Sources: apps/server/src/approvals.ts:5-15, apps/orchestrator/src/cli.ts:1140-1150, README.md:120-125
Permission Types and Metadata
Permissions are categorized by the nature of the tool being invoked. Each request carries specific metadata that is surfaced to the user to provide context for the decision.
Core Permission Categories
| Permission Kind | Description | Associated Metadata |
|---|---|---|
bash | Execution of shell commands. | command, cwd (Working Directory) |
edit | Modification of existing files. | filepath, diff (Changes) |
read | Accessing sensitive file content. | path, description |
todowrite | Writing or updating tasks/plans. | task, metadata |
skill | Invoking complex multi-step skills. | tool, patterns |
doom_loop | Detection of repetitive, non-productive tool calls. | tool, patterns |
Sources: apps/app/src/react-app/domains/session/chat/permission-approval-modal.tsx:43-55, apps/app/src/react-app/domains/session/chat/permission-approval-modal.tsx:142-160
Metadata Extraction Logic
The system extracts risk-bearing metadata to render readable summaries in the UI. Key fields include:
- Command: The specific string sent to the shell.
- Diff: A unified diff showing line-by-line changes for file edits.
- Files: A summarized list of file operations (add, delete, change).
- Scope: The patterns or directories the permission applies to.
Sources: apps/app/src/react-app/domains/session/chat/permission-approval-modal.tsx:58-71, apps/app/tests/permission-approval-modal.test.ts:21-35
User Response Mechanisms
Users have three primary ways to respond to a permission request, allowing for a balance between security and workflow efficiency.
- Deny: Rejects the request. The agent receives a failure response and must reconsider its plan.
- Allow Once: Grants permission for the specific instance only. Subsequent identical calls will trigger new prompts.
- Allow for Session (Always): Grants permission for the current session or project scope. The server stores this "Always" rule to auto-approve identical patterns later.
Sources: apps/app/src/react-app/domains/session/chat/permission-approval-modal.tsx:280-305, apps/server/src/approvals.ts:25-30
Approval Mode Configuration
The system can be configured at startup via the CLI to handle approvals automatically or manually:
--approval manual: (Default) Requires user intervention for every new restricted action.--approval auto: Automatically approves requests, typically used in trusted or automated environments.
Sources: apps/orchestrator/src/cli.ts:1115-1120, apps/orchestrator/src/cli.ts:2020-2025
UI Components for Approvals
The React-app provides dedicated components for surfacing these requests:
PermissionApprovalModal
A high-priority AlertDialog used for blocking requests that require immediate user focus. It supports keyboard navigation (Tab-trapping) and Escape-to-deny functionality.
Sources: apps/app/src/react-app/domains/session/chat/permission-approval-modal.tsx:170-200
PermissionApprovalPanel
A more integrated chat-surface component that renders the permission request inline within the conversation flow.
The presentation logic transforms technical identifiers (e.g., todowrite) into readable labels (e.g., "Approve Todo write?").
Sources: apps/app/src/react-app/domains/session/chat/permission-approval-modal.tsx:325-350, apps/app/tests/permission-approval-modal.test.ts:80-85
Implementation Details (CLI/Server)
The openwork-orchestrator manages the backend state of approvals. It exposes endpoints for listing and replying to approvals, allowing the system to be driven entirely via CLI for headless environments.
Orchestrator Approval Commands
openwork approvals list: Retrieves a JSON list of pending requests.openwork approvals reply <id> --allow|--deny: Submits a user decision.
Sources: apps/orchestrator/src/cli.ts:1145-1155, apps/orchestrator/src/cli.ts:2505-2550
Logic Summary
- Validation: Replies are validated to ensure only "allow" or "deny" states are submitted.
- Redaction: Sensitive metadata in logs (like tokens or passwords) is redacted before being stored or surfaced.
- Timeout: Requests are subject to an
approval-timeout(default 30,000ms), after which they may fail if unresolved.
Sources: apps/orchestrator/src/cli.ts:70-75, apps/orchestrator/src/cli.ts:1750-1770, apps/orchestrator/src/cli.ts:2535-2545