Assumed Role Cannot Assume Another Role - amazon-web-services

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.

Related

IAM User Not Authorized to AssumeRole

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?

IAM CodeBuild policy condition - principal tag equals resource tag

Goal:
Create an IAM role policy that allows the role to perform defined actions on aws resources only if the role tag equals the resource tag.
For example:
IAM tag:
foo=bar
CodeBuild project tag:
foo=bar
IAM role policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codebuild:List*",
"codebuild:DescribeTestCases",
"codebuild:DescribeCodeCoverages",
"codebuild:BatchGet*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/foo": "${aws:PrincipalTag/foo}"
}
}
}
]
}
When the user assumes the role, the user is denied access to codebuild:ListProjects on projects that have the same foo=bar key pair as the role within the AWS console and AWS CLI.
AWS console error:
User: arn:aws:sts::123456789:assumed-role/example-role/example-user is not authorized to perform: codebuild:ListProjects
AWS CLI error using the command: aws codebuild list-projects --profile test
An error occurred (AccessDeniedException) when calling the ListProjects operation: User: arn:aws:sts::123456789:assumed-role/example-role/botocore-session-59458209 is not authorized to perform: codebuild:ListProjects
Attempts:
#1
Use actual key pair value in policy condition:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codebuild:List*",
"codebuild:DescribeTestCases",
"codebuild:DescribeCodeCoverages",
"codebuild:BatchGet*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/foo": "bar"
}
}
}
]
}
Result to codebuild:ListProjects access denied error on aws console
#2
Remove aws key brackets from aws:PrincipalTag/foo(shooting from the hip here)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codebuild:List*",
"codebuild:DescribeTestCases",
"codebuild:DescribeCodeCoverages",
"codebuild:BatchGet*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/foo": "aws:PrincipalTag/foo"
}
}
}
]
}
#3
Used the resource type within the resource tag condition codebuild:ResourceTag/foo
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codebuild:List*",
"codebuild:DescribeTestCases",
"codebuild:DescribeCodeCoverages",
"codebuild:BatchGet*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"codebuild:ResourceTag/foo": "${aws:PrincipalTag/foo}"
}
}
}
]
}
Same codebuild:ListProjects access denied error on aws console
From docs:
CodeBuild supports authorization based on tags for project-based actions
I think ListProjects action is not project-based. It is for entire codebuild, rather then for a specific project.

AWS cli: not authorized to perform: sts:AssumeRole on resource

I have an AWS account in which I am assuming a role named A(role-A), from that role I have created another role named B(role-B) through the web console and attached the administrator policy to that role
Here is cli configuration
[default]
aws_access_key_id = <>
aws_secret_access_key = <>
region = eu-central-1
[role-B]
role_arn = arn:aws:iam::<id>:role/ics-role
mfa_serial = arn:aws:iam::<id>:mfa/<name>
external_id = <name>
source_profile = default
role-B which I have created from role-A
When i try to get the role details
aws --profile role-B sts get-caller-identity
I am getting the following error
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::<>:user/<> is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::<>:role/ics-role
You'll need to check the trust relationship policy document of the iam role to confirm that your user is in it.
Additionally make sure that the iam user has explicit permissions allowing them to assume that role.
The trust relationship should look something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::1234567890:user/person"
]
},
"Action": "sts:AssumeRole"
}
]
}
My issue was I had a condition set in the policy json.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000:dave"
},
"Action": "sts:AssumeRole",
"Condition": {
// Condition set here
}
}]
}
I removed the condition and it works now no issues.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000:dave"
},
"Action": "sts:AssumeRole"
}]
}

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 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