Match the Bedrock e2e inference profile to the configured region

The matrix hardcoded the us. cross-region inference profile while the
upstream host follows AWS_REGION, so any non-US region made Bedrock
reject every request with 'The provided model identifier is invalid' —
including the allowlisted call in TestModelAllowlistEnforced, which
asserts a 200. Derive the profile prefix (us/eu/apac/us-gov) from the
region, default the region to eu-central-1 to match the CI credentials,
and strip whichever prefix was chosen when building the guardrail
allowlist.
This commit is contained in:
Claude
2026-07-21 11:26:37 +00:00
parent a79363d801
commit 7d9f7d0d69
2 changed files with 33 additions and 5 deletions

View File

@@ -95,17 +95,36 @@ func availableProviders() []providerCase {
}
// Bedrock: path-routed, bearer auth. Model is a cross-region inference
// profile id (distinct string from the first-party Anthropic case).
// profile id (distinct string from the first-party Anthropic case). The
// profile's region prefix must match the endpoint's region family — an
// eu.* profile against a us-east endpoint (or vice versa) makes Bedrock
// reject the request with "The provided model identifier is invalid".
// Defaults pair eu-central-1 with the eu.* profile; AWS_REGION overrides
// the region and the prefix follows its family.
if k := os.Getenv("AWS_BEARER_TOKEN_BEDROCK"); k != "" {
region := os.Getenv("AWS_REGION")
if region == "" {
region = "us-east-1"
region = "eu-central-1"
}
ps = append(ps, providerCase{name: "bedrock", catalogID: "bedrock_api", upstream: "https://bedrock-runtime." + region + ".amazonaws.com", apiKey: k, model: "us.anthropic.claude-haiku-4-5", kind: harness.WireBedrock})
ps = append(ps, providerCase{name: "bedrock", catalogID: "bedrock_api", upstream: "https://bedrock-runtime." + region + ".amazonaws.com", apiKey: k, model: bedrockProfilePrefix(region) + ".anthropic.claude-haiku-4-5", kind: harness.WireBedrock})
}
return ps
}
// bedrockProfilePrefix maps an AWS region to its cross-region inference
// profile prefix: us-east-1 -> us, eu-central-1 -> eu, ap-southeast-1 -> apac,
// us-gov-west-1 -> us-gov.
func bedrockProfilePrefix(region string) string {
switch {
case strings.HasPrefix(region, "us-gov-"):
return "us-gov"
case strings.HasPrefix(region, "ap-"):
return "apac"
default:
return strings.SplitN(region, "-", 2)[0]
}
}
// providerRequest builds a create request for a matrix provider: enabled, with
// a uniquely-priced model for body-routed providers and none for the
// path-routed Vertex (whose model lives in the request path).

View File

@@ -21,7 +21,14 @@ import (
func catalogModel(pc providerCase) string {
switch pc.kind {
case harness.WireBedrock:
return strings.TrimPrefix(pc.model, "us.")
// Strip whichever cross-region inference-profile prefix the matrix
// picked for the configured AWS region (us., eu., apac., us-gov.).
for _, p := range []string{"us-gov.", "apac.", "us.", "eu."} {
if strings.HasPrefix(pc.model, p) {
return strings.TrimPrefix(pc.model, p)
}
}
return pc.model
case harness.WireVertex:
return strings.SplitN(pc.model, "@", 2)[0]
default:
@@ -35,7 +42,9 @@ func catalogModel(pc providerCase) string {
func disallowedModel(pc providerCase) string {
switch pc.kind {
case harness.WireBedrock:
return "us.anthropic.claude-opus-4-8"
// Same profile prefix as the allowed model so only the model name
// differs; the guardrail must deny it before it reaches AWS.
return strings.SplitN(pc.model, ".", 2)[0] + ".anthropic.claude-opus-4-8"
case harness.WireVertex:
return "claude-opus-4-8@20250101"
default: