paybondpaybond
Sign in

Spend controls for Google ADK tools

Harbor verify before FunctionTool execute, auto-evidence after success, and policy budgets for Google ADK — TypeScript and Python.

Google ADK agents run tools through FunctionTool.execute. Paybond hooks that boundary — Harbor verifies spend before side effects and auto-submits evidence after success — not as model middleware.

Install @paybond/google-adk (npm) with @google/adk, or paybond-kit[google-adk] (pip). Adapter reference: /docs/kit/google-adk.

  • Harbor verify before execute

    Wrapped FunctionTool handlers authorize operation and amount before paid work.

  • Auto-evidence

    Guarded tools finalize spend and submit signed evidence after success.

  • Policy budgets

    Versioned YAML caps per-call and intent spend for Gemini and GCP agents.

  • TypeScript and Python

    Same google-adk adapter on npm (@paybond/google-adk) and pip (paybond-kit[google-adk]).

Why Paybond (not just ADK callbacks)?

ADK before_tool_callback and host confirmations do not enforce Harbor spend budgets, capability tokens, or signed completion evidence bound to an intent.

Google ADK callbacks alone versus Paybond Harbor spend controls
  • Model / input guardrails

    ADK callbacks alone
    Yes — SDK or host checks and approvals
    With Paybond
    Yes — plus Harbor authorize at the tool boundary
  • Spend boundary

    ADK callbacks alone
    No per-tool Harbor budget or capability token
    With Paybond
    Per-call and intent budgets enforced before invoke
  • Signed evidence

    ADK callbacks alone
    SDK traces / logs only
    With Paybond
    Signed completion digests bound to the intent
  • Intent binding

    ADK callbacks alone
    No Harbor intent or settlement receipt
    With Paybond
    Capability token + intentId from authenticated bind
  • Paid tool deny / HITL

    ADK callbacks alone
    Host or SDK approvals only
    With Paybond
    Harbor verify, deny, or HITL hold before side effects

How it works

Paybond wraps Google ADK FunctionTool execute: Harbor authorize before your handler runs, then auto-evidence after success.

Adapter flow

  1. FunctionTool.execute

    Google ADK agent invokes a side-effecting tool

  2. Paybond wrap

    Harbor authorize before your handler runs

    • Verify spend and operation
    • Deny or HITL hold
    • Issue / check capability
  3. Tool runs

    Your execute handler performs the paid work

  4. Evidence

    Wrapped tool finalizes spend and auto-evidence

Paybond wraps Google ADK FunctionTool execute: Harbor authorize before your handler runs, then auto-evidence after success.

Tool boundary, not model middleware

Paybond wraps FunctionTool.execute (or rebuilds guarded tools) so Harbor authorize runs before your handler and auto-evidence fires after success. Read-only registry tools pass through unchanged. Use Paybond A2A card/contracts discovery beside ADK RemoteA2aAgent — each agent that executes paid tools must wrap locally; there is no A2A spend proxy in v1.

3-minute quickstart

Smoke the google-adk adapter Harbor contract — no Gemini credentials required for this check:

Terminal
Terminal commandSwipe to inspect long lines
paybond login
paybond agent demo google-adk smoke \
  --operation paid-tool \
  --requested-spend-cents 100 \
  --evidence-preset cost_and_completion \
  --format table

Install first:

Terminal
Terminal commandSwipe to inspect long lines
# TypeScript
npm install @paybond/google-adk @google/adk
# Python
pip install "paybond-kit[google-adk]"

When the smoke succeeds you should see:

  • ✓ Spend approved
  • ✓ Tool completed
  • ✓ Evidence verified (cost_and_completion)

What success looks like

Example status after a Paybond-guarded Google ADK tool call: approved spend, requested amount, and verified cost_and_completion evidence.

What success looks like

Authorized tool call · illustrative

Sandbox path
Operation
paid-tool
Status
Approved
Requested
$1.00
Evidence
Verified
Preset
cost_and_completion

Scaffold

Terminal
Terminal commandSwipe to inspect long lines
# TypeScript
paybond init agent-middleware --framework google-adk --out paybond-google-adk.ts
# Python
paybond init agent-middleware --framework google-adk --out paybond_google_adk.py
paybond policy init --preset saas --out paybond.policy.yaml

Validate before deploy:

Terminal
Terminal commandSwipe to inspect long lines
paybond policy validate-tools --file paybond.policy.yaml --local-only

Wire middleware

Recommended wiring

paybond.agent with framework google-adk returns guarded tools for your LlmAgent.

paybond-session.ts

TS
Code exampleSwipe to inspect long lines
import { FunctionTool, LlmAgent } from "@google/adk";
import { Paybond } from "@paybond/kit";

const paybond = await Paybond.open({ apiKey: process.env.PAYBOND_API_KEY! });

const bookHotelTool = new FunctionTool({
  name: "travel.book_hotel",
  description: "Book a hotel room",
  parameters: {
    type: "object",
    properties: {
      city: { type: "string" },
      estimatedPriceCents: { type: "integer", minimum: 0 },
    },
    required: ["city", "estimatedPriceCents"],
  },
  execute: async (args) => bookHotel(args),
});

const { agentTools: tools } = await paybond.agent({
  policy: "saas",
  framework: "google-adk",
  tools: [bookHotelTool, searchWebTool],
});

const agent = new LlmAgent({ name: "Travel", tools });

Manual hook wiring

When you already bound a PaybondAgentRun:

paybond-session.ts

TS
Code exampleSwipe to inspect long lines
import { createPaybondGoogleAdkConfig } from "@paybond/google-adk";

const config = createPaybondGoogleAdkConfig(run, sdkTools);
const guardedTools = config.tools;

Approval holds: when Harbor returns an approval hold, Python guarded tools raise RuntimeError with a Paybond message; TypeScript rethrows a clear Error (Paybond capability approval required: …) with the Harbor error as cause. Approve in the tenant console, store the approval token on the run with the ADK functionCallId, then retry with the same operation, amount, metadata, and approvalToken. Hard denials must not execute the tool.

Bypass classes: GOOGLE_SEARCH and ADK built-ins, unwrapped tools, AgentTool / RemoteA2aAgent remote hops, and before_tool_callback-only checks are not governed.

Production: omit sandbox defaults on paybond.agent() / paybond.instrument(), use deferred bind, then instrumented.bind({ intentId, capabilityToken }) per session. Tenant and intent IDs come from the Paybond session binding — never from unauthenticated tool args.

Production checklist

Production checklist for Paybond-guarded Google ADK tools.

Production checklist

Works with

Works with

  • Gemini
  • OpenAI
  • Anthropic
  • MCP

Ready to test?

Developer reference: /docs/kit/google-adk.