← Back to blog

Kvlar v0.3.0: Approval Webhooks, Python SDK, and Production Readiness

By Kvlar Team

Kvlar v0.3.0 is out. This release focuses on production readiness and developer ergonomics — approval webhooks for human-in-the-loop workflows, a Python SDK, health checks, and graceful shutdown.

Human approval webhooks

When a policy rule uses require_approval, the tool call is now routable to an external system via webhooks. This unlocks real human-in-the-loop workflows: Slack approval bots, email-based review, or custom approval UIs.

The webhook system has two parts:

Core types (in kvlar-core, pure, no I/O):

use kvlar_core::{ApprovalRequest, ApprovalResponse};

// Request sent to the webhook
let request = ApprovalRequest::new(
    "query",                    // tool name
    serde_json::json!({"sql": "DELETE FROM users WHERE id = 5"}),
    "approve-data-modification" // matched rule
);

// Response from the webhook
let response = ApprovalResponse::Approved;
// or: ApprovalResponse::Denied { reason: Some("too broad".into()) }

HTTP transport (in kvlar-proxy):

use kvlar_proxy::WebhookApprovalBackend;

let backend = WebhookApprovalBackend::new(
    "https://approvals.internal/kvlar",
    Duration::from_secs(300), // 5 min timeout
);

The proxy sends a POST with the approval request JSON. Your webhook returns {"decision": "approved"} or {"decision": "denied", "reason": "..."}.

Python SDK

For teams not running Rust, the new Python SDK wraps the kvlar CLI binary:

from kvlar import KvlarEngine, Decision

engine = KvlarEngine()  # finds kvlar binary on PATH

result = engine.evaluate(
    policy="policy.yaml",
    resource="query",
    parameters={"sql": "DROP TABLE users"}
)

if result.decision == Decision.DENY:
    print(f"Blocked: {result.reason}")

The SDK also supports policy validation and test suite execution:

engine.validate("policy.yaml")  # raises KvlarError on invalid

result = engine.test_policy("tests.yaml")
print(f"{result.passed}/{result.total} tests passed")

Install with pip once the package is published:

pip install kvlar

The Python SDK uses subprocess execution rather than FFI — this keeps the architecture simple, avoids unsafe code, and means the SDK always uses the exact same policy engine as the CLI.

Health check endpoint

Production deployments need liveness probes. Kvlar now has a built-in /health endpoint:

kvlar proxy --stdio --policy policy.yaml --health 127.0.0.1:9101 -- npx server-name

The endpoint returns JSON with runtime stats:

{
  "status": "ok",
  "uptime_secs": 3600,
  "policy_loaded": true,
  "rules_count": 14,
  "requests_evaluated": 1247,
  "requests_allowed": 1189,
  "requests_denied": 42,
  "requests_approval": 16,
  "version": "0.3.0"
}

Wire it up to Docker health checks, Kubernetes liveness probes, or your load balancer.

Graceful shutdown

The proxy now handles SIGTERM and SIGINT properly — draining active connections, flushing audit logs, and cleaning up child processes. This matters for container orchestration where graceful shutdown prevents dropped requests during rolling deployments.

Structured errors

Error handling is now categorized with error codes:

  • PolicyError — invalid YAML, missing fields, parse failures
  • EvaluationError — engine failures during rule matching
  • ProxyError — transport and connection issues
  • ConfigError — invalid configuration

Each error carries a code, message, and optional context — making programmatic error handling straightforward in both Rust and Python consumers.

Upgrade

cargo install kvlar-cli  # installs v0.3.0

What's next

  • TypeScript SDK — for Node.js environments
  • Audit log export — ship structured logs to your SIEM
  • SHIELD — managed enterprise runtime enforcement

Star the repo or follow on X for updates.