Skip to content

feat(interventions): add cedar vended intervention handler#2365

Open
lizradway wants to merge 7 commits into
strands-agents:mainfrom
lizradway:cedar
Open

feat(interventions): add cedar vended intervention handler#2365
lizradway wants to merge 7 commits into
strands-agents:mainfrom
lizradway:cedar

Conversation

@lizradway
Copy link
Copy Markdown
Member

Description

Adds a CedarAuthorization intervention handler that evaluates Cedar authorization policies at the tool-call boundary, providing identity-aware access control for agent tool invocations.

The handler integrates with @cedar-policy/cedar-wasm (optional peer dependency) to evaluate Cedar policies before each tool call, returning deny() or proceed() based on the policy decision.

Follows the cedar-for-agents schema generator conventions:

  • One Cedar action per tool (e.g. Action::"search")
  • Resource is unconstrained by default (use resourceResolver for domain-specific entities)
  • Context is nested: { input: <tool args>, session: { hour_utc, call_count, environment } }

Cedar-to-tool mapping

Cedar concept Maps to Example
Principal User identity from invocationState (via principalResolver) User::"alice@acme.com"
Action Tool name Action::"search"
Resource Unconstrained default, or domain object via resourceResolver Resource::"agent" or Record::"42"
Context.input Tool's input arguments { query: "report" }
Context.session Automatic invocation metadata { hour_utc: 14, call_count: 3 }

Key features

  • Fail-closed design — missing principal identity denies all tool calls
  • File-based or inline policies — pass Cedar policy text directly or a path to a .cedar file
  • Pluggable resource resolution — map tools to domain-specific Cedar resources via record or function
  • Context enrichment — automatic hour_utc, call_count, environment in session context, plus custom enricher callback
  • Session-aware rate limiting — built-in per-session call counters with LRU eviction
  • Configurable error handlingonError: 'throw' | 'deny' | 'proceed'

Usage

import { Agent } from '@strands-agents/sdk'
import { CedarAuthorization } from '@strands-agents/sdk/vended-interventions/cedar'

const cedar = new CedarAuthorization({
  policies: './policies/agent.cedar',
  entities: './policies/entities.json',
  principalResolver: (state) => {
    if (!state.user_id) return undefined
    return { type: 'User', id: String(state.user_id) }
  },
})

const agent = new Agent({
  tools: [searchTool, deleteTool],
  interventions: [cedar],
})

await agent.invoke('Delete record 42', {
  invocationState: { user_id: 'alice@acme.com' },
})

Related Issues

Documentation PR

N/A

Type of Change

New feature

Testing

How have you tested the change?

  • I ran npm run check for TypeScript (type-check, tests, lint)
  • 20 unit tests using real Cedar policy evaluation (no mocks) covering: permit/deny, default-deny, role-based access, rate limiting, environment restrictions, fail-closed on missing principal, malformed policy handling, resource resolution (default, record-based, function), context enrichment, file-based policy/entity loading, onError modes (throw/deny/proceed), session reset
  • 3 integration tests with real Bedrock model + real cedar-wasm: policy permit, policy forbid, fail-closed
  • Interactive example (examples/cedar/) tested end-to-end with 5 scenarios

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Comment thread strands-ts/src/vended-interventions/cedar/cedar.ts
Comment thread strands-ts/src/vended-interventions/cedar/cedar.ts
Comment thread strands-ts/src/vended-interventions/cedar/cedar.ts
Comment thread strands-ts/src/vended-interventions/cedar/cedar.ts
Comment thread strands-ts/src/vended-interventions/cedar/cedar.ts
Comment thread strands-ts/src/vended-interventions/cedar/__tests__/cedar.test.ts Outdated
@github-actions
Copy link
Copy Markdown
Contributor

Assessment: Comment

Well-structured Cedar authorization handler that follows existing vended-intervention patterns. The fail-closed security design, real Cedar evaluation in tests, and comprehensive coverage of authorization scenarios are strong.

Review Themes
  • Environment compatibility: The module uses Node.js-specific APIs (node:fs, @cedar-policy/cedar-wasm/nodejs) at the top level, and the test file naming (cedar.test.ts vs cedar.test.node.ts) doesn't reflect this — it will be picked up by the browser test project where it cannot run.
  • Type safety: The cast from Record<string, unknown> (InvocationState) to Record<string, JSONValue> silently narrows types in a way that could surprise consumers.
  • API ambiguity: The policies string parameter overloads path detection and inline text in a way that has edge cases (non-.cedar file paths, inline text ending with .cedar).
  • Session management: The "LRU eviction" described in the PR is actually FIFO, and _maxSessions isn't configurable.

Good first vended intervention — the core authorization logic is clean and the test suite covers the important authorization scenarios thoroughly.

@lizradway lizradway marked this pull request as ready for review May 28, 2026 21:08
Comment thread strands-ts/src/vended-interventions/cedar/cedar.ts
Comment thread strands-ts/src/vended-interventions/cedar/cedar.ts
@github-actions
Copy link
Copy Markdown
Contributor

Assessment: Comment

The Cedar authorization handler is well-implemented with a fail-closed security design and thorough test coverage using real Cedar policy evaluation.

Review Themes
  • Environment compatibility: The module is Node.js-only due to @cedar-policy/cedar-wasm/nodejs and node:fs imports, but the test file naming (cedar.test.ts) would include it in the browser test project. Should be cedar.test.node.ts.
  • API clarity: The policies parameter overloads file-path detection with inline text via endsWith('.cedar') heuristic, which has edge cases. Consider separate policies/policiesFile options.
  • Session management: The eviction strategy is FIFO (not LRU as described), and _maxSessions is not configurable.
  • API review: Per team/API_BAR_RAISING.md, this introduces a new public class (CedarAuthorization) that customers will directly use. Consider adding the needs-api-review label to ensure the public API surface gets appropriate review.

Solid implementation overall — the core authorization logic, TSDoc, and test scenarios are comprehensive.

@github-actions github-actions Bot added size/xl and removed size/xl labels May 29, 2026
@yonib05 yonib05 added area-hil Human in the loop and suspend/resume area-tool Tool behavior/api enhancement New feature or request python Pull requests that update python code labels May 29, 2026
@lizradway lizradway removed the area-tool Tool behavior/api label May 29, 2026
@lizradway lizradway requested a review from mkmeral May 29, 2026 19:07
@lizradway lizradway added needs-api-review Makes changes to the public API surface area-interventions Related to interventions labels May 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-hil Human in the loop and suspend/resume area-interventions Related to interventions enhancement New feature or request needs-api-review Makes changes to the public API surface python Pull requests that update python code size/xl

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants