Skip to main content

Local-runtime spend caps and capability-gated model routing for AI agents. Prompts, API keys, and signing keys stay inside the customer runtime. Zero data plane involvement.

Project description

agentguard-spend (Python)

Local-runtime spend caps and capability-gated model routing for AI agents.

Also available in: Español (LATAM) · Português (BR)

Python 3.10+ port of @agentguard-run/spend. Byte-identical decision-log format and Ed25519 signing — verifiable across both runtimes with the same public key.

Every policy decision runs inside your process. Prompts, provider API keys, and signing keys never leave your runtime. Each enforcement decision produces an Ed25519-signed, hash-chained receipt suitable for audit and compliance review.

Why no proxy

Every funded competitor in AI spend governance (Portkey, Helicone, LiteLLM, Cloudflare AI Gateway, Vercel AI Gateway) proxies your traffic. That means your prompts and provider keys flow through their infrastructure. agentguard-spend never sees any of that. The policy runs in your process. The signed log lives in your storage.

The procurement consequence: your security review covers this SDK like any other library, not like a vendor that handles your data.

Status

Private preview. Designed for enterprise, OEM, and platform integration.

For evaluation access, OEM licensing, or strategic partnership inquiries: invest@agentguard.run

Install

pip install agentguard-spend
# Optional provider extras:
pip install "agentguard-spend[openai]"
pip install "agentguard-spend[anthropic]"
pip install "agentguard-spend[bedrock]"
# Or all of them:
pip install "agentguard-spend[all]"

Production dependency: cryptography>=42 (for Ed25519). The provider SDKs (openai, anthropic, boto3) are peer/optional; install only what you use.

Quickstart

import asyncio
from openai import OpenAI

from agentguard_spend import (
    SpendPolicy,
    SpendScope,
    SpendCap,
    SigningKeys,
    SpendGuardConfig,
    InMemorySpendStore,
    InMemoryDecisionLogStore,
    generate_keypair,
    with_spend_guard,
)

# Generate or load signing keys. They never leave your runtime.
# In production these come from your HSM / KMS / Vault.
private_key, public_key = generate_keypair()  # 32-byte seed + 32-byte pubkey

policy = SpendPolicy(
    id="finance-ops-v1",
    name="Finance ops daily caps",
    scope=SpendScope(tenantId="acme-corp"),
    caps=[
        SpendCap(
            amountCents=500,
            window="per_day",
            action="downgrade",
            downgradeTo="claude-sonnet-4-6",
            reason="Opus daily soft cap reached, route to Sonnet",
        ),
        SpendCap(
            amountCents=1000,
            window="per_day",
            action="block",
            reason="Hard daily ceiling",
        ),
    ],
    mode="enforce",
    version=1,
    effectiveFrom="2026-05-23T00:00:00.000Z",
)

openai_client = OpenAI()
guarded = with_spend_guard(
    openai_client,
    policy=policy,
    scope=SpendScope(tenantId="acme-corp", userId="alice", agentId="finance-bot"),
    config=SpendGuardConfig(
        policy=policy,
        spendStore=InMemorySpendStore(),
        logStore=InMemoryDecisionLogStore(),
        signingKeys=SigningKeys(privateKey=private_key, publicKey=public_key),
    ),
)

# Drop-in: same API as openai.chat.completions.create
completion = guarded.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello"}],
)

When the policy fires:

Action Result
allow Call passes through unchanged
downgrade The model parameter is rewritten to downgradeTo, then the call proceeds
block An AgentGuardBlockedError is raised before the provider is contacted
shadow Call passes through; the decision is logged for analysis only

Anthropic and Bedrock bindings

from anthropic import Anthropic
from agentguard_spend.bindings import with_anthropic_spend_guard

raw = Anthropic()
guarded = with_anthropic_spend_guard(
    raw,
    policy=policy,
    scope=SpendScope(tenantId="acme-corp"),
)
guarded.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
)
import boto3
from agentguard_spend.bindings import with_bedrock_spend_guard

raw = boto3.client("bedrock-runtime")
guarded = with_bedrock_spend_guard(
    raw,
    policy=policy,
    scope=SpendScope(tenantId="acme-corp"),
)
guarded.invoke_model(
    modelId="anthropic.claude-sonnet-4-v1:0",
    body=b'{"messages":[{"role":"user","content":"hi"}],"max_tokens":256}',
)

Capability-gated escalation

You can require a capability tier on a policy:

policy = SpendPolicy(
    # ...
    requiredCapability="payment_initiate",
)

Calls that do not present a capabilityClaim at or above this tier are blocked immediately. Tiers (ascending): read_only < data_write < payment_initiate < payment_execute.

Verifying a signed log

Anyone with the public key can verify the chain:

from agentguard_spend import verify_chain

entries = await load_entries()  # from your storage
result = await verify_chain(entries, public_key)
if not result.ok:
    print(f"chain invalid at sequence {result.sequence}: {result.reason}")

Each entry binds the previous entry's hash via SHA-256 and is signed with Ed25519. Tampering with any field of any entry invalidates the chain from that point forward.

Cross-language interoperability

agentguard-spend (Python) and @agentguard-run/spend (TypeScript) produce byte-identical canonical-JSON serialization for the same SpendDecision. That means an Ed25519 signature created in either runtime verifies in the other. The repo includes a cross-language parity test:

  • Fixture: test_vectors/fixed_decision.json
  • TS reference generator: test_vectors/compute_expected_ts.js
  • Python assertion: tests/test_cross_language_parity.py

License and usage thresholds

The SDK is free for:

  • Evaluation, prototyping, and non-commercial development at any volume
  • Production deployments processing up to 10,000 enforcement calls per calendar month

A separate commercial license is required for:

  • Production deployments processing more than 10,000 enforcement calls per month
  • Deployments operated as a service to third parties
  • Redistribution, sublicensing, public hosting, republication

Inbound commercial-license inquiries: invest@agentguard.run

Full terms in LICENSE. All patent rights expressly reserved (see Section 2 of LICENSE).

Patent notice

Protected by 6 U.S. patent-pending applications:

  • 63/983,615 · 63/983,621 · 63/983,843 · 63/984,626 (filed February 2026)
  • 64/071,781 · 64/071,789 (filed May 21, 2026)

See LICENSE Section 7 and PATENTS.md.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentguard_spend-0.1.4.tar.gz (26.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentguard_spend-0.1.4-py3-none-any.whl (37.0 kB view details)

Uploaded Python 3

File details

Details for the file agentguard_spend-0.1.4.tar.gz.

File metadata

  • Download URL: agentguard_spend-0.1.4.tar.gz
  • Upload date:
  • Size: 26.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for agentguard_spend-0.1.4.tar.gz
Algorithm Hash digest
SHA256 b6b7a9bcc3a5db98b254c0a8c3d2c9bbdab5561b0b6e5f3866655f48429d1187
MD5 3c00e227db8085e2e8470784738486dd
BLAKE2b-256 489512b195521a223af48df33a97e5cf8aebf0228a0febc70631b5d7d20dbc0b

See more details on using hashes here.

File details

Details for the file agentguard_spend-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: agentguard_spend-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 37.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for agentguard_spend-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 a353384a4a07cea08a748f2c1990f80f96c6bf3c8a1df564757612cfcd6992d1
MD5 c48e542056294e7be2e03b20719c51a9
BLAKE2b-256 a9df1cd602db9696d02c73512714ba4cbf8eea6789f4890bcffc5639d1de05a1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page