fix(docs): document lambda:InvokeFunction for code-based evaluators - #1891
Merged
Conversation
`run eval` against a code-based evaluator fails with AccessDeniedException
for callers using the documented user policy:
Access denied when invoking Lambda function: ... User: ... is not
authorized to perform: lambda:InvokeFunction on resource:
arn:aws:lambda:...:function:<Agent>-eval-<evaluator>
`bedrock-agentcore:Evaluate` invokes the evaluator's Lambda under the
*caller's* identity, so the caller needs `lambda:InvokeFunction`. A
resource-based policy on the function alone does not cover it.
Neither iam-policy-user.json nor the PERMISSIONS.md Evaluation table
granted or mentioned it, because until the DeepEval/Autoevals tests
added in #1828 every eval path exercised was either `Builtin.*` or
`llm-as-a-judge` -- neither of which touches Lambda.
Scoped to `arn:*:lambda:*:*:function:*-eval-*` (partition wildcard per
the multi-partition rules in AGENTS.md) rather than `*`.
The same statement was added to the e2e-github-actions CI role, which
had no lambda:InvokeFunction on any of its 9 policies -- that is what
broke e2e shard 5 on main:
https://github.com/aws/agentcore-cli/actions/runs/30663047263/job/91263525976
Contributor
|
Claude Security Review: no high-confidence findings. (run) |
Contributor
Package TarballHow to installgh release download pr-1891-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.25.0.tgz |
Contributor
Coverage Report
|
notgitika
approved these changes
Aug 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
run evalagainst a code-based evaluator fails withAccessDeniedExceptionfor anyone using the documented user policy:This broke
e2e (5/5)onmain— 2 of 58 tests inthird-party-eval-lifecycle.test.ts, retried 18× over ~250s with the same denial each time, so not a flake: run 30663047263Root cause
bedrock-agentcore:Evaluateinvokes the evaluator's Lambda using the caller's identity, so the caller needslambda:InvokeFunction. A resource-based policy on the function alone does not cover this. (The error is botocore-formatted —reached max retries: 0— and the wrapper stringAccess denied when invoking Lambda function:appears nowhere in this repo, confirming it originates service-side.)Neither
docs/policies/iam-policy-user.json(zerolambda:*actions) nor the PERMISSIONS.md Evaluation table granted or mentioned it. It went unnoticed because until the DeepEval/Autoevals tests added in #1828, every eval path exercised wasBuiltin.*(evals-lifecycle.test.ts:143) orllm-as-a-judge— neither touches Lambda.third-party-eval-lifecycle.test.tsis the first test to run--type code-based, which deploys a real Lambda per evaluator.This is a user-facing gap, not just CI: anyone following the documented policy hits the identical denial.
Changes
docs/policies/iam-policy-user.json— addCodeBasedEvaluatorInvocationstatementdocs/PERMISSIONS.md— add the action to the Evaluation table + explain why the caller (not the function) needs itScoped to
arn:*:lambda:*:*:function:*-eval-*— matches the<AgentName>-eval-<evaluatorName>naming, uses the partition wildcard per the multi-partition rules in AGENTS.md, and avoidsResource: "*".Also applied outside this repo
The
e2e-github-actionsrole in the E2E account had nolambda:InvokeFunctionon any of its 9 policies. Added the equivalent statement (account-scoped) to itse2e-permissionsinline policy — statements 22 → 23, none lost. Verified withsimulate-principal-policy:E2e3pEval30379817-eval-answer_relevancyE2e3pEval30379817-eval-exact_match*-eval-*in a different accountTesting
prettier --check+secretlint+typecheckpass (pre-commit)simulate-principal-policyon the two exact ARNs that were deniedNot yet proven end-to-end. These tests only run on the CodeBuild-hosted runners in the E2E account (
runs-on: codebuild-agentcore-e2e-...), so they can't be reproduced locally, andgh run rerun --failedon the original run is refused while its attempt 2 still has a job in progress. The two failing tests should be re-run to confirm.Out of scope — two separate issues found while investigating
e2e (1/5)on attempt 1 ande2e (5/5)on attempt 2 both died much earlier, at Clone CDK repository:remote: Repository not found/ exit 128, despite the app-token step reporting success. Different shards each time, other shards clone fine in the same run — an infra flake in the app-token → clone handoff (.github/workflows/e2e-tests-full.yml:83-105) worth a retry wrapper.e2echeck showedskippingon feat: add --model-provider flag for keyless Bedrock LLM judge evaluators #1828, so this test merged without ever running against a real role. That process hole is why the gap reachedmain.