Skip to content

fix: correct AB test execution role IAM policy and promote stability - #1120

Merged
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission
May 5, 2026
Merged

fix: correct AB test execution role IAM policy and promote stability#1120
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission

Conversation

@jariy17

@jariy17jariy17 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • IAM policy — Aligns the auto-created AB test execution role with the official docs, fixing a 400 "Access denied when validating evaluator" error on every deploy with a custom evaluator
  • Promote stabilitypromote ab-test waits for executionStatus === 'RUNNING' before stopping, avoiding 409 errors when promote runs immediately after resume; throws a clear error if the test never reaches RUNNING
  • IAM — DescribeLogGroups — Split into its own statement with Resource: "*" (AWS requirement)
  • E2E coverage — Added AB test reaches RUNNING status after deploy to ab-test-target-based.test.ts to catch IAM permission regressions post-deploy
  • Status test — Fixed incorrect http-gateway resourceType assertion; replaced with ab-test + invocationUrl check
  • Local e2e script — Added scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally

IAM changes

Trust policy — added SourceAccount + SourceArn conditions to prevent confused deputy attacks:

"Condition": {
"StringEquals": { "aws:SourceAccount": "<accountId>" },
"ArnLike": { "aws:SourceArn": "arn:aws:bedrock-agentcore:*:<accountId>:ab-test/*" }
}

Permissions — 3-statement policy aligned with docs:

  • AgentCoreResources — all bedrock-agentcore actions scoped to account with ResourceAccount condition (adds GetEvaluator, GetGatewayTarget, ListGatewayTargets, ListConfigurationBundleVersions)
  • CloudWatchLogsDescribelogs:DescribeLogGroups with Resource: "*" (required by AWS)
  • CloudWatchLogs — log read/write actions scoped to evaluation and spans log groups

Running E2E tests locally

export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role>export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>
./scripts/run-e2e-local.sh e2e-tests/ab-test-target-based.test.ts

Test plan

  • e2e-tests/ab-test-target-based.test.ts — all steps pass including RUNNING check
  • e2e-tests/ab-test-config-bundle.test.ts — passes (RUNNING check deferred to follow-up once real config bundles are used)
  • Unit tests src/cli/operations/deploy/__tests__/post-deploy-ab-tests.test.ts — 23 passing
  • Unit tests src/cli/commands/pause/__tests__/promote.test.ts — 4 passing

The AB test API validates evaluator ARNs server-side using the execution
role. The auto-created role policy was missing bedrock-agentcore:GetEvaluator,
causing a 400 "Access denied when validating evaluator" error on every deploy
that included a target-based AB test with a custom evaluator.
@jariy17
jariy17 requested a review from a teamMay 4, 2026 23:26
@github-actionsgithub-actionsBot added size/xs PR size: XS agentcore-harness-reviewing AgentCore Harness review in progress labels May 4, 2026
HTTP gateways are not surfaced as top-level resources in agentcore status —
they are only used internally to build AB test invocation URLs. The test was
asserting on resourceType 'http-gateway' which never appears; fix it to
assert on the 'ab-test' resource instead.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/xs PR size: XS labels May 4, 2026
@agentcore-cli-automation

Copy link
Copy Markdown

The new EvaluatorReadStatement is scoped to Object.values(deployedResources?.evaluators ?? {}), which only contains custom evaluators deployed by this project. This will leave the original 400 error in place whenever the AB test's online-eval config references evaluators that aren't in deployedResources.evaluators:

  • Builtin evaluators (Builtin.Faithfulness, Builtin.GoalSuccessRate, etc.) — these are first-class evaluator references in OnlineEvalConfig.evaluators (see src/schema/schemas/primitives/online-eval-config.ts:23-24 and the handling in AgentCoreOnlineEvaluationConfig.ts:143-161). If the service validates evaluator ARNs uniformly using the execution role, Builtins will fail the same check the PR is trying to fix.
  • External evaluator ARNsOnlineEvalConfig.evaluators also accepts raw ARNs pointing at evaluators outside this project / another account. Those are never in deployedResources.evaluators either.

Separately, even for the custom-evaluator case, the policy grants GetEvaluator on every evaluator in the project rather than just the ones this specific AB test transitively references via its onlineEvalConfigArns. That's a least-privilege concern but not a functional blocker.

