ApproveKit
Human approval gates for risky AI agent actions.
ApproveKit is a lightweight, framework-agnostic Python package that wraps tool calls, evaluates simple policy rules, pauses risky actions for human review, and records every outcome in SQLite audit history.
It is built for agent builders, platform engineers, and teams who need a practical local-first approval layer before giving agents access to tools like email, production writes, record deletion, or PII access.
Reviewers
Browser reviewer — approve or reject pending requests from a local web UI:
Terminal reviewer — inspect, approve, and reject from the command line:
What It Does
- Wrap any Python callable with
@kit.guard. - Auto-approve low-risk tools while still writing audit entries.
- Hold risky tool calls until a reviewer approves or rejects them.
- Default-deny on timeout.
- Redact configured payload fields before persistence.
- Review pending requests in a browser with
approvekit-web. - Keep a durable SQLite audit trail.
Install
pip install approvekit
For local development:
python3 -m pip install -e ".[dev]"
Quick Start
from approvekit import ApproveKit, Policy, Storage
policy = Policy.from_dict({
"default_timeout": 60,
"rules": [
{
"tool": "send_email",
"require_approval": True,
"risk_level": "high",
"redact_fields": ["body"],
},
{
"tool": "read_record",
"require_approval": False,
"auto_approve": True,
"risk_level": "low",
},
],
})
storage = Storage(db_path="/tmp/approvekit.db")
kit = ApproveKit(policy=policy, storage=storage)
@kit.guard
def send_email(to: str, subject: str, body: str) -> dict:
return {"status": "sent", "to": to, "subject": subject}
send_email(
to="ceo@example.com",
subject="Quarterly report",
body="Sensitive content that will be redacted in storage.",
)
In a second terminal:
approvekit-web --db /tmp/approvekit.db --port 8765
Open http://127.0.0.1:8765 to approve or reject the pending request.
Guided Demo
Terminal 1:
python3 demo/agent.py --db /tmp/approvekit_demo.db --reset
Terminal 2:
approvekit-web --db /tmp/approvekit_demo.db --port 8765
The demo walks through:
- auto-approved read
- approval-required email
- PII access with redacted fields
- rejected delete
- production write that times out unless reviewed
The terminal reviewer is still available:
approvekit-review --db /tmp/approvekit_demo.db
Policy Reference
default_timeout: 60
rules:
- tool: send_email
require_approval: true
timeout: 45
risk_level: high
redact_fields: [body]
- tool: read_record
require_approval: false
auto_approve: true
risk_level: low
- tool: "*"
require_approval: true
risk_level: medium
| Field | Type | Description |
|---|---|---|
tool |
string | Exact tool name, or * for fallback. |
require_approval |
bool | Whether a human decision is required before execution. |
timeout |
int | Seconds to wait before default-deny timeout. |
auto_approve |
bool | Execute immediately and write an approved audit entry. |
risk_level |
string | Informational label shown in reviewer UI and audit metadata. |
redact_fields |
list | Dict field names to mask before request/audit persistence. |
Architecture
Agent tool call
-> ApproveKit guard
-> Policy evaluation
-> Auto-approved path OR pending request in SQLite
-> Web/CLI reviewer decision
-> Approved tool execution OR rejected/timeout block
-> Audit entry
Only approved risky requests execute the wrapped tool body. Rejected and timed-out requests are persisted and audited without executing the action.
Project Structure
approvekit/
core.py # guard decorator and approval wait loop
policy.py # policy rules, YAML/JSON loading, redaction settings
storage.py # SQLite request and audit persistence
reviewer.py # terminal reviewer
web.py # local browser reviewer
demo/
agent.py # guided two-terminal demo
tests/
test_*.py # approve, reject, timeout, storage, policy, web tests
docs/
MVP_IMPLEMENTATION_PLAN.md
Development
python3 -m pip install -e ".[dev]"
python3 -m pytest -q
Maintainer Release Flow
The repository supports one-command patch/minor/major releases via release.py.
Prerequisites:
ghCLI is installed and authenticated (gh auth login).- GitHub repository secrets are set for Actions publishing:
TEST_PYPI_API_TOKENPYPI_API_TOKEN
One-command patch release:
python3 release.py patch
What it does:
- bumps version in
pyproject.tomlandapprovekit/__init__.py - scaffolds a new
CHANGELOG.mdrelease section - runs tests + build + twine checks
- commits, tags, and pushes (
vX.Y.Z) - creates a GitHub Release (
gh release create)
Publishing is then handled automatically by .github/workflows/publish-pypi.yml when the release is published.
Documentation
- Landing page: http://approvekit.theajaykumar.com
- Developer docs: http://approvekit.theajaykumar.com/docs.html
- MVP tracker:
docs/MVP_IMPLEMENTATION_PLAN.md - Changelog:
CHANGELOG.md
License
MIT
Metadata
Release files for approvekit 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| approvekit-0.1.2.tar.gz | 24.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| approvekit-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.0 kB
Release files / approvekit-0.1.2.tar.gz
| Download URL | approvekit-0.1.2.tar.gz |
|---|---|
| Size | 24.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b534da99238aef280bcbed7a3d680831ddbccd15533ef2efcd22e8ad52439c82
|
|
BLAKE2b-256 checksum How to use checksums |
d969cbab57637f375ca26891dc3b8ab21a12a8b07a2e52844e8f9665df8c61e3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / approvekit-0.1.2-py3-none-any.whl
| Download URL | approvekit-0.1.2-py3-none-any.whl |
|---|---|
| Size | 21.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2da1cbad89ad82ba3be9c09c09f8c70347b2194f74af46ba755775270c2840a9
|
|
BLAKE2b-256 checksum How to use checksums |
d317eefda64c520a61f33fb25be514bf291bf1c9edffb63e02c5a84dea4f0fe3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|