v0.5 AgentGuard
AgentGuard v0.5.0 — Wire-level firewall for AI agents
Released: 2026-05-05 License: Apache-2.0 (self-hosted) · Hosted multi-tenant build at https://agentguard.lictorate.com
Two new binaries —
agentguard-mcp-gatewayandagentguard-llm-proxy— sit between your agent and its tools/LLM. Set one environment variable and every action is gated against your policy with no code path the agent can bypass.
TL;DR
- New transports. Wire-level MCP gateway and LLM API proxy. No SDK changes required.
- SDK hardened. v0.4.x had bypass paths in the LangChain, CrewAI, and browser-use adapters via
gt.func,gt._tool, and the moderninvoke/stream/batchAPI surface. All closed. - Operator-facing disclosures. Four v0.4.x correctness issues affecting metrics accuracy, session cost limits, per-agent override semantics, and policy loading. If you run v0.4.x, these affect you — upgrade. See § Security & correctness disclosures.
- Breaking: Python ≥ 3.9, Node ≥ 18, stricter policy loader. See § Migration.
Wire-level enforcement (the headline)
Until v0.5, AgentGuard relied on the agent author wrapping their tools with the SDK. Fine when the author cooperates — but a careless gt.func(...) or a framework that calls tool.invoke() instead of tool.run() would skip the gate entirely. v0.5 closes this by giving operators two wire-level binaries the agent cannot bypass.
agentguard-mcp-gateway
JSON-RPC bridge for MCP clients (Claude Desktop, Cursor, Cline, Continue, Zed). Spawns one or more downstream MCP servers as subprocesses, namespaces their tools (fs:read_file, github:create_issue), and gates every tools/call through the policy engine before forwarding upstream. Five client config examples ship in examples/.
agentguard-llm-proxy
HTTP server speaking OpenAI Chat Completions and Anthropic Messages on the wire. Set OPENAI_BASE_URL=http://127.0.0.1:8081/v1 (or the Anthropic equivalent) and existing SDK code flows through unchanged. Tool-call blocks inside response streams are buffered, gated, and either:
- forwarded byte-identical (
ALLOW), - rewritten to a synthetic refusal (
DENY), or - surfaced for human approval (
REQUIRE_APPROVAL),
with full streaming and non-streaming support and 100-concurrent-stream race-clean stress coverage.
Quickstarts: docs/QUICKSTART_MCP.md · docs/QUICKSTART_LLM_PROXY.md
Architecture: docs/PROXY_ARCHITECTURE.md
SDK adapter hardening
The v0.4.1 audit found that the Python adapters were silently bypassing modern framework call paths and exposing unwrapped internals as one-line escape hatches. This was the largest credibility issue in v0.4.x. v0.5 rewrites all three Python adapters as composition wrappers with strict allowlists.
- Every modern call path gated. LangChain
invoke/ainvoke/stream/batch. CrewAI_run/run. browser-usegoto/click/fill/type/press/select/check/uncheck/evaluate/evaluate_handle/set_extra_http_headers/route/expose_function/add_init_script. gt.funcandgt._toolare no longer escape hatches. Both raiseAttributeErrorwith a security explanation.browser-useadapter scope expanded beyondgoto.GuardedFramemirrorsGuardedPage. Form values >256 chars are truncated to<redacted; len=N>for PII safety.datapolicy scope wired in for form-input gating with PII pattern enforcement.- MCP Python adapter
__main__is no longer empty. It is now a single-upstream proxying gateway via--upstream "<cmd>". For multi-upstream namespaced gateways, use the new Goagentguard-mcp-gateway. - Real-framework integration tests run weekly + per-PR against actual upstream packages. The previously-failing CrewAI tests in
tests/integration/test_at_real_crewai.pynow pass end-to-end via an offlineBaseLLMsubclass driving CrewAI's native function-calling path without an OpenAI key.
Security & correctness disclosures
These are v0.4.x bugs that silently affected operator behavior. Workarounds for operators who cannot upgrade immediately are listed below each entry, but the recommended action is to upgrade.
AG-26-01 — Per-agent override silently dropped base policy denies
Severity: High — silent privilege escalation. Affected: v0.3.0–v0.4.1.
A per-agent override block containing only allow: rules silently replaced the base policy's deny: rules instead of merging. An operator who allowed a specific tool for one agent could inadvertently let rm -rf * through if it was denied at the base level.
- v0.5 behavior: default is
merge. Setoverride_mode: replaceon the agent block to reproduce v0.4.x semantics. - Workaround on v0.4.x: audit every
agents.<id>.override:block and re-state base denies explicitly.
AG-26-02 — est_cost == 0 bypass on session cost limits
Severity: High — cost-control bypass. Affected: v0.4.0–v0.4.1.
A tool reporting est_cost: 0 on every action could accumulate real upstream LLM spend without ever tripping the session cost limit, because zero was treated as "uncounted" rather than "counted as zero."
- v0.5 behavior: all actions count toward the session ceiling regardless of
est_cost. - Workaround on v0.4.x: set
est_costto a small positive floor (e.g.0.0001) on any zero-cost-declared tool.
AG-26-03 — Rate-limit metrics double-counting
Severity: Medium — operator dashboards inaccurate. Affected: v0.4.0–v0.4.1.
agentguard_checks_total and agentguard_denied_total were over-counted in proportion to the rate-limit hit rate. Prometheus dashboards built on these series report inflated traffic.
- v0.5 behavior: counted exactly once per check.
- Workaround on v0.4.x: none at the metrics layer; treat affected dashboards as upper bounds.
AG-26-04 — time_window without require_prior was a deprecation warning
Severity: Low — silent policy misload risk.
v0.4.x emitted a deprecation warning and continued; v0.5 promotes to a hard load error. Operators with policies in this shape will see a load failure on upgrade — fix the policies before deploying.
Architecture (unblocks v0.6 multi-tenant)
PolicyProviderinterface (pkg/policy/provider.go). Engines consume a provider rather than loading policies directly. v0.6's database-backed multi-tenant provider drops in without engine changes.BufferedAsyncLogger(pkg/audit/buffered.go). Bounded queue + N workers + disk-overflow recovery.Log()no longer blocks the request path.- Tenant-aware URL routing.
/v1/t/{tenant}/...routes alongside the legacy/v1/...family. SDKs accept atenant_id(Python) /tenantId(TS) constructor parameter. v0.5 ships single-tenant (local); v0.6 lights up the rest of the path. - Versioned wire schema.
pkg/proxy/schema/v1/with cross-language contract tests (Go ↔ Python ↔ TypeScript).schema_version: "v1"field on every request/response. agentguard checkCLI subcommand. One-shot policy evaluation for CI. Four input modes (per-field flags,--request '<json>',--stdin,--batchJSONL) and four exit codes (0=allow, 1=deny, 2=approval, 3=error) with a severity-rank batch reducer.
Approval round-trip
/v1/checkhonorsapproval_id. When the model retries a denied tool call after a human approves on the dashboard, the central server consults the approval queue and returns the resolved decision instead of producing a fresh approval cycle. "Approve once, model proceeds" works end-to-end.- Replay defense. The retry must match the original on AgentID, Scope, Command, Path, Domain, URL, and Action. An attacker who learns an approved id cannot replay it against a different action. New metric:
agentguard_approval_replay_mismatch_total.
Performance
v0.4.1 had zero benchmarks in the repo. v0.5 ships:
- Five named benchmarks:
Engine.Check(allow + deny),GlobMatchdouble-star (match + no-match),FileLogger.Log,Dispatcher.Sendqueue-full. --debug-pprofflag (localhost-only bind by design).--session-cost-ttlflag with boot WARNING when set to 0.docs/SLO.md— target p50<1ms / p95<3ms / p99<5ms. Measured baseline ≈ 5µs end-to-end per check on AMD Ryzen 7 5800X.
Observability
- Audit
Transportfield —transport: "sdk" | "mcp_gateway" | "llm_api_proxy"on every entry./v1/audit?transport=filter. Dashboard renders color-coded chips per transport. - Operator health endpoints —
/v1/healthand/v1/t/{tenant}/healthwithlast_request_at,last_policy_load_at, and a warnings array. - New metrics:
agentguard_llmproxy_buffer_overflow_total{provider}agentguard_llmproxy_streams_activeagentguard_llmproxy_streams_rejected_totalagentguard_llmproxy_non_streaming_overflow_total{provider}agentguard_approval_replay_mismatch_total- audit-buffered counters
Operational hygiene
- Audit log rotation enabled by default.
--audit-max-size-mb,--audit-max-backups,--audit-max-age-days,--audit-compress. recoverPanicmiddleware on every HTTP handler and goroutine wrapper. A panic in any single handler no longer kills the process.bufio.Scanner.Err()checked everywhere in audit-log readers. Oversized lines no longer silently truncate/v1/auditresults or therequire_priorhistory adapter.- Glob
**semantics documented and locked by regression test (path-vs-domain asymmetry preserved as a stable contract).
Governance / OSS hygiene
- Full canonical Apache-2.0 LICENSE (216 lines). v0.4.1 shipped a 14-line stub; every redistributor was technically out of compliance.
NOTICE,SECURITY.md,CODE_OF_CONDUCT.md(Contributor Covenant 2.1),CODEOWNERS,SUPPORT.md,dependabot.yml, three issue templates.golangci-lint-actionpinned (wasversion: latest).
Breaking changes
Policy schema
time_windowwithoutrequire_prioris now a hard load error (was a deprecation warning in v0.4.x).- Per-agent override defaults to
merge. To reproduce v0.4.x replace-all behavior, setoverride_mode: replaceon the agent block.
SDK
- Python ≥ 3.9 required (3.8 dropped).
- Node ≥ 18.0.0 required.
- TypeScript constructor throws on unknown
failModevalues (was silently accepting). - Unknown kwargs to
@guarded(**kwargs)(Python) andguarded(...)(TS) raise. GuardedTool.func,GuardedTool._tool, and any non-allowlisted attribute access on Python adapter wrappers now raiseAttributeError. Code that depended on direct internal access must be updated to call gated methods.
See docs/MIGRATION.md § v0.4.1 → v0.5.0 for the full upgrade walkthrough.
Compatibility (non-breaking)
- Go binaries — backward-compatible at v0.5.0.
- TypeScript SDK — backward-compatible at v0.5.0.
- Python SDK API — backward-compatible.
GuardedTool(my_tool, guard)andGuardedCrewTool(my_tool, guard=guard)continue to work; only the internal class topology changes. - Python framework floors — unchanged:
crewai >= 0.80, < 2.0,langchain-core >= 0.3, < 2.0. Verified end-to-end againstcrewai 1.14.4andlangchain-core 1.3.3on Python 3.13.
Test coverage
| Layer | Coverage |
|---|---|
| Go (overall) | 72.5% |
| pkg/llmproxy (new) | 80.5% |
| pkg/mcpgw (new) | 79.9% |
| pkg/proxy | 90.4% |
| pkg/policy | 85.6% |
| Python SDK (unit) | 77.0% |
| TypeScript SDK | 95.6% statements / 98.0% lines |
- 16 Go packages, all
-race -count=1clean. - 314 Python unit tests + 21 integration tests (skip cleanly when frameworks not installed).
- 78 TypeScript tests.
- Property-based tests for glob matchers, redactor, dispatcher concurrency, OpenAI parser, Anthropic parser.
- Captured-fixture wire-format contract tests across Go ↔ Python ↔ TypeScript.
- Real-framework E2E tests in weekly CI cron (LangChain, CrewAI, browser-use).
- Adversarial replay scenarios for the approval-id round-trip.
- 100-concurrent-stream race-clean stress test for the LLM proxy.
Get started
# Install all three binaries go install github.com/Caua-ferraz/AgentGuard/cmd/agentguard@v0.5.0 go install github.com/Caua-ferraz/AgentGuard/cmd/agentguard-mcp-gateway@v0.5.0 go install github.com/Caua-ferraz/AgentGuard/cmd/agentguard-llm-proxy@v0.5.0Run the central server
agentguard serve
--policy configs/default.yaml
--dashboard
--api-key "$(openssl rand -hex 16)"
For MCP clients (Claude Desktop, Cursor, Cline, Continue, Zed) — wire your client config to agentguard-mcp-gateway. See docs/QUICKSTART_MCP.md and examples/<client>-config.json.
For OpenAI / Anthropic SDK code — point the SDK at the LLM proxy:
agentguard-llm-proxy \ --listen 127.0.0.1:8081 \ --policy configs/default.yaml \ --guard-url http://127.0.0.1:8080 \ --api-key "$AGENTGUARD_API_KEY"export OPENAI_BASE_URL=http://127.0.0.1:8081/v1
or: export ANTHROPIC_BASE_URL=http://127.0.0.1:8081
See docs/QUICKSTART_LLM_PROXY.md and examples/<sdk>-config.py.
The three transports — SDK adapter, MCP gateway, LLM API proxy — are complementary, not exclusive. Run the SDK for in-process gating, the MCP gateway for tool-call gating at the protocol boundary, and the LLM proxy for tool-call gating inside model responses. Pick whatever combination matches your threat model.
Audit findings
This release closes ~92 of the ~150 findings from the v0.4.1 multi-perspective audit (AUDIT_REPORT.md); per-finding disposition is in .audit/v05_findings_map.md. The two largest cross-cutting themes — adapter modern-API bypass and the empty-MCP-server class — are fully closed.
Carried forward to v0.6 (documented in .audit/v05_decisions.md):
- Hash-chain tamper-evident audit log (rotation + transport tag landed in v0.5; cryptographic chain is v0.6).
- Notifier-side spool-to-disk (audit-side closed in v0.5).
- Multi-tenant data-structure sharding (URL plumbing landed in v0.5).
- ~17
TODO(v0.6, #N)markers in production code with consolidated tracking issues.
Reporting
- Bugs: GitHub Issues.
- Security vulnerabilities: cauaferraz@lictorate.com — do not file public issues. See
SECURITY.md.
Self-hosted is Apache-2.0 forever. AgentGuard Cloud (hosted, multi-tenant) is in design at https://agentguard.lictorate.com.
# AgentGuard v0.5.0 — Wire-level firewall for AI agentsReleased: 2026-05-05
License: Apache-2.0 (self-hosted) · Hosted multi-tenant build at https://agentguard.lictorate.com/
Two new binaries —
agentguard-mcp-gatewayandagentguard-llm-proxy— sit between your agent and its tools/LLM. Set one environment variable and every action is gated against your policy with no code path the agent can bypass.
TL;DR
- New transports. Wire-level MCP gateway and LLM API proxy. No SDK changes required.
- SDK hardened. v0.4.x had bypass paths in the LangChain, CrewAI, and browser-use adapters via
gt.func,gt._tool, and the moderninvoke/stream/batchAPI surface. All closed. - Operator-facing disclosures. Four v0.4.x correctness issues affecting metrics accuracy, session cost limits, per-agent override semantics, and policy loading. If you run v0.4.x, these affect you — upgrade. See § Security & correctness disclosures.
- Breaking: Python ≥ 3.9, Node ≥ 18, stricter policy loader. See § Migration.
Wire-level enforcement (the headline)
Until v0.5, AgentGuard relied on the agent author wrapping their tools with the SDK. Fine when the author cooperates — but a careless gt.func(...) or a framework that calls tool.invoke() instead of tool.run() would skip the gate entirely. v0.5 closes this by giving operators two wire-level binaries the agent cannot bypass.
agentguard-mcp-gateway
JSON-RPC bridge for MCP clients (Claude Desktop, Cursor, Cline, Continue, Zed). Spawns one or more downstream MCP servers as subprocesses, namespaces their tools (fs:read_file, github:create_issue), and gates every tools/call through the policy engine before forwarding upstream. Five client config examples ship in examples/.
agentguard-llm-proxy
HTTP server speaking OpenAI Chat Completions and Anthropic Messages on the wire. Set OPENAI_BASE_URL=http://127.0.0.1:8081/v1 (or the Anthropic equivalent) and existing SDK code flows through unchanged. Tool-call blocks inside response streams are buffered, gated, and either:
- forwarded byte-identical (
ALLOW), - rewritten to a synthetic refusal (
DENY), or - surfaced for human approval (
REQUIRE_APPROVAL),
with full streaming and non-streaming support and 100-concurrent-stream race-clean stress coverage.
Quickstarts: [docs/QUICKSTART_MCP.md](https://claude.ai/QUICKSTART_MCP.md) · [docs/QUICKSTART_LLM_PROXY.md](https://claude.ai/QUICKSTART_LLM_PROXY.md)
Architecture: [docs/PROXY_ARCHITECTURE.md](https://claude.ai/PROXY_ARCHITECTURE.md)
SDK adapter hardening
The v0.4.1 audit found that the Python adapters were silently bypassing modern framework call paths and exposing unwrapped internals as one-line escape hatches. This was the largest credibility issue in v0.4.x. v0.5 rewrites all three Python adapters as composition wrappers with strict allowlists.
- Every modern call path gated. LangChain
invoke/ainvoke/stream/batch. CrewAI_run/run. browser-usegoto/click/fill/type/press/select/check/uncheck/evaluate/evaluate_handle/set_extra_http_headers/route/expose_function/add_init_script. gt.funcandgt._toolare no longer escape hatches. Both raiseAttributeErrorwith a security explanation.browser-useadapter scope expanded beyondgoto.GuardedFramemirrorsGuardedPage. Form values >256 chars are truncated to<redacted; len=N>for PII safety.datapolicy scope wired in for form-input gating with PII pattern enforcement.- MCP Python adapter
__main__is no longer empty. It is now a single-upstream proxying gateway via--upstream "<cmd>". For multi-upstream namespaced gateways, use the new Goagentguard-mcp-gateway. - Real-framework integration tests run weekly + per-PR against actual upstream packages. The previously-failing CrewAI tests in
tests/integration/test_at_real_crewai.pynow pass end-to-end via an offlineBaseLLMsubclass driving CrewAI's native function-calling path without an OpenAI key.
Security & correctness disclosures
These are v0.4.x bugs that silently affected operator behavior. Workarounds for operators who cannot upgrade immediately are listed below each entry, but the recommended action is to upgrade.
AG-26-01 — Per-agent override silently dropped base policy denies
Severity: High — silent privilege escalation.
Affected: v0.3.0–v0.4.1.
A per-agent override block containing only allow: rules silently replaced the base policy's deny: rules instead of merging. An operator who allowed a specific tool for one agent could inadvertently let rm -rf * through if it was denied at the base level.
- v0.5 behavior: default is
merge. Setoverride_mode: replaceon the agent block to reproduce v0.4.x semantics. - Workaround on v0.4.x: audit every
agents.<id>.override:block and re-state base denies explicitly.
AG-26-02 — est_cost == 0 bypass on session cost limits
Severity: High — cost-control bypass.
Affected: v0.4.0–v0.4.1.
A tool reporting est_cost: 0 on every action could accumulate real upstream LLM spend without ever tripping the session cost limit, because zero was treated as "uncounted" rather than "counted as zero."
- v0.5 behavior: all actions count toward the session ceiling regardless of
est_cost. - Workaround on v0.4.x: set
est_costto a small positive floor (e.g.0.0001) on any zero-cost-declared tool.
AG-26-03 — Rate-limit metrics double-counting
Severity: Medium — operator dashboards inaccurate.
Affected: v0.4.0–v0.4.1.
agentguard_checks_total and agentguard_denied_total were over-counted in proportion to the rate-limit hit rate. Prometheus dashboards built on these series report inflated traffic.
- v0.5 behavior: counted exactly once per check.
- Workaround on v0.4.x: none at the metrics layer; treat affected dashboards as upper bounds.
AG-26-04 — time_window without require_prior was a deprecation warning
Severity: Low — silent policy misload risk.
v0.4.x emitted a deprecation warning and continued; v0.5 promotes to a hard load error. Operators with policies in this shape will see a load failure on upgrade — fix the policies before deploying.
Architecture (unblocks v0.6 multi-tenant)
PolicyProviderinterface (pkg/policy/provider.go). Engines consume a provider rather than loading policies directly. v0.6's database-backed multi-tenant provider drops in without engine changes.BufferedAsyncLogger(pkg/audit/buffered.go). Bounded queue + N workers + disk-overflow recovery.Log()no longer blocks the request path.- Tenant-aware URL routing.
/v1/t/{tenant}/...routes alongside the legacy/v1/...family. SDKs accept atenant_id(Python) /tenantId(TS) constructor parameter. v0.5 ships single-tenant (local); v0.6 lights up the rest of the path. - Versioned wire schema.
pkg/proxy/schema/v1/with cross-language contract tests (Go ↔ Python ↔ TypeScript).schema_version: "v1"field on every request/response. agentguard checkCLI subcommand. One-shot policy evaluation for CI. Four input modes (per-field flags,--request '<json>',--stdin,--batchJSONL) and four exit codes (0=allow, 1=deny, 2=approval, 3=error) with a severity-rank batch reducer.
Approval round-trip
/v1/checkhonorsapproval_id. When the model retries a denied tool call after a human approves on the dashboard, the central server consults the approval queue and returns the resolved decision instead of producing a fresh approval cycle. "Approve once, model proceeds" works end-to-end.- Replay defense. The retry must match the original on AgentID, Scope, Command, Path, Domain, URL, and Action. An attacker who learns an approved id cannot replay it against a different action. New metric:
agentguard_approval_replay_mismatch_total.
Performance
v0.4.1 had zero benchmarks in the repo. v0.5 ships:
- Five named benchmarks:
Engine.Check(allow + deny),GlobMatchdouble-star (match + no-match),FileLogger.Log,Dispatcher.Sendqueue-full. --debug-pprofflag (localhost-only bind by design).--session-cost-ttlflag with boot WARNING when set to 0.[docs/SLO.md](https://claude.ai/SLO.md)— target p50<1ms / p95<3ms / p99<5ms. Measured baseline ≈ 5µs end-to-end per check on AMD Ryzen 7 5800X.
Observability
- Audit
Transportfield —transport: "sdk" | "mcp_gateway" | "llm_api_proxy"on every entry./v1/audit?transport=filter. Dashboard renders color-coded chips per transport. - Operator health endpoints —
/v1/healthand/v1/t/{tenant}/healthwithlast_request_at,last_policy_load_at, and a warnings array. - New metrics:
agentguard_llmproxy_buffer_overflow_total{provider}agentguard_llmproxy_streams_activeagentguard_llmproxy_streams_rejected_totalagentguard_llmproxy_non_streaming_overflow_total{provider}agentguard_approval_replay_mismatch_total- audit-buffered counters
Operational hygiene
- Audit log rotation enabled by default.
--audit-max-size-mb,--audit-max-backups,--audit-max-age-days,--audit-compress. recoverPanicmiddleware on every HTTP handler and goroutine wrapper. A panic in any single handler no longer kills the process.bufio.Scanner.Err()checked everywhere in audit-log readers. Oversized lines no longer silently truncate/v1/auditresults or therequire_priorhistory adapter.- Glob
**semantics documented and locked by regression test (path-vs-domain asymmetry preserved as a stable contract).
Governance / OSS hygiene
- Full canonical Apache-2.0 LICENSE (216 lines). v0.4.1 shipped a 14-line stub; every redistributor was technically out of compliance.
NOTICE,SECURITY.md,CODE_OF_CONDUCT.md(Contributor Covenant 2.1),CODEOWNERS,SUPPORT.md,dependabot.yml, three issue templates.golangci-lint-actionpinned (wasversion: latest).
Breaking changes
Policy schema
time_windowwithoutrequire_prioris now a hard load error (was a deprecation warning in v0.4.x).- Per-agent override defaults to
merge. To reproduce v0.4.x replace-all behavior, setoverride_mode: replaceon the agent block.
SDK
- Python ≥ 3.9 required (3.8 dropped).
- Node ≥ 18.0.0 required.
- TypeScript constructor throws on unknown
failModevalues (was silently accepting). - Unknown kwargs to
@guarded(**kwargs)(Python) andguarded(...)(TS) raise. GuardedTool.func,GuardedTool._tool, and any non-allowlisted attribute access on Python adapter wrappers now raiseAttributeError. Code that depended on direct internal access must be updated to call gated methods.
See [docs/MIGRATION.md](https://claude.ai/MIGRATION.md) § v0.4.1 → v0.5.0 for the full upgrade walkthrough.
Compatibility (non-breaking)
- Go binaries — backward-compatible at v0.5.0.
- TypeScript SDK — backward-compatible at v0.5.0.
- Python SDK API — backward-compatible.
GuardedTool(my_tool, guard)andGuardedCrewTool(my_tool, guard=guard)continue to work; only the internal class topology changes. - Python framework floors — unchanged:
crewai >= 0.80, < 2.0,langchain-core >= 0.3, < 2.0. Verified end-to-end againstcrewai 1.14.4andlangchain-core 1.3.3on Python 3.13.
Test coverage
| Layer | Coverage |
|---|---|
| Go (overall) | 72.5% |
pkg/llmproxy (new) |
80.5% |
pkg/mcpgw (new) |
79.9% |
pkg/proxy |
90.4% |
pkg/policy |
85.6% |
| Python SDK (unit) | 77.0% |
| TypeScript SDK | 95.6% statements / 98.0% lines |
- 16 Go packages, all
-race -count=1clean. - 314 Python unit tests + 21 integration tests (skip cleanly when frameworks not installed).
- 78 TypeScript tests.
- Property-based tests for glob matchers, redactor, dispatcher concurrency, OpenAI parser, Anthropic parser.
- Captured-fixture wire-format contract tests across Go ↔ Python ↔ TypeScript.
- Real-framework E2E tests in weekly CI cron (LangChain, CrewAI, browser-use).
- Adversarial replay scenarios for the approval-id round-trip.
- 100-concurrent-stream race-clean stress test for the LLM proxy.
Get started
# Install all three binaries
go install github.com/Caua-ferraz/AgentGuard/cmd/agentguard@v0.5.0
go install github.com/Caua-ferraz/AgentGuard/cmd/agentguard-mcp-gateway@v0.5.0
go install github.com/Caua-ferraz/AgentGuard/cmd/agentguard-llm-proxy@v0.5.0
# Run the central server
agentguard serve \
--policy configs/default.yaml \
--dashboard \
--api-key "$(openssl rand -hex 16)"For MCP clients (Claude Desktop, Cursor, Cline, Continue, Zed) — wire your client config to agentguard-mcp-gateway. See [docs/QUICKSTART_MCP.md](https://claude.ai/QUICKSTART_MCP.md) and examples/<client>-config.json.
For OpenAI / Anthropic SDK code — point the SDK at the LLM proxy:
agentguard-llm-proxy \
--listen 127.0.0.1:8081 \
--policy configs/default.yaml \
--guard-url http://127.0.0.1:8080 \
--api-key "$AGENTGUARD_API_KEY"
export OPENAI_BASE_URL=http://127.0.0.1:8081/v1
# or: export ANTHROPIC_BASE_URL=http://127.0.0.1:8081See [docs/QUICKSTART_LLM_PROXY.md](https://claude.ai/QUICKSTART_LLM_PROXY.md) and examples/<sdk>-config.py.
The three transports — SDK adapter, MCP gateway, LLM API proxy — are complementary, not exclusive. Run the SDK for in-process gating, the MCP gateway for tool-call gating at the protocol boundary, and the LLM proxy for tool-call gating inside model responses. Pick whatever combination matches your threat model.
Audit findings
This release closes ~92 of the ~150 findings from the v0.4.1 multi-perspective audit (AUDIT_REPORT.md); per-finding disposition is in .audit/v05_findings_map.md. The two largest cross-cutting themes — adapter modern-API bypass and the empty-MCP-server class — are fully closed.
Carried forward to v0.6 (documented in .audit/v05_decisions.md):
- Hash-chain tamper-evident audit log (rotation + transport tag landed in v0.5; cryptographic chain is v0.6).
- Notifier-side spool-to-disk (audit-side closed in v0.5).
- Multi-tenant data-structure sharding (URL plumbing landed in v0.5).
- ~17
TODO(v0.6, #N)markers in production code with consolidated tracking issues.
Reporting
- Bugs: GitHub Issues.
- Security vulnerabilities: cauaferraz@lictorate.com — do not file public issues. See
[SECURITY.md](https://claude.ai/SECURITY.md).
Self-hosted is Apache-2.0 forever. AgentGuard Cloud (hosted, multi-tenant) is in design at https://agentguard.lictorate.com/.