When I call sts:AssumeRole
from account A eu-west-1
on role in account B and with those returned credentials I call list objects from s3 bucket located in eu-south-1
it fails with following error.
botocore.exceptions.ClientError: An error occurred (InvalidToken) when calling the ListObjectsV2 operation: The provided token is malformed or otherwise invalid.
import boto3
role_arn = "..."
bucket_name = "..."
sts_client = boto3.client(
"sts",
region_name="eu-west-1",
)
sts_response = sts_client.assume_role(
RoleArn=role_arn,
RoleSessionName="test-session-name",
)
credentials = sts_response["Credentials"]
session = boto3.session.Session(
aws_access_key_id=credentials["AccessKeyId"],
aws_secret_access_key=credentials["SecretAccessKey"],
aws_session_token=credentials["SessionToken"],
)
s3_client = session.client(
"s3",
region_name="eu-south-1",
)
res = s3_client.list_objects_v2(Bucket=bucket_name)
# botocore.exceptions.ClientError
Two issues here
Even though I used region_name
it still calls global sts endpoint https://sts.amazonaws.com
which may be quite unexpected. It can be overriden by endpoint_url
sts_client = boto3.client(
"sts",
endpoint_url="https://sts.eu-west-1.amazonaws.com",
)
or set environment variable AWS_STS_REGIONAL_ENDPOINTS=regional
see docs
export AWS_STS_REGIONAL_ENDPOINTS=regional
eu-south-1
is one of so called opt-in region. It means you have to manually activate this region in your account to use it. And that is the root cause of credentials being invalid for some services/api calls.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html
Session tokens from Regional AWS STS endpoints are valid in all AWS Regions. Session tokens from the global STS endpoint are valid only in AWS Regions that are enabled by default