Unable to use terraform with AWS IAM role with MFA configuration - amazon-web-services

My organisation uses a gateway account for which i have aws credentials.
We also have our personal account, in order to access our personal account users in gateway account assume IAM roles ( created in the personal account).
With such configuration i am trying to create terraform resource but somehow keep on getting error -> Error: operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: xxxxxxx, api error AccessDenied: User: arn:aws:iam::xxxxxx:user/xx-xxxxxx is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::xxxxxxx2:role/xxxxxx
Here is the provider configuration i am trying.
provider "aws" {
alias = "mad"
profile = "personal account"
region = "ap-south-1"
assume_role {
role_arn = "arn:aws:iam::xxxxxxx:role/personal account"
}
}
Update :- the role uses mfa too.
Personal account has trust relationship which allows gatgeway account iam user to assume to role.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::gateway-account-id:user/user"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}

The user user/xx-xxxxxx which you use to run the TF script which is going to assume role role/xxxxxx must have sts:AssumeRole.
You can add such permission to the user, by adding the following inline policy to it:
{
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::xxxxxxx2:role/xxxxxx"
]
}
UPDATE
Also for MFA you need to use token option in your provider configuration, or use any of the workarounds provided in TF github issue.

Related

Creating IAM policy and role in destination account

Context:
At the moment I manually create a Policy and Role in the stag account (destination) to allow devops group users from the root account to list all S3 objects taht live in stag account. What I need to do is that, get rid of manual Policy and Role creation process in the stag account to have a configuration in Terraform which handles it as usual.
So far I tried replicating some examples that I've seen on the web but the problem is, most of them duplicate users in all accounts which is not fit for my setup. On the other hand, when I follow some other examples, the Policy and Role is created in the root account rather than the stag account. As a result using role_arn = arn:aws:iam::222222222222:role/devops in CLI config for john gives me An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::111111111111:user/john is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::222222222222:role/devops. I would greatly appreciate it if someone would help me out with this.
Setup:
The root (111111111111) account is dedicated to IAM groups and users only, nothing else.
There is user john who is part of devops group.
The stag (222222222222) account is dedicated to S3 only (for now), not for IAM groups or users.
There are many buckets.
Requirement:
Allow john to run $ aws s3 ls to list all objects in all S3 buckets.
Manually created policy in stag account
# arn:aws:iam::222222222222:policy/devops-role-permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
Manually created role in stag account
# arn:aws:iam::222222222222:role/devops
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
}
}
]
}
Terraform root policy config
resource "aws_iam_policy" "devops_role_assumption_in_stag_account" {
name = "devops-role-assumption-in-stag-account"
description = "Allows devops group to assume role in stag account."
policy = jsonencode(
{
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Action" : "sts:AssumeRole",
"Resource" : "arn:aws:iam::222222222222:role/devops"
}
]
}
)
}
Terraform root group policy attachment config
resource "aws_iam_group_policy_attachment" "devops_role_assumption_in_stag_account" {
group = aws_iam_group.devops.name
policy_arn = aws_iam_policy.devops_role_assumption_in_stag_account.arn
}

Using AWS federated identity from Github Action to assume role in another AWS account

I have 2 AWS accounts, source and destination. AWS OIDC federation is configured so that I can use the token from Github Action to login to AWS using the official action:
- name: configure aws credentials
uses: aws-actions/configure-aws-credentials#v1
with:
role-to-assume: arn:aws:iam::<source account id>:role/role-A
aws-region: us-east-1
Now, I want to use Terraform to manage resources on both accounts, source and destination. I followed a guide to allow role-A to assume role-B in the destination account.
I am getting a weird error:
Error: 022-08-31T09:28:04.246] [ERROR] default -
Error: error configuring Terraform AWS Provider: IAM Role (arn:aws:iam::<destination account id>:role/role-B) cannot be assumed.
There are a number of possible causes of this - the most common are:
* The credentials used in order to assume the role are invalid
* The credentials do not have appropriate permission to assume the role
* The role ARN is not valid
Error: operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: 7227d0e8-e955-45ac-8f08-fc48699564e3, api error AccessDenied: User: arn:aws:sts::<source account id>:assumed-role/role-A/GitHubActions is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::<destination account id>:role/role-B
with provider["registry.terraform.io/hashicorp/aws"].security,
on cdk.tf.json line 4125, in provider.aws[1]:
4125: }
I can't figure out what the problem is. Role A has the following IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<destination account id>:role/role-B"
}
]
}
I'll appreciate help figuring out why the request is failing... It seems like everything is configured correctly...
Edit:
Added the trust policy for Role B:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<source account id>:role/role-A"
},
"Action": "sts:AssumeRole"
}
]
}

