from __future__ import annotations
from typing import Any, Dict, Optional
import boto3
def build_boto3_session(auth: Optional[Dict[str, Any]]) -> boto3.Session:
"""Create a boto3 Session.
auth:
- None or {"mode":"default"}: use ambient AWS creds (env/instance profile/etc)
- {"mode":"assume_role","role_arn":..., "external_id":..., "session_name"?, "region_name"?}
"""
if auth is None or auth.get("mode", "default") == "default":
return boto3.Session(region_name=(auth or {}).get("region_name"))
mode: str = str(auth.get("mode"))
if mode != "assume_role":
raise ValueError(f"Unsupported auth mode: {mode}")
role_arn: Optional[str] = auth.get("role_arn")
external_id: Optional[str] = auth.get("external_id")
session_name: str = auth.get("session_name", "aws-mcp-audit")
if role_arn is None or external_id is None:
raise ValueError("assume_role requires role_arn and external_id")
base: boto3.Session = boto3.Session(region_name=auth.get("region_name"))
sts = base.client("sts", region_name=base.region_name or "us-east-1")
resp = sts.assume_role(
RoleArn=role_arn,
RoleSessionName=session_name,
ExternalId=external_id,
)
creds = resp["Credentials"]
return boto3.Session(
aws_access_key_id=creds["AccessKeyId"],
aws_secret_access_key=creds["SecretAccessKey"],
aws_session_token=creds["SessionToken"],
region_name=auth.get("region_name"),
)