Architecture overview
Veto acts as a transparent proxy layer that wraps your tools without changing their interface:The interception flow
When you wrap your tools with Veto, it creates a validation layer that intercepts every call:Validation process
When the agent calls a tool, Veto follows this validation flow:Rule matching
Veto uses a two-step process to determine which rules apply:- Tool-specific rules — Rules with a matching
toolslist - Global rules — Rules with no
toolsfield (apply to every call)
Condition evaluation
Conditions are evaluated in order until one matches. Veto prioritizes deterministic conditions for performance:- Static conditions
- Expression conditions
Decision flow
Once a rule matches, Veto takes action based on the rule’saction field:
Block
Denies the tool call and throws an error:Allow
Explicitly allows the tool call to proceed. Useful for whitelisting specific patterns:Require approval
Routes the call to a human approval workflow. See Human-in-the-loop for details.Warn and Log
Non-blocking actions that record the event without stopping execution:- warn — Logs a warning message (severity: warning)
- log — Logs an info message (severity: info)
History tracking
Veto maintains a call history for each session, enabling:- Sequential rules — Block actions based on previous calls
- Rate limiting — Prevent repeated sensitive operations
- Audit trails — Export complete decision history
Sequential rules example
Exporting decisions
Performance characteristics
- Deterministic conditions: ~0.1ms overhead (local evaluation)
- Expression conditions: ~0.5ms overhead (AST evaluation)
- No network calls for local validation mode
- Type preservation: Wrapped tools maintain full TypeScript types
- Zero runtime dependencies beyond your chosen validation mode
Next steps
Rules
Learn the complete YAML rule format
Validation modes
Choose between local, API, or cloud validation
Human-in-the-loop
Set up approval workflows
Writing rules
Best practices for rule design