A couple of ways to address this:

  1. Resolve evaluators transitively from the referenced online eval configs. For each online eval config referenced by testSpec.evaluationConfig, look up its evaluators list in projectSpec.onlineEvalConfigs, and for each entry:

    • Builtin.* → construct the builtin ARN (arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*)
    • arn:... → use as-is
    • otherwise → look up in deployedResources.evaluators

    Pass that de-duplicated list as evaluatorArns. This fixes both the Builtin/external case and the over-broad scoping.

  2. If tightening the scope is risky, at minimum add arn:${partition}:bedrock-agentcore:::evaluator/Builtin.* to the Resource list (and optionally arn:${partition}:bedrock-agentcore:${region}:${accountId}:evaluator/*) so users with builtin evaluators don't hit the same 400.

Could you also confirm whether you tested the fix with a Builtin evaluator in the online eval config, or only with a custom one? The test plan only mentions ab-test-target-based.test.ts / ab-test-config-bundle.test.ts — knowing which evaluator types those exercise would help.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 4, 2026
@github-actions

github-actionsBot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines43.11%9016 / 20912
🔵Statements42.4%9575 / 22582
🔵Functions39.96%1555 / 3891
🔵Branches39.98%5808 / 14527
Generated in workflow #2425 for commit 5b72ab3 by the Vitest Coverage Report Action

The resource cast was missing invocationUrl, causing a TypeScript error
when asserting the AB test's gateway invocation URL was present.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/s PR size: S labels May 4, 2026
- Include stdout in promote failure message so the JSON error is visible
- Add scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/s PR size: S labels May 5, 2026
When promote is called immediately after resume, the AB test may still be
in UPDATING state and reject the STOPPED transition with a 409. Retry up
to 6 times with a 10s delay to wait for the transition to complete.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus is no longer UPDATING before
attempting to stop. The service rejects updates with 409 while a
state transition is in progress (e.g. after resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus === 'RUNNING' before issuing the
STOPPED transition. The service 409s if the test is still UPDATING
(e.g. transitioning from a prior resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…figs
Previously GetEvaluator was scoped to all project evaluators. Now it's
scoped to only the evaluators referenced by the specific online eval
configs this AB test uses, handling all three cases:
- Custom evaluators: looked up from deployedResources.evaluators
- Builtin.* evaluators: ARN constructed from the builtin ID
- External ARN references: used as-is
@github-actionsgithub-actionsBot removed the size/m PR size: M label May 5, 2026
@jariy17

Copy link
Copy Markdown
ContributorAuthor

Addressed in 44bc3f2. The evaluator ARN resolution is now transitive from the online eval configs the AB test references — handling all three cases:

  • Custom evaluators — looked up from deployedResources.evaluators
  • Builtin.* evaluators — ARN constructed as arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*
  • External ARN references — used as-is

The policy is now scoped to only the evaluators this specific AB test transitively references (not all project evaluators), addressing the least-privilege concern.

The e2e tests exercise a custom evaluator (ABTestEvaluator in ab-test-target-based.test.ts). We haven't explicitly tested with Builtin evaluators, but the ARN construction follows the same pattern used in the L3 CDK constructs (AgentCoreOnlineEvaluationConfig.ts:143-161).

Replace the hand-rolled per-resource policy with the canonical policy
from https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/ab-testing-prereqs.html:
- Trust policy: add SourceAccount + SourceArn conditions
- Permissions: single AgentCoreResources statement scoped to
arn:aws:bedrock-agentcore:*:${accountId}:* with ResourceAccount condition
- Add missing actions: GetGatewayTarget, ListGatewayTargets,
ListConfigurationBundleVersions
- CloudWatch logs scoped to account via PrincipalAccount pattern
- Remove per-evaluator/per-resource ARN tracking (no longer needed)
@github-actionsgithub-actionsBot added the size/m PR size: M label May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…-utils
Extract waitForRunningThenStop into promote-utils.ts so it can be unit
tested without pulling in React/ink. Add 4 tests covering: immediate
RUNNING, polling until RUNNING, timeout throws, and error message content.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Comment threadsrc/cli/operations/deploy/post-deploy-ab-tests.ts
padmak30
padmak30 previously approved these changes May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: correct AB test execution role IAM policy and promote stabilityfix: align AB test execution role IAM policy and fix promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: align AB test execution role IAM policy and fix promote stabilityfix: correct AB test execution role IAM policy and promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@notgitika
notgitika self-requested a review May 5, 2026 20:59
@notgitika

Copy link
Copy Markdown
Contributor

waitForRunningThenStop fixes the CLI promote race condition, but if there is a TUI path that calls updateABTest({ executionStatus: "STOPPED" }) directly, it has the same bug right?

Comment threadscripts/run-e2e-local.sh
@jariy17
jariy17 merged commit 9f231d0 into mainMay 5, 2026
25 checks passed
@jariy17
jariy17 deleted the fix/ab-test-role-evaluator-permission branch May 5, 2026 22:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jariy17@agentcore-cli-automation@notgitika@padmak30
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix: correct AB test execution role IAM policy and promote stability by jariy17 · Pull Request #1120 · aws/agentcore-cli · GitHub
Skip to content

fix: correct AB test execution role IAM policy and promote stability - #1120

Merged
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission
May 5, 2026
Merged

fix: correct AB test execution role IAM policy and promote stability#1120
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission

Conversation

@jariy17

@jariy17jariy17 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • IAM policy — Aligns the auto-created AB test execution role with the official docs, fixing a 400 "Access denied when validating evaluator" error on every deploy with a custom evaluator
  • Promote stabilitypromote ab-test waits for executionStatus === 'RUNNING' before stopping, avoiding 409 errors when promote runs immediately after resume; throws a clear error if the test never reaches RUNNING
  • IAM — DescribeLogGroups — Split into its own statement with Resource: "*" (AWS requirement)
  • E2E coverage — Added AB test reaches RUNNING status after deploy to ab-test-target-based.test.ts to catch IAM permission regressions post-deploy
  • Status test — Fixed incorrect http-gateway resourceType assertion; replaced with ab-test + invocationUrl check
  • Local e2e script — Added scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally

IAM changes

Trust policy — added SourceAccount + SourceArn conditions to prevent confused deputy attacks:

"Condition": {
"StringEquals": { "aws:SourceAccount": "<accountId>" },
"ArnLike": { "aws:SourceArn": "arn:aws:bedrock-agentcore:*:<accountId>:ab-test/*" }
}

Permissions — 3-statement policy aligned with docs:

  • AgentCoreResources — all bedrock-agentcore actions scoped to account with ResourceAccount condition (adds GetEvaluator, GetGatewayTarget, ListGatewayTargets, ListConfigurationBundleVersions)
  • CloudWatchLogsDescribelogs:DescribeLogGroups with Resource: "*" (required by AWS)
  • CloudWatchLogs — log read/write actions scoped to evaluation and spans log groups

Running E2E tests locally

export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role>export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>
./scripts/run-e2e-local.sh e2e-tests/ab-test-target-based.test.ts

Test plan

  • e2e-tests/ab-test-target-based.test.ts — all steps pass including RUNNING check
  • e2e-tests/ab-test-config-bundle.test.ts — passes (RUNNING check deferred to follow-up once real config bundles are used)
  • Unit tests src/cli/operations/deploy/__tests__/post-deploy-ab-tests.test.ts — 23 passing
  • Unit tests src/cli/commands/pause/__tests__/promote.test.ts — 4 passing

The AB test API validates evaluator ARNs server-side using the execution
role. The auto-created role policy was missing bedrock-agentcore:GetEvaluator,
causing a 400 "Access denied when validating evaluator" error on every deploy
that included a target-based AB test with a custom evaluator.
@jariy17
jariy17 requested a review from a teamMay 4, 2026 23:26
@github-actionsgithub-actionsBot added size/xs PR size: XS agentcore-harness-reviewing AgentCore Harness review in progress labels May 4, 2026
HTTP gateways are not surfaced as top-level resources in agentcore status —
they are only used internally to build AB test invocation URLs. The test was
asserting on resourceType 'http-gateway' which never appears; fix it to
assert on the 'ab-test' resource instead.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/xs PR size: XS labels May 4, 2026
@agentcore-cli-automation

Copy link
Copy Markdown

The new EvaluatorReadStatement is scoped to Object.values(deployedResources?.evaluators ?? {}), which only contains custom evaluators deployed by this project. This will leave the original 400 error in place whenever the AB test's online-eval config references evaluators that aren't in deployedResources.evaluators:

  • Builtin evaluators (Builtin.Faithfulness, Builtin.GoalSuccessRate, etc.) — these are first-class evaluator references in OnlineEvalConfig.evaluators (see src/schema/schemas/primitives/online-eval-config.ts:23-24 and the handling in AgentCoreOnlineEvaluationConfig.ts:143-161). If the service validates evaluator ARNs uniformly using the execution role, Builtins will fail the same check the PR is trying to fix.
  • External evaluator ARNsOnlineEvalConfig.evaluators also accepts raw ARNs pointing at evaluators outside this project / another account. Those are never in deployedResources.evaluators either.

Separately, even for the custom-evaluator case, the policy grants GetEvaluator on every evaluator in the project rather than just the ones this specific AB test transitively references via its onlineEvalConfigArns. That's a least-privilege concern but not a functional blocker.

A couple of ways to address this:

  1. Resolve evaluators transitively from the referenced online eval configs. For each online eval config referenced by testSpec.evaluationConfig, look up its evaluators list in projectSpec.onlineEvalConfigs, and for each entry:

    • Builtin.* → construct the builtin ARN (arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*)
    • arn:... → use as-is
    • otherwise → look up in deployedResources.evaluators

    Pass that de-duplicated list as evaluatorArns. This fixes both the Builtin/external case and the over-broad scoping.

  2. If tightening the scope is risky, at minimum add arn:${partition}:bedrock-agentcore:::evaluator/Builtin.* to the Resource list (and optionally arn:${partition}:bedrock-agentcore:${region}:${accountId}:evaluator/*) so users with builtin evaluators don't hit the same 400.

Could you also confirm whether you tested the fix with a Builtin evaluator in the online eval config, or only with a custom one? The test plan only mentions ab-test-target-based.test.ts / ab-test-config-bundle.test.ts — knowing which evaluator types those exercise would help.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 4, 2026
@github-actions

github-actionsBot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines43.11%9016 / 20912
🔵Statements42.4%9575 / 22582
🔵Functions39.96%1555 / 3891
🔵Branches39.98%5808 / 14527
Generated in workflow #2425 for commit 5b72ab3 by the Vitest Coverage Report Action

The resource cast was missing invocationUrl, causing a TypeScript error
when asserting the AB test's gateway invocation URL was present.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/s PR size: S labels May 4, 2026
- Include stdout in promote failure message so the JSON error is visible
- Add scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/s PR size: S labels May 5, 2026
When promote is called immediately after resume, the AB test may still be
in UPDATING state and reject the STOPPED transition with a 409. Retry up
to 6 times with a 10s delay to wait for the transition to complete.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus is no longer UPDATING before
attempting to stop. The service rejects updates with 409 while a
state transition is in progress (e.g. after resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus === 'RUNNING' before issuing the
STOPPED transition. The service 409s if the test is still UPDATING
(e.g. transitioning from a prior resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…figs
Previously GetEvaluator was scoped to all project evaluators. Now it's
scoped to only the evaluators referenced by the specific online eval
configs this AB test uses, handling all three cases:
- Custom evaluators: looked up from deployedResources.evaluators
- Builtin.* evaluators: ARN constructed from the builtin ID
- External ARN references: used as-is
@github-actionsgithub-actionsBot removed the size/m PR size: M label May 5, 2026
@jariy17

Copy link
Copy Markdown
ContributorAuthor

Addressed in 44bc3f2. The evaluator ARN resolution is now transitive from the online eval configs the AB test references — handling all three cases:

  • Custom evaluators — looked up from deployedResources.evaluators
  • Builtin.* evaluators — ARN constructed as arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*
  • External ARN references — used as-is

The policy is now scoped to only the evaluators this specific AB test transitively references (not all project evaluators), addressing the least-privilege concern.

The e2e tests exercise a custom evaluator (ABTestEvaluator in ab-test-target-based.test.ts). We haven't explicitly tested with Builtin evaluators, but the ARN construction follows the same pattern used in the L3 CDK constructs (AgentCoreOnlineEvaluationConfig.ts:143-161).

Replace the hand-rolled per-resource policy with the canonical policy
from https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/ab-testing-prereqs.html:
- Trust policy: add SourceAccount + SourceArn conditions
- Permissions: single AgentCoreResources statement scoped to
arn:aws:bedrock-agentcore:*:${accountId}:* with ResourceAccount condition
- Add missing actions: GetGatewayTarget, ListGatewayTargets,
ListConfigurationBundleVersions
- CloudWatch logs scoped to account via PrincipalAccount pattern
- Remove per-evaluator/per-resource ARN tracking (no longer needed)
@github-actionsgithub-actionsBot added the size/m PR size: M label May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…-utils
Extract waitForRunningThenStop into promote-utils.ts so it can be unit
tested without pulling in React/ink. Add 4 tests covering: immediate
RUNNING, polling until RUNNING, timeout throws, and error message content.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Comment threadsrc/cli/operations/deploy/post-deploy-ab-tests.ts
padmak30
padmak30 previously approved these changes May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: correct AB test execution role IAM policy and promote stabilityfix: align AB test execution role IAM policy and fix promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: align AB test execution role IAM policy and fix promote stabilityfix: correct AB test execution role IAM policy and promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@notgitika
notgitika self-requested a review May 5, 2026 20:59
@notgitika

Copy link
Copy Markdown
Contributor

waitForRunningThenStop fixes the CLI promote race condition, but if there is a TUI path that calls updateABTest({ executionStatus: "STOPPED" }) directly, it has the same bug right?

Comment threadscripts/run-e2e-local.sh
@jariy17
jariy17 merged commit 9f231d0 into mainMay 5, 2026
25 checks passed
@jariy17
jariy17 deleted the fix/ab-test-role-evaluator-permission branch May 5, 2026 22:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jariy17@agentcore-cli-automation@notgitika@padmak30
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: correct AB test execution role IAM policy and promote stability by jariy17 · Pull Request #1120 · aws/agentcore-cli · GitHub
Skip to content

fix: correct AB test execution role IAM policy and promote stability - #1120

Merged
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission
May 5, 2026
Merged

fix: correct AB test execution role IAM policy and promote stability#1120
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission

Conversation

@jariy17

@jariy17jariy17 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • IAM policy — Aligns the auto-created AB test execution role with the official docs, fixing a 400 "Access denied when validating evaluator" error on every deploy with a custom evaluator
  • Promote stabilitypromote ab-test waits for executionStatus === 'RUNNING' before stopping, avoiding 409 errors when promote runs immediately after resume; throws a clear error if the test never reaches RUNNING
  • IAM — DescribeLogGroups — Split into its own statement with Resource: "*" (AWS requirement)
  • E2E coverage — Added AB test reaches RUNNING status after deploy to ab-test-target-based.test.ts to catch IAM permission regressions post-deploy
  • Status test — Fixed incorrect http-gateway resourceType assertion; replaced with ab-test + invocationUrl check
  • Local e2e script — Added scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally

IAM changes

Trust policy — added SourceAccount + SourceArn conditions to prevent confused deputy attacks:

"Condition": {
"StringEquals": { "aws:SourceAccount": "<accountId>" },
"ArnLike": { "aws:SourceArn": "arn:aws:bedrock-agentcore:*:<accountId>:ab-test/*" }
}

Permissions — 3-statement policy aligned with docs:

  • AgentCoreResources — all bedrock-agentcore actions scoped to account with ResourceAccount condition (adds GetEvaluator, GetGatewayTarget, ListGatewayTargets, ListConfigurationBundleVersions)
  • CloudWatchLogsDescribelogs:DescribeLogGroups with Resource: "*" (required by AWS)
  • CloudWatchLogs — log read/write actions scoped to evaluation and spans log groups

Running E2E tests locally

export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role>export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>
./scripts/run-e2e-local.sh e2e-tests/ab-test-target-based.test.ts

Test plan

  • e2e-tests/ab-test-target-based.test.ts — all steps pass including RUNNING check
  • e2e-tests/ab-test-config-bundle.test.ts — passes (RUNNING check deferred to follow-up once real config bundles are used)
  • Unit tests src/cli/operations/deploy/__tests__/post-deploy-ab-tests.test.ts — 23 passing
  • Unit tests src/cli/commands/pause/__tests__/promote.test.ts — 4 passing

The AB test API validates evaluator ARNs server-side using the execution
role. The auto-created role policy was missing bedrock-agentcore:GetEvaluator,
causing a 400 "Access denied when validating evaluator" error on every deploy
that included a target-based AB test with a custom evaluator.
@jariy17
jariy17 requested a review from a teamMay 4, 2026 23:26
@github-actionsgithub-actionsBot added size/xs PR size: XS agentcore-harness-reviewing AgentCore Harness review in progress labels May 4, 2026
HTTP gateways are not surfaced as top-level resources in agentcore status —
they are only used internally to build AB test invocation URLs. The test was
asserting on resourceType 'http-gateway' which never appears; fix it to
assert on the 'ab-test' resource instead.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/xs PR size: XS labels May 4, 2026
@agentcore-cli-automation

Copy link
Copy Markdown

The new EvaluatorReadStatement is scoped to Object.values(deployedResources?.evaluators ?? {}), which only contains custom evaluators deployed by this project. This will leave the original 400 error in place whenever the AB test's online-eval config references evaluators that aren't in deployedResources.evaluators:

  • Builtin evaluators (Builtin.Faithfulness, Builtin.GoalSuccessRate, etc.) — these are first-class evaluator references in OnlineEvalConfig.evaluators (see src/schema/schemas/primitives/online-eval-config.ts:23-24 and the handling in AgentCoreOnlineEvaluationConfig.ts:143-161). If the service validates evaluator ARNs uniformly using the execution role, Builtins will fail the same check the PR is trying to fix.
  • External evaluator ARNsOnlineEvalConfig.evaluators also accepts raw ARNs pointing at evaluators outside this project / another account. Those are never in deployedResources.evaluators either.

Separately, even for the custom-evaluator case, the policy grants GetEvaluator on every evaluator in the project rather than just the ones this specific AB test transitively references via its onlineEvalConfigArns. That's a least-privilege concern but not a functional blocker.

A couple of ways to address this:

  1. Resolve evaluators transitively from the referenced online eval configs. For each online eval config referenced by testSpec.evaluationConfig, look up its evaluators list in projectSpec.onlineEvalConfigs, and for each entry:

    • Builtin.* → construct the builtin ARN (arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*)
    • arn:... → use as-is
    • otherwise → look up in deployedResources.evaluators

    Pass that de-duplicated list as evaluatorArns. This fixes both the Builtin/external case and the over-broad scoping.

  2. If tightening the scope is risky, at minimum add arn:${partition}:bedrock-agentcore:::evaluator/Builtin.* to the Resource list (and optionally arn:${partition}:bedrock-agentcore:${region}:${accountId}:evaluator/*) so users with builtin evaluators don't hit the same 400.

Could you also confirm whether you tested the fix with a Builtin evaluator in the online eval config, or only with a custom one? The test plan only mentions ab-test-target-based.test.ts / ab-test-config-bundle.test.ts — knowing which evaluator types those exercise would help.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 4, 2026
@github-actions

github-actionsBot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines43.11%9016 / 20912
🔵Statements42.4%9575 / 22582
🔵Functions39.96%1555 / 3891
🔵Branches39.98%5808 / 14527
Generated in workflow #2425 for commit 5b72ab3 by the Vitest Coverage Report Action

The resource cast was missing invocationUrl, causing a TypeScript error
when asserting the AB test's gateway invocation URL was present.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/s PR size: S labels May 4, 2026
- Include stdout in promote failure message so the JSON error is visible
- Add scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/s PR size: S labels May 5, 2026
When promote is called immediately after resume, the AB test may still be
in UPDATING state and reject the STOPPED transition with a 409. Retry up
to 6 times with a 10s delay to wait for the transition to complete.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus is no longer UPDATING before
attempting to stop. The service rejects updates with 409 while a
state transition is in progress (e.g. after resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus === 'RUNNING' before issuing the
STOPPED transition. The service 409s if the test is still UPDATING
(e.g. transitioning from a prior resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…figs
Previously GetEvaluator was scoped to all project evaluators. Now it's
scoped to only the evaluators referenced by the specific online eval
configs this AB test uses, handling all three cases:
- Custom evaluators: looked up from deployedResources.evaluators
- Builtin.* evaluators: ARN constructed from the builtin ID
- External ARN references: used as-is
@github-actionsgithub-actionsBot removed the size/m PR size: M label May 5, 2026
@jariy17

Copy link
Copy Markdown
ContributorAuthor

Addressed in 44bc3f2. The evaluator ARN resolution is now transitive from the online eval configs the AB test references — handling all three cases:

  • Custom evaluators — looked up from deployedResources.evaluators
  • Builtin.* evaluators — ARN constructed as arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*
  • External ARN references — used as-is

The policy is now scoped to only the evaluators this specific AB test transitively references (not all project evaluators), addressing the least-privilege concern.

The e2e tests exercise a custom evaluator (ABTestEvaluator in ab-test-target-based.test.ts). We haven't explicitly tested with Builtin evaluators, but the ARN construction follows the same pattern used in the L3 CDK constructs (AgentCoreOnlineEvaluationConfig.ts:143-161).

Replace the hand-rolled per-resource policy with the canonical policy
from https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/ab-testing-prereqs.html:
- Trust policy: add SourceAccount + SourceArn conditions
- Permissions: single AgentCoreResources statement scoped to
arn:aws:bedrock-agentcore:*:${accountId}:* with ResourceAccount condition
- Add missing actions: GetGatewayTarget, ListGatewayTargets,
ListConfigurationBundleVersions
- CloudWatch logs scoped to account via PrincipalAccount pattern
- Remove per-evaluator/per-resource ARN tracking (no longer needed)
@github-actionsgithub-actionsBot added the size/m PR size: M label May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…-utils
Extract waitForRunningThenStop into promote-utils.ts so it can be unit
tested without pulling in React/ink. Add 4 tests covering: immediate
RUNNING, polling until RUNNING, timeout throws, and error message content.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Comment threadsrc/cli/operations/deploy/post-deploy-ab-tests.ts
padmak30
padmak30 previously approved these changes May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: correct AB test execution role IAM policy and promote stabilityfix: align AB test execution role IAM policy and fix promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: align AB test execution role IAM policy and fix promote stabilityfix: correct AB test execution role IAM policy and promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@notgitika
notgitika self-requested a review May 5, 2026 20:59
@notgitika

Copy link
Copy Markdown
Contributor

waitForRunningThenStop fixes the CLI promote race condition, but if there is a TUI path that calls updateABTest({ executionStatus: "STOPPED" }) directly, it has the same bug right?

Comment threadscripts/run-e2e-local.sh
@jariy17
jariy17 merged commit 9f231d0 into mainMay 5, 2026
25 checks passed
@jariy17
jariy17 deleted the fix/ab-test-role-evaluator-permission branch May 5, 2026 22:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jariy17@agentcore-cli-automation@notgitika@padmak30
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: correct AB test execution role IAM policy and promote stability by jariy17 · Pull Request #1120 · aws/agentcore-cli · GitHub
Skip to content

fix: correct AB test execution role IAM policy and promote stability - #1120

Merged
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission
May 5, 2026
Merged

fix: correct AB test execution role IAM policy and promote stability#1120
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission

Conversation

@jariy17

@jariy17jariy17 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • IAM policy — Aligns the auto-created AB test execution role with the official docs, fixing a 400 "Access denied when validating evaluator" error on every deploy with a custom evaluator
  • Promote stabilitypromote ab-test waits for executionStatus === 'RUNNING' before stopping, avoiding 409 errors when promote runs immediately after resume; throws a clear error if the test never reaches RUNNING
  • IAM — DescribeLogGroups — Split into its own statement with Resource: "*" (AWS requirement)
  • E2E coverage — Added AB test reaches RUNNING status after deploy to ab-test-target-based.test.ts to catch IAM permission regressions post-deploy
  • Status test — Fixed incorrect http-gateway resourceType assertion; replaced with ab-test + invocationUrl check
  • Local e2e script — Added scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally

IAM changes

Trust policy — added SourceAccount + SourceArn conditions to prevent confused deputy attacks:

"Condition": {
"StringEquals": { "aws:SourceAccount": "<accountId>" },
"ArnLike": { "aws:SourceArn": "arn:aws:bedrock-agentcore:*:<accountId>:ab-test/*" }
}

Permissions — 3-statement policy aligned with docs:

  • AgentCoreResources — all bedrock-agentcore actions scoped to account with ResourceAccount condition (adds GetEvaluator, GetGatewayTarget, ListGatewayTargets, ListConfigurationBundleVersions)
  • CloudWatchLogsDescribelogs:DescribeLogGroups with Resource: "*" (required by AWS)
  • CloudWatchLogs — log read/write actions scoped to evaluation and spans log groups

Running E2E tests locally

export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role>export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>
./scripts/run-e2e-local.sh e2e-tests/ab-test-target-based.test.ts

Test plan

  • e2e-tests/ab-test-target-based.test.ts — all steps pass including RUNNING check
  • e2e-tests/ab-test-config-bundle.test.ts — passes (RUNNING check deferred to follow-up once real config bundles are used)
  • Unit tests src/cli/operations/deploy/__tests__/post-deploy-ab-tests.test.ts — 23 passing
  • Unit tests src/cli/commands/pause/__tests__/promote.test.ts — 4 passing

The AB test API validates evaluator ARNs server-side using the execution
role. The auto-created role policy was missing bedrock-agentcore:GetEvaluator,
causing a 400 "Access denied when validating evaluator" error on every deploy
that included a target-based AB test with a custom evaluator.
@jariy17
jariy17 requested a review from a teamMay 4, 2026 23:26
@github-actionsgithub-actionsBot added size/xs PR size: XS agentcore-harness-reviewing AgentCore Harness review in progress labels May 4, 2026
HTTP gateways are not surfaced as top-level resources in agentcore status —
they are only used internally to build AB test invocation URLs. The test was
asserting on resourceType 'http-gateway' which never appears; fix it to
assert on the 'ab-test' resource instead.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/xs PR size: XS labels May 4, 2026
@agentcore-cli-automation

Copy link
Copy Markdown

The new EvaluatorReadStatement is scoped to Object.values(deployedResources?.evaluators ?? {}), which only contains custom evaluators deployed by this project. This will leave the original 400 error in place whenever the AB test's online-eval config references evaluators that aren't in deployedResources.evaluators:

  • Builtin evaluators (Builtin.Faithfulness, Builtin.GoalSuccessRate, etc.) — these are first-class evaluator references in OnlineEvalConfig.evaluators (see src/schema/schemas/primitives/online-eval-config.ts:23-24 and the handling in AgentCoreOnlineEvaluationConfig.ts:143-161). If the service validates evaluator ARNs uniformly using the execution role, Builtins will fail the same check the PR is trying to fix.
  • External evaluator ARNsOnlineEvalConfig.evaluators also accepts raw ARNs pointing at evaluators outside this project / another account. Those are never in deployedResources.evaluators either.

Separately, even for the custom-evaluator case, the policy grants GetEvaluator on every evaluator in the project rather than just the ones this specific AB test transitively references via its onlineEvalConfigArns. That's a least-privilege concern but not a functional blocker.

A couple of ways to address this:

  1. Resolve evaluators transitively from the referenced online eval configs. For each online eval config referenced by testSpec.evaluationConfig, look up its evaluators list in projectSpec.onlineEvalConfigs, and for each entry:

    • Builtin.* → construct the builtin ARN (arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*)
    • arn:... → use as-is
    • otherwise → look up in deployedResources.evaluators

    Pass that de-duplicated list as evaluatorArns. This fixes both the Builtin/external case and the over-broad scoping.

  2. If tightening the scope is risky, at minimum add arn:${partition}:bedrock-agentcore:::evaluator/Builtin.* to the Resource list (and optionally arn:${partition}:bedrock-agentcore:${region}:${accountId}:evaluator/*) so users with builtin evaluators don't hit the same 400.

Could you also confirm whether you tested the fix with a Builtin evaluator in the online eval config, or only with a custom one? The test plan only mentions ab-test-target-based.test.ts / ab-test-config-bundle.test.ts — knowing which evaluator types those exercise would help.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 4, 2026
@github-actions

github-actionsBot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines43.11%9016 / 20912
🔵Statements42.4%9575 / 22582
🔵Functions39.96%1555 / 3891
🔵Branches39.98%5808 / 14527
Generated in workflow #2425 for commit 5b72ab3 by the Vitest Coverage Report Action

The resource cast was missing invocationUrl, causing a TypeScript error
when asserting the AB test's gateway invocation URL was present.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/s PR size: S labels May 4, 2026
- Include stdout in promote failure message so the JSON error is visible
- Add scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/s PR size: S labels May 5, 2026
When promote is called immediately after resume, the AB test may still be
in UPDATING state and reject the STOPPED transition with a 409. Retry up
to 6 times with a 10s delay to wait for the transition to complete.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus is no longer UPDATING before
attempting to stop. The service rejects updates with 409 while a
state transition is in progress (e.g. after resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus === 'RUNNING' before issuing the
STOPPED transition. The service 409s if the test is still UPDATING
(e.g. transitioning from a prior resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…figs
Previously GetEvaluator was scoped to all project evaluators. Now it's
scoped to only the evaluators referenced by the specific online eval
configs this AB test uses, handling all three cases:
- Custom evaluators: looked up from deployedResources.evaluators
- Builtin.* evaluators: ARN constructed from the builtin ID
- External ARN references: used as-is
@github-actionsgithub-actionsBot removed the size/m PR size: M label May 5, 2026
@jariy17

Copy link
Copy Markdown
ContributorAuthor

Addressed in 44bc3f2. The evaluator ARN resolution is now transitive from the online eval configs the AB test references — handling all three cases:

  • Custom evaluators — looked up from deployedResources.evaluators
  • Builtin.* evaluators — ARN constructed as arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*
  • External ARN references — used as-is

The policy is now scoped to only the evaluators this specific AB test transitively references (not all project evaluators), addressing the least-privilege concern.

The e2e tests exercise a custom evaluator (ABTestEvaluator in ab-test-target-based.test.ts). We haven't explicitly tested with Builtin evaluators, but the ARN construction follows the same pattern used in the L3 CDK constructs (AgentCoreOnlineEvaluationConfig.ts:143-161).

Replace the hand-rolled per-resource policy with the canonical policy
from https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/ab-testing-prereqs.html:
- Trust policy: add SourceAccount + SourceArn conditions
- Permissions: single AgentCoreResources statement scoped to
arn:aws:bedrock-agentcore:*:${accountId}:* with ResourceAccount condition
- Add missing actions: GetGatewayTarget, ListGatewayTargets,
ListConfigurationBundleVersions
- CloudWatch logs scoped to account via PrincipalAccount pattern
- Remove per-evaluator/per-resource ARN tracking (no longer needed)
@github-actionsgithub-actionsBot added the size/m PR size: M label May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…-utils
Extract waitForRunningThenStop into promote-utils.ts so it can be unit
tested without pulling in React/ink. Add 4 tests covering: immediate
RUNNING, polling until RUNNING, timeout throws, and error message content.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Comment threadsrc/cli/operations/deploy/post-deploy-ab-tests.ts
padmak30
padmak30 previously approved these changes May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: correct AB test execution role IAM policy and promote stabilityfix: align AB test execution role IAM policy and fix promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: align AB test execution role IAM policy and fix promote stabilityfix: correct AB test execution role IAM policy and promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@notgitika
notgitika self-requested a review May 5, 2026 20:59
@notgitika

Copy link
Copy Markdown
Contributor

waitForRunningThenStop fixes the CLI promote race condition, but if there is a TUI path that calls updateABTest({ executionStatus: "STOPPED" }) directly, it has the same bug right?

Comment threadscripts/run-e2e-local.sh
@jariy17
jariy17 merged commit 9f231d0 into mainMay 5, 2026
25 checks passed
@jariy17
jariy17 deleted the fix/ab-test-role-evaluator-permission branch May 5, 2026 22:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jariy17@agentcore-cli-automation@notgitika@padmak30
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix: correct AB test execution role IAM policy and promote stability by jariy17 · Pull Request #1120 · aws/agentcore-cli · GitHub
Skip to content

fix: correct AB test execution role IAM policy and promote stability - #1120

Merged
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission
May 5, 2026
Merged

fix: correct AB test execution role IAM policy and promote stability#1120
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission

Conversation

@jariy17

@jariy17jariy17 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • IAM policy — Aligns the auto-created AB test execution role with the official docs, fixing a 400 "Access denied when validating evaluator" error on every deploy with a custom evaluator
  • Promote stabilitypromote ab-test waits for executionStatus === 'RUNNING' before stopping, avoiding 409 errors when promote runs immediately after resume; throws a clear error if the test never reaches RUNNING
  • IAM — DescribeLogGroups — Split into its own statement with Resource: "*" (AWS requirement)
  • E2E coverage — Added AB test reaches RUNNING status after deploy to ab-test-target-based.test.ts to catch IAM permission regressions post-deploy
  • Status test — Fixed incorrect http-gateway resourceType assertion; replaced with ab-test + invocationUrl check
  • Local e2e script — Added scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally

IAM changes

Trust policy — added SourceAccount + SourceArn conditions to prevent confused deputy attacks:

"Condition": {
"StringEquals": { "aws:SourceAccount": "<accountId>" },
"ArnLike": { "aws:SourceArn": "arn:aws:bedrock-agentcore:*:<accountId>:ab-test/*" }
}

Permissions — 3-statement policy aligned with docs:

  • AgentCoreResources — all bedrock-agentcore actions scoped to account with ResourceAccount condition (adds GetEvaluator, GetGatewayTarget, ListGatewayTargets, ListConfigurationBundleVersions)
  • CloudWatchLogsDescribelogs:DescribeLogGroups with Resource: "*" (required by AWS)
  • CloudWatchLogs — log read/write actions scoped to evaluation and spans log groups

Running E2E tests locally

export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role>export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>
./scripts/run-e2e-local.sh e2e-tests/ab-test-target-based.test.ts

Test plan

  • e2e-tests/ab-test-target-based.test.ts — all steps pass including RUNNING check
  • e2e-tests/ab-test-config-bundle.test.ts — passes (RUNNING check deferred to follow-up once real config bundles are used)
  • Unit tests src/cli/operations/deploy/__tests__/post-deploy-ab-tests.test.ts — 23 passing
  • Unit tests src/cli/commands/pause/__tests__/promote.test.ts — 4 passing

The AB test API validates evaluator ARNs server-side using the execution
role. The auto-created role policy was missing bedrock-agentcore:GetEvaluator,
causing a 400 "Access denied when validating evaluator" error on every deploy
that included a target-based AB test with a custom evaluator.
@jariy17
jariy17 requested a review from a teamMay 4, 2026 23:26
@github-actionsgithub-actionsBot added size/xs PR size: XS agentcore-harness-reviewing AgentCore Harness review in progress labels May 4, 2026
HTTP gateways are not surfaced as top-level resources in agentcore status —
they are only used internally to build AB test invocation URLs. The test was
asserting on resourceType 'http-gateway' which never appears; fix it to
assert on the 'ab-test' resource instead.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/xs PR size: XS labels May 4, 2026
@agentcore-cli-automation

Copy link
Copy Markdown

The new EvaluatorReadStatement is scoped to Object.values(deployedResources?.evaluators ?? {}), which only contains custom evaluators deployed by this project. This will leave the original 400 error in place whenever the AB test's online-eval config references evaluators that aren't in deployedResources.evaluators:

  • Builtin evaluators (Builtin.Faithfulness, Builtin.GoalSuccessRate, etc.) — these are first-class evaluator references in OnlineEvalConfig.evaluators (see src/schema/schemas/primitives/online-eval-config.ts:23-24 and the handling in AgentCoreOnlineEvaluationConfig.ts:143-161). If the service validates evaluator ARNs uniformly using the execution role, Builtins will fail the same check the PR is trying to fix.
  • External evaluator ARNsOnlineEvalConfig.evaluators also accepts raw ARNs pointing at evaluators outside this project / another account. Those are never in deployedResources.evaluators either.

Separately, even for the custom-evaluator case, the policy grants GetEvaluator on every evaluator in the project rather than just the ones this specific AB test transitively references via its onlineEvalConfigArns. That's a least-privilege concern but not a functional blocker.

A couple of ways to address this:

  1. Resolve evaluators transitively from the referenced online eval configs. For each online eval config referenced by testSpec.evaluationConfig, look up its evaluators list in projectSpec.onlineEvalConfigs, and for each entry:

    • Builtin.* → construct the builtin ARN (arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*)
    • arn:... → use as-is
    • otherwise → look up in deployedResources.evaluators

    Pass that de-duplicated list as evaluatorArns. This fixes both the Builtin/external case and the over-broad scoping.

  2. If tightening the scope is risky, at minimum add arn:${partition}:bedrock-agentcore:::evaluator/Builtin.* to the Resource list (and optionally arn:${partition}:bedrock-agentcore:${region}:${accountId}:evaluator/*) so users with builtin evaluators don't hit the same 400.

Could you also confirm whether you tested the fix with a Builtin evaluator in the online eval config, or only with a custom one? The test plan only mentions ab-test-target-based.test.ts / ab-test-config-bundle.test.ts — knowing which evaluator types those exercise would help.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 4, 2026
@github-actions

github-actionsBot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines43.11%9016 / 20912
🔵Statements42.4%9575 / 22582
🔵Functions39.96%1555 / 3891
🔵Branches39.98%5808 / 14527
Generated in workflow #2425 for commit 5b72ab3 by the Vitest Coverage Report Action

The resource cast was missing invocationUrl, causing a TypeScript error
when asserting the AB test's gateway invocation URL was present.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/s PR size: S labels May 4, 2026
- Include stdout in promote failure message so the JSON error is visible
- Add scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/s PR size: S labels May 5, 2026
When promote is called immediately after resume, the AB test may still be
in UPDATING state and reject the STOPPED transition with a 409. Retry up
to 6 times with a 10s delay to wait for the transition to complete.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus is no longer UPDATING before
attempting to stop. The service rejects updates with 409 while a
state transition is in progress (e.g. after resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus === 'RUNNING' before issuing the
STOPPED transition. The service 409s if the test is still UPDATING
(e.g. transitioning from a prior resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…figs
Previously GetEvaluator was scoped to all project evaluators. Now it's
scoped to only the evaluators referenced by the specific online eval
configs this AB test uses, handling all three cases:
- Custom evaluators: looked up from deployedResources.evaluators
- Builtin.* evaluators: ARN constructed from the builtin ID
- External ARN references: used as-is
@github-actionsgithub-actionsBot removed the size/m PR size: M label May 5, 2026
@jariy17

Copy link
Copy Markdown
ContributorAuthor

Addressed in 44bc3f2. The evaluator ARN resolution is now transitive from the online eval configs the AB test references — handling all three cases:

  • Custom evaluators — looked up from deployedResources.evaluators
  • Builtin.* evaluators — ARN constructed as arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*
  • External ARN references — used as-is

The policy is now scoped to only the evaluators this specific AB test transitively references (not all project evaluators), addressing the least-privilege concern.

The e2e tests exercise a custom evaluator (ABTestEvaluator in ab-test-target-based.test.ts). We haven't explicitly tested with Builtin evaluators, but the ARN construction follows the same pattern used in the L3 CDK constructs (AgentCoreOnlineEvaluationConfig.ts:143-161).

Replace the hand-rolled per-resource policy with the canonical policy
from https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/ab-testing-prereqs.html:
- Trust policy: add SourceAccount + SourceArn conditions
- Permissions: single AgentCoreResources statement scoped to
arn:aws:bedrock-agentcore:*:${accountId}:* with ResourceAccount condition
- Add missing actions: GetGatewayTarget, ListGatewayTargets,
ListConfigurationBundleVersions
- CloudWatch logs scoped to account via PrincipalAccount pattern
- Remove per-evaluator/per-resource ARN tracking (no longer needed)
@github-actionsgithub-actionsBot added the size/m PR size: M label May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…-utils
Extract waitForRunningThenStop into promote-utils.ts so it can be unit
tested without pulling in React/ink. Add 4 tests covering: immediate
RUNNING, polling until RUNNING, timeout throws, and error message content.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Comment threadsrc/cli/operations/deploy/post-deploy-ab-tests.ts
padmak30
padmak30 previously approved these changes May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: correct AB test execution role IAM policy and promote stabilityfix: align AB test execution role IAM policy and fix promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: align AB test execution role IAM policy and fix promote stabilityfix: correct AB test execution role IAM policy and promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@notgitika
notgitika self-requested a review May 5, 2026 20:59
@notgitika

Copy link
Copy Markdown
Contributor

waitForRunningThenStop fixes the CLI promote race condition, but if there is a TUI path that calls updateABTest({ executionStatus: "STOPPED" }) directly, it has the same bug right?

Comment threadscripts/run-e2e-local.sh
@jariy17
jariy17 merged commit 9f231d0 into mainMay 5, 2026
25 checks passed
@jariy17
jariy17 deleted the fix/ab-test-role-evaluator-permission branch May 5, 2026 22:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jariy17@agentcore-cli-automation@notgitika@padmak30
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: correct AB test execution role IAM policy and promote stability by jariy17 · Pull Request #1120 · aws/agentcore-cli · GitHub
Skip to content

fix: correct AB test execution role IAM policy and promote stability - #1120

Merged
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission
May 5, 2026
Merged

fix: correct AB test execution role IAM policy and promote stability#1120
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission

Conversation

@jariy17

@jariy17jariy17 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • IAM policy — Aligns the auto-created AB test execution role with the official docs, fixing a 400 "Access denied when validating evaluator" error on every deploy with a custom evaluator
  • Promote stabilitypromote ab-test waits for executionStatus === 'RUNNING' before stopping, avoiding 409 errors when promote runs immediately after resume; throws a clear error if the test never reaches RUNNING
  • IAM — DescribeLogGroups — Split into its own statement with Resource: "*" (AWS requirement)
  • E2E coverage — Added AB test reaches RUNNING status after deploy to ab-test-target-based.test.ts to catch IAM permission regressions post-deploy
  • Status test — Fixed incorrect http-gateway resourceType assertion; replaced with ab-test + invocationUrl check
  • Local e2e script — Added scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally

IAM changes

Trust policy — added SourceAccount + SourceArn conditions to prevent confused deputy attacks:

"Condition": {
"StringEquals": { "aws:SourceAccount": "<accountId>" },
"ArnLike": { "aws:SourceArn": "arn:aws:bedrock-agentcore:*:<accountId>:ab-test/*" }
}

Permissions — 3-statement policy aligned with docs:

  • AgentCoreResources — all bedrock-agentcore actions scoped to account with ResourceAccount condition (adds GetEvaluator, GetGatewayTarget, ListGatewayTargets, ListConfigurationBundleVersions)
  • CloudWatchLogsDescribelogs:DescribeLogGroups with Resource: "*" (required by AWS)
  • CloudWatchLogs — log read/write actions scoped to evaluation and spans log groups

Running E2E tests locally

export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role>export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>
./scripts/run-e2e-local.sh e2e-tests/ab-test-target-based.test.ts

Test plan

  • e2e-tests/ab-test-target-based.test.ts — all steps pass including RUNNING check
  • e2e-tests/ab-test-config-bundle.test.ts — passes (RUNNING check deferred to follow-up once real config bundles are used)
  • Unit tests src/cli/operations/deploy/__tests__/post-deploy-ab-tests.test.ts — 23 passing
  • Unit tests src/cli/commands/pause/__tests__/promote.test.ts — 4 passing

The AB test API validates evaluator ARNs server-side using the execution
role. The auto-created role policy was missing bedrock-agentcore:GetEvaluator,
causing a 400 "Access denied when validating evaluator" error on every deploy
that included a target-based AB test with a custom evaluator.
@jariy17
jariy17 requested a review from a teamMay 4, 2026 23:26
@github-actionsgithub-actionsBot added size/xs PR size: XS agentcore-harness-reviewing AgentCore Harness review in progress labels May 4, 2026
HTTP gateways are not surfaced as top-level resources in agentcore status —
they are only used internally to build AB test invocation URLs. The test was
asserting on resourceType 'http-gateway' which never appears; fix it to
assert on the 'ab-test' resource instead.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/xs PR size: XS labels May 4, 2026
@agentcore-cli-automation

Copy link
Copy Markdown

The new EvaluatorReadStatement is scoped to Object.values(deployedResources?.evaluators ?? {}), which only contains custom evaluators deployed by this project. This will leave the original 400 error in place whenever the AB test's online-eval config references evaluators that aren't in deployedResources.evaluators:

  • Builtin evaluators (Builtin.Faithfulness, Builtin.GoalSuccessRate, etc.) — these are first-class evaluator references in OnlineEvalConfig.evaluators (see src/schema/schemas/primitives/online-eval-config.ts:23-24 and the handling in AgentCoreOnlineEvaluationConfig.ts:143-161). If the service validates evaluator ARNs uniformly using the execution role, Builtins will fail the same check the PR is trying to fix.
  • External evaluator ARNsOnlineEvalConfig.evaluators also accepts raw ARNs pointing at evaluators outside this project / another account. Those are never in deployedResources.evaluators either.

Separately, even for the custom-evaluator case, the policy grants GetEvaluator on every evaluator in the project rather than just the ones this specific AB test transitively references via its onlineEvalConfigArns. That's a least-privilege concern but not a functional blocker.

A couple of ways to address this:

  1. Resolve evaluators transitively from the referenced online eval configs. For each online eval config referenced by testSpec.evaluationConfig, look up its evaluators list in projectSpec.onlineEvalConfigs, and for each entry:

    • Builtin.* → construct the builtin ARN (arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*)
    • arn:... → use as-is
    • otherwise → look up in deployedResources.evaluators

    Pass that de-duplicated list as evaluatorArns. This fixes both the Builtin/external case and the over-broad scoping.

  2. If tightening the scope is risky, at minimum add arn:${partition}:bedrock-agentcore:::evaluator/Builtin.* to the Resource list (and optionally arn:${partition}:bedrock-agentcore:${region}:${accountId}:evaluator/*) so users with builtin evaluators don't hit the same 400.

Could you also confirm whether you tested the fix with a Builtin evaluator in the online eval config, or only with a custom one? The test plan only mentions ab-test-target-based.test.ts / ab-test-config-bundle.test.ts — knowing which evaluator types those exercise would help.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 4, 2026
@github-actions

github-actionsBot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines43.11%9016 / 20912
🔵Statements42.4%9575 / 22582
🔵Functions39.96%1555 / 3891
🔵Branches39.98%5808 / 14527
Generated in workflow #2425 for commit 5b72ab3 by the Vitest Coverage Report Action

The resource cast was missing invocationUrl, causing a TypeScript error
when asserting the AB test's gateway invocation URL was present.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/s PR size: S labels May 4, 2026
- Include stdout in promote failure message so the JSON error is visible
- Add scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/s PR size: S labels May 5, 2026
When promote is called immediately after resume, the AB test may still be
in UPDATING state and reject the STOPPED transition with a 409. Retry up
to 6 times with a 10s delay to wait for the transition to complete.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus is no longer UPDATING before
attempting to stop. The service rejects updates with 409 while a
state transition is in progress (e.g. after resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus === 'RUNNING' before issuing the
STOPPED transition. The service 409s if the test is still UPDATING
(e.g. transitioning from a prior resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…figs
Previously GetEvaluator was scoped to all project evaluators. Now it's
scoped to only the evaluators referenced by the specific online eval
configs this AB test uses, handling all three cases:
- Custom evaluators: looked up from deployedResources.evaluators
- Builtin.* evaluators: ARN constructed from the builtin ID
- External ARN references: used as-is
@github-actionsgithub-actionsBot removed the size/m PR size: M label May 5, 2026
@jariy17

Copy link
Copy Markdown
ContributorAuthor

Addressed in 44bc3f2. The evaluator ARN resolution is now transitive from the online eval configs the AB test references — handling all three cases:

  • Custom evaluators — looked up from deployedResources.evaluators
  • Builtin.* evaluators — ARN constructed as arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*
  • External ARN references — used as-is

The policy is now scoped to only the evaluators this specific AB test transitively references (not all project evaluators), addressing the least-privilege concern.

The e2e tests exercise a custom evaluator (ABTestEvaluator in ab-test-target-based.test.ts). We haven't explicitly tested with Builtin evaluators, but the ARN construction follows the same pattern used in the L3 CDK constructs (AgentCoreOnlineEvaluationConfig.ts:143-161).

Replace the hand-rolled per-resource policy with the canonical policy
from https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/ab-testing-prereqs.html:
- Trust policy: add SourceAccount + SourceArn conditions
- Permissions: single AgentCoreResources statement scoped to
arn:aws:bedrock-agentcore:*:${accountId}:* with ResourceAccount condition
- Add missing actions: GetGatewayTarget, ListGatewayTargets,
ListConfigurationBundleVersions
- CloudWatch logs scoped to account via PrincipalAccount pattern
- Remove per-evaluator/per-resource ARN tracking (no longer needed)
@github-actionsgithub-actionsBot added the size/m PR size: M label May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…-utils
Extract waitForRunningThenStop into promote-utils.ts so it can be unit
tested without pulling in React/ink. Add 4 tests covering: immediate
RUNNING, polling until RUNNING, timeout throws, and error message content.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Comment threadsrc/cli/operations/deploy/post-deploy-ab-tests.ts
padmak30
padmak30 previously approved these changes May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: correct AB test execution role IAM policy and promote stabilityfix: align AB test execution role IAM policy and fix promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: align AB test execution role IAM policy and fix promote stabilityfix: correct AB test execution role IAM policy and promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@notgitika
notgitika self-requested a review May 5, 2026 20:59
@notgitika

Copy link
Copy Markdown
Contributor

waitForRunningThenStop fixes the CLI promote race condition, but if there is a TUI path that calls updateABTest({ executionStatus: "STOPPED" }) directly, it has the same bug right?

Comment threadscripts/run-e2e-local.sh
@jariy17
jariy17 merged commit 9f231d0 into mainMay 5, 2026
25 checks passed
@jariy17
jariy17 deleted the fix/ab-test-role-evaluator-permission branch May 5, 2026 22:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jariy17@agentcore-cli-automation@notgitika@padmak30
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: correct AB test execution role IAM policy and promote stability by jariy17 · Pull Request #1120 · aws/agentcore-cli · GitHub
Skip to content

fix: correct AB test execution role IAM policy and promote stability - #1120

Merged
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission
May 5, 2026
Merged

fix: correct AB test execution role IAM policy and promote stability#1120
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission

Conversation

@jariy17

@jariy17jariy17 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • IAM policy — Aligns the auto-created AB test execution role with the official docs, fixing a 400 "Access denied when validating evaluator" error on every deploy with a custom evaluator
  • Promote stabilitypromote ab-test waits for executionStatus === 'RUNNING' before stopping, avoiding 409 errors when promote runs immediately after resume; throws a clear error if the test never reaches RUNNING
  • IAM — DescribeLogGroups — Split into its own statement with Resource: "*" (AWS requirement)
  • E2E coverage — Added AB test reaches RUNNING status after deploy to ab-test-target-based.test.ts to catch IAM permission regressions post-deploy
  • Status test — Fixed incorrect http-gateway resourceType assertion; replaced with ab-test + invocationUrl check
  • Local e2e script — Added scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally

IAM changes

Trust policy — added SourceAccount + SourceArn conditions to prevent confused deputy attacks:

"Condition": {
"StringEquals": { "aws:SourceAccount": "<accountId>" },
"ArnLike": { "aws:SourceArn": "arn:aws:bedrock-agentcore:*:<accountId>:ab-test/*" }
}

Permissions — 3-statement policy aligned with docs:

  • AgentCoreResources — all bedrock-agentcore actions scoped to account with ResourceAccount condition (adds GetEvaluator, GetGatewayTarget, ListGatewayTargets, ListConfigurationBundleVersions)
  • CloudWatchLogsDescribelogs:DescribeLogGroups with Resource: "*" (required by AWS)
  • CloudWatchLogs — log read/write actions scoped to evaluation and spans log groups

Running E2E tests locally

export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role>export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>
./scripts/run-e2e-local.sh e2e-tests/ab-test-target-based.test.ts

Test plan

  • e2e-tests/ab-test-target-based.test.ts — all steps pass including RUNNING check
  • e2e-tests/ab-test-config-bundle.test.ts — passes (RUNNING check deferred to follow-up once real config bundles are used)
  • Unit tests src/cli/operations/deploy/__tests__/post-deploy-ab-tests.test.ts — 23 passing
  • Unit tests src/cli/commands/pause/__tests__/promote.test.ts — 4 passing

The AB test API validates evaluator ARNs server-side using the execution
role. The auto-created role policy was missing bedrock-agentcore:GetEvaluator,
causing a 400 "Access denied when validating evaluator" error on every deploy
that included a target-based AB test with a custom evaluator.
@jariy17
jariy17 requested a review from a teamMay 4, 2026 23:26
@github-actionsgithub-actionsBot added size/xs PR size: XS agentcore-harness-reviewing AgentCore Harness review in progress labels May 4, 2026
HTTP gateways are not surfaced as top-level resources in agentcore status —
they are only used internally to build AB test invocation URLs. The test was
asserting on resourceType 'http-gateway' which never appears; fix it to
assert on the 'ab-test' resource instead.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/xs PR size: XS labels May 4, 2026
@agentcore-cli-automation

Copy link
Copy Markdown

The new EvaluatorReadStatement is scoped to Object.values(deployedResources?.evaluators ?? {}), which only contains custom evaluators deployed by this project. This will leave the original 400 error in place whenever the AB test's online-eval config references evaluators that aren't in deployedResources.evaluators:

  • Builtin evaluators (Builtin.Faithfulness, Builtin.GoalSuccessRate, etc.) — these are first-class evaluator references in OnlineEvalConfig.evaluators (see src/schema/schemas/primitives/online-eval-config.ts:23-24 and the handling in AgentCoreOnlineEvaluationConfig.ts:143-161). If the service validates evaluator ARNs uniformly using the execution role, Builtins will fail the same check the PR is trying to fix.
  • External evaluator ARNsOnlineEvalConfig.evaluators also accepts raw ARNs pointing at evaluators outside this project / another account. Those are never in deployedResources.evaluators either.

Separately, even for the custom-evaluator case, the policy grants GetEvaluator on every evaluator in the project rather than just the ones this specific AB test transitively references via its onlineEvalConfigArns. That's a least-privilege concern but not a functional blocker.

A couple of ways to address this:

  1. Resolve evaluators transitively from the referenced online eval configs. For each online eval config referenced by testSpec.evaluationConfig, look up its evaluators list in projectSpec.onlineEvalConfigs, and for each entry:

    • Builtin.* → construct the builtin ARN (arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*)
    • arn:... → use as-is
    • otherwise → look up in deployedResources.evaluators

    Pass that de-duplicated list as evaluatorArns. This fixes both the Builtin/external case and the over-broad scoping.

  2. If tightening the scope is risky, at minimum add arn:${partition}:bedrock-agentcore:::evaluator/Builtin.* to the Resource list (and optionally arn:${partition}:bedrock-agentcore:${region}:${accountId}:evaluator/*) so users with builtin evaluators don't hit the same 400.

Could you also confirm whether you tested the fix with a Builtin evaluator in the online eval config, or only with a custom one? The test plan only mentions ab-test-target-based.test.ts / ab-test-config-bundle.test.ts — knowing which evaluator types those exercise would help.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 4, 2026
@github-actions

github-actionsBot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines43.11%9016 / 20912
🔵Statements42.4%9575 / 22582
🔵Functions39.96%1555 / 3891
🔵Branches39.98%5808 / 14527
Generated in workflow #2425 for commit 5b72ab3 by the Vitest Coverage Report Action

The resource cast was missing invocationUrl, causing a TypeScript error
when asserting the AB test's gateway invocation URL was present.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/s PR size: S labels May 4, 2026
- Include stdout in promote failure message so the JSON error is visible
- Add scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/s PR size: S labels May 5, 2026
When promote is called immediately after resume, the AB test may still be
in UPDATING state and reject the STOPPED transition with a 409. Retry up
to 6 times with a 10s delay to wait for the transition to complete.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus is no longer UPDATING before
attempting to stop. The service rejects updates with 409 while a
state transition is in progress (e.g. after resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus === 'RUNNING' before issuing the
STOPPED transition. The service 409s if the test is still UPDATING
(e.g. transitioning from a prior resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…figs
Previously GetEvaluator was scoped to all project evaluators. Now it's
scoped to only the evaluators referenced by the specific online eval
configs this AB test uses, handling all three cases:
- Custom evaluators: looked up from deployedResources.evaluators
- Builtin.* evaluators: ARN constructed from the builtin ID
- External ARN references: used as-is
@github-actionsgithub-actionsBot removed the size/m PR size: M label May 5, 2026
@jariy17

Copy link
Copy Markdown
ContributorAuthor

Addressed in 44bc3f2. The evaluator ARN resolution is now transitive from the online eval configs the AB test references — handling all three cases:

  • Custom evaluators — looked up from deployedResources.evaluators
  • Builtin.* evaluators — ARN constructed as arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*
  • External ARN references — used as-is

The policy is now scoped to only the evaluators this specific AB test transitively references (not all project evaluators), addressing the least-privilege concern.

The e2e tests exercise a custom evaluator (ABTestEvaluator in ab-test-target-based.test.ts). We haven't explicitly tested with Builtin evaluators, but the ARN construction follows the same pattern used in the L3 CDK constructs (AgentCoreOnlineEvaluationConfig.ts:143-161).

Replace the hand-rolled per-resource policy with the canonical policy
from https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/ab-testing-prereqs.html:
- Trust policy: add SourceAccount + SourceArn conditions
- Permissions: single AgentCoreResources statement scoped to
arn:aws:bedrock-agentcore:*:${accountId}:* with ResourceAccount condition
- Add missing actions: GetGatewayTarget, ListGatewayTargets,
ListConfigurationBundleVersions
- CloudWatch logs scoped to account via PrincipalAccount pattern
- Remove per-evaluator/per-resource ARN tracking (no longer needed)
@github-actionsgithub-actionsBot added the size/m PR size: M label May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…-utils
Extract waitForRunningThenStop into promote-utils.ts so it can be unit
tested without pulling in React/ink. Add 4 tests covering: immediate
RUNNING, polling until RUNNING, timeout throws, and error message content.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Comment threadsrc/cli/operations/deploy/post-deploy-ab-tests.ts
padmak30
padmak30 previously approved these changes May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: correct AB test execution role IAM policy and promote stabilityfix: align AB test execution role IAM policy and fix promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: align AB test execution role IAM policy and fix promote stabilityfix: correct AB test execution role IAM policy and promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@notgitika
notgitika self-requested a review May 5, 2026 20:59
@notgitika

Copy link
Copy Markdown
Contributor

waitForRunningThenStop fixes the CLI promote race condition, but if there is a TUI path that calls updateABTest({ executionStatus: "STOPPED" }) directly, it has the same bug right?

Comment threadscripts/run-e2e-local.sh
@jariy17
jariy17 merged commit 9f231d0 into mainMay 5, 2026
25 checks passed
@jariy17
jariy17 deleted the fix/ab-test-role-evaluator-permission branch May 5, 2026 22:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jariy17@agentcore-cli-automation@notgitika@padmak30
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix: correct AB test execution role IAM policy and promote stability by jariy17 · Pull Request #1120 · aws/agentcore-cli · GitHub
Skip to content

fix: correct AB test execution role IAM policy and promote stability - #1120

Merged
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission
May 5, 2026
Merged

fix: correct AB test execution role IAM policy and promote stability#1120
jariy17 merged 16 commits into
mainfrom
fix/ab-test-role-evaluator-permission

Conversation

@jariy17

@jariy17jariy17 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • IAM policy — Aligns the auto-created AB test execution role with the official docs, fixing a 400 "Access denied when validating evaluator" error on every deploy with a custom evaluator
  • Promote stabilitypromote ab-test waits for executionStatus === 'RUNNING' before stopping, avoiding 409 errors when promote runs immediately after resume; throws a clear error if the test never reaches RUNNING
  • IAM — DescribeLogGroups — Split into its own statement with Resource: "*" (AWS requirement)
  • E2E coverage — Added AB test reaches RUNNING status after deploy to ab-test-target-based.test.ts to catch IAM permission regressions post-deploy
  • Status test — Fixed incorrect http-gateway resourceType assertion; replaced with ab-test + invocationUrl check
  • Local e2e script — Added scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally

IAM changes

Trust policy — added SourceAccount + SourceArn conditions to prevent confused deputy attacks:

"Condition": {
"StringEquals": { "aws:SourceAccount": "<accountId>" },
"ArnLike": { "aws:SourceArn": "arn:aws:bedrock-agentcore:*:<accountId>:ab-test/*" }
}

Permissions — 3-statement policy aligned with docs:

  • AgentCoreResources — all bedrock-agentcore actions scoped to account with ResourceAccount condition (adds GetEvaluator, GetGatewayTarget, ListGatewayTargets, ListConfigurationBundleVersions)
  • CloudWatchLogsDescribelogs:DescribeLogGroups with Resource: "*" (required by AWS)
  • CloudWatchLogs — log read/write actions scoped to evaluation and spans log groups

Running E2E tests locally

export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role>export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>
./scripts/run-e2e-local.sh e2e-tests/ab-test-target-based.test.ts

Test plan

  • e2e-tests/ab-test-target-based.test.ts — all steps pass including RUNNING check
  • e2e-tests/ab-test-config-bundle.test.ts — passes (RUNNING check deferred to follow-up once real config bundles are used)
  • Unit tests src/cli/operations/deploy/__tests__/post-deploy-ab-tests.test.ts — 23 passing
  • Unit tests src/cli/commands/pause/__tests__/promote.test.ts — 4 passing

The AB test API validates evaluator ARNs server-side using the execution
role. The auto-created role policy was missing bedrock-agentcore:GetEvaluator,
causing a 400 "Access denied when validating evaluator" error on every deploy
that included a target-based AB test with a custom evaluator.
@jariy17
jariy17 requested a review from a teamMay 4, 2026 23:26
@github-actionsgithub-actionsBot added size/xs PR size: XS agentcore-harness-reviewing AgentCore Harness review in progress labels May 4, 2026
HTTP gateways are not surfaced as top-level resources in agentcore status —
they are only used internally to build AB test invocation URLs. The test was
asserting on resourceType 'http-gateway' which never appears; fix it to
assert on the 'ab-test' resource instead.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/xs PR size: XS labels May 4, 2026
@agentcore-cli-automation

Copy link
Copy Markdown

The new EvaluatorReadStatement is scoped to Object.values(deployedResources?.evaluators ?? {}), which only contains custom evaluators deployed by this project. This will leave the original 400 error in place whenever the AB test's online-eval config references evaluators that aren't in deployedResources.evaluators:

  • Builtin evaluators (Builtin.Faithfulness, Builtin.GoalSuccessRate, etc.) — these are first-class evaluator references in OnlineEvalConfig.evaluators (see src/schema/schemas/primitives/online-eval-config.ts:23-24 and the handling in AgentCoreOnlineEvaluationConfig.ts:143-161). If the service validates evaluator ARNs uniformly using the execution role, Builtins will fail the same check the PR is trying to fix.
  • External evaluator ARNsOnlineEvalConfig.evaluators also accepts raw ARNs pointing at evaluators outside this project / another account. Those are never in deployedResources.evaluators either.

Separately, even for the custom-evaluator case, the policy grants GetEvaluator on every evaluator in the project rather than just the ones this specific AB test transitively references via its onlineEvalConfigArns. That's a least-privilege concern but not a functional blocker.

A couple of ways to address this:

  1. Resolve evaluators transitively from the referenced online eval configs. For each online eval config referenced by testSpec.evaluationConfig, look up its evaluators list in projectSpec.onlineEvalConfigs, and for each entry:

    • Builtin.* → construct the builtin ARN (arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*)
    • arn:... → use as-is
    • otherwise → look up in deployedResources.evaluators

    Pass that de-duplicated list as evaluatorArns. This fixes both the Builtin/external case and the over-broad scoping.

  2. If tightening the scope is risky, at minimum add arn:${partition}:bedrock-agentcore:::evaluator/Builtin.* to the Resource list (and optionally arn:${partition}:bedrock-agentcore:${region}:${accountId}:evaluator/*) so users with builtin evaluators don't hit the same 400.

Could you also confirm whether you tested the fix with a Builtin evaluator in the online eval config, or only with a custom one? The test plan only mentions ab-test-target-based.test.ts / ab-test-config-bundle.test.ts — knowing which evaluator types those exercise would help.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 4, 2026
@github-actions

github-actionsBot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines43.11%9016 / 20912
🔵Statements42.4%9575 / 22582
🔵Functions39.96%1555 / 3891
🔵Branches39.98%5808 / 14527
Generated in workflow #2425 for commit 5b72ab3 by the Vitest Coverage Report Action

The resource cast was missing invocationUrl, causing a TypeScript error
when asserting the AB test's gateway invocation URL was present.
@github-actionsgithub-actionsBot added size/s PR size: S and removed size/s PR size: S labels May 4, 2026
- Include stdout in promote failure message so the JSON error is visible
- Add scripts/run-e2e-local.sh to replicate the GitHub Actions e2e workflow locally
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/s PR size: S labels May 5, 2026
When promote is called immediately after resume, the AB test may still be
in UPDATING state and reject the STOPPED transition with a 409. Retry up
to 6 times with a 10s delay to wait for the transition to complete.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus is no longer UPDATING before
attempting to stop. The service rejects updates with 409 while a
state transition is in progress (e.g. after resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Poll getABTest until executionStatus === 'RUNNING' before issuing the
STOPPED transition. The service 409s if the test is still UPDATING
(e.g. transitioning from a prior resume).
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…figs
Previously GetEvaluator was scoped to all project evaluators. Now it's
scoped to only the evaluators referenced by the specific online eval
configs this AB test uses, handling all three cases:
- Custom evaluators: looked up from deployedResources.evaluators
- Builtin.* evaluators: ARN constructed from the builtin ID
- External ARN references: used as-is
@github-actionsgithub-actionsBot removed the size/m PR size: M label May 5, 2026
@jariy17

Copy link
Copy Markdown
ContributorAuthor

Addressed in 44bc3f2. The evaluator ARN resolution is now transitive from the online eval configs the AB test references — handling all three cases:

  • Custom evaluators — looked up from deployedResources.evaluators
  • Builtin.* evaluators — ARN constructed as arn:${partition}:bedrock-agentcore:::evaluator/Builtin.*
  • External ARN references — used as-is

The policy is now scoped to only the evaluators this specific AB test transitively references (not all project evaluators), addressing the least-privilege concern.

The e2e tests exercise a custom evaluator (ABTestEvaluator in ab-test-target-based.test.ts). We haven't explicitly tested with Builtin evaluators, but the ARN construction follows the same pattern used in the L3 CDK constructs (AgentCoreOnlineEvaluationConfig.ts:143-161).

Replace the hand-rolled per-resource policy with the canonical policy
from https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/ab-testing-prereqs.html:
- Trust policy: add SourceAccount + SourceArn conditions
- Permissions: single AgentCoreResources statement scoped to
arn:aws:bedrock-agentcore:*:${accountId}:* with ResourceAccount condition
- Add missing actions: GetGatewayTarget, ListGatewayTargets,
ListConfigurationBundleVersions
- CloudWatch logs scoped to account via PrincipalAccount pattern
- Remove per-evaluator/per-resource ARN tracking (no longer needed)
@github-actionsgithub-actionsBot added the size/m PR size: M label May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
…-utils
Extract waitForRunningThenStop into promote-utils.ts so it can be unit
tested without pulling in React/ink. Add 4 tests covering: immediate
RUNNING, polling until RUNNING, timeout throws, and error message content.
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
Comment threadsrc/cli/operations/deploy/post-deploy-ab-tests.ts
padmak30
padmak30 previously approved these changes May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: correct AB test execution role IAM policy and promote stabilityfix: align AB test execution role IAM policy and fix promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@jariy17jariy17 changed the title fix: align AB test execution role IAM policy and fix promote stabilityfix: correct AB test execution role IAM policy and promote stabilityMay 5, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 5, 2026
@notgitika
notgitika self-requested a review May 5, 2026 20:59
@notgitika

Copy link
Copy Markdown
Contributor

waitForRunningThenStop fixes the CLI promote race condition, but if there is a TUI path that calls updateABTest({ executionStatus: "STOPPED" }) directly, it has the same bug right?

Comment threadscripts/run-e2e-local.sh
@jariy17
jariy17 merged commit 9f231d0 into mainMay 5, 2026
25 checks passed
@jariy17
jariy17 deleted the fix/ab-test-role-evaluator-permission branch May 5, 2026 22:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jariy17@agentcore-cli-automation@notgitika@padmak30