How does assuming multiple IAM roles at the same time work? - amazon-web-services

I have an ECS task using a task role to access a DynamoDB table in the same account A. It also requires access to a DynamoDB table in a different account B, which is granted through assuming an IAM role.
My understanding is that after assuming the role, the task now has a set of temporary credentials for each role. This allows the task to use the new credentials to make requests to account B's table, while still using the original credentials to make requests to account A's table.
Assuming this is correct, how are the creds used for a given request determined? Does it only use the cross account role for making account B requests, and the original creds for the account A requests?
What if access to account B S3 buckets are also required and the permissions were granted to account A, which were then given to original task role? After assuming the cross account role, does the cross account S3 request fail because the assumed role doesn't have S3 permissions, even though the original take role does?

AWS resources cannot just assume a role themselves. They have to be told to do so, and use the SDK of your choice to do so (or the CLI). Soon as you understand how that works it becomes a lot more clear how this works. Since you mentioned and ec2 instance, I'll use the CLI to show this
AcctCredentials=($(aws sts assume-role --role-arn "$1" --role-session-name TheSessionName --query '[Credentials.AccessKeyId,Credentials.SecretAccessKey,Credentials.SessionToken]' --output text))
unset AWS_SECURITY_TOKEN
echo "Security Tokens for Cross Account Access received"
export AWS_ACCESS_KEY_ID=${AcctCredentials[0]}
echo $AWS_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=${AcctCredentials[1]}
export AWS_SESSION_TOKEN=${AcctCredentials[2]}
export AWS_SECURITY_TOKEN=${AcctCredentials[2]}
doing that you are setting your env variables in the ec2 to these new credentials. This means any other CLI commands run or any script that is launched from the same shell as this one will use these credentials.
If you need to go back to the credentials from before, you will either need to reset/save your credentials from before or exit the shell this command was run in and return to your default credentials.
If this was in a lambda for instance however, you might be using Python and the Boto3 to do something very similar. It would replace the tokens there.
It is also entirely possible to save your tokens as a Profile that the commands can use, and then per command specify the profile you are using for that command.

Related

How to list all roles associated with an AWS SSO account

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”

Is it possible to share Parameter Store keys in another AWS Account for same region?

The use case: The database credentials are stored in Parameter Store for an AWS source Account and we need to share such credentials with other AWS Account.
I know the recommendation is to use System Manager, but that is not a valid option for custom reasons.
We won't access Parameter Store from a Lambda inside another AWS Account/VPC. Instead, we need to access such keys from the AWS CLI to fill in the application environment variables at build time - again, it's not ideal. 🤷‍♂️
In summary, we have an AWS Cross-Account / Same region / IAM user (another account) scenario to access the Parameter Store keys from the source AWS Account.
Thanks in advance for any kind of guidance/direction 👊
I think you could create an IAM Role in the account with parameter store, give that Role permission to access parameter store, and configure it to let the IAM user you created in the other account to assume that Role and do what it needs.
Something like aws sts assume-role --role-arn "arn:aws:iam::123456789012:role/example-role" --role-session-name AWSCLI-Session and then aws ssm get-parameter --name "MyStringParameter"
to make it short: its not possible to share parameter store, only secrets from secrets manager

AWS CLI without configuring access/secret keys

Need to access cross account EC2 describe/start instance API via AWS CLI without configuring access/secret keys in "aws configure".
Assuming that you have default credentials stored for an account (Let's call it dev) but you want to run EC2 describe/start instance API on an instance which is in another account(Let's call it prod) via this account without configuring your prod credentials.
To achieve this you will use an IAM role, which has the EC2:describeInstance access needed in your Prod account. An authenticated user in your Dev account will assume a privileged IAM role in the Prod account with an API call to STS:AssumeRole. This API call will return temporary security credentials that the Dev user’s AWS CLI will automatically use to access resources in the Prod account.
You can set the credentials temporary via environment variables. If you pack this is an bash script, they only last for the execution.
#!/bin/bash
export AWS_ACCESS_KEY_ID=***
export AWS_SECRET_ACCESS_KEY=***
export AWS_DEFAULT_REGION=eu-central-1
aws ec2 <your command>
If you are in a cli of an ec2, best way to do this is to use the IAM role attached to the instance which has permissions ec2:StartInstances and ec2:DescribeInstances for the target ec2.

