Skip to main content
The Security system evaluates agent actions for potential risks before execution. It provides pluggable security analyzers that assess action risk levels and enforce confirmation policies based on security characteristics. Source: openhands-sdk/penhands/sdk/security/

Core Responsibilities

The Security system has four primary responsibilities:
  1. Risk Assessment - Capture and validate LLM-provided risk levels for actions
  2. Confirmation Policy - Determine when user approval is required based on risk
  3. Action Validation - Enforce security policies before execution
  4. Audit Trail - Record security decisions in event history

Architecture

Key Components

Risk Levels

Security analyzers return one of four risk levels:

Risk Level Definitions

Security Analyzers

LLMSecurityAnalyzer

Leverages the LLM’s inline risk assessment during action generation: Analysis Process:
  1. Schema Enhancement: A required security_risk parameter is added to each tool’s schema
  2. LLM Generation: The LLM generates tool calls with security_risk as part of the arguments
  3. Risk Extraction: The agent extracts the security_risk value from the tool call arguments
  4. ActionEvent Creation: The security risk is stored on the ActionEvent
  5. Analyzer Query: LLMSecurityAnalyzer.security_risk() returns the pre-assigned risk level
  6. No Additional LLM Calls: Risk assessment happens inline—no separate analysis step
Example Tool Call:
The LLM reasons about risk in context when generating the action, eliminating the need for a separate security analysis call. Configuration:
  • Enabled When: A LLMSecurityAnalyzer is configured for the agent
  • Schema Modification: Automatically adds security_risk field to non-read-only tools
  • Zero Overhead: No additional LLM calls or latency beyond normal action generation

NoOpSecurityAnalyzer

Passthrough analyzer that skips analysis: Use Case: Development, trusted environments, or when confirmation mode handles all actions

Confirmation Policy

The confirmation policy determines when user approval is required. There are three policy implementations: Source: confirmation_policy.py

Policy Types

ConfirmRisky (Default Policy)

The most flexible policy with configurable thresholds: Configuration:
  • threshold (default: HIGH) - Risk level at or above which confirmation is required
    • Cannot be set to UNKNOWN
    • Uses reflexive comparison: risk.is_riskier(threshold) returns True if risk >= threshold
  • confirm_unknown (default: True) - Whether UNKNOWN risk requires confirmation

Confirmation Rules by Policy

ConfirmRisky with threshold=HIGH (Default)

ConfirmRisky with threshold=MEDIUM

ConfirmRisky with threshold=LOW

Key Rules:
  • Risk comparison is reflexive: HIGH.is_riskier(HIGH) returns True
  • UNKNOWN handling is configurable via confirm_unknown flag
  • Threshold cannot be UNKNOWN - validated at policy creation time

Component Relationships

Relationship Characteristics:
  • Agent → Security: Validates actions before execution
  • Security → Tools: Examines tool characteristics (annotations)
  • Security → MCP: Uses MCP hints for risk assessment
  • Conversation → Agent: Pauses for user confirmation when required
  • Optional Component: Security analyzer can be disabled for trusted environments

See Also