Skip to main content

Human-in-the-loop approval middleware for risky AI agent actions

Project description

ApproveKit

Human approval gates for risky AI agent actions.

ApproveKit

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:

Web reviewer UI showing two pending approval requests with approve and reject buttons

Terminal reviewer — inspect, approve, and reject from the command line:

Terminal reviewer showing list output and approve/reject commands

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:

  • gh CLI is installed and authenticated (gh auth login).
  • GitHub repository secrets are set for Actions publishing:
    • TEST_PYPI_API_TOKEN
    • PYPI_API_TOKEN

One-command patch release:

python3 release.py patch

What it does:

  • bumps version in pyproject.toml and approvekit/__init__.py
  • scaffolds a new CHANGELOG.md release 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

License

MIT

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

approvekit-0.1.2.tar.gz (24.6 kB view details)

Uploaded Source

Built Distribution

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

approvekit-0.1.2-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file approvekit-0.1.2.tar.gz.

File metadata

  • Download URL: approvekit-0.1.2.tar.gz
  • Upload date:
  • Size: 24.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for approvekit-0.1.2.tar.gz
Algorithm Hash digest
SHA256 b534da99238aef280bcbed7a3d680831ddbccd15533ef2efcd22e8ad52439c82
MD5 9ad145d994a7b48139ca40cf088f7af6
BLAKE2b-256 d969cbab57637f375ca26891dc3b8ab21a12a8b07a2e52844e8f9665df8c61e3

See more details on using hashes here.

File details

Details for the file approvekit-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: approvekit-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 21.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for approvekit-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2da1cbad89ad82ba3be9c09c09f8c70347b2194f74af46ba755775270c2840a9
MD5 b7275cdff6527821cbf686a504469229
BLAKE2b-256 d317eefda64c520a61f33fb25be514bf291bf1c9edffb63e02c5a84dea4f0fe3

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