In Brief
- AWS released Dogwood in early August under Apache 2.0: a policy language extending Cedar with temporal conditions that read an agent’s event history, and any syntactically valid Cedar policy remains a valid Dogwood policy with no migration.
- AWS’s own worked example and the independent MasuGate paper name the same defect from opposite directions: a limit metered after responses loses to concurrent requests that are all in flight before any one resolves.
- Sequence-aware policy expresses what point-in-time authorization cannot — tool-call ordering, single-use approval gates, data freshness, cumulative caps — and Amazon Bedrock AgentCore now ships the machinery for those patterns as a managed service with a 24-hour look-back window, though several of AWS’s own worked example policies do not implement the pattern they illustrate.
- The costs are stated by AWS itself: evaluation is stateful and its time complexity can depend on event-log length, temporal conditions lose Cedar’s automated-reasoning tooling, and the reference interpreter is explicitly not intended for production use.
- MasuGate’s PostgreSQL-backed prototype eliminated stale authorizations in every benchmarked workload at a throughput cost that peaks at roughly 7% against hand-written transactions at the higher benchmarked service time — results its authors scope as controlled benchmarks rather than deployment traces.
Why This Matters
The controls practitioners actually want on agents — no trade without a fresh price lookup, no transfer past a session budget, one approval consumed per execution — are properties of sequences of tool calls, and the deterministic engines authorizing those calls have mostly evaluated one request at a time; the shipped exceptions, Microsoft’s Agent Governance Toolkit and Omnigent with their cumulative cost budgets, stop at spend counters rather than general history. That gap is where approval gates get replayed and spend caps get raced. In the span of one week in August, a hyperscaler shipped a policy language that reads the agent’s history before permitting its next action, and an arXiv paper formalized why history alone is still not enough under concurrency. Together they mark out what the next layer of agent governance looks like, what it costs, and how much of it is real today.
Key Findings
1. Point-in-time authorization cannot see the workflow it guards
Cedar — the open-source authorization language behind Policy in Amazon Bedrock AgentCore — was built for deterministic, single-request decisions at a default-deny boundary: “When you associate a Policy with a Gateway, it blocks everything by default.” That amnesia is a feature for classic authorization. Identical requests always get identical answers, and evaluation stays fast and analyzable.
It is also exactly the wrong shape for agent workflows. InfoQ’s analysis puts the limit plainly: a sequence of actions is outside what Cedar can describe. AWS VP and Distinguished Engineer Marc Brooker, interviewed by Ken Yeung, frames the requirement: “Often the answer to ‘can I do this now?’ depends on what has come before,” and such rules “are really not possible to cleanly express in the authorization languages that we have today.”
The question of where the authorization decision for an agent’s tool call should live — outside the agent, at a boundary its context cannot rewrite — was settled by a wave of July research and the productized gateways that match it. This month’s development is about what that boundary may read. AWS’s temporal-policy walkthrough walks through seven patterns that only exist over histories: workflow sequencing, output-to-input integrity (current inputs must match prior outputs), data freshness, cumulative budget caps, single-use human approval gates, mutual exclusion between contradictory actions, and permissions that tighten after inactivity.
The walkthrough’s code deserves a closer read than its headings. The published integrity policy correlates the prior call’s input.profile_id — an input, not the returned portfolio IDs the prose promises to match. The cumulative cap authorizes execute_trade while summing input.cost from get_market_price requests, so it never totals trades. The mutual-exclusion policy omits the event-kind suffix the language requires, and its verdict table contradicts the rule’s own direction and 24-hour window. The pattern names are the contribution; the example policies are illustrations to test before trusting, not controls to copy.
A blunter sibling shipped alongside. Gateway rate limiting now sets per-user ceilings keyed to identities already managed through OAuth or IAM: request rates on every target behind the gateway, token throughput on model inference specifically, and concurrent connections held open for a request’s lifetime. Rate limits answer “how much”; the temporal patterns answer “in what order, under which prior conditions.” The two compose rather than compete.
2. Dogwood makes history a policy input without abandoning Cedar
Dogwood is AWS’s answer, released as an Apache 2.0 specification and reference interpreter. Its design bet is continuity: “Any syntactically valid Cedar policy is a syntactically valid Dogwood policy, so an existing Cedar policy set can be reused as-is, with no rewrite and no migration.” Temporal reasoning arrives as a when temporal clause. The core surface is three past-only operators — formerly, previous, and since — plus exists and tp binders and native count/sum aggregation, defined over a core subset of Metric First-Order Temporal Logic (MFOTL), a formalism from the runtime-verification literature; the release post’s worked shapes lean on standard-library macros (count_within, count_distinct_within, sum_within) layered above those primitives.
A spending cap reads like this in AWS’s post:
forbid ( principal, action == AgentCore::Action::"Transfer", resource )
when temporal {
sum_within(a, 1h, AgentCore::Action::"Transfer"::request{ input.amount: a }) > 5000
};
The language guide pins down the semantics with unusual care for a v1. Every event predicate carries a mandatory event-kind suffix; ::request and ::response are the conventional kinds, and a custom schema may define others. formerly “is the existential past operator: it holds at the decision timepoint if its body held at some timepoint within the window.” Windows are closed intervals with second precision; the language is past-only, so nothing later than the decision timepoint is ever read. Aggregation is deliberately spare — count and sum exist, min/max/avg do not — and by default evaluation is pinned to the caller, so a decision consults a key-local slice of the trace rather than the whole log.
The evaluation path keeps Cedar at the core. Per InfoQ, temporal conditions translate into Cedar context fields populated from the event history before evaluation, with a bind operator naming aggregates so they can be compared against the current request. The hard engineering moves to the history store, not the decision engine.
That key-local detail matters for cost, and the discipline of the ::request/::response distinction matters for correctness — which is where both August artifacts converge.
3. The named defect is concurrency, and two artifacts hit it independently
AWS’s worked example is a confession of the industry’s default pattern. A cap that sums Transfer::response events looks identical to one that sums Transfer::request events; InfoQ observes that one word separates the two policies. AWS’s own post states the difference: “Because this policy only sums the amounts associated with responses, an agent can circumvent the intended limit by issuing many concurrent transfer requests before any one of them resolves.” Metering at settlement loses to concurrency; the limit has to bind at admission.
The failure shape is not new — only the layer is. Cloud billing-plane spend controls lose to agent-speed spending the same way: there the meter lags by hours, here by the round-trip of an in-flight request, and in both cases the control watches a trailing indicator.
Stateful Governance for Concurrent Agentic Systems (Yuxiang Peng and Xiaodi Wu, posted to arXiv August 3) formalizes the general case and names it stale authorization: a decision correct when made becomes unsafe by the time its effect commits. Their minimal example is two agents transferring from different accounts against a shared team budget one credit under its limit — both individually permitted, jointly a violation. In the authors’ framing, “both requests may carry the same computed spent_24h value, and the policy engine cannot see that the first committed transfer invalidates the second request’s context.” It is a check-then-act race over policy state, and their experiments show a Cedar baseline committing both racing transfers.
The two fixes are not the same fix, and the distinction is the sharpest thing a practitioner can take from reading the artifacts together. Dogwood makes the gateway’s own event log a policy input, and because a request event enters the trace at admission, request-counted limits close the specific circumvention AWS models. MasuGate targets the facts that live outside any gateway’s log — budget rows, inventory counts, approval flags in provider databases — which can change between the policy read and the committed effect no matter how complete the history is. History fixes expressiveness. It does not, by itself, fix atomicity.
4. MasuGate buys atomicity with database machinery, at measured cost
MasuGate’s correctness condition, policy-state serializability, requires “committed effects to be explainable as authorized against the policy state immediately before they occur” — every commit must be justifiable against the state at its serial position, not at request time. The mechanism is recognizably a database one. Providers declare certified read-only views of governance facts and contracts over effect footprints; the runtime maps a decision’s reads and writes to named logical scopes, locks only overlapping scopes, and evaluates the policy and commits the effect inside that protection. Two modes handle the human in the loop: transaction mode for immediate effects, and a reservation/hold mode that sets aside capacity for a pending approval so the delay neither blocks unrelated work nor gets invalidated by it.
The paper’s key numbers:
| Result | Baselines | MasuGate | Source |
|---|---|---|---|
| Full-conflict workload: 256 ops against a 50-unit budget | naive and Cedar baselines: ~79–81 commits, 30–31 stale allows | exactly 50 commits, 0 stale allows | arXiv 2608.02764 |
| Throughput at 10 ms simulated service time | — | 86.4 ops/s, 0.93× hand-written transactions, 1.64× a global lock | arXiv 2608.02764 |
| Scripted procurement workflow (256 workflows, shared budgets + inventory) | Microsoft’s Agent Governance Toolkit and Omnigent: 12.6–41.4 stale authorizations | 0 stale authorizations | arXiv 2608.02764 |
The approval results are the part most relevant to human-in-the-loop designs. In the long-running workload, a global lock preserved a pending approval’s basis only by freezing all other work, while MasuGate’s hold and reservation modes preserved every pending approval as unrelated transfers on disjoint scopes continued (arXiv 2608.02764). That is the property an escalation queue needs: the approval a human is still reading stays valid without stopping the fleet.
A throughput cost of roughly 7% against manually written transactions at the higher of the two benchmarked service times — near zero at the lower — with scoped locks beating a global lock by 1.64× as service time grows, is a defensible price for zero stale allows — in a benchmark. The authors are candid about the scoping: “The workloads are controlled benchmarks rather than deployment traces,” the prototype exercises one policy-state provider, and “MasuGate cannot create consistency guarantees that the policy-state provider cannot enforce.” Effects on external APIs, where holding a database transaction across network I/O is unattractive, are named and deferred. This is a research prototype establishing that the property is achievable at tolerable cost, not a system to deploy.
5. Remembering is priced in evaluation cost, lost tooling, and bounded windows
Point-in-time Cedar evaluates in bounded time and supports automated policy analysis. Temporal conditions give both up, and AWS says so in the release post: evaluation requires stateful tracking of events and its “time complexity of evaluation can depend on the length of the event log,” while “temporal conditions do not currently support the powerful automated reasoning analysis tools that Cedar provides.” A policy you can no longer formally analyze, evaluated against a log that grows with agent activity, is a real regression from Cedar’s guarantees — accepted deliberately, in exchange for expressiveness.
The open-source interpreter is scoped accordingly. The repository README states it is not intended for production use and exists to make the language’s semantics understandable; it validates policies, lowers pure-Cedar subsets, and replays event traces, with an in-memory temporal engine that has no eviction or size cap. InfoQ enumerates what a production engine would still need: trusted timestamps, authenticated events, durable storage, tenant isolation, and retention policy.
AWS’s managed answer to the growth problem is a hard bound. In AgentCore’s temporal policies, every evaluated request carries a session identifier, trajectories are scoped to session plus end-user identity, and “Within an active session, agent trajectories carry a maximum look-back window of 24 hours. Any trajectory events older than that are automatically deleted.” Policy changes invalidate existing sessions rather than evaluate new rules over old traces. The first 100 temporal policies per policy engine are included in the existing per-authorization-request price. The companion capabilities post states the enforcement property that makes the whole layer worth having: “The agent does not see the policy logic and cannot reason around it, regardless of how it is prompted or whatever defects it carries.”
Practical Implications
Write every aggregate limit over request events, not response events. This is the one rule that travels regardless of stack. A cap summed over completions is a cap an agent defeats by parallelism — AWS’s worked example is the vendor writing that on the wall. Audit existing rate limits and budget checks in gateways and middleware for the same one-word defect: if the counter increments on settlement, the limit meters the past.
On AWS, temporal policies in AgentCore Policy are the adopt-now surface — design the session boundary deliberately. The session identifier defines the unit of memory: what shares a session shares a budget and an approval history, and the 24-hour look-back plus session invalidation on policy change are operating constraints to plan around, not surprises to discover. The first 100 policies ride the existing per-request price, so cost is not the barrier to trying it.
Off AWS, treat Dogwood as a specification to learn and test against, not software to deploy. The interpreter earns its keep in CI — validating policies, replaying recorded traces to check verdicts — while the production engine remains yours to build, with the trusted-event-history problem (authenticated, timestamped, durable, tenant-isolated) as the actual engineering cost. Budget for that before budgeting for policy authoring.
Inventory which of your limits read state no event log contains. A budget row in Postgres, an inventory count, an approval flag — anything a policy reads from a mutable store can go stale between decision and effect, and history-aware policy does not fix that. Where the store is a database you own, MasuGate’s pattern is implementable today with transactions and scoped locks; the paper is a design document for it. Where effects cross API boundaries, nothing surveyed here closes the gap yet — the MasuGate authors defer it as future work.
Make approval gates consume — and audit the reference example before copying it. One approval per execution is the difference between an approval gate and an approval precedent, and it is AgentCore’s stated intent. The published policy falls short of that intent on two counts: it correlates only approval status and resource, never the trade’s arguments, and it marks consumption with the execute_trade response event — the same settlement race the budget example warns about, so a second large trade authorized before the first one’s response still sees the approval as unspent. Bind each approval to the exact arguments or a unique approval ID, and consume it at admission, not at settlement.
Open Questions
- Who ships a production-grade open temporal engine? The open release is a specification and a semantics-only interpreter, while the production-grade evaluation available today runs inside the managed AgentCore service; whether gateway vendors or an OSS effort take up the spec determines if this becomes a portable standard or a managed-service feature with a published grammar.
- Does the managed engine itself satisfy policy-state serializability? Public documentation describes evaluation against the session trajectory but does not state whether concurrent evaluations against the same trajectory are serialized end-to-end with effect commitment — precisely the property MasuGate names. Public detail on that boundary remains thin.
- Can automated reasoning be recovered for temporal conditions? Cedar’s analyzability was a headline reason AWS chose it; the temporal extension currently forfeits it, and whether a useful analyzable fragment exists is an open research question.
- The stated roadmap — absolute-time windows, liveness operators (what must happen, not only what must not), multi-agent orchestration policies — would each expand expressiveness and evaluation cost together; liveness in particular changes the enforcement model from blocking actions to demanding them.
- Who authors these policies? Brooker’s expectation is that most developers won’t write Dogwood directly, with frameworks and agents generating policies from requirements — which relocates the correctness question to the generator, for a policy class whose request/response subtlety already caught the vendor’s own illustrative example.
Sources
- Introducing Dogwood: runtime verification for AI agents (AWS Open Source Blog)
- dogwood-policy/dogwood repository (GitHub)
- The Dogwood Guide — Temporal expressions
- Stateful Governance for Concurrent Agentic Systems (arXiv:2608.02764)
- Securing AI agents with temporal policies in Amazon Bedrock AgentCore (AWS Machine Learning Blog)
- Control agent behaviors and cost beyond a single action: new capabilities in Amazon Bedrock AgentCore (AWS Machine Learning Blog)
- AWS Open-Sources Dogwood, Extending Cedar to Govern Sequences of Agent Tool Calls (InfoQ)
- Dogwood: AWS’s New Policy Language for AI Agent Rules (The AI Economy, Ken Yeung)
- Why Policy in Amazon Bedrock AgentCore chose Cedar for securing agentic workflows (AWS Security Blog)