GitHub - makerchecker/MakerChecker: Roles, segregation of duties, and tamper-evident audit for the AI agents you already run. Open-source, self-hosted.
Pangram verdict · v3.3
We believe that this document is fully AI-generated
AI likelihood · overall
AIArticle text · 984 words · 4 segments analyzed
The open-source security layer for AI agents. Deny-by-default enforcement, human approvals, and a cryptographically signed audit trail — so your agent runs only what it's granted and provably can't approve its own work.
Website · Live Demo · mc scan · Docs
Your agents keep running in their existing framework (LangChain, Claude SDK, CrewAI). MakerChecker sits in front of every tool call as a checkpoint and behind it as a signed ledger: an agent acts only through a role, runs only the skills it was granted, cannot exceed its limits, and cannot approve its own work.
🚀 Quick Start 1 — Scan your code Find what your agent can already do on its own, classified by risk. No install, nothing leaves your machine: npx @makerchecker/scan . It flags every consequential action — deleting data, moving money, running shell commands, exfiltrating secrets — names each against the real incident it resembles, and can write the governance code for you with --fix. → packages/scan 2 — Guarantee its behavior Import the controls and wrap any tool. The agent can now only run what its role was granted — a call it isn't allowed is denied before it executes: npm i @makerchecker/embedded import { createGovernor, GovernanceDeniedError } from "@makerchecker/embedded";
const gov = createGovernor() .defineSkill("place-order@1", { riskTier: "high" }) .defineRole("agent") .defineRole("risk-desk") .grant("risk-desk", "place-order@1") // the agent is NOT granted it — deny by default .defineAgent("trader", "agent");
// Wrap your tool once. Now the agent structurally can't fire it. const placeOrder = gov.governedTool("trader", "place-order@1", (order) => broker.submit(order));
try { await placeOrder({ symbol: "BTC", qty: 10 }); } catch (err) { if (err instanceof GovernanceDeniedError) console.log(err.code); // "skill_not_granted" } High-risk skills go to a separate role, so an agent can never approve its own work — and every decision, allowed or denied, commits to a signed audit log.
→ packages/embedded 3 — Working with auditors? Step 2 already writes a signed log. When auditors need a durable, queryable, tamper-evident record — plus a human-approval inbox and a review console — run the self-hosted server: docker compose up Every decision is Ed25519-signed and hash-chained: change any row and verification breaks. Export a bundle and anyone verifies it offline — no database, no trust in the process that produced it. → full server setup below
These are three independent packages — mc scan, @makerchecker/embedded, and the server — that enforce the same controls and write the same signed audit format. Adopt any one on its own.
🔬 Governed Use Cases Runnable examples of agents doing consequential work behind a human gate:
Pharmacovigilance case processing — an agent triages adverse-event reports, but a medical reviewer signs before an expedited 15-day regulatory report transmits. examples/pv-icsr-processing Medical-device (MDR) complaint triage — a regulatory officer decides reportability behind a gate before draft reports are generated. examples/mdr-reportability-triage Oncology patient access — an agent handles benefit matching but is blocked from submitting copay enrollments without a specialist signing. examples/oncology-patient-access Daily cash reconciliation — a finance agent reconciles transactions but locks at exception gates until a cash officer signs off. examples/daily-cash-reconciliation
🔌 Integrate With Your Framework Drop-in connectors govern the tools you already have:
LangChain → packages/connector-langchain Claude Agent SDK → packages/connector-claude-agent TypeScript / Python SDKs → packages/sdk · packages/sdk-python
When you run the server, the SDK's governedTool routes each call through a proxy session for centralized authorization and recording: import { createClient, governedTool, GovernanceDeniedError } from "@makerchecker/sdk";
const client = createClient({ baseUrl: "http://localhost:3000", apiKey:
"mk_..." }); const { session } = await client.proxy.openSession({ label: "recon-run" });
const match = governedTool( client, session.id, "recon-preparer", // agent whose role grants are evaluated "txn-match@1", // skillRef: name@version (input) => matchTxns(input), );
await match({ statement, ledger }); // throws GovernanceDeniedError if denied await client.proxy.closeSession(session.id);
🖥 Self-Hosted Server (optional) Run the full gateway when you need centralized enforcement across many agents, a human-approval inbox, and a review console. docker compose up brings up Postgres, the server on localhost:3000, and a seeded demo, printing two API keys — an admin key (your agent authenticates runs) and an officer key (a human reviewer approves gated actions). The seeded pharmacovigilance flow parks at a medical-review gate where the requester is refused as its own approver: export H='authorization: Bearer mk_...' # admin key export OFFICER='authorization: Bearer mk_...' # officer key
curl -X POST localhost:3000/api/flows/pv-icsr-processing/runs -H "$H" -H 'content-type: application/json' -d '{}' curl localhost:3000/api/approvals -H "$H"
# The requester cannot approve their own run — rejected with 403 curl -X POST localhost:3000/api/approvals/<id>/decision -H "$H" -H 'content-type: application/json' \ -d '{"decision":"approved","reason":"self-approval attempt"}'
# A separate officer signs; only now does the action proceed curl -X POST localhost:3000/api/approvals/<id>/decision -H "$OFFICER" -H 'content-type: application/json' \ -d '{"decision":"approved","reason":"Seriousness confirmed; file 15-day expedited ICSRs."}'
curl localhost:3000/api/audit/verify -H "$H" Full setup, Kubernetes/Helm, and running with live models: docs/quickstart.md.
🔒 Verifiable Audit Trail Every decision and tool call commits to a hash-chained log — each event a SHA-256 over the RFC 8785 canonical JSON of the event, chained through prev_hash from genesis and Ed25519-signed. Change any row and verification breaks. Anyone can verify an exported bundle offline — no database, and no trust in the process that produced it: npx @makerchecker/proof-verifier verify bundle.json Spec: docs/audit-spec.md.
🗂 Packages
Package License What it is
packages/scan Apache-2.0 mc scan — finds and classifies what your agent can do.
packages/embedded Apache-2.0 Importable enforcement primitives — governance in your code.
packages/proof-verifier Apache-2.0 Independently verify a signed audit bundle offline.
packages/sdk Apache-2.0 TypeScript client + governedTool for the server.
packages/sdk-python Apache-2.0 Python client + governed_tool.
packages/connector-langchain Apache-2.0 Govern LangChain tools.
packages/connector-claude-agent Apache-2.0 Govern Claude Agent SDK tools.
packages/server AGPL-3.0 Self-hosted Fastify + Postgres gateway, flow engine, audit writer.
packages/web AGPL-3.0 React console: approvals inbox, run log, registry.
packages/shared AGPL-3.0 Domain types, canonical JSON, crypto utilities.
📄 License & Contributing
Server, Web, Shared: AGPL-3.0. mc scan, embedded, SDKs, connectors, examples: Apache-2.0 — embed them in closed-source agents freely. Commercial (non-copyleft) licensing: hello@makerchecker.ai.
Contributing: CONTRIBUTING.md · Security: SECURITY.md · Code of Conduct: CODE_OF_CONDUCT.md