test(e2e): cover Bedrock reached with the gateway's own AWS identity

Every Bedrock test in the suite names os.environ/AWS_ACCESS_KEY_ID and
os.environ/AWS_SECRET_ACCESS_KEY in its litellm_params, so all of them keep
passing when the gateway's own AWS identity is revoked, repointed at the wrong
role, or stripped of its Bedrock grant. That identity is how the gateway is
actually deployed on AWS, and nothing covered it.

Adds one deployment carrying only a region, so boto3 has to fall through to
its ambient chain, plus the registry row it claims.
This commit is contained in:
Yuneng Jiang 2026-08-13 12:07:35 -07:00
parent add095b494
commit 107f8d1cd1
No known key found for this signature in database
2 changed files with 78 additions and 0 deletions

View file

@ -43,3 +43,4 @@
- {id: other.a2a.message_send.bridge_invokes, module: other, tier: P1, area: a2a, assertions: [bridge_invokes], source: "a2a_protocol/litellm_completion_bridge/handler.py", rationale: "A2A message/send routes through the completion bridge to a real provider and logs an asend_message spend row"}
- {id: other.a2a.version.serves_pinned_0_3, module: other, tier: P1, area: a2a, assertions: [serves_pinned_0_3], source: "agent_endpoints/a2a_endpoints.py _served_version", rationale: "An agent pinning 0.3 returns the flat 0.3 message shape (parts on the result)"}
- {id: other.a2a.version.serves_pinned_1_0, module: other, tier: P1, area: a2a, assertions: [serves_pinned_1_0], source: "agent_endpoints/a2a_endpoints.py _served_version", rationale: "An agent pinning 1.0 returns the nested 1.0 message shape (result.message with ROLE_AGENT)"}
- {id: other.auth.aws_ambient_credentials.resolves_without_static_keys, module: other, tier: P0, area: auth, assertions: [resolves_without_static_keys], source: "llms/bedrock/base_aws_llm.py boto3.Session() fallback", rationale: "A Bedrock deployment carrying only a region must resolve credentials from the gateway's own AWS identity (EKS Pod Identity, IRSA, instance profile), which is how it is deployed on AWS; every other Bedrock test names static keys in litellm_params and so stays green when that identity is revoked or misassociated"}

View file

@ -0,0 +1,77 @@
"""Live e2e: Bedrock reached with the credentials the gateway's environment gives it.
A deployment whose litellm_params name no `aws_access_key_id` and no
`aws_secret_access_key` must still reach Bedrock, by resolving credentials
through boto3's ambient chain (`base_aws_llm.py` falls through to
`boto3.Session()`). That is how the gateway is deployed on AWS: an EKS Pod
Identity association, an IRSA role, or an EC2 instance profile supplies the
identity, and the config carries a region and nothing secret.
Nothing else in the suite covers that. Every other Bedrock test names
`os.environ/AWS_ACCESS_KEY_ID` and `os.environ/AWS_SECRET_ACCESS_KEY` in its
litellm_params, so all of them keep passing if the pod's own identity is
revoked, misassociated, or stripped of its Bedrock grant. This test is the one
that goes red, and it is deliberately the cheapest possible shape of that
signal: one short completion, no tools, no streaming.
"""
from __future__ import annotations
import pytest
from e2e_config import unique_marker
from e2e_http import Success
from lifecycle import ResourceManager
from models import ChatBody, ChatMessage, LiteLLMParamsBody
from proxy_client import ProxyClient
pytestmark = pytest.mark.e2e
BEDROCK_MODEL = "bedrock/converse/us.anthropic.claude-haiku-4-5-20251001-v1:0"
class TestAmbientAwsCredentials:
@pytest.mark.covers(
"other.auth.aws_ambient_credentials.resolves_without_static_keys",
exercised_on=["chat_completions"],
)
def test_bedrock_deployment_without_static_keys_completes(
self, proxy: ProxyClient, resources: ResourceManager
) -> None:
"""A key-less Bedrock deployment answers a real completion.
`aws_region_name` is the only AWS field set. Adding either static
credential here would defeat the test: boto3 prefers what it is handed,
so the call would pass without the ambient identity ever being consulted.
"""
model = f"e2e-bedrock-ambient-{unique_marker()}"
model_id = proxy.create_model(
model,
LiteLLMParamsBody(model=BEDROCK_MODEL, aws_region_name="os.environ/AWS_REGION"),
)
resources.defer(lambda: proxy.delete_model(model_id))
result = proxy.chat(
resources.key(),
ChatBody(
model=model,
messages=[
ChatMessage(role="user", content=f"Reply with one word. {unique_marker()}")
],
max_tokens=16,
),
)
match result:
case Success(data=response):
assert response.choices, (
f"Bedrock answered without a completion, so the request reached AWS but "
f"came back empty: {response}"
)
case failure:
pytest.fail(
"Bedrock was unreachable using only the gateway's ambient AWS identity. "
"A credentials error here means the pod lost that identity (association "
"removed or repointed, or its role lost Bedrock); any other error means "
f"the deployment itself is wrong. Got: {failure}"
)