Implementation:Ollama Ollama Agent Approval
| Knowledge Sources | |
|---|---|
| Domains | Agent Loop, Security |
| Last Updated | 2025-02-15 00:00 GMT |
Overview
Manages tool execution approval in the agent loop, controlling which commands an LLM agent can run and prompting the user for permission when needed.
Description
Maintains an allowlist and prefix-based allowlist for approved tools. Classifies commands into three categories: auto-allowed (safe read-only commands like git status, ls, go test), denied (dangerous commands like rm -rf, sudo, credential access), and requiring-approval (everything else). Uses a terminal-based interactive selector with numbered options (Execute once / Allow for session / Deny) to prompt users. Supports hierarchical prefix matching so approving cat:tools/ also covers subdirectories.
Usage
Used as the primary safety gate between AI-generated tool calls and actual system execution in the ollama run agent loop.
Code Reference
Source Location
- Repository: Ollama
- File: x/agent/approval.go
- Lines: 1-1125
Signature
type ApprovalDecision int
const (
ApprovalDeny ApprovalDecision = iota
ApprovalOnce
ApprovalAlways
)
type ApprovalResult struct {
Decision ApprovalDecision
DenyReason string
}
type ApprovalManager struct {
allowlist map[string]bool
prefixes map[string]bool
mu sync.RWMutex
}
func NewApprovalManager() *ApprovalManager
func (m *ApprovalManager) IsAutoAllowed(toolName string, args map[string]any) bool
func (m *ApprovalManager) IsDenied(toolName string, args map[string]any) (bool, string)
func ToolDisplayName(toolName string) string
Import
import "github.com/ollama/ollama/x/agent"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| toolName | string | Yes | Name of the tool (e.g. "bash", "web_search") |
| args | map[string]any | Yes | Tool arguments including "command" for bash |
Outputs
| Name | Type | Description |
|---|---|---|
| allowed | bool | Whether the command is auto-allowed |
| denied | bool | Whether the command is auto-denied |
| reason | string | Explanation for denial |
Usage Examples
mgr := agent.NewApprovalManager()
// Check if command is auto-allowed
if mgr.IsAutoAllowed("bash", map[string]any{"command": "git status"}) {
// Execute without prompting
}
// Check if command is denied
if denied, reason := mgr.IsDenied("bash", map[string]any{"command": "rm -rf /"}); denied {
fmt.Println("Denied:", reason)
}