Skip to content

Commit 06ed398

Browse files
committed
fix(bedrock): decide the AWS auth mode with one rule for fields and signing
A block signs with a saved AWS credential only when bedrockAuthMode is 'credential', the same rule that shows and serializes the picker. The agent test no longer leaks a persistent mock rejection.
1 parent dfa8567 commit 06ed398

6 files changed

Lines changed: 56 additions & 27 deletions

File tree

‎apps/sim/blocks/blocks/agent.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,8 @@ Return ONLY the JSON array.`,
565565
},
566566
bedrockCredential: {
567567
type: 'string',
568-
description: 'Saved AWS credential ID for Bedrock, used instead of access keys',
568+
description:
569+
"Saved AWS credential ID for Bedrock, used instead of access keys when bedrockAuthMode is 'credential'",
569570
},
570571
responseFormat: {
571572
type: 'json',

‎apps/sim/blocks/utils.test.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,24 @@ describe('getSelectedBedrockCredential', () => {
163163
).toBeUndefined()
164164
expect(getSelectedBedrockCredential({})).toBeUndefined()
165165
})
166+
167+
it('signs with a credential exactly when the block shows and serializes the credential picker', () => {
168+
const picker = getProviderCredentialSubBlocks().find(
169+
(subBlock) => subBlock.id === 'bedrockCredential'
170+
)
171+
const cases: Record<string, unknown>[] = [
172+
{ bedrockCredential: 'cred-1' },
173+
{ bedrockAuthMode: '', bedrockCredential: 'cred-1' },
174+
{ bedrockAuthMode: 'access_keys', bedrockCredential: 'cred-1' },
175+
{ bedrockAuthMode: 'credential', bedrockCredential: 'cred-1' },
176+
]
177+
for (const values of cases) {
178+
const withModel = { model: 'bedrock/my-inference-profile', ...values }
179+
expect(getSelectedBedrockCredential(values) !== undefined, JSON.stringify(values)).toBe(
180+
evaluateSubBlockCondition(picker?.condition, withModel)
181+
)
182+
}
183+
})
166184
})
167185

168186
describe('getApiKeyCondition / shouldRequireApiKeyForModel', () => {

‎apps/sim/blocks/utils.ts‎

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -513,47 +513,49 @@ function getModelProviderCondition(...providerIds: ProviderId[]) {
513513
}
514514

515515
/**
516-
* Bedrock fields shown for one AWS authentication mode. A block saved before
517-
* the mode existed has no `bedrockAuthMode` and keeps its access keys. Like
518-
* {@link getModelProviderCondition}, the answer is folded into a single `model`
519-
* clause, so blocks that wrap these fields in their own condition still can.
516+
* Whether a block's Bedrock call signs with a saved AWS credential. The one rule
517+
* behind both the fields a block shows and serializes and the credential its
518+
* call uses: only an explicit `bedrockAuthMode: 'credential'` selects one, so a
519+
* block saved before the mode existed (no `bedrockAuthMode`) keeps its access keys.
520+
*/
521+
function usesSavedBedrockCredential(values: { bedrockAuthMode?: unknown } | undefined): boolean {
522+
return values?.bedrockAuthMode === 'credential'
523+
}
524+
525+
/**
526+
* Bedrock fields shown for one AWS authentication mode, decided by
527+
* {@link usesSavedBedrockCredential}. Like {@link getModelProviderCondition}, the
528+
* answer is folded into a single `model` clause.
520529
*/
521530
function getBedrockAuthModeCondition(mode: 'access_keys' | 'credential') {
522531
return (values?: Record<string, unknown>) => {
523532
const model = typeof values?.model === 'string' ? values.model : ''
524-
const usesCredential = values?.bedrockAuthMode === 'credential'
525533
return buildModelVisibilityCondition(
526534
model,
527535
findProviderFromModel(model.trim()) === 'bedrock' &&
528-
usesCredential === (mode === 'credential')
536+
usesSavedBedrockCredential(values) === (mode === 'credential')
529537
)
530538
}
531539
}
532540

533541
/**
534542
* The saved AWS credential ID a block's Bedrock call signs with, or undefined
535-
* when the block uses access keys. A block saved before the auth mode existed
536-
* has no `bedrockAuthMode` and uses a credential only when one is set. A block
537-
* set to a saved credential whose ID resolves blank (an empty reference) is
538-
* refused, so its call never falls back to inline keys or the deployment's own
539-
* AWS credentials.
543+
* when the block uses access keys (see {@link usesSavedBedrockCredential}). A
544+
* block set to a saved credential whose ID resolves blank (an empty reference)
545+
* is refused, so its call never falls back to inline keys or the deployment's
546+
* own AWS credentials.
540547
*/
541-
export function getSelectedBedrockCredential({
542-
bedrockAuthMode,
543-
bedrockCredential,
544-
}: {
548+
export function getSelectedBedrockCredential(values: {
545549
bedrockAuthMode?: unknown
546550
bedrockCredential?: unknown
547551
}): string | undefined {
548-
if (bedrockAuthMode === 'access_keys') return undefined
549-
const credentialId = typeof bedrockCredential === 'string' ? bedrockCredential.trim() : ''
552+
if (!usesSavedBedrockCredential(values)) return undefined
553+
const credentialId =
554+
typeof values.bedrockCredential === 'string' ? values.bedrockCredential.trim() : ''
550555
if (credentialId) return credentialId
551-
if (bedrockAuthMode === 'credential') {
552-
throw new Error(
553-
'Select an AWS credential for Bedrock, or switch AWS Authentication to access keys'
554-
)
555-
}
556-
return undefined
556+
throw new Error(
557+
'Select an AWS credential for Bedrock, or switch AWS Authentication to access keys'
558+
)
557559
}
558560

559561
/**
@@ -727,7 +729,8 @@ export const PROVIDER_CREDENTIAL_INPUTS = {
727729
},
728730
bedrockCredential: {
729731
type: 'string',
730-
description: 'Saved AWS credential ID for Bedrock, used instead of access keys',
732+
description:
733+
"Saved AWS credential ID for Bedrock, used instead of access keys when bedrockAuthMode is 'credential'",
731734
},
732735
} as const
733736

‎apps/sim/executor/handlers/agent/handler.test.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,7 @@ describe('AgentBlockHandler', () => {
11561156
await handler.execute(mockContext, mockBlock, {
11571157
...baseInputs,
11581158
model: 'bedrock/claude',
1159+
bedrockAuthMode: 'credential',
11591160
bedrockCredential: 'aws-cred',
11601161
bedrockRegion: 'us-west-2',
11611162
})
@@ -1175,19 +1176,19 @@ describe('AgentBlockHandler', () => {
11751176
})
11761177

11771178
it('fails a Bedrock call whose AWS credential cannot be used instead of sending it', async () => {
1178-
mockResolveBedrockCredentialSession.mockRejectedValue(
1179+
mockResolveBedrockCredentialSession.mockRejectedValueOnce(
11791180
new Error('Not authorized to use this AWS credential')
11801181
)
11811182

11821183
await expect(
11831184
handler.execute(mockContext, mockBlock, {
11841185
...baseInputs,
11851186
model: 'bedrock/claude',
1187+
bedrockAuthMode: 'credential',
11861188
bedrockCredential: 'aws-cred',
11871189
})
11881190
).rejects.toThrow('Not authorized to use this AWS credential')
11891191
expect(mockExecuteProviderRequest).not.toHaveBeenCalled()
1190-
mockResolveBedrockCredentialSession.mockReset()
11911192
})
11921193

11931194
it('fails a Bedrock call set to a saved AWS credential when the credential resolves blank', async () => {
@@ -1215,6 +1216,7 @@ describe('AgentBlockHandler', () => {
12151216
await handler.execute(mockContext, mockBlock, {
12161217
...baseInputs,
12171218
model: 'bedrock/claude',
1219+
bedrockAuthMode: 'credential',
12181220
bedrockCredential: 'aws-cred',
12191221
fallbackModels: [{ model: 'gpt-4o-mini' }],
12201222
})

‎apps/sim/executor/handlers/evaluator/handler.test.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ describe('EvaluatorBlockHandler', () => {
197197
await handler.execute(mockContext, mockBlock, {
198198
...admissionInputs,
199199
model: 'bedrock/claude',
200+
bedrockAuthMode: 'credential',
200201
bedrockCredential: 'aws-cred',
201202
})
202203

@@ -240,6 +241,7 @@ describe('EvaluatorBlockHandler', () => {
240241
await handler.execute(mockContext, mockBlock, {
241242
...admissionInputs,
242243
model: 'bedrock/claude',
244+
bedrockAuthMode: 'credential',
243245
bedrockCredential: 'aws-cred',
244246
fallbackModels: [{ model: 'claude-sonnet-5' }],
245247
})
@@ -261,6 +263,7 @@ describe('EvaluatorBlockHandler', () => {
261263
handler.execute(mockContext, mockBlock, {
262264
...admissionInputs,
263265
model: 'bedrock/claude',
266+
bedrockAuthMode: 'credential',
264267
bedrockCredential: 'aws-cred',
265268
})
266269
).rejects.toThrow('Not authorized to use this AWS credential')

‎apps/sim/executor/handlers/router/handler.test.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ describe('RouterBlockHandler', () => {
199199
await handler.execute(mockContext, mockBlock, {
200200
prompt: 'Pick a destination',
201201
model: 'bedrock/claude',
202+
bedrockAuthMode: 'credential',
202203
bedrockCredential: 'aws-cred',
203204
})
204205

@@ -578,6 +579,7 @@ describe('RouterBlockHandler V2', () => {
578579
context: 'Help me',
579580
model: 'bedrock/claude',
580581
routes: [{ id: 'route-support', title: 'Support', value: 'Needs help' }],
582+
bedrockAuthMode: 'credential',
581583
bedrockCredential: 'aws-cred',
582584
})
583585

0 commit comments

Comments
 (0)