Top 1% Upwork (8 years) 286+ client deployments 2,036+ projects shipped GoHighLevel Certified Partner Featured speaker: GHL Summit 2025 Client Login
← All issues
The Scale Brief · Issue #148

Your agent has every tool every turn.
That's a security and quality problem.

Look at your agent's tool registry. Count the tools. Now imagine the agent has access to all of them on every single turn — including the turn where the user just said "hi".

The default in most agent frameworks is to hand the full tool list to the model on every turn. The model picks. This is the "we trust the model" school of thought. It works fine until it doesn't.

Two failure modes show up reliably:

  1. Quality drift. The model sees 12 tools but the current turn only needs one of them. It picks a similar-looking wrong tool. The user gets a polite but irrelevant response. This happens far more than agent builders admit.
  2. Privilege escalation. A jailbroken or confused user gets the model to invoke cancel_subscription from a billing-inquiry conversation. Or worse: send_email_to(arbitrary_address) with content the user dictated. The tools were "available," so the model used them.

Both go away under least-privilege tool access: each turn gets only the tools that match the detected intent. Default deny. Explicit grants. The same rule that secured Unix syscalls 50 years ago.

The pattern

One intent classifier + one tool gate. The classifier was the subject of Issue #147 — a cheap-model planner that outputs structured JSON: { intent, tool, args, needs_reasoning }. Today's pattern is what happens between the classifier and the executor.

The gate is a small map: intent → allowed tools. When the executor goes to run, it filters the model's tool list down to only what the gate allows for the classified intent. Anything outside the allowlist is unavailable to that turn's model call — not refused, not visible.

const INTENT_TOOLS = {
  balance_query:    ['get_account'],
  schedule_call:    ['book_calendar', 'list_calendar_slots'],
  cancel_order:     ['lookup_order', 'cancel_order'],
  billing_question: ['lookup_billing', 'get_account'],
  greeting:         [],  // no tools — agent just talks
  free_form:        ['get_account', 'lookup_order', 'lookup_billing']  // fallback, narrow
};

async function gatedExecutor(plan, fullToolRegistry) {
  const allowed = INTENT_TOOLS[plan.intent] || [];
  const scopedTools = fullToolRegistry.filter(t => allowed.includes(t.name));

  // Audit log: every tool-gate decision logged for review
  log({ event: 'tool_gate', intent: plan.intent, allowed, requested: plan.tool });

  if (plan.tool && !allowed.includes(plan.tool)) {
    // Planner asked for a tool that's not allowed for this intent.
    // Don't silently retry — surface it so the gate map can be refined.
    return { error: 'gate_violation', intent: plan.intent, tool: plan.tool };
  }
  return await runWithTools(plan, scopedTools);
}

The greeting intent has zero tools. The balance_query has exactly one. cancel_order requires two consecutive tools (lookup then cancel) which means the agent literally cannot cancel something without first having looked it up.

What this fixes

The edge cases

The dashboard signal

One number tells you whether the gate is well-tuned: gate-violation rate per intent. High violation rate on a specific intent means the classifier is misclassifying that intent (or the gate is too narrow). Zero violations across the board for a week of traffic means either the gate is correctly calibrated, or your classifier is so cautious it never recommends a tool — both worth investigating.

The audit pattern

For every agent we deploy at AutomateScale: explicit INTENT_TOOLS map + tool-gate executor + audit log of every gate decision. The gate sits between the planner from Issue #147 and the executor. It's where security review happens. Want us to audit yours? Apply for the audit.

The one-line summary

Every tool your agent has is a tool a jailbroken prompt can invoke. Default deny + explicit per-intent grants is what 50 years of Unix taught us about least-privilege — and what most agent frameworks unlearned. Ship the gate before the next CVE-shaped surprise.

Enjoyed this? One essay like this every Sunday — 12,400+ founders read it.
Subscribe free RSS

Keep reading

Issue #147
The Cheap-Model Planner: Route, Don't Reason
Planner pattern this gate sits behind.
Issue #149
Idempotency Keys For Agent Actions
The retry-safety layer that pairs with this gate.
Issue #150 · NEW
12 Business Automations + The OS That Makes Them Compound
Why scattered automation can't compound — and the business-OS architecture that fixes it.
★★★★★

"I highly recommend Adam and his team. They are exceptional."

Digital Marketing Automation | Funnel setup · 3.8h·2021 · Upwork verified →
★★★★★

"I highly recommend Adam and his team. They are exceptional."

Digital Marketing Automation | Funnel setup · 3.8h·2021·Upwork verified → · Upwork ✓
★★★★★

"Adam was very helpful and made time to discuss my project on short notice. He clearly knows his stuff and provided useful insights. I'd recommend working with him."

60 minute consultation · 2024·Upwork verified → · Upwork ✓
Run the audit on your agents

The Scale Audit ships the gate
+ 24 other patterns on every deploy.

Apply for an audit and we'll ship the INTENT_TOOLS map + gate executor + audit log as part of the engagement.

Apply for a free audit All issues