AWS group user not allowed to assume role - access denied

I have a user and I'm trying to impersonate a role for running a service on Kubernetes. However, when I tried using STS to assume the role, I get the following error:
$ aws sts assume-role --role-arn "arn:aws:iam::{ACCOUNT_ID}:role/service-myservice" --role-session-name AWSCLI-Session
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::{ACCOUNT_ID}:user/me is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::{ACCOUNT_ID}:role/service-myservice
I find this odd because this user belongs to a user group with the AdministratorAccess permission attached to it, which should give it access to anything on AWS. This is it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
So, what am I doing wrong here?
What you have here is the IAM policy attached to this User, aka - what is this user is able to do.
You need to set the Trust Relationship as well. This defines which resources or principals is able to use this role/user. Could be Lambda, EC2 or in your case: an IAM User.
See here for example.
The IAM User/Role (in that case, role) you want to assume must have the Trust Relationship as follow:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account_id>:role/<role_name>
},
"Action": "sts:AssumeRole"
}
]
}

How can I listUsers in Cognito from another account

Try to use cognitoIdentityService.listUsers with a role running ec2 machine and it works great in the local org (orgA).
I also want the same role to listUser in another org (orgB).
I created a a role with trust in the orgB with orgA in the Trust relationship and gave it Cognito permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxxx:root"
},
"Action": "sts:AssumeRole"
}
]
}
Then in orgA i added an inline policy to the role i want to give access
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::xxxxxxxxxxxx:role/orgBCognitoAccess"
}
}
I pass the REGION and USERPOOLID to my function.
const params = {
"UserPoolId": UserPoolId,
"Filter": `email = \"${email}\"`,
"Limit": 1
}
cognitoIdentityService.listUsers(params, (err, data) => {
But all i get in return is an error. Should it be switch roles when it sees the userpool does not exist? Is that logic I have to write in or can it be done at all?
{"message":"User pool ca-central-1_BBBBBBBB does not exist.","code":"ResourceNotFoundException","time":"2021-01-18T18:01:29.279Z","requestId":"acc14424-9f1d-411a-95f2-1a302e5773f8","statusCode":400,"retryable":false,"retryDelay":21.27495199615266}
Thanks
Yes, you have given permissions and everything to the roles, but you are still using role in OrgA, so to make the API call you to have to switch role in OrgB and use those credentials for making the client and eventually make the call.
sts_client = boto3.client('sts')
# Call the assume_role method of the STSConnection object and pass the role
# ARN and a role session name.
assumed_role_object=sts_client.assume_role(
RoleArn="arn:aws:iam::account-of-role-to-assume:role/name-of-role",
RoleSessionName="AssumeRoleSession1"
)
# From the response that contains the assumed role, get the temporary
# credentials that can be used to make subsequent API calls
credentials=assumed_role_object['Credentials']
# Use the temporary credentials that AssumeRole returns to make a
# connection to Amazon S3
s3_resource=boto3.resource(
's3',
aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken'],
)
# Use the Amazon S3 resource object that is now configured with the
# credentials to access your S3 buckets.
for bucket in s3_resource.buckets.all():
print(bucket.name)
you can find more details in the documentation
To verify this during the testing you can make GetCallerIdentity this gives you enough details.
{
"UserId": "AIDASAMPLEUSERID",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/DevAdmin"
}

API Gateway resource policy: specify IAM role as AWS principal

I am trying to setup an API Gateway endpoint with a resource policy, which allows access to a specific IAM role in my account. The IAM role is cross-account, setup with a trust policy which allows AssumeRole to a specific IAM user principal from another account.
In the API Gateway resource policy, when I set AWS principal to the role ARN: arn:aws:iam::********:role/myRole, I get the following 403 error when invoking the API:
User: arn:aws:sts::********:assumed-role/myRole/mySession is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-west-2:********:********/test/POST/echo
But, if I change the AWS principal to be the temporary STS user ARN: arn:aws:sts::********:assumed-role/myRole/mySession, then I can invoke the API successfully.
Here's the resource policy that doesn't work:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::********:role/myRole"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:********:********/*"
}
]
}
Here's the resource policy that works:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::********:assumed-role/myRole/mySession"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:********:********/*"
}
]
}
Can IAM roles be used as AWS principals for API Gateway resource policy?
Based on the documentation https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-policy-language-overview.html,
Principal – The account or user who is allowed access to the actions
and resources in the statement. In a resource policy, the principal is
the IAM user or account who is the recipient of this permission.
Looks like roles cannot be added as a principal.
P.S: Spent two days trying to restrict access using roles, but couldn't get it to work.