Summary
BedrockOpenAI signs the hop-by-hop Connection request header. In our environment, that header changes between the SDK and Bedrock Mantle, so Bedrock calculates a different SigV4 canonical request and rejects valid AWS SSO credentials with HTTP 401.
This reproduces with openai==2.52.0 using BedrockOpenAI directly, without any downstream wrapper.
Minimal reproduction
from openai import BedrockOpenAI
client = BedrockOpenAI(
aws_region="us-east-1",
base_url="https://bedrock-mantle.us-east-1.api.aws/openai/v1",
)
client.responses.create(
model="openai.gpt-5.6-sol",
input="What is 1 + 1? Reply with only the number.",
)
The AWS credentials are valid:
aws sts get-caller-identity
The request fails with AuthenticationError, HTTP 401, and Bedrock reports that its calculated request signature does not match the submitted signature.
Diagnosis
Immediately before transport, the SDK signs:
Bedrock's canonical-request diagnostic shows it received:
Connection is a hop-by-hop header, so intermediaries may alter or remove it. Signing it makes the SigV4 signature depend on a value that is not stable end-to-end.
A temporary client-level workaround confirms this diagnosis:
import httpx
from openai import BedrockOpenAI
client = BedrockOpenAI(
aws_region="us-east-1",
base_url="https://bedrock-mantle.us-east-1.api.aws/openai/v1",
http_client=httpx.Client(headers={"Connection": ""}),
)
response = client.responses.create(
model="openai.gpt-5.6-sol",
input="What is 1 + 1? Reply with only the number.",
)
assert response.output_text == "2"
Independent patch validation
I cloned the current main branch, reproduced the direct SDK failure, and added a regression test that signs a request containing Connection: keep-alive. On the current implementation, connection appears in both the signed headers and the SigV4 SignedHeaders list.
I then made the minimal local patch in src/openai/lib/_bedrock_auth.py: exclude connection before constructing the AWSRequest passed to SigV4Auth.
With only that change:
- The new regression test passes.
pytest tests/lib/test_bedrock_auth_conformance.py -q -n 0 passes: 21 passed.
- Ruff check and format check pass.
- The same direct live
BedrockOpenAI request above succeeds without a custom http_client and returns 2.
Suggested fix
Exclude connection from the header mapping passed to the Bedrock SigV4 signer. This is the smallest change that fixes the live reproduction and avoids signing a hop-by-hop header that can be rewritten in transit.
I intentionally omitted the raw AWS error body because it can echo temporary session-token values.
Summary
BedrockOpenAIsigns the hop-by-hopConnectionrequest header. In our environment, that header changes between the SDK and Bedrock Mantle, so Bedrock calculates a different SigV4 canonical request and rejects valid AWS SSO credentials with HTTP 401.This reproduces with
openai==2.52.0usingBedrockOpenAIdirectly, without any downstream wrapper.Minimal reproduction
The AWS credentials are valid:
The request fails with
AuthenticationError, HTTP 401, and Bedrock reports that its calculated request signature does not match the submitted signature.Diagnosis
Immediately before transport, the SDK signs:
Bedrock's canonical-request diagnostic shows it received:
Connectionis a hop-by-hop header, so intermediaries may alter or remove it. Signing it makes the SigV4 signature depend on a value that is not stable end-to-end.A temporary client-level workaround confirms this diagnosis:
Independent patch validation
I cloned the current
mainbranch, reproduced the direct SDK failure, and added a regression test that signs a request containingConnection: keep-alive. On the current implementation,connectionappears in both the signed headers and the SigV4SignedHeaderslist.I then made the minimal local patch in
src/openai/lib/_bedrock_auth.py: excludeconnectionbefore constructing theAWSRequestpassed toSigV4Auth.With only that change:
pytest tests/lib/test_bedrock_auth_conformance.py -q -n 0passes:21 passed.BedrockOpenAIrequest above succeeds without a customhttp_clientand returns2.Suggested fix
Exclude
connectionfrom the header mapping passed to the Bedrock SigV4 signer. This is the smallest change that fixes the live reproduction and avoids signing a hop-by-hop header that can be rewritten in transit.I intentionally omitted the raw AWS error body because it can echo temporary session-token values.