Human approval middleware for Python tool calls.
ApproveKit wraps ordinary Python functions. It evaluates policy before execution, blocks risky calls for human review, and records final decisions in SQLite.
Architecture
Full request lifecycle — from agent runtime through policy evaluation and human review to audit persistence.
Install
pip install approvekit
The MVP targets Python 3.9+ and only requires PyYAML at runtime.
Guard Tools
from approvekit import ApproveKit, Policy, Storage
policy = Policy.from_yaml("policy.yaml")
storage = Storage(db_path="/tmp/approvekit.db")
kit = ApproveKit(policy=policy, storage=storage)
@kit.guard
def prod_write(key: str, value: dict) -> dict:
return {"status": "written", "key": key}
If policy requires approval, the function body does not run until a reviewer approves the request.
Policy
default_timeout: 60
rules:
- tool: prod_write
require_approval: true
timeout: 30
risk_level: high
redact_fields: [value]
- tool: read_record
require_approval: false
auto_approve: true
risk_level: low
- tool: "*"
require_approval: true
risk_level: medium
| Field | Purpose |
|---|---|
tool |
Exact function name, or * for unknown tools. |
require_approval |
Creates a pending request before execution. |
timeout |
Seconds before the request defaults to denied. |
auto_approve |
Executes immediately while still writing an approved audit entry. |
redact_fields |
Masks matching dict keys recursively before storing request and audit payloads. |
Reviewer UI
approvekit-web --db /tmp/approvekit_demo.db --port 8765
The local browser reviewer shows pending requests, policy metadata, redacted arguments, approval/rejection controls, reviewer notes, and recent audit entries.
approvekit-web
approvekit-reviewCLI fallback
approvekit-review --db /tmp/approvekit_demo.db
Local JSON API
| Endpoint | Behavior |
|---|---|
GET /api/requests?status=pending |
List pending approval requests. |
GET /api/requests?status=all |
List all requests. |
POST /api/requests/<id>/approve |
Approve a pending request with optional JSON notes. |
POST /api/requests/<id>/reject |
Reject a pending request with optional JSON notes. |
GET /api/audit |
Return audit history. |
Audit Behavior
- Auto-approved calls create approved audit entries.
- Approved risky calls execute and then write approved audit entries.
- Rejected calls do not execute and write rejected audit entries.
- Timed-out calls do not execute and write timeout audit entries.
- Redacted fields stay masked in requests and audit logs.
Guided Demo
python3 demo/agent.py --db /tmp/approvekit_demo.db --reset approvekit-web --db /tmp/approvekit_demo.db --port 8765
Approve the email, approve the PII request, reject the delete request, and leave the production write alone to see timeout/default-deny behavior.