From ffb6029c2de5fbe133f90423c9e6e383d878a2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Wed, 8 Apr 2026 22:54:35 +0200 Subject: [PATCH] fix(ai-models): use AWS provider chain for Bedrock IRSA auth (#19470) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - `buildBedrockProvider` ignored `authType: "role"` and only honored static `accessKeyId`/`secretAccessKey` pairs, so deployments relying on IRSA (e.g. EKS pods with `AWS_WEB_IDENTITY_TOKEN_FILE` + `AWS_ROLE_ARN`) had no way to authenticate — `@ai-sdk/amazon-bedrock` does not walk the AWS default credential chain on its own. - When `authType === 'role'`, wire `fromNodeProviderChain()` from `@aws-sdk/credential-providers` (already a server dependency, used by the S3 and logic-function drivers) into `createAmazonBedrock` so IRSA and other ambient AWS credentials resolve correctly. - The static-credentials path is unchanged for `authType !== 'role'`. ## Test plan - [ ] Deploy a server pod with IRSA + an `ai-models-config` entry using `"authType": "role"` and verify Bedrock calls succeed (no `Could not load credentials from any providers` error). - [ ] Verify static-credentials providers (`accessKeyId` + `secretAccessKey`) still work as before. - [ ] `npx nx lint:diff-with-main twenty-server` passes. - [ ] `npx nx typecheck twenty-server` passes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 --- .../services/sdk-provider-factory.service.ts | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-models/services/sdk-provider-factory.service.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-models/services/sdk-provider-factory.service.ts index d3c1cda9b9..d3c6c6c24e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-models/services/sdk-provider-factory.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-models/services/sdk-provider-factory.service.ts @@ -10,6 +10,7 @@ import { createMistral } from '@ai-sdk/mistral'; import { createOpenAI, type OpenAIProvider } from '@ai-sdk/openai'; import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { createXai } from '@ai-sdk/xai'; +import { fromNodeProviderChain } from '@aws-sdk/credential-providers'; import { type LanguageModel } from 'ai'; import { type AiSdkPackage } from 'twenty-shared/ai'; @@ -131,9 +132,27 @@ export class SdkProviderFactoryService { private buildBedrockProvider( config: AiProviderConfig, ): AiSdkProviderInstance { + const region = config.region ?? 'us-east-1'; + const useRoleCredentials = config.authType === 'role'; + const awsCredentialProvider = useRoleCredentials + ? fromNodeProviderChain({ clientConfig: { region } }) + : undefined; + const provider = createAmazonBedrock({ - region: config.region ?? 'us-east-1', - ...(config.accessKeyId && + region, + ...(awsCredentialProvider && { + credentialProvider: async () => { + const credentials = await awsCredentialProvider(); + + return { + accessKeyId: credentials.accessKeyId, + secretAccessKey: credentials.secretAccessKey, + sessionToken: credentials.sessionToken, + }; + }, + }), + ...(!useRoleCredentials && + config.accessKeyId && config.secretAccessKey && { accessKeyId: config.accessKeyId, secretAccessKey: config.secretAccessKey,