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 GetBucketLocation operation: The provided token is malformed or otherwise invalid.
code
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",
)
location = s3_client.get_bucket_location(
Bucket=bucket_name,
)
print(location) # works
# {'LocationConstraint': 'eu-south-1'}
res = s3_client.list_objects_v2(Bucket=bucket_name)
# botocore.exceptions.ClientError
Two issues here
STS region
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",
region_name="eu-west-1",
endpoint_url="https://sts.eu-west-1.amazonaws.com",
)
Issue two
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