What user am I when I upload a file to a S3 bucket with the AWS CLI?

I'm learning AWS using the AWS CLI and LocalStack.
I'm working with tutorials such as this, which describe how to create a S3 bucket and upload a file to it.
What I'd like to understand is the role of users in relation to AWS commands, and whether or not there is a relationship between a user and a profile (the latter is created when you run the aws configure CLI command).
When I run a AWS CLI command such as aws --endpoint-url=http://localhost:4572 s3 cp ./foo.json s3://my-bucket/path/to/foo.json what user am I running that command as? I have not explicitly created any users using the AWS IAM CLI or by other means. Is a profile implicitly a user? I.e. when I run aws configure, does the default profile created mean a user named default is created in AWS IAM?
Well, it's easy to check actually.
https://docs.aws.amazon.com/cli/latest/reference/sts/get-caller-identity.html
Is a profile implicitly a user?
No, profile is just that - credentials profile. Whether it's a user or a role, AWS CLI doesn't care as long as those credentials are valid.
when I run aws configure, does the default profile created mean a user named default is created in AWS IAM
Going from previous point, no. Nothing is done implicitly in IAM. When you run aws configure you supply credentials that already exist, not the other way around.

How to manage multiple IAM users on a single EC2 instance?

For different AWS services, I need different IAM users to secure the access control. Sometimes, I even need to use different IAM user credentials within a single project in a EC2 instance. What's the proper way to manage this and how I can deploy/attach these IAM user credentials to a single EC2 instance?
While I fully agree with accepted answer that using static credentials is one way of solving this problem, I would like to suggest some improvements over it (and proposed Secrets Manager).
What I would advise as architectural step forward to achieve full isolation of credentials, having them dynamic, and not stored in central place (Secrets Manager proposed above) is dockerizing application and running on AWS Elastic Container Service (ECS). This way you can assign different IAM role to different ECS Tasks.
Benefits over Secrets Manager solution
- use case of someone tampering with credentials in Secrets Manager is fully avoided, as credentials are of dynamic nature (temporary, and automatically assumed through SDKs)
Credentials are managed on AWS side for you
Only ECS Service can assume this IAM role, meaning you can't have actual person stealing the credentials, or developer connecting to production environment from his local machine with this credentials.
AWS Official Documentation for Task Roles
The normal way to provide credentials to applications running on an Amazon EC2 instance is to assign an IAM Role to the instance. Temporary credentials associated with the role when then be provided via Instance Metadata. The AWS SDKs will automatically use these credentials.
However, this only works for one set of credentials. If you wish to use more than one credential, you will need to provide the credentials in a credentials file.
The AWS credentials file can contain multiple profiles, eg:
[default]
aws_access_key_id = AKIAaaaaa
aws_secret_access_key = abcdefg
[user2]
aws_access_key_id = AKIAbbbb
aws_secret_access_key = xyzzzy
As a convenience, this can also be configured via the AWS CLI:
$ aws configure --profile user2
AWS Access Key ID [None]: AKIAbbbb
AWS Secret Access Key [None]: xyzzy
Default region name [None]: us-east-1
Default output format [None]: text
The profile to use can be set via an Environment Variable:
Linux: export AWS_PROFILE="user2"
Windows: set AWS_PROFILE="user2"
Alternatively, when calling AWS services via an SDK, simply specify the Profile to use. Here is an example with Python from Credentials — Boto 3 documentation:
session = boto3.Session(profile_name='user2')
# Any clients created from this session will use credentials
# from the [user2] section of ~/.aws/credentials.
dev_s3_client = session.client('s3')
There is an equivalent capability in the SDKs for other languages, too.