') + ')', '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('^' + ".*" + ', '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" + ', '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('^' + ".*" + ', '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); } })(); })(); feat(deploy): auto-provision the default deployment target from STS by AlexanderRichey · Pull Request #2145 · aws/agentcore-cli · GitHub
Skip to content

feat(deploy): auto-provision the default deployment target from STS - #2145

Merged
1 commit merged into
refactorfrom
feat/deploy-auto-default-target
Aug 31, 2026
Merged

feat(deploy): auto-provision the default deployment target from STS#2145
1 commit merged into
refactorfrom
feat/deploy-auto-default-target

Conversation

@AlexanderRichey

Copy link
Copy Markdown
Contributor

Summary

A brand-new user can now run

agentcore project create --name MyProject
cd MyProject
agentcore project deploy

and get a deployed CloudFormation stack with no hand-editing of config files, no prompts, and no prior AWS setup beyond valid credentials — including into a region that has never been CDK-bootstrapped.

  • When the requested target is default (defaulted or explicit) and agentcore/aws-targets.json is missing, empty, or lacks a default entry, FsProjectManager.deploy now synthesizes it: account from STS GetCallerIdentity, region from the CLI's already-resolved effective region (--region → env → ~/.aws/config → fallback), validated against AgentCoreRegionSchema before anything is written.
  • The entry is merged into the raw file contents, so existing targets keep their order, key order, and any unknown fields; the CLI reports one stderr line (Created default deployment target: …) and proceeds with the deploy in the same invocation.
  • Named targets are never invented — --target staging on an unconfigured project keeps the existing ProjectStateErrors, and the backend's account-match assertion is unchanged.
  • Failure modes are clean: an unsupported region fails with the resolved region plus the supported list (file untouched); unresolvable/expired credentials fail with an actionable InvalidEnvironmentError instead of an SDK stack trace.
  • The STS lookup is injectable via ProjectManagerConfig.resolveAccount (like json/runner/checkTool), so unit tests never call AWS.

Vended CDK template restore

This PR also reverts src/assets/cdk/{bin/cdk.ts,lib/cdk-stack.ts,test/cdk.test.ts,package.json} to their pre-#2120 state (byte-identical to adb02a1d^, pin @aws/agentcore-cdk@0.1.0-alpha.45). #2120 rewrote the template around an AgentCorePayments L3 that no published @aws/agentcore-cdk exports (alpha.49 and alpha.50 both ship only AgentCorePaymentManager/AgentCorePaymentConnector), so every fresh scaffold failed cdk synth at tsc before reaching AWS. The template shape from #2120 can be re-landed once a release ships that construct.

Testing

  • bun test src: 2310 pass, 0 fail. New coverage: file absent / [] → default synthesized; non-default entries preserved byte-for-byte (including unknown keys and non-canonical key order); missing named target → existing error, no STS call; unsupported region → actionable error, file untouched; STS failure → actionable error; existing default entry → used as-is, file untouched.
  • tsc --noEmit clean on the repo's code; oxlint clean at the committed toolchain version.

Live end-to-end (account 501930284170)

  • Happy path (us-east-1): fresh project, project deploy with no flags or edits → exit 0, target synthesized and written, stack AgentCore-DeployE2e0830-default reached CREATE_COMPLETE (verified via aws cloudformation describe-stacks).
  • Un-bootstrapped region (eu-west-1): verified no CDKToolkit existed, then a single project deploy --region eu-west-1 synthesized the target, bootstrapped unprompted (Bootstrapping aws://…/eu-west-1, new CDKToolkit at BootstrapVersion 32), and took AgentCore-DeployE2eBoot0830-default to CREATE_COMPLETE in one invocation.
  • Idempotency: a second deploy succeeded with no re-synthesis and a byte-identical aws-targets.json.
  • Both e2e stacks were destroyed afterwards; the eu-west-1 CDKToolkit was left standing.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XfADH54TZn2SSGUUixft8P

`project deploy` now synthesizes the `default` target when
aws-targets.json is missing, empty, or lacks a `default` entry: the
account comes from STS GetCallerIdentity and the region from the CLI's
already-resolved effective region, validated against
AgentCoreRegionSchema before anything is written. Existing entries are
preserved byte-for-byte, the synthesized entry is reported on stderr,
and the deploy proceeds in the same invocation. Named targets still
require explicit configuration, and unsupported regions or
unresolvable credentials fail with actionable errors before the file
is touched.
Also restores the vended CDK app (bin/cdk.ts, lib/cdk-stack.ts,
test/cdk.test.ts, package.json) to its last publishable state: it
referenced an AgentCorePayments L3 that no released @aws/agentcore-cdk
exports, so every fresh scaffold failed `cdk synth` at tsc before
reaching AWS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XfADH54TZn2SSGUUixft8P
@github-actionsgithub-actionsBot added the size/l PR size: L label Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.93671% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.29%. Comparing base (3d449c5) to head (5264d47).

Files with missing linesPatch %Lines
src/core/project/backends/cdk/environment.ts0.00%4 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## refactor #2145 +/- ##
============================================
- Coverage 97.29% 97.29% -0.01% 
============================================
Files 479 479 Lines 29673 29734 +61 ============================================
+ Hits 28871 28929 +58 - Misses 802 805 +3 

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

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

@agentcore-devx-automationagentcore-devx-automationBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 31, 2026

@agentcore-devx-automationagentcore-devx-automationBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AgentCore Harness Review

Verdict: Changes requested

The STS auto-provisioning feature itself — the change described in the commit title — looks great. The default-target-only guard, the "leave existing entries byte-for-byte" behavior, the actionable errors for unsupported regions and unresolvable credentials, and the resolveAccount injection point for tests are all thoughtful, and the coverage in manager.test.ts and deploy/index.test.ts is genuinely thorough.

The problems are in the CDK asset rework that got bundled into the same commit.

1. Unnecessary downgrade of @aws/agentcore-cdk (src/assets/cdk/package.json)

The commit downgrades @aws/agentcore-cdk from 0.1.0-alpha.49 to 0.1.0-alpha.45 and justifies it as "restoring the vended CDK app to its last publishable state" because the old file referenced an AgentCorePayments L3 that no released version exports.

The premise (no released version exports AgentCorePayments) is correct — I verified against every published 0.1.0-alpha.* on the registry. But the conclusion doesn't follow: every symbol the new inline cdk-stack.ts imports (AgentCoreApplication, AgentCoreMcp, AgentCorePaymentManager, AgentCorePaymentConnector, CustomJWTAuthorizerConfig, HarnessDeploymentConfig) is exported by alpha.45, .46, .47, .48, .49, and .50 with the same shapes. Alpha.45 was never uniquely required to make this build.

Downgrading four minor releases silently drops several Gateway fixes shipped between .45 and .49, e.g.:

  • Omitting ProtocolConfiguration when enableSemanticSearch === false (emitting 'NONE' produces a template CloudFormation rejects).
  • cfnTarget.node.addDependency(this.role) for both gateway targets and Lambda-backed targets (without it, target creation can race the DefaultPolicy attach and surface as an opaque "NoStack" rollback in the toolkit).
  • Retriever mapping changes in KB-backed targets.

Options:

  • Pin to 0.1.0-alpha.49 (previous state) and keep the new inline payment construction — this fixes the broken scaffold without regressing Gateway.
  • Bump to 0.1.0-alpha.50 (current latest).

Either preserves the intent (a scaffolded project's cdk synth passes tsc) without shedding fixes.

2. Payment coverage in the vended CDK dropped to zero (src/assets/cdk/test/cdk.test.ts)

The two existing tests — synthesizes manual and Quick Create payment connectors and preserves complete and type-distinct payment resource identities — were deleted, not adapted. The new inline payment wiring in cdk-stack.ts is substantial (~100 lines) and does non-obvious things: it filters agents through isPaymentEligibleAgent, injects AGENTCORE_PAYMENT_* env vars, adds an sts:AssumeRole grant on ProcessPaymentRole, and adds a broad set of bedrock-agentcore:* payment actions directly to the runtime role (a deliberate deviation from the beta guide, per the inline comment). None of that is covered by a synth-time template assertion any more, so a future edit that drops an env var, mis-scopes an IAM resource, or breaks the eligibility filter will ship without a red test.

At minimum, please restore synth-level assertions that:

  • A paymentSpec with an eligible Python HTTP agent produces the expected env vars on the runtime and the two IAM statements on its role.
  • Ineligible agents (non-HTTP protocol, or non-.py entrypoint) do not receive those env vars or grants.
  • A connector referencing a credentialName with no deployed provider fails synth with the "no deployed credential provider was found" error from bin/cdk.ts.

3. Scope of the commit

The auto-provisioning change and the CDK-asset rework are independent and each substantial. Bundling them makes the title/description mismatch the diff (nothing in the title hints at the payment L3 replacement or the @aws/agentcore-cdk version change), and it makes bisect/revert coarser than it needs to be. Not a merge blocker on its own, but worth splitting if you end up rerolling for the items above.

The STS auto-provisioning path is otherwise good to go once these are addressed.

@jariy17jariy17 closed this pull request by merging all changes into refactor in f2b73d6Aug 31, 2026
@jariy17
jariy17 deleted the feat/deploy-auto-default-target branch August 31, 2026 16:12
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/lPR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@AlexanderRichey@codecov-commenter@jariy17