IAM User Not Authorized to AssumeRole - amazon-web-services

I am trying to do role assumption with Java from IAM User auditor of account1 to another AWS account account2 but it always give me the error message as follow:
AWSSecurityTokenServiceException: User: arn:aws:iam::account1:user/auditor is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::account2:role/roleTester (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: d6cf1458-a3ab-40f4-b24f-f1459a79a82d; Proxy: null)
The trust relationship of the role roleTester in account2 that would allow account1 to access the account2's resources is as follows:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account1:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "d5d2c143-f6b4-48e9-bd16-8708d86a0152"
}
}
}
]
}
Meanwhile, in the IAM User auditor in account1 has the inline policy as follow:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sts:*",
"Resource": "arn:aws:iam::account1:role/AuditorCheck"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "sts:*",
"Resource": "*"
}
]
}
Using the access key of IAM user auditor, I tried to run the following code but returned error.
BasicAWSCredentials credentials = new BasicAWSCredentials("accesskey", "secretkey"); //Mitigant credential
AWSCredentialsProvider credentialsProvider = new EnvironmentVariableCredentialsProvider();
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials)) // IAM User Auditor credential
.withRegion(Regions.EU_CENTRAL_1)
.build();
AssumeRoleRequest roleRequest = new AssumeRoleRequest()
.withRoleArn("arn:aws:iam::account2:role/roleTester") //the ARN of the role provided by cloud customers
.withExternalId("d5d2c143-f6b4-48e9-bd16-8708d86a0152") // the external ID provided by cloud customers
.withRoleSessionName("test");
AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);
Credentials sessionCredentials = roleResponse.getCredentials();
BasicSessionCredentials awsCredentials = new BasicSessionCredentials(
sessionCredentials.getAccessKeyId(),
sessionCredentials.getSecretAccessKey(),
sessionCredentials.getSessionToken());
Is there something wrong with either of the trust relationship of account2 or the inline policy of account1?

Related

Assumed Role Cannot Assume Another Role

