Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cdk/src/constructs/bedrock-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ export const DEFAULT_BEDROCK_MODEL_IDS: readonly string[] = [
// this entry and that default in the same change — a fallback the role cannot
// invoke fails every task on the stack, not just an edge case.
'anthropic.claude-opus-4-8',
// Claude Opus 5 — granted ahead of anything selecting it (#744). The grant
// must be DEPLOYED before the platform default flips, or every task fails at
// turn 0 with AccessDenied. Bare ID by contract: Bedrock refuses the bare ID
// for on-demand invocation ("ValidationException: … isn't supported. Retry
// your request with the ID or ARN of an inference profile"), and both grant
// sites derive the `us.`-prefixed inference-profile ARN — the invocable one —
// from this entry. Opus 4.8 above stays granted: blueprints may pin it
// per-repo, so removing it would fail those repos at turn 0.
'anthropic.claude-opus-5',
'anthropic.claude-haiku-4-5-20251001-v1:0',
];

Expand Down
8 changes: 8 additions & 0 deletions cdk/src/handlers/shared/workflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ export const WORKFLOW_MODEL_ALLOWLIST: readonly string[] = [
// `bedrockModels` context) in the same change.
'anthropic.claude-opus-4-8',
'us.anthropic.claude-opus-4-8',
// Claude Opus 5 (#744) — kept in step with the IAM grant added to
// DEFAULT_BEDROCK_MODEL_IDS in the same change, per the note above. Only the
// bare and `us.`-prefixed forms: `global.anthropic.claude-opus-5` is a live
// profile but is deliberately withheld until the grant sites derive the
// `global.` ARN (#747) — admitting it here first would pass admission and then
// fail at turn 0 with AccessDenied, exactly the drift this comment warns about.
'anthropic.claude-opus-5',
'us.anthropic.claude-opus-5',
'anthropic.claude-haiku-4-5-20251001-v1:0',
'us.anthropic.claude-haiku-4-5-20251001-v1:0',
];
Expand Down
8 changes: 8 additions & 0 deletions cdk/test/constructs/ecs-agent-cluster.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,14 @@ describe('EcsAgentCluster construct', () => {
expect(serialized).toContain('inference-profile/us.anthropic.claude-sonnet-4-6');
expect(serialized).toContain('anthropic.claude-opus-4-20250514-v1:0');
expect(serialized).toContain('anthropic.claude-haiku-4-5-20251001-v1:0');
// Claude Opus 5 (#744) — AgentCore/ECS parity. Both ARNs: the bare id isn't
// on-demand invocable, so the `us.` profile is the one actually called.
expect(serialized).toContain('foundation-model/anthropic.claude-opus-5');
expect(serialized).toContain('inference-profile/us.anthropic.claude-opus-5');
// REGRESSION (#744): Opus 4.8 stays granted alongside Opus 5 — blueprints may
// pin it per-repo, so dropping it would fail those repos at turn 0.
expect(serialized).toContain('foundation-model/anthropic.claude-opus-4-8');
expect(serialized).toContain('inference-profile/us.anthropic.claude-opus-4-8');
});

test('task role can DescribeAvailabilityZones so a CDK target repo can `cdk synth` on a fresh clone (ECS-parity)', () => {
Expand Down
15 changes: 13 additions & 2 deletions cdk/test/stacks/agent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,24 @@ describe('AgentStack', () => {

test('runtime is granted the default Bedrock model set', () => {
// Default (no bedrockModels context): the runtime execution role must hold
// bedrock:InvokeModel on the three default foundation models + their US
// inference profiles, scoped (never Resource: '*').
// bedrock:InvokeModel on every default foundation model + its US
// inference profile, scoped (never Resource: '*').
const serialized = JSON.stringify(template.findResources('AWS::IAM::Policy'));
expect(serialized).toContain('foundation-model/anthropic.claude-sonnet-4-6');
expect(serialized).toContain('inference-profile/us.anthropic.claude-sonnet-4-6');
expect(serialized).toContain('anthropic.claude-opus-4-20250514-v1:0');
expect(serialized).toContain('anthropic.claude-haiku-4-5-20251001-v1:0');
// Claude Opus 5 (#744). Granted ahead of any default flip: the bare id is
// not on-demand invocable (Bedrock returns ValidationException), so the
// `us.`-prefixed inference profile is the one actually called — both ARNs
// must be present or the agent gets AccessDenied at turn 0.
expect(serialized).toContain('foundation-model/anthropic.claude-opus-5');
expect(serialized).toContain('inference-profile/us.anthropic.claude-opus-5');
// REGRESSION (#744): Opus 4.8 stays granted alongside Opus 5. Blueprints may
// pin 4.8 per-repo; dropping it would fail those repos at turn 0. Retiring
// 4.8 is a separate, announced change — not a side effect of adding 5.
expect(serialized).toContain('foundation-model/anthropic.claude-opus-4-8');
expect(serialized).toContain('inference-profile/us.anthropic.claude-opus-4-8');
});

test('bedrockModels context override propagates to the runtime execution role', () => {
Expand Down
Loading