AWS Dogwood Gives Agent Guardrails a Memory
By extending Cedar with temporal logic, AWS makes 'what happened before?' an enforceable question at the tool-call boundary.
The demo-day failure mode for AI agents isn't the forbidden tool call. It's the permitted one that shouldn't have happened yet — or again, or without a human signing off first. An agent that's allowed to transfer money is allowed to transfer money fifty times in a minute. An agent that's allowed to delete a file is allowed to delete one nobody backed up. Every individual call clears the permission check; the sequence is the incident.
Dogwood, which AWS open-sourced this week under Apache 2.0, is the most serious attempt yet from a major cloud to close that gap with a language instead of vibes. It extends Cedar — the authorization language AWS released in 2023 and built Amazon Verified Permissions on — with temporal operators, so a policy can consult what already happened before it answers yes. Marc Brooker, the AWS VP and distinguished engineer behind much of Lambda and Aurora DSQL, frames the gap plainly: authorization that judges "each action, each tool call, each step in isolation" is "incomplete," because "often the answer to 'can I do this now?' depends on what has come before."
Policies with a memory
Every valid Cedar policy is a valid Dogwood policy, so existing policy sets carry over untouched, along with Cedar's deny-by-default semantics — forbid always beats permit. What's new is the when temporal { ... } clause, which matches against the agent's event history. The flagship pattern is approval-before-action:
permit ( principal, action == AgentCore::Action::"SellShares", resource )
when temporal {
formerly within 1h AgentCore::Action::"ApproveSale"::response{
input.stock: context.input.stock,
input.shares: context.input.shares,
output.approved: true
}
};
The sale only goes through if a matching approval — same stock, same share count — happened in the last hour. Alongside formerly, a standard library adds aggregations: count_within for rate limits, count_distinct_within for rules like "no more than three distinct payees per hour," and sum_within for cumulative caps:
forbid ( principal, action == AgentCore::Action::"Transfer", resource )
when temporal {
sum_within(a, 1h, AgentCore::Action::"Transfer"::request{ input.amount: a }) > 5000
};
That's a running spending cap in five lines, enforced outside the model. No system prompt to inject around, no LLM judge to sweet-talk.
Runtime verification, wearing a lanyard
AWS didn't invent this math, and to its credit it says so. Those aggregation operators aren't primitives — they're macros drawn from Metric First-Order Temporal Logic, the formalism behind academic runtime monitors like ETH Zurich's MonPoly, which researchers have used for over a decade to check audit logs against compliance rules. Dogwood's contribution is the packaging: Cedar-compatible syntax, a Rust reference interpreter, and schema generation straight from an agent's MCP tool manifest, one action type per tool.
Compare that with what teams actually deploy today. Prompt-level guardrails are suggestions to a model that, in Brooker's words, is a "persistent problem solver" that "will find another way." LLM-judge middleware is probabilistic and costs a model call per decision. OPA can express some of this if you assemble and feed it the history yourself, but Rego has no native notion of time or event sequence — the bookkeeping becomes your problem. And MCP-era permissioning is binary per tool: you can grant an agent delete_file or not, but you can't say "only after a backup_file for the same path succeeded." That rule is a Dogwood one-liner, and it's exactly the granularity real agent incidents keep demanding. Startups like Invariant Labs got to trace-level guardrails earlier, but a Cedar-compatible language from AWS is what makes platform teams treat the pattern as infrastructure rather than a bolt-on.
What adopting it looks like
The intended enforcement point is a gateway between the agent and its tools. In AWS's world that's AgentCore Policy, the tool-call governance layer of Amazon Bedrock AgentCore, which picked up Dogwood's temporal rules with a built-in compiler and state tracking (rate limiting went GA alongside). Because the engine sits outside the agent process, a prompt-injected agent can't talk its way past it — the whole point of putting the check at the boundary instead of in the prompt.
For local work, the repo ships a dogwood-language Rust crate and a CLI with validate, lower, and replay commands. replay is the sleeper feature: point it at a recorded event trace and check what your policy would have permitted or blocked at each step. That's unit testing for governance — runnable in CI against traces of past incidents. lower shows the desugared Cedar that temporal clauses compile to, with history injected into context.* slots at runtime. The repo even bundles skill files for Claude Code, Cursor, and Copilot, which tells you who AWS expects to be writing these policies.
Authoring has sharp edges, though, and AWS flags one itself: rate-limit on request events, not response events, because an agent can fire concurrent calls that all pass the check before any of them resolve. That's a time-of-check-to-time-of-use bug expressed in policy. Formal syntax doesn't exempt you from concurrency reasoning.
The catches, and the call
Three caveats deserve equal billing with the launch. First, the reference interpreter is explicitly not production-ready — no event authentication, no timestamp-integrity checks, no multi-tenant isolation, no audit logging. The event log is now your security boundary: if an attacker can forge an approval event into it, the policy happily permits the action. Production-grade enforcement today means AgentCore Policy, which is the familiar AWS motion — Firecracker fed Lambda, Cedar fed Verified Permissions — of an open language with gravity toward a managed service.
Second, temporal conditions currently give up Cedar's headline feature: automated-reasoning analysis. Plain Cedar policies can be exhaustively analyzed for conflicts and coverage; Dogwood's temporal clauses can't yet. There's real irony in a formal-methods project whose new constructs escape formal analysis, and it matters in practice — bugs in your temporal rules get caught by replay testing, not by proof.
Third, evaluation is stateful, and its cost can grow with the length of the event log. On a hot path brokering every tool call, that's a latency budget item, not a footnote.
Still, the call here is easy: genuine shift, not launch-week hype. Deterministic, history-aware enforcement at the tool boundary is the right architecture for agent safety, and it's where the industry was already converging piecemeal. If your agents touch money, production data, or the outside world, start writing Dogwood rules now and replay them against your traces — the language will outlive the caveats. Just go in clear-eyed about the v0 reality: an expressive language, a reference-grade interpreter, and a production path that currently runs through AWS.
Sources & further reading
- Your AI agent's next tool call may be valid but wrong. AWS's Dogwood promises to fix that. — thenewstack.io
- Introducing Dogwood: runtime verification for AI agents — aws.amazon.com
- Reference parser and interpreter for the Dogwood policy language — github.com
- Dogwood: AWS's New Policy Language for AI Agent Rules — theaieconomy.substack.com
Rachel has been embedded in the developer tooling ecosystem for nearly eight years, covering everything from IDE wars and package-manager drama to the quiet rise of AI-assisted coding. She has a soft spot for open-source maintainers and an unhealthy number of terminal emulators installed on a single laptop.
Discussion 0
No comments yet
Be the first to weigh in.