From the creators of
VulnZapVulnZap

The authorization layerfor browser execution

Control what your AI agents can and cannot do with enforceable tool and data policies. Deterministic guardrails for autonomous AI agents.

Veto terminal interface

The deployment gap

65% are experimenting. Only 11% are shipping.

65%
Piloting AI agents
11%
In production

The blocker isn't capability. It's authorization.

Gartner, 2025

What happens when your agent goes rogue?

run_agent.pypython3
09:41:03
navigategoogle.com/flights
✓ allow
09:41:05
clickbutton#search
✓ allow
09:41:12
navigatepaypal.com/checkout
← no policy
09:41:14
clickbutton#purchase
← no policy
09:41:15
evaluatedocument.cookie
← no policy
$2,847 charged. Credentials exposed. No audit trail.

This is what "autonomous" looks like without authorization.

Every generation builds a permission layer.

1969·Bell Labs gave Unix permissions.

Before: programs destroyed each other.

After: multi-user computing.

1994·Netscape gave the web the padlock.

Before: passwords flew in plaintext.

After: e-commerce.

2008·Apple gave apps the permission dialog.

Before: apps had full device access.

After: the app economy.

2025·Agents have everything.
Where's ours?
Core Features

Authorization primitives

Policy enforcement

Allow, deny, or require approval. Per domain, per action, per selector.

Real-time interception

Every tool call passes through Veto before execution. <5ms overhead.

Human-in-the-loop

Route sensitive actions to Slack, email, or dashboard for approval.

Full audit trail

Every decision logged. Searchable, exportable, compliance-ready.

Declarative policy example

rules:
- action: allow
domains: ["google.com"]
- action: block
domains: ["*checkout*"]
- action: require_approval
selectors: ["button#purchase"]

Drop in. Lock down.

Three lines of code. Full authorization control.

import { chromium } from 'playwright'
import { Veto } from 'veto'
const browser = await chromium.launch()
const page = await browser.newPage()
const tools = [
{
type: 'function',
function: {
name: 'browser_navigate',
description: 'Navigate to a URL',
parameters: {
type: 'object',
properties: {
url: { type: 'string' }
},
required: ['url']
}
}
},
{
type: 'function',
function: {
name: 'browser_click',
description: 'Click a selector',
parameters: {
type: 'object',
properties: {
selector: { type: 'string' }
},
required: ['selector']
}
}
}
]
const toolHandlers = {
browser_navigate: async ({ url }: { url: string }) => page.goto(url),
browser_click: async ({ selector }: { selector: string }) => page.click(selector)
}
const veto = await Veto.init()
const wrappedTools = veto.wrap(tools)
await agent.run('Book a flight under $400', { tools: wrappedTools, toolHandlers })
1
Wrap toolsAgent calls them as usual
2
Validate argumentsPolicies match inputs
3
Enforce decisionsAllow, block, or approve

Works with your stack

Drop-in integration with popular agent frameworks

PlaywrightBrowser automation
Browser UseBrowser-based agents
LangChainLLM framework
LangGraphAgent workflows
CrewAIMulti-agent teams
Vercel AIAI SDK
PydanticAITyped agents
MCPModel Context Protocol

Pricing

Start free. Scale when ready.

Free

$0/mo
  • 10K decisions/mo
  • 1 agent
  • 7-day logs
  • Local policies

Team

$99/mo
  • 100K decisions/mo
  • 10 agents
  • 30-day logs
  • Cloud dashboard

Business

$499/mo
  • 1M decisions/mo
  • Unlimited agents
  • 90-day logs
  • Managed policies

Enterprise

Custom
  • Unlimited decisions
  • Unlimited agents
  • Custom retention
  • Custom policies

Sign up now and we'll notify you when your account is ready.

Sign up with WorkOS

Have a pilot invite code? Enter it here

FAQ

Veto wraps your browser automation library and intercepts every action before execution. Each action is evaluated against your policy rules, which can allow, deny, or require human approval.