Repository navigation
AgentGuard v1.4.0 #76
Caua-ferraz
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
AgentGuard 1.4.0 — Release Notes
Released: 2026-10-15
Headline: Guard every coding agent, prove the audit log wasn't touched, and test your policy like code.
Why this release exists
1.3 made AgentGuard easy to install and put Claude Code behind it. 1.4 is about the questions people ask next:
agentguard audit verifynames the exact place.agentguard testruns it against test cases in CI, including the raw tool calls your coding agents send.agentguard reportwrites the evidence for a period, mapped to SOC 2 criteria.It also brings remote MCP servers to the MCP gateway, adds an OpenAI Agents SDK adapter, and fixes several ways a tool call could get past the policy unchecked. Two of them were found while preparing this release, and both affect 1.3: commands hidden inside
bash -coreval, and disguised spellings of a blocked address.What's new
Cursor, Gemini CLI and Codex CLI
agentguard setupcan now connect Cursor, Gemini CLI and Codex CLI as well as Claude Code. Each one gets a hook that checks its tool calls on your AgentGuard server before they run:web_fetch(every URL in the request), MCP toolsapply_patch(every file the patch touches), MCP toolsAllowed calls carry on under the agent's own permissions. Denied calls are blocked and the agent sees why. Calls that need approval wait up to 5 minutes for you in the dashboard or with
agentguard approve. When one action touches several things, such as a patch that edits three files, each one is checked and the strictest answer wins. Gemini'sweb_fetchURLs are read the way Gemini itself parses them, so a disguised host can't slip past a network rule.Fail open or fail closed. When connecting an agent,
setupasks what should happen if AgentGuard isn't running:agentguard hook <agent> --fail-closed): an unreachable server, a rejected API key or an unreadable call is denied with ruledeny:hook:fail_closed.Each agent has a ready-made rule block (
configs/cursor.yaml,configs/gemini-cli.yaml,configs/codex.yaml), andsetupoffers to add it to your policy. The audit log and dashboard tag every call with its agent (claude_code,cursor,gemini_cli,codex_cli). SeeCODING_AGENTS.md.A tamper-evident audit log
The chain. With
--audit-seal, every entry carries a sequence number, the previous entry's hash and its own HMAC-SHA256. The chain also links across rotated and gzipped files.Verifying it.
agentguard audit verifychecks it offline. Edit a byte, delete a line, swap two lines or cut the file short, and it exits 1 with the file and line where the chain breaks. A log with no sealed entries gets "NOT SEALED" and exit 1 too, since nothing could be verified.Anchors. AgentGuard publishes the head of the chain every 5 minutes and on every rotation, in three places:
GET /v1/audit/head.Pass one to
audit verify --anchorand even someone holding the key can't rewrite history before it.New installs are sealed by default.
agentguard setupgenerates a key that only you can read.Off unless you turn it on otherwise. Existing installs keep byte-identical logs until you turn sealing on. The audit format version is unchanged.
Policies as code:
agentguard testagentguard testruns every case against your policy. Each case starts fresh, so earlier cases can't change later ones. A case can seed the history arequire_priorrule needs, or give a coding agent's raw tool call throughhook:, which goes through the same mapping as the real hook.The command fits CI:
--output junitfor test reports,--runto filter cases, and exit 1 when anything fails. AgentGuard's own CI runs 158 cases against the shipped policies. SeePOLICY_REFERENCE.md§ Testing policies.Sessions and replay
parent_session_id). It can be set in four places:Guard(parent_session_id=...);parentSessionId;X-AgentGuard-Parent-Sessionheader;GET /v1/sessionslists sessions with their agents, subagents, transports and counts by decision.GET /v1/sessions/{id}returns one session's calls and its child sessions.GET /v1/auditandagentguard auditgainsince,until, session and parent-session filters.The dashboard has a new Sessions tab. Pick a session and replay it with one lane per agent and subagent:
#session=<id>links can be shared.Compliance evidence:
agentguard reportThe report covers one period. It comes as Markdown, JSON or a single HTML page, and contains:
A section maps this evidence to SOC 2 criteria CC6.1, CC6.6, CC7.2, CC7.3 and CC8.1. It is labelled as supporting evidence for an auditor, not a certification.
It reads the audit log files, rotated ones included, and verifies them. Or it can read a running server with
--url. It exits 1, still writing the report, if the audit log fails verification. SeeCOMPLIANCE.md.Remote MCP servers in the MCP gateway
2025-06-18is supported.OpenAI Agents SDK adapter
guard_toolandguard_toolscheck each tool call before it runs, andagentguard_tool_guardrailplugs into the SDK's own guardrails. A denied call raisesAgentGuardDenied, and the tool never runs. Install it withpip install "agentguardproxy[openai-agents]"; it supportsopenai-agents0.3.3 up to 1.0.Security fixes
A command hidden inside another shell skipped the shell rules.
bash -c 'rm -rf /',eval rm -rf /,timeout 5 bash -c '…'andenv sudo …each read as one harmless-looking command. Under the coding-agent blocks, which allow everything except what they deny or send to approval, they passed without the approvalrm -rfandsudoneed. This has affected Claude Code since 1.3.sh/bash/zshand other shells'-cscripts;eval, and here-strings fed to a shell;env,sudo,pkexec,nohup,timeout,xargs,chroot,npx,uv run,poetry runand more.curl … | shmatch inside them too, and a deny on any part wins.bash -cthat AgentGuard can't read (arithmetic, a heredoc,case) asks for approval rather than passing.A disguised address got past network rules. A deny on the cloud metadata address
169.254.169.254didn't catch the same address written another way:http://0xa9fea9fe/,http://2852039166/orhttp://[::ffff:a9fe:a9fe]/;metadata.google.internal.with a trailing dot.Browsers, Node and curl all reach the metadata endpoint with those. AgentGuard now writes every host one standard way before matching, so the rule holds. The shipped agent blocks also deny GCE's
metadatashort name and AWS's IPv6 endpointfd00:ec2::254.A
tools/callwithout an id skipped the policy. The MCP gateway passed any message without an id straight to the MCP servers as a notification, so atools/callsent that way reached them unchecked. This affected local and remote servers. Only real notifications are forwarded now.Tool arguments could hide the real command. The Python adapters (LangChain, CrewAI, MCP, OpenAI Agents) read
commandbeforecmdandpathbeforefile_path. A model sending{"command": "ls", "cmd": "rm -rf /"}to a tool that readscmdgotlschecked andrm -rf /run. Arguments that disagree like this are now denied. The OpenAI Agents adapter also checks exactly the arguments the tool will receive.require_priorfailed open. If the history behind arequire_priorcondition couldn't be read, a deny or approval rule gated on it never fired. It now fires; an allow rule still doesn't.Other fixes
sincefilter put entries that fell in the same second as the bound on the wrong side.Breaking changes
None in the public API: no field, route, flag, subcommand or schema version was removed or renamed. Some behavior is stricter:
require_priorwith an unreadable history: deny and approval rules fire, and allow rules don't match. With no history configured at all, nothing changes.GET /v1/auditanswers 400 to asince/untilthat isn't RFC 3339, or to anuntilbeforesince. 1.3 ignored both parameters.command/cmdorpath/file_pathdisagree.bash -c,evaland launchers. A command that ran unchecked inside them now gets the same verdict as on its own.sudo Xis denied whenXis denied.bash -cscript AgentGuard can't split asks for approval.notifications/*message.Upgrade notes
require_priorrules if your history lookups can fail. Runagentguard testwith cases for them.agentguard setup→ Update, orgo install github.com/Caua-ferraz/AgentGuard/cmd/...@v1.4.0. The SQLite or Postgres store adds two columns on first start. Postgres builds the new indexes in the background; on SQLite a large audit table can make that first start slower.--audit-seal --audit-seal-key-file <file>. Keep the key somewhere the agent can't write.agentguard setup.Details:
MIGRATION.md§ v1.3.x → v1.4.0.Known limitations
/v1/auditand/v1/sessionsread only the live file. Useagentguard reportoraudit verifyfor rotated files..or..can't be opened from the dashboard; useGET /v1/audit?session_id=.find -exec,su -c,ssh host 'cmd',docker run,makeand piping a script into a shell (… | bash), as well as interpreters (python -c,node -e).xargs rm -rfis checked asrm -rfwithout the arguments xargs adds. The full list is inPOLICY_REFERENCE.md§ Compound shell commands.Get started
Full change list:
CHANGELOG.md§ 1.4.0.This discussion was created from the release AgentGuard v1.4.0.
All reactions