Skip to content

fix(migrate): backfill credential secret ARNs v0 didn't record - #2600

Merged
notgitika merged 2 commits into
aws:refactorfrom
notgitika:fix/migrate-credential-secret-arn
Oct 15, 2026
Merged

notgitika merged 2 commits into
aws:refactorfrom
notgitika:fix/migrate-credential-secret-arn

Conversation

@notgitika

Copy link
Copy Markdown
Contributor

Description

v0 never records clientSecretArn for API-key credential providers, and doesn't always for OAuth ones, but v1's CDK app needs that ARN to let a Gateway read the secret. So agentcore migrate failed at v1 synth for any v0 project with an authenticated Gateway target.

Migrate now looks up each missing secret ARN with GetApiKeyCredentialProvider / GetOauth2CredentialProvider, using the selected target's credentials and region, and writes it into the synth workspace. On a fresh migration it also writes it into the project's agentcore/.cli/deployed-state.json, so a post-migration agentcore build works before the first deploy.

  • A new credential secrets check reports what was found: found the secret ARNs v0 didn't record for X, Y; migrating records them in agentcore/.cli/deployed-state.json.
  • A lookup that fails for a credential a Gateway target uses blocks the plan, with advice for the actual cause: provider not found, no stored secret, or a permission error naming the one API that was called. A failure for any other credential is only a warning.
  • No lookups happen when nothing is missing. Payment providers are skipped.
  • The pending (multi-target) path only feeds the target's synth. Its files were already written, and the target's first v1 deploy records the ARN through normal credential provisioning.

Known limitation: agentcore/.cli is gitignored, so the git gate can't see a v0 deploy that happens between plan and apply. Apply would then overwrite deployed-state.json with the planned copy.

Related Issue

Closes #2599

Documentation PR

Not applicable.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran bun test (4567 pass, 0 fail)
  • I ran the relevant end-to-end tests with bun run test:e2e, or explained why they are not applicable. I didn't run the e2e suite. Instead I ran it end to end against real AWS: a v0 0.31.1 project (LiteLLM Harness, Memory, IAM Gateway with an OpenAPI target on an API-key credential, two API-key credentials) went from migrate (ready, 6 logical-ID moves, 0 replacements), through the first v1 deploy, a prompt update and redeploy, and adding then removing a runtime. Physical IDs, provider ARNs and memory records matched the v0 baseline throughout.
  • I ran bun run typecheck
  • I ran bun run lint:check
  • I ran bun run format:check
  • I ran bun run build
  • If I modified src/assets/, I updated affected snapshots with bun test <test-file> --update-snapshots and committed them (not applicable)

Checklist

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

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

v0 never records clientSecretArn for API-key credential providers, and v1's
CDK app needs it to let a Gateway read the secret, so migrate failed at v1
synth for any v0 project with an authenticated Gateway target. Migrate now
looks up each missing secret ARN with the selected target's credentials and
records it in the synth workspace and the migrated deployed-state.json.

Closes aws#2599
@github-actions github-actions Bot added the size/l PR size: L label Oct 15, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Oct 15, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Oct 15, 2026

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AgentCore Harness Review

Verdict: Looks good

Nice fix. The backfill logic correctly scopes the "blocking" vs "warning" distinction to Gateway-referenced credentials, the error paths cover ResourceNotFoundException, no-stored-secret, and generic API failures with actionable messages, and the Windows path separator is normalized in the check message.

A few things I verified while reviewing (no changes requested):

  • kinds.get(name) filter correctly skips PaymentCredentialProvider and stale credentials no longer in the spec, and the authorizer strings (ApiKeyCredentialProvider / OAuthCredentialProvider) match src/projectSchemas/v0/schemas/deployed-state.ts and the v1 credential writer in src/core/project/backends/cdk/credentials.ts.
  • gatewayCredentialNames only matches API_KEY and OAUTH outbound auth types, which matches OutboundAuthTypeSchema and the stated invariant that these are the only types requiring a secret ARN at synth time.
  • When blocking.length > 0 the returned deployedState still contains partially-filled entries, but because the plan reports ready: false, apply never runs and the on-disk file isn't overwritten — so re-running agentcore migrate will re-fetch cleanly.
  • The pending-run path in index.ts (around line 609) parses the already-written v1 spec loosely but only uses credentials to look up authorizerType; worst case the backfill is a no-op if the spec is malformed, which is acceptable.
  • Tests use real temp directories and only fake the Identity client at the SDK boundary — no excessive mocking.
  • No new telemetry needed; this is a bugfix within an existing feature that doesn't currently emit telemetry.

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Oct 15, 2026
@codecov-commenter

