Skip to content

feat: show Bedrock external ID in the provider edit form - #26919

Merged
evgeniy-scherbina merged 7 commits into
mainfrom
feat/bedrock-external-id-ui
Jul 2, 2026
Merged

feat: show Bedrock external ID in the provider edit form#26919
evgeniy-scherbina merged 7 commits into
mainfrom
feat/bedrock-external-id-ui

Conversation

@evgeniy-scherbina

@evgeniy-scherbina evgeniy-scherbina commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Surfaces the server-generated STS external ID on the Bedrock provider edit form. When a provider assumes a role, the form shows the external ID read-only with a copy icon and a short note to add it to the target role's trust policy as an sts:ExternalId condition.

The value is display-only: it is passed to the form as its own prop rather than as an editable form value, so it is never submitted back. This matches the backend contract, where the external ID is server-owned and a changed value is rejected.

Builds on the backend in #26869. Follow-up to #26578.

@evgeniy-scherbina
evgeniy-scherbina changed the base branch from main to feat/bedrock-external-id July 1, 2026 16:08
@evgeniy-scherbina evgeniy-scherbina changed the title Feat/bedrock external id UI a3b92b788cb6b6bae9fae7ca7ce56b3dff0d3189 Jul 1, 2026
@evgeniy-scherbina evgeniy-scherbina changed the title a3b92b788cb6b6bae9fae7ca7ce56b3dff0d3189 feat: show Bedrock external ID in the provider edit form Jul 1, 2026
@evgeniy-scherbina
evgeniy-scherbina marked this pull request as ready for review July 1, 2026 17:33
@evgeniy-scherbina

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

@coder-agents-review

coder-agents-review Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Chat: Review posted | View chat
Requested: 2026-07-01 17:33 UTC by @evgeniy-scherbina
Spend: $16.72 / $100.00

Review history
  • R1 (2026-07-01): 16 reviewers, 1 Note, 3 P3, COMMENT. Review

deep-review v0.9.0 | Round 1 | d2d0bce..a3b92b7

Last posted: Round 1, 4 findings (3 P3, 1 Note), COMMENT. Review

Finding inventory

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 P3 Open ProviderForm.tsx:546 No Storybook story covers the external ID display R1 Netero Yes
CRF-2 P3 Open providerFormApiMap.ts:58 Comment on bedrockExternalId restates generated type and consumer behavior R1 Gon (raised as P2, downgraded to P3) Yes
CRF-3 Nit Dropped by orchestrator (file naming convention is mixed, not consistently verb-prefixed) providerFormApiMap.ts:61 bedrockExternalId verb-prefix naming R1 Gon No
CRF-4 Note Open providerFormApiMap.ts:66 External ID lifecycle outlives role ARN; UI shows trust-policy text with no role set R1 Hisoka Yes
CRF-5 P3 Open docs/ai-coder/ai-gateway/providers.md:155 Docs section on role assumption omits external ID R1 Leorio Yes

Contested and acknowledged

(none)

Round log

Round 1

Panel (16 reviewers). 2 P3, 1 Note new. 1 Nit dropped. Plus 1 P3 from Netero first pass. Reviewed against d2d0bce..a3b92b7.

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Komugi flake/determinism
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

@coderagents

coderagents Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Documentation Check

Updates Needed

  • docs/ai-coder/ai-gateway/providers.md - The "Assuming an IAM role" section (lines 141-164) documents the Role ARN setup but does not mention the server-generated external ID introduced by this PR. Step 2 ("Configure the role's trust policy") should note that Coder generates an external ID visible in the provider edit form, and that users should add it as an sts:ExternalId condition in the role's trust policy. This is a security best practice for cross-account role assumption.

Automated review via Coder Agents

@coder-agents-review coder-agents-review 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.

Clean, well-scoped change. The external ID is threaded as its own prop rather than as a form value, making the read-only contract structural. Tests cover all four relevant partitions. The existing CodeExample and Label components are reused correctly.

"I tried to build a case against framings 1 and 2 and could not." - Pariston

Severity summary: 3 P3, 1 Note.


docs/ai-coder/ai-gateway/providers.md:155

P3 [CRF-5] The "Assuming an IAM role" docs section never mentions the external ID the UI now surfaces.

