Skip to content

feat: create credential providers before synthesizing a deploy - #2123

Open
notgitika wants to merge 3 commits into
refactorfrom
feat/deploy-credential-providers
Open

feat: create credential providers before synthesizing a deploy#2123
notgitika wants to merge 3 commits into
refactorfrom
feat/deploy-credential-providers

Conversation

@notgitika

@notgitika notgitika commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Creates a project's credential providers before synthesis, so the synthesized CDK app can read their ARNs out of deployed-state.json and wire them into the stack. Without this, deploying a project that declares any credential fails inside cdk synth.

What it does

  • Between the account preflight and synth, CdkBackend.deploy provisions each declared credential provider: reuse-if-present, create-if-absent, never update (so a redeploy neither mints a new secret version nor overwrites one rotated outside the CLI), then records the ARNs via updateTargetState.
  • Secrets come from the same place project add credentials writes them — .env.local (AGENTCORE_CREDENTIAL_<NAME>) or a Secrets Manager secretRef. The env-var name is now derived from one shared function in envLocal.ts so add and deploy agree.
  • Payment credentials are rejected up front (agentcore.json can't express their vendor config).

Notes

Tested e2e

Ran the full flow against a real account (us-west-2): project add credentials api-keyproject deploy. Confirmed deploy creates the API-key credential provider imperatively before synth, writes it to agentcore/.cli/deployed-state.json, then deploys the stack and merges the stackArn into the same target entry (no clobbering). Resulting file held both resources.credentials.e2ekey and stackArn.

@github-actions github-actions Bot added the size/l PR size: L label Aug 27, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 27, 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 PR. The design of running credential provisioning before cdk synth and threading the ARNs through deployed-state.json is well-motivated and the comments do a great job of capturing why. The seam boundary (IdentityProviderClient) is drawn at the SDK client rather than at fs/process boundaries, so the tests avoid excessive mocking while still exercising the real spec + .env.local parsing paths. Sharing credentialEnvVarName/CLIENT_SECRET_SUFFIX between add and deploy via envLocal.ts (with a re-export from shared.ts) removes a latent format-drift bug.

A couple of small things that aren't blockers but worth confirming intentional:

  • Stale credential entries when the spec goes to zero credentials. In src/core/project/backends/cdk.ts (~L115) updateTargetState is only called when Object.keys(provisioned).length > 0. If a user deletes their last credential from agentcore.json and re-deploys, provisioned is {}, the state write is skipped, and the previous resources.credentials map is left on disk. The doc-comment on updateTargetState promises "A resource map provided in the patch replaces the previous map for that kind wholesale, so a credential dropped from the spec stops being advertised" — that guarantee is only actually delivered when at least one credential remains. Since the synthesized CDK app looks up credentials by name, this is likely inert in practice, but if you want the drop-to-zero case to behave the same as drop-one-of-many, you'd either always call updateTargetState({ resources: { credentials: provisioned } }) or explicitly write {} when declared is non-empty on the spec side but you provisioned nothing.

  • parseEnv cast in EnvLocalFile.read (src/core/project/envLocal.ts L90): parseEnv's declared return type is Record<string, string | undefined> (last-write-wins across duplicate keys), but you cast to Record<string, string>. All callers happen to use if (!value) so undefined is handled safely today; just be aware the type is a small lie and a future caller doing env[k].trim() would compile but crash.

Neither of these needs to block the merge.

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 27, 2026
@notgitika
notgitika force-pushed the feat/deploy-credential-providers branch from 4b787a8 to 0db4266 Compare August 27, 2026 15:43
@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Aug 27, 2026
Base automatically changed from feat/deployed-state-top-level to refactor August 27, 2026 16:15
@github-actions github-actions Bot added size/xl PR size: XL and removed size/l PR size: L labels Aug 27, 2026
The synthesized CDK app reads credential provider ARNs out of
deployed-state.json and fails to synth a project that declares credentials
until they exist. Provision them between the account preflight and the
build, then record their ARNs via updateTargetState so the assembly is
synthesized against a state file that already describes them.

Providers are created when absent and reused when present, never updated,
so a redeploy neither mints a new secret version nor overwrites one rotated
outside the CLI. Payment credentials are rejected up front (agentcore.json
can't express the vendor config they need). Secrets come from the same
place 'project add credentials' writes them, so the env-var name is now
derived from one function in envLocal.ts that both sides share.
@notgitika
notgitika force-pushed the feat/deploy-credential-providers branch from 0db4266 to 3c09c23 Compare August 27, 2026 16:28
@github-actions github-actions Bot added size/l PR size: L and removed size/xl PR size: XL size/l PR size: L labels Aug 27, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 27, 2026
@codecov-commenter

codecov-commenter commented Aug 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.71689% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.38%. Comparing base (794ddbf) to head (2c47266).
⚠️ Report is 3 commits behind head on refactor.

Files with missing lines Patch % Lines
src/core/project/backends/cdk/credentials.ts 97.46% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           refactor    #2123    +/-   ##
==========================================
  Coverage     97.37%   97.38%            
==========================================
  Files           455      456     +1     
  Lines         27741    27955   +214     
==========================================
+ Hits          27014    27223   +209     
- Misses          727      732     +5     

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

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

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 27, 2026
@notgitika
notgitika marked this pull request as ready for review August 27, 2026 16:38
@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Aug 27, 2026
…v type

- Add SDK-mocked coverage for createIdentityProviderClient (the real Identity
  factory the provisioner tests bypass): ~55% -> ~95% on credentials.ts.
- Always record the provisioned credential set, so removing the last credential
  from the spec clears the stale entry instead of leaving it advertised.
- EnvLocalFile.read returns Record<string, string | undefined> (parseEnv's real
  type) rather than casting it away.
- Tighten a few verbose comments.
@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Aug 27, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 27, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 27, 2026
@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Aug 27, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 27, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

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

Labels

size/l PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants