Allow selected IAM users to switch role - amazon-iam

I have two AWS accounts(Account A & B). I want to allow few IAM users of Account B to access resources of Account A via AWS IAM roles.
I have created the role and it works fine. However, I see that any IAM user who gets hold of the role name is able to switch roles and access the resources.
Is there a way to allow only specific users of Account B to be able to switch to the role?
The trust policy statement is as follows-
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account-B:root"
},
"Action": "sts:AssumeRole"
}
]
}

You can add the users who should be restricted to assume the role to a group. Then you can attach IAM policy to the IAM group with an explicit Deny.
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Deny",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::Account_A_ID:role/Rolename"
}
}
http://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html#tutorial_cross-account-with-roles.html#tutorial_cross-account-with-roles-2

Related

can IAM user assume a role, whose trust policy allows the user, without explicit AssumeRole permission

I have a IAM role with full ec2 access with below trust policy,
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::AccountA:user/dev"
]
},
"Action": "sts:AssumeRole"
}
]
}
IAM user, dev, does not have an associated AssumeRole policy, but still be able to switch to this role.
When I expand the principal to "Account Number", as expected, I need to attach explicit AssumeRole to user(s) to switch to that role.
can someone explain why a trust policy at user level is not enforcing explicit permission?

update Route53 record set - cross account

Am facing an access issue when trying to update record set using lambda function.
Lambda - Account A
Route53 - Account B
I have an IAM role attached to lambda in Account A with an assume role permission to an IAM role in Account B. The IAM role in account B has access to update the record set in Account B.
When am triggering lambda, am receiving user is not authorized to access this resource.
Can someone help me, if i'm missing anything here or do I need any additional setup.
You are using a Lambda function in Account-A to call Route 53 in Account-B.
This will require:
An IAM Role (Role-A) in Account-A that is assigned to the Lambda function. It should grant permission to call AssumeRole(), with the Resource set to the ARN of Role-B in Account-B:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<Account-B>:role/role-b"
}
]
}
And with this Trust Relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
An IAM Role (Role-B) in Account-B that has permission to call Route 53. It should also have a trust policy allowing it to be assumed by Role-A in Account-A:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "route53:*",
"Resource": "*"
}
]
}
(This is an overly powerful policy. It would be better to limit it to the specific Route 53 actions that are required.)
And this Trust Relationship (pointing to the Role created in the previous step):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account-A>:role/role-a"
},
"Action": "sts:AssumeRole"
}
]
}
You need to use STS to get a token to call Route53 on Account B. Here are the docs on STS in boto3: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts.html#STS.Client.assume_role
You'll get back a credential that you will use to make the call to Route53.

S3 deny access to administrators

For one AWS S3 bucket, I would like to deny access to everyone except for one specific IAM role. I created a role-based policy to allow access and that works. But other IAM users are also able to access objects and I want to prevent this. I tried adding a bucket policy like this, which denies everyone except this principal and then allows this principal. But this policy blocks access to everyone including that role.
The other IAM users I am trying to block are attached to the built-in AdminstratorAccess policy.
{
"Version": "2012-10-17",
"Id": "PolicySecretBucket",
"Statement": [
{
"Sid": "StmtDenyAll",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::********:role/service-role/my-role"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "StmtAllowLambdaBot",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::********:role/service-role/my-role"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
this is how I would do it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MyExampleBucket",
"arn:aws:s3:::MyExampleBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAEXAMPLEID:*",
"ACCOUNT NUMBER"
]
}
}
}
]
}
this is how it works.
the user's will have an IAM policy which allows s3.* actions
we will deny all the s3 actions for the bucket MyExampleBucket for any user id but the user id of the role (and the user id of the root account in case if the role is deleted) using the bucket policy
to get the user id of the role:
aws iam get-role --role-name ROLE-NAME
And finally, why yours does not work: https://serverfault.com/a/988136
reference:
https://aws.amazon.com/blogs/security/how-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/
Denying access to a specific bucket is actually quite difficult.
For example, an Administrator might have permissions to assume the Role, so they can still access the bucket.
You would also need to review all policies to ensure that only authorized people can use iam:PassRole to assume the role via an Amazon EC2 instance.
An safer approach would be to put the bucket in a separate AWS Account. Then, only give cross-account access to specific users (not a Role). This way, the default is that Admins have zero access and you then grant access to the desired people. There are less ways to "get around" this type of access.

Assume AWS Role From User in Same Account

I'm a little confused about the requirements for assuming a role from an IAM user in the same AWS account.
Per this document: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html:
If the user is in the same account as the role, then you can do either
of the following:
Attach a policy to the user (identical to the previous user in a
different account).
Add the user as a principal directly in the role's trust policy.
I explicitly added an assume-role policy to the group granted to my user and it could not assume the noted role:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::123456789:role/some-role-name"
}
}
Once I added the account number as a principal to the trust policy of the target role, it started working though:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com",
"AWS": "arn:aws:iam::123456789:root"
},
"Action": "sts:AssumeRole"
}
]
}
So, I'm confused for 2 reasons:
Why didn't the first policy alone work given the documentation I've quoted?
The second bullet in the documentation says "add the user as a principal". I think I added the whole account though instead of the user. What is the syntax for adding just this user? I didn't come across it in the documents I read.
1) That looks fine to me, given that the account ID and the role name are correct. Can you add the exact error you're getting?
This is an actual example of one of my policies which let users who are granted this policy to assume the role developer in the accounts acc1, acc2, and acc3:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::acc1:role/developer",
"arn:aws:iam::acc2:role/developer",
"arn:aws:iam::acc3:role/developer"
]
}
]
}
2) Instead of root, use the arn for the IAM user. Something along the lines of "arn:aws:iam::123456789:user/John"

IAM Roles Assume Role Permission

Given an IAM role created with this permission:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": "First"
}
]
}
is there anything that tells AWS that only lambda functions in this account should be able to assume the role. I want AWS lambda to be able to assume this role when running functions in this account, but only lambda functions running in this AWS account - not lambda functions running in other random AWS account that happen to discover the ARN of this IAM role.
If it is the case that using this configuration allows any lambda function running in any AWS account to assume this role, then how can this policy be amended to only allow lambda functions running in my account to assume this role.
"Service": "lambda.amazonaws.com" tells that your IAM role can only be assumed by Lambda.
If you want to grant permissions to another account to assume the role, your IAM policy for the role may look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<AccountNumberThatCanAssumeTheRole>:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}