codecov-commenter commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.58%. Comparing base (6c45032) to head (40929b7).

Additional details and impacted files
@@             Coverage Diff              @@
##           refactor    #2600      +/-   ##
============================================
+ Coverage     96.57%   96.58%   +0.01%     
============================================
  Files           699      700       +1     
  Lines         57427    57630     +203     
============================================
+ Hits          55462    55664     +202     
- Misses         1965     1966       +1     

☔ 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.

@jariy17 jariy17 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.

Multi-target projects with an authenticated Gateway still fail v1 synth. Details inline.

const statePath = join(input.rootPath, DEPLOYED_STATE_RELATIVE_PATH);
// Read as written rather than through the schema, so what isn't patched is kept as is.
const state = JSON.parse(await readFile(statePath, "utf8")) as LooseDeployedState;
const recorded = state.targets?.[input.target]?.resources?.credentials ?? {};

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.

This only backfills the selected target. The vended CDK app synthesizes a stack for every target, so a multi-target project with an authenticated Gateway still fails v1 synth.

Repro

  1. v0 project with targets default and prod, both deployed. A Gateway target uses API_KEY or OAUTH outbound auth.
  2. agentcore migrate --target default fills in targets.default only.
  3. synthCommand runs cdk synth with no stack selector. cdk.ts loops over resolveTargetStacks, which maps every target.
  4. The prod stack throws: Credential "<name>" has no clientSecretArn in deployed state (AgentCoreGateway.js:556, @aws/agentcore-cdk@1.0.0-rc.3).

deploy --target default and build hit the same error after migrating, until prod gets its own v1 deploy.

Scope: only Gateway outbound auth. Payment connectors and harness skill git auth also read deployed-state credentials, but they only need credentialProviderArn. v0 records that.

Suggested fix

  1. Backfill every deployed target in the same account and region as the selected one. Provider names are unique there, so the same lookup works.
  2. For targets in another account or region, fail the check with a clear message.
  3. Add a two-target test with a synth fake that rejects a Gateway credential missing clientSecretArn.

I traced this through the code. I didn't run a real two-target synth.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks. The single synth covers every target, so backfilling only the selected one wasn't enough. Fixed in 40929b7:

  • Migrate now looks up missing secret ARNs for every deployed target in the same account as the active credentials, across regions (one set of credentials reaches any region of its own account), resolving credentials once per region. The written deployed-state.json (and the pending path's synth workspace) gets the ARNs for all of them.
  • A target in another account whose Gateway credentials lack an ARN now fails the credential secrets check up front, naming the target, its account/region and the active account, with the manual get-*-credential-provider steps, since migrate reads every target with one set of credentials. If nothing is missing there, the plan stays ready; unreferenced credentials still only warn.
  • Tests: the two-target test you suggested, with a synth fake that throws like the CDK does when any target's Gateway credential lacks clientSecretArn (same account, two regions → ready, both patched), plus cross-account blocking and nothing-missing cases. I also replaced the earlier test that asserted prod stays unpatched.

@nborges-aws nborges-aws 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.

no findings from me; aside from TJs comment which I agree on. Can rereview once PR updated

The vended CDK app synthesizes a stack for every target, so backfilling only
the selected target still failed v1 synth (and build/deploy after migrating)
for a multi-target project with an authenticated Gateway. Look up missing
secret ARNs for every deployed target the active credentials' account owns,
resolving credentials once per region, and fail the check with recovery
steps for a target in another account whose Gateway credentials lack one.
@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Oct 15, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Oct 15, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Oct 15, 2026

@nborges-aws nborges-aws 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.

LGTM after fixes. Thanks!

@notgitika
notgitika merged commit 3fb8f16 into aws:refactor Oct 15, 2026
20 checks passed
@notgitika
notgitika deleted the fix/migrate-credential-secret-arn branch October 15, 2026 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants