Skip to content

fix: move AWS Bedrock IAM credentials to secret installation parameters [AIS-296] - #11203

Open
Tyler Pina (tylerpina) wants to merge 15 commits into
masterfrom
fix/bedrock-secret-param-ais-296
Open

fix: move AWS Bedrock IAM credentials to secret installation parameters [AIS-296]#11203
Tyler Pina (tylerpina) wants to merge 15 commits into
masterfrom
fix/bedrock-secret-param-ais-296

Conversation

@tylerpina

@tylerpina Tyler Pina (tylerpina) commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

AIS-296

Summary

  • Adds a Contentful Function (functions/bedrock-proxy.ts) that reads accessKeyId, secretAccessKey, and region server-side via context.appInstallationParameters and proxies InvokeModel requests to AWS Bedrock using AWS SigV4 signing — credentials never touch browser-side code
  • Wires up contentful-app-manifest.json with an App Action (bedrockProxyAction) so the Dialog location calls the function via sdk.cma.appActionCall.createWithResponse instead of instantiating BedrockClient/BedrockRuntimeClient in the browser
  • Deletes the browser-side src/utils/aiApi client (the actual SAST finding) and removes accessKeyId/secretAccessKey from browser-readable state; the config AccessKey component becomes write-only (admin can set new credentials but can't read stored values back); Model becomes a static list rather than live-validating against AWS with the credentials
  • Flattens the installation parameters to top-level scalars so a Secret-typed param validates (a Secret opts the whole params object into strict scalar-only validation — nested brandProfile is flattened, enabledFeatures is JSON-encoded into a Symbol string and rehydrated in the reducer/hooks)

Notes

  • This PR is the code half of the fix. The AppDefinition Secret type declaration for accessKeyId and secretAccessKey must be applied separately before deploy — without it, the credentials are still plaintext in the browser even after this code lands.
  • SigV4 signing service name is bedrock, not bedrock-runtime — the latter is only the endpoint host prefix. Signing with the wrong name yields InvalidSignatureException on every call. Covered by a regression test in functions/bedrock-proxy.spec.ts.
  • UX change: generation is no longer streamed token-by-token; the full response is revealed at once (a skeleton loader shows while generating). Streaming was architecturally incompatible with Contentful Functions' single-response model.
  • Model availability checking (which called AWS ListFoundationModels + InvokeModelCommand using the browser-side credentials) is removed. The model list is now static.
  • On merge: update the status column for row 273 in the Cypress SAST findings spreadsheet and keep the Jira ticket in sync.

Test plan

  • npx vitest run passes (56/56)
  • npm run lint passes (0 errors, 0 warnings)
  • npx tsc --noEmit clean
  • npm run build:functions emits build/functions/bedrock-proxy.js
  • Manual — AppDefinition update: Declare accessKeyId and secretAccessKey as "type": "Secret" (and remaining installation fields as Symbol) via CMA or Contentful UI for the Bedrock app definition
  • Manual: After AppDefinition update, verify sdk.parameters.installation.accessKeyId returns *** in browser console
  • Manual: Deploy function bundle (npm run deploy:test) and confirm App Action invocation succeeds end-to-end in a test space

Generated with Claude Code

@tylerpina
Tyler Pina (tylerpina) requested review from a team as code owners July 31, 2026 14:55
@wiz-inc-38d59fb8d7

wiz-inc-38d59fb8d7 Bot commented Jul 31, 2026

Copy link
Copy Markdown

Wiz Scan Summary

Scanner Findings
Vulnerability Finding Vulnerabilities -
Data Finding Sensitive Data -
Secret Finding Secrets -
IaC Misconfiguration IaC Misconfigurations -
SAST Finding SAST Findings 1 Medium
Software Management Finding Software Management Findings -
Total 1 Medium

View scan details in Wiz

To detect these findings earlier in the dev lifecycle, try the Wiz Code extension for VS Code, JetBrains, or Visual Studio.

…rs [AIS-296]

- Adds a Contentful Function (`functions/bedrock-proxy.ts`) that reads
  accessKeyId, secretAccessKey, and region server-side via
  `context.appInstallationParameters` and proxies InvokeModel requests
  to AWS Bedrock using SigV4 signing — credentials never touch browser-side code
- Wires up `contentful-app-manifest.json` with an App Action
  (`bedrockProxyAction`) so the Dialog calls the function via
  `sdk.cma.appActionCall.createWithResponse` instead of instantiating
  BedrockRuntimeClient in the browser
- Removes direct credential usage in `useAI.tsx`, `AccessKey.tsx`, and
  `Model.tsx`; config screen becomes write-only for credentials (admin
  can set new credentials but cannot read the current values back)
- Model list becomes static — availability checks (which required live
  AWS calls with the plaintext key) are removed; all featured models
  display unconditionally
- Upgrades `@contentful/app-scripts` to ^2.3.0 and adds
  `@contentful/node-apps-toolkit` for function types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tylerpina
Tyler Pina (tylerpina) force-pushed the fix/bedrock-secret-param-ais-296 branch from 33563f2 to 5ed3ec8 Compare July 31, 2026 15:00
Tyler Pina (tylerpina) and others added 14 commits August 2, 2026 12:41
…ts [AIS-296]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Retypes all five SDK mock files (and three caller specs that directly
annotate the SDK generic) from AppInstallationParameters to
PersistedInstallationParameters, removing the nested brandProfile field
and making credentials (accessKeyId/secretAccessKey) optional top-level
scalars per the flat persisted shape.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-296]

AWS Bedrock's SigV4 signing name is `bedrock`, not `bedrock-runtime`.
The old credential scope `/bedrock-runtime/aws4_request` caused every
invocation to fail with InvalidSignatureException. Fixes the credential
scope string and the getSigningKey call site. Adds a focused unit test
(bedrock-proxy.spec.ts) that would have failed on the old name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Installation parameters are now flat (PersistedInstallationParameters)
so the old destructuring of `brandProfile` yielded undefined at runtime,
silently dropping all brand-voice fields from the system prompt. Retypes
the SDK hook to PersistedInstallationParameters and passes the flat
installation object directly to baseSystemPrompt, which accepts ProfileType
(satisfied by PersistedInstallationParameters via intersection).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…296]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant