# gautampartha/agent-spend-policy-guard- architecture

> Architecture diagram of the GitHub repository gautampartha/agent-spend-policy-guard-, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-09). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/gautampartha/agent-spend-policy-guard-
- Repository: https://github.com/gautampartha/agent-spend-policy-guard-

## Overview

#### Purpose and entry points
Agent Spend Policy Guard is a paid pre-payment authorization service for autonomous agents. It evaluates a proposed USDC spend against deterministic limits and records approved spend. The HTTP service starts from `server/app.py`; production runs Gunicorn through `server/Procfile`. Agents can exercise the paid flow through `client/demo_agent.py`.

#### HTTP and payment boundary
Flask exposes free health and policy-registration endpoints plus x402-protected policy check and status endpoints in `server/app.py`. x402 middleware challenges an unpaid request with HTTP 402, then validates an `X-PAYMENT` retry before route logic runs. This separates payment authorization for the guard service from the agent’s proposed downstream purchase.

#### Policy lifecycle
Registration accepts an agent ID, daily cap, per-transaction cap, and allowed categories. The deterministic decision engine in `server/policy_engine.py` loads the registered policy, validates request fields, rejects disallowed categories or cap violations, and returns approval state, reason, and remaining budget. No LLM or probabilistic decision layer is involved.

#### Spend accounting and persistence
SQLite access and schema/query operations live in `server/db.py`. Approved checks are persisted as spend records and accumulated by day to enforce daily budgets; denied checks do not consume the agent’s policy budget. SQLite is the key local consistency boundary and would need replacement for safe concurrent production writes.

#### x402 / Algorand settlement
The service uses `x402-avm` configured from `server/config.py` and environment values documented in `server/.env.example`. Payment verification and settlement are delegated to the GoPlausible facilitator, which submits USDC ASA transfers on Algorand Testnet. The resource-owner address receives check micropayments; the client key signs them.

#### Agent-side signing and operational setup
`client/signer.py` implements the AVM signer using Algorand SDK primitives, while `client/demo_agent.py` submits check requests and handles the 402/retry protocol. Testnet account provisioning, ASA opt-in, and balance inspection are isolated in `scripts/setup_testnet_account.py`, `scripts/opt_in_usdc.py`, and `scripts/check_balance.py`.

#### Runtime and deployment
The runtime is Python/Flask with SQLite, Algorand Testnet USDC, and the external facilitator service. Render deployment is defined by `render.yaml`; secrets remain environment-managed rather than committed. The application’s externally visible deployment boundary is the Flask/Gunicorn service, with blockchain settlement handled asynchronously through the facilitator integration.

Main entry points: [`server/app.py`](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/app.py) (Flask API), [`server/policy_engine.py`](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/policy_engine.py) (Policy Engine), [`client/demo_agent.py`](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/client/demo_agent.py) (Demo Agent), [`server/db.py`](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/db.py) (SQLite Access)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_server["Guard Service"]
  node_flask_app["Flask API<br/>HTTP service<br/>[app.py]"]
  node_x402_middleware{{"x402 Middleware<br/>payment gate<br/>[app.py]"}}
  node_policy_engine["Policy Engine<br/>deterministic rules<br/>[policy_engine.py]"]
  node_database_layer[("SQLite Access<br/>persistence layer<br/>[db.py]")]
  node_sqlite[("SQLite Store<br/>local database")]
  node_service_config["Service Config<br/>x402 configuration<br/>[config.py]"]
  node_gunicorn["Gunicorn Runtime<br/>production process"]
  node_render["Render Deployment<br/>deployment platform<br/>[render.yaml]"]
end

subgraph group_client["Agent Client"]
  node_demo_agent["Demo Agent<br/>Python client<br/>[demo_agent.py]"]
  node_signer["AVM Signer<br/>Algorand signer<br/>[signer.py]"]
  node_account_setup["Testnet Account Setup<br/>provisioning script"]
  node_usdc_opt_in["USDC Opt-In<br/>provisioning script<br/>[opt_in_usdc.py]"]
  node_balance_check["Balance Check<br/>operations script<br/>[check_balance.py]"]
end

subgraph group_external["Settlement Network"]
  node_facilitator{{"GoPlausible Facilitator<br/>x402 facilitator"}}
  node_algorand(("Algorand Testnet<br/>blockchain network"))
  node_usdc(("Testnet USDC ASA<br/>payment asset"))
end

node_demo_agent -->|"signs payment retry"| node_signer
node_demo_agent -->|"registers policy and requests check"| node_flask_app
node_flask_app -->|"protects paid routes"| node_x402_middleware
node_x402_middleware -->|"verifies X-PAYMENT"| node_facilitator
node_x402_middleware -->|"allows validated retries"| node_policy_engine
node_flask_app -->|"handles registration and checks"| node_policy_engine
node_policy_engine -->|"loads policy and records approvals"| node_database_layer
node_database_layer -->|"reads and writes"| node_sqlite
node_service_config -->|"configures x402-avm"| node_x402_middleware
node_gunicorn -->|"serves"| node_flask_app
node_render -->|"deploys"| node_gunicorn
node_facilitator -->|"submits settlement"| node_algorand
node_algorand -->|"transfers"| node_usdc
node_account_setup -.->|"prepares account"| node_usdc_opt_in
node_usdc_opt_in -.->|"enables asset holding"| node_usdc
node_balance_check -.->|"queries balance"| node_algorand

click node_demo_agent "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/client/demo_agent.py"
click node_signer "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/client/signer.py"
click node_flask_app "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/app.py"
click node_x402_middleware "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/app.py"
click node_policy_engine "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/policy_engine.py"
click node_database_layer "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/db.py"
click node_service_config "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/config.py"
click node_gunicorn "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/Procfile"
click node_render "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/render.yaml"
click node_account_setup "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/scripts/setup_testnet_account.py"
click node_usdc_opt_in "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/scripts/opt_in_usdc.py"
click node_balance_check "https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/scripts/check_balance.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_flask_app,node_x402_middleware,node_policy_engine,node_database_layer,node_sqlite,node_service_config,node_gunicorn,node_render toneBlue
class node_demo_agent,node_signer,node_account_setup,node_usdc_opt_in,node_balance_check toneAmber
class node_facilitator,node_algorand,node_usdc toneMint
```

## Components

### Guard Service

Flask authorization service and policy accounting.

- [Flask API](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/app.py): HTTP service · Exposes health, registration, protected checks, and status endpoints. · `server/app.py`
- [x402 Middleware](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/app.py): payment gate · Issues 402 challenges and validates X-PAYMENT retries before protected routes. · `server/app.py`
- [Policy Engine](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/policy_engine.py): deterministic rules · Validates spend proposals against registered limits and categories. · `server/policy_engine.py`
- [SQLite Access](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/db.py): persistence layer · Owns schema and policy/spend queries. · `server/db.py`
- **SQLite Store**: local database · Consistency boundary for policies and approved daily spend.
- [Service Config](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/config.py): x402 configuration · Configures x402-avm from environment-managed values. · `server/config.py`
- [Gunicorn Runtime](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/server/Procfile): production process · Runs the Flask service in production. · `server/Procfile`
- [Render Deployment](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/render.yaml): deployment platform · Defines the external service deployment. · `render.yaml`

### Agent Client

Agent request and payment signing flow.

- [Demo Agent](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/client/demo_agent.py): Python client · Exercises the paid policy-check flow. · `client/demo_agent.py`
- [AVM Signer](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/client/signer.py): Algorand signer · Signs x402 payment retries with the client key. · `client/signer.py`
- [Testnet Account Setup](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/scripts/setup_testnet_account.py): provisioning script · Provisions accounts for testnet use. · `scripts/setup_testnet_account.py`
- [USDC Opt-In](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/scripts/opt_in_usdc.py): provisioning script · Opts an account into the USDC ASA. · `scripts/opt_in_usdc.py`
- [Balance Check](https://github.com/gautampartha/agent-spend-policy-guard-/blob/main/scripts/check_balance.py): operations script · Inspects testnet account balances. · `scripts/check_balance.py`

### Settlement Network

External x402 facilitation and Algorand settlement.

- **GoPlausible Facilitator**: x402 facilitator · Verifies payment and submits settlement transactions.
- **Algorand Testnet**: blockchain network · Settles USDC ASA check micropayments.
- **Testnet USDC ASA**: payment asset

## Connections

- Demo Agent → AVM Signer: signs payment retry
- Demo Agent → Flask API: registers policy and requests check
- Flask API → x402 Middleware: protects paid routes
- x402 Middleware → GoPlausible Facilitator: verifies X-PAYMENT
- x402 Middleware → Policy Engine: allows validated retries
- Flask API → Policy Engine: handles registration and checks
- Policy Engine → SQLite Access: loads policy and records approvals
- SQLite Access → SQLite Store: reads and writes
- Service Config → x402 Middleware: configures x402-avm
- Gunicorn Runtime → Flask API: serves
- Render Deployment → Gunicorn Runtime: deploys
- GoPlausible Facilitator → Algorand Testnet: submits settlement
- Algorand Testnet → Testnet USDC ASA: transfers
- Testnet Account Setup → USDC Opt-In: prepares account
- USDC Opt-In → Testnet USDC ASA: enables asset holding
- Balance Check → Algorand Testnet: queries balance