I'm bumping into a role chaining issue when utilizing AWS EKS and I'm not able to identify where the chaining is incorrect.
Role A in account 1 will be assuming role B in account 2.
Role A is an arn:aws:sts::{ACCOUNT-ID-1}:assumed-role/{ROLE-NAME}/{SESSION-NAME}
Role B is a standard: arn:aws:iam::{ACCOUNT-ID-2}:role/{ROLE-NAME}
Role A is an assumed-role because on deployments into EKS, the role is assumed.
The Policy for role A is
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "sts:*",
"Resource": "*"
}
]
}
The Trust Policy for B is
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "{ORD}"
},
"ArnLike": {
"aws:PrincipalArn": [
"arn:aws:sts::{ACCOUNT-ID-1}:assumed-role/{ROLE-NAME}/{SESSION-NAME}"
]
}
}
}
]
}
*The aws:PrincipalOrgID match up correctly on validation
The role assumption is conducted in SpringBoot
#Bean
public WebIdentityTokenCredentialsProvider getCredProvider() {
return WebIdentityTokenCredentialsProvider.builder().roleSessionName("SESSION-NAME").build();
}
public AWSCredentialsProvider assumeRole() {
AWSCredentialsProvider credentials = getCredProvider();
AWSSecurityTokenService sts = AWSSecurityTokenServiceClientBuilder.standard()
.withRegion("us-west-1")
.withCredentials(credentials)
.build();
return new STSAssumeRoleSessionCredentialsProvider.Builder("arn:aws:iam::{ACCOUNT-ID-2}:role/{ROLE-NAME}", "role-b-session")
.withStsClient(sts)
.build();
}
This role assumption fails as:
com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException:
User: arn:aws:sts::{ACCOUNT-ID-1}:assumed-role/{ROLE-NAME}/{SESSION-NAME}
is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::{ACCOUNT-ID-2}:role/{ROLE-NAME}
(Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied;
I am not sure why the above would return an AccessDenied based on the configured trust and permission policies as well as the Java code.

AWS IAM / QuickSight - user is not authorized to perform: quicksight:GetDashboardEmbedUrl on resource

I am trying to use the embed QuickSight dashboard URL function in my ASP.NET MVC project. For testing, I'm simply trying to output the embed URL to a string. Here is the main part of my code:
var awsCredentials = new BasicAWSCredentials("redacted", "redacted");
AmazonSecurityTokenServiceClient stsClient = new AmazonSecurityTokenServiceClient(awsCredentials);
var tokenServiceRequest = stsClient.GetSessionToken();
var client = new AmazonQuickSightClient(
tokenServiceRequest.Credentials.AccessKeyId,
tokenServiceRequest.Credentials.SecretAccessKey,
tokenServiceRequest.Credentials.SessionToken,
Amazon.RegionEndpoint.APSoutheast2);
try
{
string machineTypeEmbedUrl =
client.GetDashboardEmbedUrlAsync(new GetDashboardEmbedUrlRequest
{
AwsAccountId = "redacted",
DashboardId = "redacted",
IdentityType = IdentityType.IAM,
ResetDisabled = true,
SessionLifetimeInMinutes = 100,
UndoRedoDisabled = false
}).Result.EmbedUrl;
}
catch (Exception ex)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest,ex.Message);
}
In order to support the permissions required, I have set up an IAM user with the STS Assume Role allowed as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1551593192075",
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Resource": "arn:aws:iam::redacted:role/assume-quicksight-role"
}
]
}
I have set up the role specified above with the following permissions, and set its trust policy so that the IAM user above can assume it.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "quicksight:RegisterUser",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "quicksight:GetDashboardEmbedUrl",
"Resource": "arn:aws:quicksight:ap-southeast-2:redacted:dashboard/redacted",
"Effect": "Allow"
}
]
}
So as far as I can tell this should work. Debug reveals I do get a session token which is passed to the embedUrl request, however I get the following error:
InnerException = {"User:
arn:aws:iam:::user/api-dev-quicksight-user is not authorized
to perform: quicksight:GetDashboardEmbedUrl on resource:
arn:aws:quicksight:ap-southeast-2::dashboard/"}
I'm not sure why this happens? I have a user that can assume the right role, and the role has the right permissions to the dashboard in question. What am I missing here?
Try to change your role like this (notice the :: double colon before dashboard):
...
"Action": "quicksight:GetDashboardEmbedUrl",
"Resource": "arn:aws:quicksight:ap-southeast-2::dashboard/*",
"Effect": "Allow"
...
This should allow the user to access all the sub-resources under the dashboard.
To follow the Least Privilege principle recommend by AWS, you should list all your resources:
...
"Resource": [
"arn:aws:quicksight:ap-southeast-2::dashboard/",
"arn:aws:quicksight:ap-southeast-2::dashboard/redacted"]
...

AWSSecurityTokenServiceException: Acced denied. User is not authorized to perform sts:AssumeRole

I'm new to aws. I want to generate temporary credentials for aws call. And for that I use example from Making Requests Using IAM User Temporary Credentials - AWS SDK for Java
Where I pass
String clientRegion = "<specific region>";
String roleARN = "<ARN from role>";
String roleSessionName = "Just random string"; //<-- maybe I should pass specific SessionName?
String bucketName = "<specific bucket name>";
And when trying assume role
stsClient.assumeRole(roleRequest);
get an error
com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException:
User: arn:aws:iam:::user/ is not authorized to perform:
sts:AssumeRole on resource: arn:aws:iam::<ID>:role/<ROLE_NAME> (Service: AWSSecurityTokenService; Status Code: 403; Error Code:
AccessDenied; Request ID:)
I have a cognito role.
I think the problem in role Trust Relationship settings.
It looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<iam user ID>:user/<USER_NAME>",
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "<user pool ID>"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}
and user policy (This user policy is attached to this Role also):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "<sidId1>",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::<path>*"
]
},
{
"Sid": "sidId2",
"Effect": "Allow",
"Action": [
"sts:AssumeRole",
"sts:AssumeRoleWithWebIdentity"
],
"Resource": [
"arn:aws:iam::<ID>:role/<ROLE_NAME>"
]
}
]
}
User policy has two warnings:
What I'm doing wrong?
UPD
I changed role Trust relationship, just delete Condition:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com",
"AWS": "arn:aws:iam::<ID>:user/<USER>"
},
"Action": [
"sts:AssumeRole",
"sts:AssumeRoleWithWebIdentity"
]
}
]
}
and now Access denied error occurred on another line of code:
// Verify that assuming the role worked and the permissions are set correctly
// by getting a set of object keys from the bucket.
ObjectListing objects = s3Client.listObjects(bucketName);
Received error response: com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: ), S3 Extended Request ID:
To be able to assume to an IAM Role, simply the IAM Role assume role policy or trust relation must explicitly allow the principal assuming role into it, which in this case it didn't. It permitted sts:AssumeRoleWithWebIdentity with some conditions which didn't apply to your case.
About the other error, as mentioned by the #user818510 your role doesn't have permission to s3:ListBucket action.

AWS Lambda cross-account access denied

