Skip to main content
This guide walks you through installing the Veto SDK, creating an agent, writing a policy with real rules, and running authorization checks to see Veto in action.
You can also create and manage agents and policies in the dashboard at app.veto.tools without writing any code.
1

Install the SDK and set up VetoClient

Install the @useveto/node package:
npm install @useveto/node
Create a VetoClient using your API key. Store the key in an environment variable — never hard-code it.
import { VetoClient } from "@useveto/node";

const veto = new VetoClient({
  apiKey: process.env.VETO_API_KEY!,
});
The client connects to https://api.veto.tools by default. You can override endpoint and timeout if needed:
const veto = new VetoClient({
  apiKey: process.env.VETO_API_KEY!,
  endpoint: "https://api.veto.tools", // default
  timeout: 5000,                       // ms, default
});
2

Create an agent

An agent represents the AI system that will make tool calls. Register it once — Veto uses the agent ID to look up which policies apply.
const agent = await veto.createAgent({
  name: "file-search-bot",
  description: "Reads files and searches the web to answer questions",
});

console.log(agent.id); // save this — you'll use it in every authorize() call
The createAgent call returns an Agent object with an id field. Store that ID in your environment or config.
3

Create a policy

A policy is a set of rules that Veto evaluates against every tool call. This policy:
  • Allows only file.read and web.search (tool allowlist)
  • Constrains file.read so the path parameter must start with /home/user/ (regex)
  • Rate-limits web.search to 50 calls per hour
const policy = await veto.createPolicy({
  agentId: agent.id,
  name: "file-search-policy",
  rules: [
    // Rule 1: only these two tools are permitted
    {
      type: "tool_allowlist",
      tools: ["file.read", "web.search"],
    },

    // Rule 2: file.read path must stay inside the safe directory
    {
      type: "parameter_constraint",
      tools: ["file.read"],
      parameters: {
        path: {
          regex: "^/home/user/",
        },
      },
    },

    // Rule 3: web.search is capped at 50 calls per hour (3600 seconds)
    {
      type: "rate_limit",
      tools: ["web.search"],
      rateLimit: {
        maxCalls: 50,
        windowSeconds: 3600,
      },
    },
  ],
});

console.log(`Policy created: ${policy.id}`);
Veto is default deny: if no policy explicitly allows a tool call, it is blocked. You don’t need to list every denied tool — omitting it from the allowlist is enough.
4

Test an allowed action

Call authorize() with a tool and parameters that your policy permits. Veto evaluates the rules and returns a result synchronously (sub-10ms).
const result = await veto.authorize(agent.id, "file.read", {
  path: "/home/user/documents/report.pdf",
});

console.log(result.allowed);  // true
console.log(result.outcome);  // "allowed"
console.log(result.reason);   // "Allowed by policy "file-search-policy""
The path value matches the regex ^/home/user/ and file.read is in the allowlist, so the call is allowed.
5

Test a denied action — tool not in allowlist

Try calling a tool that is not in the allowlist. Because Veto is default deny, any tool outside your explicit list is blocked.
const result = await veto.authorize(agent.id, "file.delete", {
  path: "/home/user/documents/report.pdf",
});

console.log(result.allowed);  // false
console.log(result.outcome);  // "denied"
console.log(result.reason);
// 'Tool "file.delete" is not in the allowlist [file.read, web.search]'
file.delete was never added to the allowlist, so Veto denies it immediately without executing any handler.
6

Test a parameter violation

Call an allowed tool but pass a parameter value that violates the constraint. Here, path points outside the permitted directory.
const result = await veto.authorize(agent.id, "file.read", {
  path: "/etc/passwd",
});

console.log(result.allowed);  // false
console.log(result.outcome);  // "denied"
console.log(result.reason);
// 'Parameter "path" value "/etc/passwd" does not match pattern /^\/home\/user\//''
The tool is in the allowlist, but the parameter constraint rejects the value before the handler ever runs.

What’s next

  • Explore the full list of rule types: tool_allowlist, tool_denylist, parameter_constraint, rate_limit, time_based
  • Add Veto to an MCP server — see MCP server guide
  • Review every decision your agent made in the audit log