Each action sends a fixed demo policy, caller-declared capability, and action metadata to /api/gate/authorize. The endpoint evaluates those supplied fields and signs the result. A separate first-party route at /api/verify recomputes the signature check. No payment provider is called.
This sandbox signs an evaluation of browser-supplied metadata. It does not authenticate the policy or capability claim, dispatch a tool, or call a payment provider.
The hosted endpoint evaluates metadata and returns a decision. The demo contains no Stripe client and performs no refund or payout.
The endpoint compares the supplied action, amount, capability claim, spend-to-date value, and policy rules. It does not authenticate those fields or implement expiry, replay, or idempotency checks.
Allow, escalate, and block results produce standalone Ed25519 receipts. The signature protects the recorded fields from later editing; it does not prove human authorization.
This fixed demo sends metadata only. The endpoint rejects reserved content keys and long strings, but integrators must still keep personal data and secrets out of caller-controlled metadata fields.
The SDK can evaluate configured tool policy before invoking an executor. Your application must keep the raw provider client outside the agent's tool registry and configure the policy, signing keys, and decision-log storage it needs.
// wrap the one function that moves money import { SpendGuard } from "@agentguard-run/spend"; const guard = new SpendGuard({ policy, signingKeys }); // the agent calls refund() instead of the raw Stripe call. // dispatchToolCall evaluates configured policy before it calls Stripe. // A block or escalation throws AgentGuardBlockedError, so this executor is not called. const refund = (orderId, amount) => guard.dispatchToolCall( { scope: "money:refund", toolName: "refund_customer", toolArgs: { orderId, amount } }, (args) => stripe.refunds.create(args) );
# wrap the one function that moves money from agentguard_spend import SpendGuard guard = SpendGuard(config) # dispatch_tool_call raises AgentGuardBlockedError when tool policy refuses. async def refund_customer(order_id, amount): return await guard.dispatch_tool_call( {"scope": "money:refund", "toolName": "refund_customer", "toolArgs": {"order_id": order_id, "amount": amount}}, lambda args: stripe.Refund.create(**args), )
Fair question, and the honest answer matters. In your integration, keep the raw Stripe client outside the agent's tool registry and expose only the wrapped function. dispatchToolCall invokes that executor only after the configured policy approves, so this protection depends on your application not exposing a bypass path. With signing configured, AgentGuard records the application-supplied request metadata and policy result in a content-free receipt whose signed fields can be checked later. It does not custody funds or proxy provider traffic.
Install the SDK and wrap the tool in your own runtime. The package license permits production use through 10,000 enforcement calls per calendar month.