fix(bedrock): honor AWS auth params in realtime handler - #32275
Conversation
Greptile SummaryThis PR fixes the Bedrock Nova Sonic realtime handler so that AWS credentials supplied via
Confidence Score: 5/5Safe to merge — the change is confined to the realtime handler's credential-resolution step, is consistent with every other Bedrock code path in the repo, and is backed by live QA evidence plus three targeted regression tests. The replacement of No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/llms/bedrock/realtime/handler.py | Replaces hardcoded EnvironmentCredentialsResolver with the shared BaseAWSLLM.get_credentials() path, adds a None guard that raises a clear BedrockError(401) instead of an AttributeError, and wires the frozen credentials into the Smithy Config alongside StaticCredentialsResolver(). |
| tests/test_litellm/llms/bedrock/realtime/test_bedrock_realtime_handler.py | Adds a stub_aws_sdk_client fixture and three regression tests covering static credentials, role-assumption param forwarding, and unresolvable-credential error handling; all use mocked AWS SDK modules with no real network calls. |
Reviews (3): Last reviewed commit: "fix(bedrock): raise clear auth error whe..." | Re-trigger Greptile
Greptile SummaryThis PR fixes the Bedrock Nova Sonic realtime handler to honour AWS auth params (static keys, role assumption, web identity, profiles) supplied via
Confidence Score: 3/5The handler change solves the right problem but the Smithy credential resolver wiring needs verification before merging — if StaticCredentialsResolver requires a credentials argument, the fix will fail at runtime for every realtime request. The intent and the get_credentials delegation are correct, but StaticCredentialsResolver() is instantiated with no arguments while research on the smithy_aws_core SDK indicates it expects an AWSCredentialsIdentity (or equivalent) at construction time. The test suite stubs the resolver with FakeStaticCredentialsResolver that accepts no args, so the production path is not exercised and would raise TypeError on every request. The raw Config fields (aws_access_key_id etc.) may also be unrecognised by the Smithy Config constructor and silently ignored. litellm/llms/bedrock/realtime/handler.py lines 97–104 — the StaticCredentialsResolver constructor call and how credentials are passed to the Smithy Config need to be validated against the actual smithy_aws_core API (and confirmed with a live end-to-end test).
|
| Filename | Overview |
|---|---|
| litellm/llms/bedrock/realtime/handler.py | Replaces hardcoded EnvironmentCredentialsResolver with boto3-resolved credentials via get_credentials(), but uses StaticCredentialsResolver() with no constructor arguments — likely incorrect per smithy_aws_core API, which requires credentials to be passed to the resolver's constructor. |
| tests/test_litellm/llms/bedrock/realtime/test_bedrock_realtime_handler.py | New tests stub aws_sdk_bedrock_runtime and smithy_aws_core correctly; however FakeStaticCredentialsResolver takes no constructor arguments, which masks the fact that the real StaticCredentialsResolver likely requires an AWSCredentialsIdentity argument. |
Reviews (2): Last reviewed commit: "fix(bedrock): honor AWS auth params in r..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
c5454af
into
litellm_internal_staging
Relevant issues
Linear ticket
Resolves LIT-3923
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewDelays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Both runs below hit a live proxy on localhost against the real Bedrock Nova Sonic model in us-east-1, with AWS credentials supplied only through litellm_params under non-standard env var names; every standard AWS_* credential variable was scrubbed from the proxy environment before launch. Before is the merge-base commit b4a10fb, after is this branch at 489e94b. The config, launcher, and client are byte-identical across the two arms; only the checkout changes
Config (
qa_config.yaml):Proxy launcher (
run_proxy_qa.sh), which loads session credentials produced byaws configure export-credentials --format env, re-exports them under the non-standard names the config reads, and unsets every standard AWS variable before starting the proxy:Env check printed at proxy start, identical in both arms, confirming no standard AWS_* credential vars remain in the proxy environment:
The client (
qa_realtime_client.py) opensws://localhost:56759/v1/realtime?model=bedrock-sonicauthenticated with the master key, sendssession.update(text modalities), oneconversation.item.createuser message "Say hello in one sentence.", thenresponse.create, and prints every received event type with a 60 second overall timeoutBefore, at merge-base b4a10fb: the session connects and then hangs silently, zero events in 60 seconds
The before proxy log confirms the hang; this is the last Bedrock realtime line, the stream is never established and no error is surfaced:
After, on this branch at 489e94b, same config, same launcher, same client:
The after proxy log shows the stream opening with the litellm_params credentials:
Type
🐛 Bug Fix
Changes
The Bedrock Nova Sonic realtime handler (
litellm/llms/bedrock/realtime/handler.py, backing/v1/realtime) accepted every standard AWS auth param inasync_realtime(aws_access_key_id, aws_secret_access_key, aws_session_token, aws_role_name, aws_session_name, aws_profile_name, aws_web_identity_token, aws_sts_endpoint, aws_external_id) but ignored all of them: the Smithy client config was built with a hardcodedaws_credentials_identity_resolver=EnvironmentCredentialsResolver(), which only ever reads the ambient AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY environment variables. Credentials supplied via litellm_params were silently dropped and the session hung at stream open with zero events and no errorThe fix resolves credentials with the same machinery every other Bedrock path uses:
BaseAWSLLM.get_credentials(...), which handles static keys, session tokens, role assumption via STS, web identity tokens (IRSA), named profiles, and falls back to the boto3 default chain when nothing is configured. The resolved credentials are frozen and fed to the SmithyConfigasaws_access_key_id/aws_secret_access_key/aws_session_tokenalongside the SDK's ownStaticCredentialsResolver; this is the smithy_aws_core static-credentials flow, where the SigV4 auth scheme builds identity properties from those config fields and the resolver returns them as theAWSCredentialsIdentityused for signingThis makes static keys stored under non-standard env names, role assumption (
aws_role_name/aws_session_name/aws_external_id), web identity auth, profile auth, and STS endpoint overrides work for the realtime endpoint. When no aws params are given, behavior is now the boto3 default credential chain, consistent with bedrock chat/converse and strictly more capable than the previous env-only behavior. The optional-import error message for aws_sdk_bedrock_runtime is unchangedRegression tests in
tests/test_litellm/llms/bedrock/realtime/test_bedrock_realtime_handler.pystub the optionalaws_sdk_bedrock_runtime/smithy_aws_coremodules in sys.modules and assert that static credentials passed toasync_realtimereach the captured Smithy config through the realget_credentialspath, and that role-assumption params are forwarded toget_credentialswith the resolved credentials landing on the config; both tests fail on the base branch and pass with the fixFollow-up commit c89bffc: when
get_credentialsresolves nothing anywhere (returns None), the handler now raises a BedrockError with a clear message ("No AWS credentials found for Bedrock realtime") instead of an obscure AttributeError onget_frozen_credentials; covered by a regression test that fails on the previous commit