I am setting up our AWS to have multiple accounts, with our IAM users defined in one account and our resources defined in one or more other accounts, with policies set up to allow users to assume roles on the production and staging accounts. I am using this Coinbase blog postas a guide. In a nutshell, the approach is to call aws sts get-session-token to get temporary credentials (you have to do this if you use MFA), and then use those credentials to call assume-role for the role you want.
However, it appears that you can't assume-role with a duration any longer than an hour using temporary credentials. When I run this:
aws sts assume-role --role-arn arn:aws:iam::<REDACTED>:role/power-user --role-session-name my_session --duration <DURATION>
If I use a duration any longer than an hour, I get this error:
An error occurred (ValidationError) when calling the AssumeRole operation: The requested DurationSeconds exceeds the 1 hour session limit for roles assumed by role chaining.
This will be a hard sell for my dev team if they have to enter their MFA tokens once an hour. Is there a way to assume-role with teporary credentials that last more than an hour?
You can assume a role for 12 hours if you are using IAM long-term creds. Whereas if you are using temporary creds (e.g. from GetSessionToken API) to call AssumeRole, then you cannot assume the role for more than an hour.
I wonder why would you need to call GetSessionToken API first and not use AssumeRole API directly with MFA?
Related
Was trying to start a session[terminal] via ssm on an instance in another account. using command
aws ssm start-session --target i-yyyaf4692d801d1xx --region ap-south-1
but it was failing with response as "Target is not connected".
we get this response when the instance is usually not found in the inventory of Systems Manager. - which i can't add, as the instance is in another account
END Goal: I wish to use users created in Account A to be able to start sessions on instances on Account B. both part of the same organisation.
Also,
my user has appropriate permissions have verified it through IAM Simulator
it seems instance IDs are unique and associated to one account only.
the instance is accessible by local users in that account.
[update 9th Jan 2023]
Thanks for the responses, its clear that IAM Role[with assume role sts] suffices the request conditions.
But i was looking for some seamless method, where we dont need to generate temporary credentials and use them for access each time.
May be a script to do this task or something would do. As IAM Principal: Users need to generate temp creds manually which is not the case with IAM Roles
You need to delegate access between the accounts. You can do this by creating a role in the target account which is allowed to assumed by users in the other account.
Setup the access:
Create an IAM role with necessary IAM permissions to access the instances in the target account (account B)
Create a trust relationship on the role in the target account to trust the appropriate principals (users or roles) in the source account (account A).
Grant the appropriate principals (users or roles) in the the source account (account A) permission to call the sts assume-role API for the role in the target account (account B)
Use the access:
From your user profile or role in account A, call the sts assume-role API to obtain credentials for the role you created in account B.
Use the credentials returned by the sts assume-role call in order to call the API using the identity assumed in account B to access the resources.
See: cross-account IAM access for more details.
I am new to AWS.
Having a list of AWS SSO account aliases and account IDs, I need to iterate through those and check whether they have a specific role assigned to them.
What is the best way to do it? Note that, every account has a specific role associated to it, which I can assume in order to access everything in that account.
For example, given the account ID 999999999999, I guess I could do something like the following:
aws sts assume-role --role-arn "arn:aws:iam::999999999999:role/CommonMemberAccess" --role-session-name "MY-SESSION"
The above will print a JSON object with AccessKeyId, SecretAccessKey and SessionToken.
I could then export the above as env variables, for example,
export AWS_ACCESS_KEY_ID=AccessKeyId
export AWS_SECRET_ACCESS_KEY=SecretAccessKey
export AWS_SESSION_TOKEN=SessionToken
And finally, list the roles within the specific account as follows
aws iam list-roles
Eventually, I will need to do the above by connecting to the AWS API using Go (I am also new to Go). But as a starting point, I would like to know what I can do using the command line aws client.
Is the above a reasonable approach? How would you do this better?
You may try this cli command.
aws iam list-roles —-path-prefix /aws-reserved/sso.
In otherway, you can filter IAM roles associated with SSO by checking their ‘AssumeRolePolicyDocument’.
The ‘Principal’ attribute has to be the ARN of a federated identity provider which has its metadata document issued by AWS SSO
(you can check its SAML metadata XML document with the following cli command),
aws iam get-saml-provider —-saml-provider-arn “arn:of:federated:saml-provider:from:AssumeRolePolicy”
I am trying to programmatically generate temporary credentials for an assumed role (cross-account) based off of MFA credentials. My ultimate goal is that I only want to have to enter in my MFA token code a single time, and then assume multiple different roles without needing to re-enter my MFA token code (until the MFA session expires).
I am able to obtain temporary MFA credentials no problem:
aws sts get-session-token --serial-number arn:aws-us-gov:iam::<serialnumber>:mfa/<user> --token-code <token code>
I then take the resulting session credentials/token and store it in ~/.aws/credentials
I then want to obtain temporary credentials for an assume role, like the AWS documentation seems to imply is OK:
You cannot call any AWS STS API except AssumeRole or GetCallerIdentity.
However, when I attempt to do so, I get an InvalidClientTokenId error with the following command:
aws sts assume-role --profile default-mfa --role-arn arn:aws-us-gov:iam::<account id>:role/Sandbox_Role --role-session-name clie-access-example --duration 900
I do not have any environment variables set up for AWS credentials (i.e. no AWS_SESSION_TOKEN or AWS_SECRET_ACCESS_KEY environment variables). Also note that I am requesting a token that expires in less than an hour (since as far as I am aware, you cannot request tokens that live longer than an hour with temporary credentials)
Note that if I assume a role implicitly using a profile, everything is fine:
aws sts get-caller-identity --profile role-profile
of for a command that requires actual permissions:
aws dynamodb list-tables --profile role-profile
where my ~/.aws/config file looks like:
[default]
region = us-gov-west-1
output = json
[default-mfa]
region = us-gov-west-1
output = json
[role-profile]
source_profile = default-mfa
region = us-gov-west-1
My AWS user itself does not have any permissions and must assume a role to be able to do anything.
Eventually I will also want to retrieve the assumed role credentials via Postman and store them in my Postman environment so that I can easily switch roles in postman simply by switching environments without needing to copy MFA credentials by hand more than once before the MFA session expires.
An error occurred (AccessDenied) when calling the AssumeRole operation: Roles may not be assumed by root accounts.
How to solve the issue.
Example:
aws sts assume-role --role-arn "arn:aws:iam::293424211206:role/QuickSightEmbed" --role-session-name tom.smith#example.com
aws sts assume-role --role-arn "arn:aws:iam::293424211206:role/QuickSightEmbed" --role-session-name tom.smith#example.com
This is an appropriate error to receive; root doesn’t need to assume any role, it has total access.
Considering the security implications of using root credentials, you should not use root credentials for anything except rare cases when you genuinely need root access, and you certainly should not use root credentials in a web app where they might be exposed.
Instead, create an IAM user with the appropriate permissions to assume the role you want to assume and use this new IAM users credentials in your application.
I'm trying to get a session token in order to set environment variables in order to use a tool which uploads to S3 but doesn't directly support AWS profiles.
aws sts get-session-token --profile myprofile
Enter MFA code for arn:aws:iam::1234567890:mfa/myid:
An error occurred (AccessDenied) when calling the GetSessionToken operation:
Cannot call GetSessionToken with session credentials
Subsequent calls skip the MFA check, indicating that it passed ok.
Running get-session-token without the --profile parameter works fine:
$ aws sts get-session-token
{
"Credentials": {
...
What could be going wrong? Am I even going about this the right way?
The relevant part of my ~/.aws/config:
[profile otherprofile]
mfa_serial=arn:aws:iam::xxx:mfa/myid
aws_access_key_id=xxx
aws_secret_access_key=xxx
[profile myprofile]
source_profile=otherprofile
region=ap-southeast-2
role_arn=arn:aws:iam::xxx:role/owner
mfa_serial=arn:aws:iam::xxx:mfa/myid
Your initial call is using an IAM role. It is attempting to call get-session-token, which will return some temporary credentials.
However, when an IAM Role is used, the AWS CLI automatically uses your normal credentials to call assume-role, thereby receiving back a set of temporary credentials. It is not possible to call get-session-token with temporary credentials (from the role). This is why the error message says Cannot call GetSessionToken with session credentials.
If you wish to call get-session-token, you will need to do it with your normal credentials, as you have done in your second example.
To retrieve the access id, access key and session token from a profile you can use aws configure.
E.g.
aws configure get aws_access_key_id --profile myprofile
aws configure get aws_secret_access_key --profile myprofile
aws configure get aws_session_token --profile myprofile