I have 2 AWS accounts. Account 1 has a CloudSearch domain that I need to query from a Lambda function in account 2. I've followed a tutorial here for creating a role in account 1 that allows cross-account access.
So, in account 1 I have a role arn:aws:iam::111111111111:role/my_cloudsearch_query_role that looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "cloudsearch:search",
"Resource": "*"
}
]
}
This role has one trusted entity, account 2, and I can see the correct account ID under the Trusted Entities section for the role in the IAM console.
In account 2, I've created a Lambda function with an execution role that looks like this:
{
"roleName": "my_cloudsearch_query_role",
"policies": [
{
"document": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/my_cloudsearch_query_role"
}
]
},
"name": "oneClick_lambda_basic_execution_1526469274620",
"type": "inline"
}
]
}
My Lambda function (Python 3) code tries to query CloudSearch like this:
client = boto3.client('cloudsearchdomain', endpoint_url=endpoint)
response = client.search(
query="(and name:'foobar')",
queryParser='structured',
returnFields='curr_addr',
size=1
)
All calls to the Lambda function fail with the following error:
An error occurred (AccessDenied) when calling the Search operation: User: arn:aws:sts::222222222222:assumed-role/my_cloudsearch_query_role/my_lambda_func is not authorized to perform: cloudsearch:search on resource: myCSDomain
I'm positive that I've gotten the account IDs correct so there's no mix-up. Is there something else I need to do to get it working?
You need to assume the role in account 111111111111 and then use the returned credentials to create your client object. Use assume_role boto3 API call to get the credentials. Here's a sample code:
role_arn = "arn:aws:iam::111111111111:role/my_cloudsearch_query_role"
sts = boto3.client('sts', region_name="us-east-1")
token = sts.assume_role(RoleArn=role_arn, RoleSessionName="Session1")
credentials = token['Credentials']
access_key = credentials['AccessKeyId']
secret_key = credentials['SecretAccessKey']
token = credentials['SessionToken']
session = boto3.session.Session(
aws_access_key_id=access_key,
aws_secret_access_key=secret_key,
aws_session_token=token
)
client = session.client('cloudsearchdomain', endpoint_url=endpoint)
response = client.search(...)
Please update the role_arn with the correct details. Documentation about Session object can be found here.

AWS ElasticSearch write to account "A" from lambda in account "B"

I have an AWS ElasticSearch Cluster in account "A".
I'm trying to create a lambda (triggered from a DynamoDB Stream) in account "B" that will write to ES in account "A".
I'm getting the following error:
{
"Message":"User: arn:aws:sts::AccountB:assumed-role/lambdaRole1/sourceTableToES is not authorized to perform: es:ESHttpPost on resource: beta-na-lifeguard"
}
I have tried putting the STS as well as the ROLE into the ES access policy (within account "A") with no luck. Here is my policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AccountA:user/beta-elasticsearch-admin"
},
"Action": "es:*",
"Resource": "*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::AccountA:user/beta-elasticsearch-readwrite",
"arn:aws:iam::AccountA:role/beta-na-DynamoDBStreamLambdaElasticSearch",
"arn:aws:sts::AccountB:assumed-role/lambdaRole1/sourceTableToES",
"arn:aws:iam::AccountB:role/service-role/lambdaRole1"
]
},
"Action": [
"es:ESHttpGet",
"es:ESHttpPost",
"es:ESHttpPut"
],
"Resource": "*"
}
]
}
In my code above I was adding arn:aws:sts::AccountB:assumed-role/lambdaRole1/sourceTableToSNS into the AccountA ES access list, that is wrong. Instead do the following:
I already had arn:aws:iam::AccountA:role/beta-na-DynamoDBStreamLambdaElasticSearch in the ES access list, I needed to add a trust relationship (from the IAM role screen) for that role to be assumable by AccountB. I added this into the trust relationship:
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AccountB:root"
},
"Action": "sts:AssumeRole"
}
Then, in my accountB lambda code, I needed to assume that role. Here is the relevent code from the lambda.
var AWS = require('aws-sdk');
var sts = new AWS.STS({ region: process.env.REGION });
var params = {
RoleSessionName: "hello-cross-account-session",
RoleArn: "arn:aws:iam::accountA:role/beta-na-DynamoDBStreamLambdaElasticSearch",
DurationSeconds: 900
};
sts.assumeRole(params, function (err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
context.fail('failed to assume role ' + err);
return;
}
log("assumed role successfully! %j", data)
postToES(bulkUpdateCommand, context);
});
When you create a "role" for another account you also need to setup the "Trust relationships". This is done in the AWS IAM console under "Roles". Second tab for your role is "Trust relationships". You will need to specify the account details for the other account as trusted.
The "Trust relationships" is a policy document itself. Here is an example that will allow you to call AssumeRole from another account to my AWS account.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::2812XXXXYYYY:root"
},
"Action": "sts:AssumeRole"
}
]
}
In your role, just specify permissions as normal just like you were granting permissions for another IAM user / service (e.g. remove all those account type entries). The Trust relationships policy document defines who can call AssumeRole to be granted those permissions.
Creating a Role to Delegate Permissions to an IAM User
Modifying a Role