Skip to main content
Human-in-the-Loop (HITL) approvals provide a security boundary that prevents autonomous agents from performing sensitive actions without explicit operator consent. The workflow bridges the asynchronous nature of agent runs with interactive decision-making across multiple surfaces (Web Console, CLI, and TUI).

Approval Workflow Overview

When an agent proposes a tool execution that is marked as sensitive or falls outside current policy allowlists, the palyrad daemon suspends the run and creates an ApprovalRecord crates/palyra-daemon/src/journal.rs#58-69. This record acts as a pending request that must be resolved by an authorized principal before the agent can continue.

High-Level Data Flow

The following diagram illustrates the lifecycle of an approval from tool proposal to execution. Diagram: Tool Approval Lifecycle Sources: crates/palyra-daemon/src/gateway.rs#77-82, crates/palyra-daemon/src/journal.rs#58-69, apps/web/src/chat/useChatRunStream.ts#159-161

Decision Scopes and Persistence

Operators can choose the duration and breadth of an approval. These scopes are defined in the ApprovalDecisionScope enum crates/palyra-daemon/src/journal.rs#57-59.
ScopeCode IdentifierDescription
OnceonceValid only for the specific proposal_id currently requested apps/web/src/chat/chatShared.tsx#81.
SessionsessionValid for the current session_id for the remainder of the interaction apps/web/src/chat/chatShared.tsx#81.
TimeboxedtimeboxedValid across all sessions for a specific duration (TTL), typically 5 minutes apps/web/src/chat/chatShared.tsx#28.

Decision Caching

The daemon maintains an internal cache of active approvals to minimize database lookups during high-frequency tool calls. The cache capacity is governed by APPROVAL_DECISION_CACHE_CAPACITY crates/palyra-daemon/src/gateway.rs#102. Sources: crates/palyra-daemon/src/gateway.rs#102, crates/palyra-daemon/src/journal.rs#57-59, apps/web/src/chat/chatShared.tsx#27-28

Implementation Entities

The HITL system is implemented across the JournalStore for persistence and the Gateway for real-time signaling. Diagram: Approval Entity Relationship Sources: crates/palyra-daemon/src/journal.rs#58-71, crates/palyra-daemon/src/gateway.rs#57-63

Key Functions

Console Approval UI

The Web Console provides an interactive interface for managing pending approvals via the ChatConsolePanel apps/web/src/chat/ChatConsolePanel.tsx#81.

UI Components

State Management

The useChatRunStream hook manages the local state of pending approvals using approvalDrafts apps/web/src/chat/ChatConsolePanel.tsx#146. When an operator clicks “Approve” or “Deny”, the decideInlineApproval function is called apps/web/src/chat/ChatConsolePanel.tsx#160, which transmits the decision via the ConsoleApiClient. Sources: apps/web/src/chat/ChatConsolePanel.tsx#81-160, apps/web/src/chat/chatShared.tsx#141-221

CLI Approval Commands

The palyra CLI provides a set of commands for auditing and resolving approvals from the terminal. These commands are defined in the approvals module crates/palyra-cli/src/commands/approvals.rs.

Command Tree

  • palyra approvals list: Displays all pending and historical approval records.
  • palyra approvals approve <id>: Grants permission for a specific record.
  • palyra approvals deny <id>: Rejects a specific record.
  • palyra approvals export: Exports the approval history in NDJSON format for external auditing crates/palyra-daemon/src/gateway.rs#111-113.

Constraints and Safety

Sources: crates/palyra-cli/src/commands/approvals.rs, crates/palyra-daemon/src/gateway.rs#108-113