Skip to content

Commit b625d02

Browse files
committed
refactor(api): Update Bedrock client initialization to use boto3 for credential resolution
- Replace custom credential chain with boto3 session for more reliable AWS credentials retrieval in both local and ECS environments. - Enhance logging to provide visibility into available credential sources during client initialization. - Ensure proper error handling for missing AWS credentials.
1 parent a001835 commit b625d02

1 file changed

Lines changed: 36 additions & 27 deletions

File tree

backend/routers/voice_simple.py

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -204,36 +204,45 @@ def __init__(self, voice_prompt: str, agent_id: str, user_id: str, session_id: s
204204
def _initialize_client(self):
205205
"""Initialize the Bedrock client with proper credential resolution.
206206
207-
Uses a custom credential chain optimized for ECS/local environments:
208-
- Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) for local dev
209-
- ECS Task Role credentials via container metadata endpoint for production
207+
Uses boto3 session to get credentials which works reliably in both:
208+
- Local dev (environment variables or AWS CLI config)
209+
- ECS (task role via container metadata)
210210
"""
211-
from smithy_aws_core.identity.chain import ChainedIdentityResolver
212-
from smithy_aws_core.identity.environment import EnvironmentCredentialsResolver
213-
from smithy_aws_core.identity.container import ContainerCredentialsResolver
214-
from smithy_http.aio.aiohttp import AIOHTTPClient
211+
import os
212+
from smithy_aws_core.identity.static import StaticCredentialsResolver
215213

216-
# Create HTTP client for credential resolution (needed by ContainerCredentialsResolver)
217-
http_client = AIOHTTPClient()
214+
# Debug: Check what credential sources are available
215+
logger.info(f"[NovaSonic] Checking credential sources:")
216+
logger.info(f" - AWS_ACCESS_KEY_ID present: {bool(os.getenv('AWS_ACCESS_KEY_ID'))}")
217+
logger.info(f" - AWS_CONTAINER_CREDENTIALS_RELATIVE_URI present: {bool(os.getenv('AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'))}")
218+
logger.info(f" - Region: {settings.AWS_REGION}")
218219

219-
# Create custom credential chain that tries in order:
220-
# 1. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) - for local dev
221-
# 2. ECS container credentials (via AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) - for ECS
222-
# Note: We explicitly skip IMDS (EC2 metadata) to avoid connection errors in ECS Fargate
223-
credentials_resolver = ChainedIdentityResolver(
224-
resolvers=[
225-
EnvironmentCredentialsResolver(),
226-
ContainerCredentialsResolver(http_client=http_client),
227-
]
228-
)
229-
230-
config = Config(
231-
region=settings.AWS_REGION,
232-
aws_credentials_identity_resolver=credentials_resolver,
233-
endpoint_uri=f"https://bedrock-runtime.{settings.AWS_REGION}.amazonaws.com",
234-
)
235-
self.client = BedrockRuntimeClient(config=config)
236-
logger.info("[NovaSonic] Bedrock client initialized with ECS-optimized credential chain")
220+
# Use boto3 to get credentials (handles ECS, environment, etc. automatically)
221+
try:
222+
session = boto3.Session()
223+
credentials = session.get_credentials()
224+
225+
if not credentials:
226+
raise Exception("No AWS credentials found. Check ECS task role or environment variables.")
227+
228+
frozen_creds = credentials.get_frozen_credentials()
229+
logger.info(f"[NovaSonic] Retrieved credentials via boto3 (access_key: {frozen_creds.access_key[:10]}...)")
230+
231+
# Create config with credentials AND resolver
232+
config = Config(
233+
region=settings.AWS_REGION,
234+
aws_access_key_id=frozen_creds.access_key,
235+
aws_secret_access_key=frozen_creds.secret_key,
236+
aws_session_token=frozen_creds.token, # Will be None for env vars, set for IAM role
237+
aws_credentials_identity_resolver=StaticCredentialsResolver(), # Required for SigV4
238+
endpoint_uri=f"https://bedrock-runtime.{settings.AWS_REGION}.amazonaws.com",
239+
)
240+
self.client = BedrockRuntimeClient(config=config)
241+
logger.info("[NovaSonic] Bedrock client initialized successfully with boto3 credentials")
242+
243+
except Exception as e:
244+
logger.error(f"[NovaSonic] Failed to initialize client: {e}")
245+
raise
237246

238247
async def send_event(self, event_json: str):
239248
"""Send an event to the stream."""

0 commit comments

Comments
 (0)