openhands-sdk/penhands/sdk/security/
Core Responsibilities
The Security system has four primary responsibilities:- Risk Assessment - Capture and validate LLM-provided risk levels for actions
- Confirmation Policy - Determine when user approval is required based on risk
- Action Validation - Enforce security policies before execution
- 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:- Schema Enhancement: A required
security_riskparameter is added to each tool’s schema - LLM Generation: The LLM generates tool calls with
security_riskas part of the arguments - Risk Extraction: The agent extracts the
security_riskvalue from the tool call arguments - ActionEvent Creation: The security risk is stored on the
ActionEvent - Analyzer Query:
LLMSecurityAnalyzer.security_risk()returns the pre-assigned risk level - No Additional LLM Calls: Risk assessment happens inline—no separate analysis step
- Enabled When: A
LLMSecurityAnalyzeris configured for the agent - Schema Modification: Automatically adds
security_riskfield 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 actionsConfirmation 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)returnsTrueifrisk >= threshold
- Cannot be set to
confirm_unknown(default:True) - WhetherUNKNOWNrisk 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)returnsTrue - UNKNOWN handling is configurable via
confirm_unknownflag - 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
- Agent Architecture - How agents use security analyzers
- Tool System - Tool annotations and metadata; includes MCP tool hints
- Security Guide - Configuring security policies