"The docs walk operators through role assumption in three steps (create role, configure trust policy, enter the ARN). Step 2 says 'Configure the role's trust policy to allow the gateway's base identity to assume it' and stops there. The UI now shows an external ID with help text about adding it to the trust policy." (Leorio)

An operator following the docs to set up Bedrock role assumption gets no mention of the external ID or confused deputy prevention. The security hardening step is discoverable only through the edit form. Consider adding a step in the docs covering where to find the external ID and how to add the sts:ExternalId condition to the trust policy.

🤖

🤖 This review was automatically generated with Coder Agents.

Comment on lines +58 to +60
// The external ID is server-generated and returned on read when the Bedrock
// provider assumes a role. It is read-only: the form displays it but never
// submits it.

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.

P3 [CRF-2] Comment restates what the generated type and the consuming component already document.

"The first sentence duplicates the JSDoc on AIProviderBedrockSettings.external_id in typesGenerated.ts. The second sentence ('the form displays it but never submits it') describes ProviderForm's behavior, not this function's." (Gon)

The comment documents consumer behavior ("the form displays it but never submits it"), creating a maintenance hazard: if the form changes, this comment silently misleads. Trim to the function's own contract:

// Server-generated STS external ID; read-only.

🤖

return undefined;
}
const s = provider.settings as SettingsWire | null;
return s?.external_id || undefined;

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.

Note [CRF-4] External ID lifecycle outlives the role ARN it was generated from.

"The server preserves the external ID after role removal (ensureBedrockExternalID only generates, never clears; the merge function carries it forward). The UI gate is editing && bedrockExternalId, with no check on whether role_arn is currently set." (Hisoka)

If an admin once set a role ARN, then cleared it, the external ID persists server-side. The UI renders "Add it to the assumed role's trust policy" next to an empty Role ARN field. Not a bug per se: the external ID is valid for future role configurations, and the text is forward-looking. Worth knowing.

🤖

Base automatically changed from feat/bedrock-external-id to main July 1, 2026 20:44
…xternal ID review

- Add EditBedrockWithExternalId Storybook story so the read-only external ID
  block on the Bedrock edit form has coverage (CRF-1).
- Trim the bedrockExternalId comment to describe the function's own contract
  instead of restating the generated JSDoc and consumer behavior (CRF-2).

Modified by Coder Agents on behalf of Jake Howell.
@jakehwll

jakehwll commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Addressed the actionable frontend review findings in d70b941:

  • CRF-1 (ProviderForm.tsx:546): Added an EditBedrockWithExternalId Storybook story that passes bedrockExternalId="7QF3ZK2MLP4RS6TUVWXY2ABCDE" and asserts the External ID label, the code value, the sts:ExternalId help text, and the copy button are all visible.
  • CRF-2 (providerFormApiMap.ts:58): Trimmed the comment on bedrockExternalId to describe the function's own contract (// Server-generated STS external ID; read-only.) rather than restating the generated JSDoc and consumer behavior.

Left as-is:

  • CRF-4 (Note): The reviewer marked this as informational ("Not a bug per se"). The external ID is forward-looking and remains valid for future role configurations, so gating the display on values.roleArn would hide useful context.
  • CRF-5 (docs): Not part of the frontend feedback set. Happy to add the docs step for sts:ExternalId in docs/ai-coder/ai-gateway/providers.md too if you'd like it in the same PR.

🤖 This comment was written by Coder Agents on behalf of @jakehwll.

…-id-ui

# Conflicts:
#	coderd/ai_providers_internal_test.go
#	coderd/ai_providers_test.go

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

Im a little unsure on STS external ID comment, but being its generated I think we're in a fine state.

Code-wise all looks fine to me 🙂

@evgeniy-scherbina

Copy link
Copy Markdown
Contributor Author

@jakehwll thanks for the review and fixes! I'll add docs in a separate PR.

@evgeniy-scherbina
evgeniy-scherbina merged commit dee41c3 into main Jul 2, 2026
26 of 27 checks passed
@evgeniy-scherbina
evgeniy-scherbina deleted the feat/bedrock-external-id-ui branch July 2, 2026 14:55
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants