Skip to content

feat: generate Cedar policies from natural language in project add policy - #2127

Open
tejaskash wants to merge 2 commits into
refactorfrom
feat/policy-generate
Open

feat: generate Cedar policies from natural language in project add policy#2127
tejaskash wants to merge 2 commits into
refactorfrom
feat/policy-generate

Conversation

@tejaskash

Copy link
Copy Markdown
Contributor

What

Extracts project add policy --generate from #2121 per review, as a stacked PR (base: feat/project-add-policy). This PR re-adds exactly what #2121 dropped:

  • --generate <text> and --gateway <name> on project add policy: generate the Cedar statement from a natural-language description against the deployed engine and gateway, stream progress, print the generated Cedar and every generation finding, then write the policy into the spec.
  • PolicyClient core sub-client (src/core/policy.tsx): resolves the deployed engine and gateway by exact service name (via the shared policyEngineResourceName / gatewayResourceName rules that stay in feat: project add/remove policy-engine and policy with natural-language generation #2121), starts the generation, polls with an injectable delay, surfaces statusReasons and findings on failure, accepts both cedar and Dogwood policy definition members.
  • CorePolicyClient consumer-owned interface, TestPolicyClient, and the wiring through Core / CoreClient / handler configs.
  • Handler-side fail-fast before the multi-minute generation call: engine exists, policy name unique, gateway resolved from the spec (single gateway inferred, multiple demand --gateway).

Testing

  • Unit: PolicyClient tested with a fake at the SDK .send() boundary (pagination, poll exhaustion, GENERATE_FAILED reasons, Dogwood members, findings-only assets); handler flows tested through the real root handler with TestPolicyClient.
  • Live e2e in us-west-2 (run while this code was part of feat: project add/remove policy-engine and policy with natural-language generation #2121): --generate "forbid IAM principals from calling any tool on this gateway" --gateway tools against a deployed stack produced real Cedar with a DENY_ALL finding printed; the generated policy deployed to ACTIVE and was removed cleanly.

Follow-up

deployed-state.json (#2105) can replace the list-and-match resolution with a state-file read; kept out of this PR to keep the extraction a pure move.

@agentcore-devx-automation agentcore-devx-automation Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Nice, self-contained addition. A few observations, none blocking:

  • PolicyClient mocks at the AWS SDK boundary via control.send with instanceof-based command dispatch, which matches the existing convention in configBundle.test.ts / gateway.test.ts. No excessive mocking.
  • Telemetry is done centrally in src/index.ts at the command-run level, so no per-handler instrumentation is needed here.
  • Pre-flight validation in handlers/project/add/policy/index.ts (engine exists, no duplicate policy name, gateway resolvable) correctly happens before the ~minute-long generation call, and the write path is only entered after generatePolicy succeeds — so failed generations don't dirty the project spec (verified in the "fails without writing when generation fails" test).
  • Poll budget is 3s × 40 = 120s with a clear "may still complete" exhaustion message; the loop also handles the Dogwood definition.policy variant in addition to definition.cedar.
  • The service-name resolution correctly reuses policyEngineResourceName / gatewayResourceName, keeping it in sync with the L3 constructs.

Minor things I noticed but wouldn't block on:

  • GetGatewayCommand is called with gatewayIdentifier: deployed.gatewayId without a null check; if the List response ever omitted gatewayId for a matched summary, we'd send undefined. Unlikely in practice.
  • With pollDelayMs = 0 in tests, the "polling exhausts while still generating" case executes 40 real send calls back-to-back; fine, just a note.

LGTM.

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 27, 2026
@tejaskash
tejaskash force-pushed the feat/policy-generate branch from 4c72bd7 to ef9f23c Compare August 27, 2026 18:44
@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Aug 27, 2026
@tejaskash

Copy link
Copy Markdown
Contributor Author

Note on the failing e2e check: it is .github/workflows/e2e-tests.yml running via pull_request_target from the default branch, which assumes main's npm layout (package-lock.json, test-artifacts:* scripts) that the bun-based refactor tree doesn't have. It misfires here only because this PR's base is a feature branch (stacked on #2121), so the refactor-base gating doesn't apply. The real e2e for this tree is the AWS CodeBuild agentcore-e2e check, which passes on #2121. Once #2121 merges and this PR retargets refactor, the proper gating applies.

@tejaskash

Copy link
Copy Markdown
Contributor Author

Same applies to the failing pr-tarball check: a default-branch pull_request_target workflow that expects main's npm lockfile. Both misfires resolve when this PR retargets refactor after #2121 merges; the refactor-tree CI (build, unit-test, check, CodeQL, CodeBuild e2e) is what gates this code.

Comment thread src/core/index.tsx
@@ -7,6 +7,7 @@ import { GatewayClient } from "./gateway";
import { HarnessClient } from "./harness";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PAUSE FOR STANDUP ASK:

  • This is the first time where we have an add project command calling a core client. How should we introduce this? Also, don't you want to confirm the policy before adding to agentcore.json

Base automatically changed from feat/project-add-policy to refactor August 27, 2026 19:27
@tejaskash
tejaskash force-pushed the feat/policy-generate branch from ef9f23c to 20de140 Compare August 27, 2026 19:28
@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Aug 27, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 27, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.23%. Comparing base (2595b9d) to head (20de140).
⚠️ Report is 1 commits behind head on refactor.

Additional details and impacted files
@@              Coverage Diff              @@
##           refactor    #2127       +/-   ##
=============================================
- Coverage     97.22%   71.23%   -26.00%     
=============================================
  Files           463      115      -348     
  Lines         28160    10591    -17569     
=============================================
- Hits          27378     7544    -19834     
- Misses          782     3047     +2265     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants