Why Amazon Bedrock AgentCore chose Cedar, how Cedar policies are structured, and how the Gateway becomes the single choke point for every agent-to-tool request.
Cedar is the open-source authorization language behind Amazon Verified Permissions. AWS chose it for agent authorization because security decisions about non-deterministic agents must themselves be deterministic and auditable.
The same request + policies always yields the same decision. No model in the loop, no ambiguity.
Policies are declarative text you can review, diff, and put under change control.
Cedar is designed for analysis — you can reason about what a policy set does before it ships.
forbid overrides every permit. And the baseline is default deny: an agent has no permissions until a policy explicitly grants them.
Why it fits agents: you can't predict what an agent will try, but you can guarantee what it will be allowed to do. Cedar turns an unpredictable actor into a bounded one.
Every Cedar policy answers three questions: who (Principal), what (Action), and on what (Resource) — optionally gated by conditions.
Which agent or identity.
Which operation.
Which tool or data.
Permit — scoped, conditional access
Forbid — an override that always wins
AgentCore::OAuthUser, actions as AgentCore::Action::"<target>___<tool>", and the resource is the gateway itself: AgentCore::Gateway::"<gateway-arn>". Note the triple underscore joining target name to tool name — a detail that bites people on their first policy.
The same permit, written the way Amazon Bedrock AgentCore actually expects it
Why conditions are the powerful part: a single policy can constrain two very different data sources. Principal tags come from the JWT — the LLM cannot hallucinate or alter them. Tool arguments in context.input come from the LLM's own tool call — so Cedar is where you bound them to sane values. Unexpected arguments get rejected deterministically.
Build a request the way an agent would, then evaluate it against a fixed policy set. Watch Cedar decide — and see why. This runs entirely in your browser; no AWS needed.
portfolio-agent may invoke Tool:market-data when business hours
read / write its own Memory:session
trading-agent may executeTrade on Tool:trade-api when approval attached
Memory:pii-namespace (forbid always wins)
Try these on camera: (1) portfolio-agent · invoke · market-data with hours on → ALLOW; turn hours off → DENY (condition fails → default deny). (2) any request touching pii-namespace → DENY even if a permit exists (forbid wins). (3) trading-agent · executeTrade · trade-api → DENY until you attach approval.
The Gateway is where policy meets traffic. Every agent-to-tool request flows through it, Cedar evaluates the request, and the Gateway allows or denies. One place to enforce, one place to audit.
Agent asks to call a tool.
Intercepts every request.
Cedar decides allow / deny.
Call proceeds, or is blocked + logged.
The Gateway mediates Model Context Protocol connections, so tool servers are reached through a governed broker.
Custom code runs before/after policy evaluation — token enrichment, request logging, rate limiting, content scanning.
Prompt-attack detection, content filtering, and PII detection applied at the Gateway level.
tools/list, Cedar's partial evaluation hides any tool that would always be denied, so the agent never sees it.
allowedWorkloadConfiguration on the authorizer.
LOG_ONLY: it evaluates every request and writes the decision, but blocks nothing. Validate your rules against real traffic there, then switch to ENFORCE. Going straight to enforce is how you discover a missing baseline permit during business hours — remember the engine is deny-by-default, so without an explicit permit, everything stops.
The payoff: because all tool traffic funnels through the Gateway, "tool misuse" from M1 has exactly one place to be stopped — and every attempt, allowed or denied, lands in your audit trail (M6). A forbid rule added via the control-plane API takes effect immediately, which makes it a genuine emergency kill switch — no redeploy.
PolicyEngineMode, PolicyValidationMode