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 Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

agentguard_spend-0.1.9-py3-none-any.whl (74.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: agentguard_spend-0.1.9-py3-none-any.whl
  • Upload date:
  • Size: 74.8 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.9-py3-none-any.whl
Algorithm Hash digest
SHA256 f0149f512b60865008c88155ed0db6750983ac342218e4f069e6f1cd03a1832d
MD5 8c8f9c45b10d9afac93d0522f2ea48ee
BLAKE2b-256 49686c3344e8fd3d9e190839788cbc1f49dd568034a568c251fa196720cc50c0

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