AWS Access keys without accessing the console - amazon-iam

Is it possible to get AWS access keys without generating one from the console?
I want to be able to create a script that will ask for user/password/(TOTP) and generate temporary access keys in order to perform multiple tasks.
The goal being to be able to give one program to dev so they don't even have to deal with access keys every time since they know their password.
I looked everywhere I believe, but cannot find any resources on if it is even doable.
Thank you!

Yes it is doable.
Both via Command Line Interface (CLI) and API are possible.
The CLI command is:
aws iam create-access-key
The API call is:
CreateAccessKey
See documentation reference below for more information. It is a good read and covers best practice topics like rotating your keys with API or CLI. Another good best practice is NOT using your root account for everyday use.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey_CLIAPI
UPDATE KEY ROTATION EXAMPLE USING CLI:
Before you try this from the CLI - create a new IAM user with Administrator privileges.
Step 1 - configure the CLI to use the Administrator keys:
aws configure
then enter the Access Key ID and Secret Access Key for Administrator.
Step 2 - list the keys for user foo
aws iam list-access-keys --user-name foo
The output will be similar to:
{
"AccessKeyMetadata": [
{
"UserName": "foo",
"AccessKeyId": "AKIAIY*****A7YBHCBEBQ",
"Status": "Active",
"CreateDate": "2018-11-10T14:02:56Z"
}
]
}
Verify there is only one, because a user can have maximum of 2. If they have 2 already, then step 3 will fail.
Step 3 - create a new key for user foo
aws iam create-access-key --user-name foo
you will see output similar to below. This is the only time you will see the secret key for the new set, so you need to preserve it.
{
"AccessKey": {
"UserName": "foo",
"AccessKeyId": "****GAGA*****WEFWEWE",
"Status": "Active",
"SecretAccessKey": "*****sEcReT*****Tasdasd",
"CreateDate": "2018-12-01T19:16:41Z"
}
}
You new key is created and active. Now you need to remove the older key to complete the rotation. I will leave that step up to you.
If you get the error:
An error occurred (InvalidClientTokenId) when calling the ListAccessKeys operation: The security token included in the request is invalid.
then this is a sign you are trying this from an account that your token is old, invalid, or doesnt have the correct privileges.

Related

Is there any way to check the value of aws:MultiFactorAuthPresent

I have a policy that denies operations except if aws global context key aws:MultiFactorAuthPresent is true. Meaning that the operation requires that you are authenticated via MFA.
The policy is working ok, and I can see that when I use my aws profile without mfa the operations are denied and when I use the profile with MFA they work.
Now, is there any command / api operation that tells me if my credentials used MFA (aws:MultiFactorAuthPresent)?
I need it for troubleshooting purpose mainly when other people complain that they are getting Operation Denied? Something like aws sts get-caller-identity but that also print out if the credentials used an MFA code.
If I understand correctly, you would want to check if certain users did authenticate themselves with MFA before doing some operations in your account.
I'm not aware of any kind of CLI command for this. What would be helpful for you is to take a look a the CloudTrail Event History. This should log all the operations done by other users. If you download this list of events as a JSON, you should be able find a section with sessionContext for every event.
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "...",
"arn": "...",
"accountId": "...",
"userName": "..."
},
"webIdFederationData": {},
"attributes": {
"creationDate": "2022-02-18T14:08:57Z",
"mfaAuthenticated": "false"
}
}
We can notice that every it is logged that session used by the user/role is MFA authenticated or not.
If you are willing to search for operations done by certain users, you should be able to detect if they were using MFA or not. Just as warning, this JSON file can be huge and could be really painful to go through it.
If you simply want to make sure that users are using MFA when working with AWS CLI you can also enforce MFA usage with aws sts get-session-token (see also https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/get-session-token.html). Therefore users start creating a temporary session with explicit MFA usage (see parameter --serial-numer and --token-code). All commands execute with these temporary session credentials are MFA enforced.

Identify AWS IAM user that assumed an IAM role

I'm working on a system that receives new findings from Amazon GuardDuty. Most access in our organization is delegated to IAM roles instead of directly to users, so the findings usually result from the actions of assumed roles, and the actor identity of the GuardDuty finding looks something like this:
"resource": {
"accessKeyDetails": {
"accessKeyId": "ASIALXUWSRBXSAQZECAY",
"principalId": "AROACDRML13PHK3X7J1UL:129545928468",
"userName": "my-permitted-role",
"userType": "AssumedRole"
},
"resourceType": "AccessKey"
},
I know that the accessKeyId is created when a security principal performs the iam:AssumeRole action. But I can't tell who assumed the role in the first place! If it was an IAM user, I want to know the username. Is there a way to programmatically map temporary AWS STS keys (starts with ASIA...) back to an original user?
Ideally I'm looking for a method that runs in less than 30 seconds so I can use it as part of my security event pipeline to enrich GuardDuty findings with the missing information.
I've already looked at aws-cli and found aws cloudtrail lookup-events but it lacks the ability to narrow the query to a specific accessKeyId so it takes a loooong time to run. I've explored the CloudTrail console but it's only about as capable as aws-cli here. I tried saving my CloudTrail logs to S3 and running an Athena query, but that was pretty slow too.
This seems like it would be a common requirement. Is there something obvious that I'm missing?
Actually, aws-cli can perform a lookup on the session! Just make sure to specify ResourceName as the attribute key in the lookup attributes.
$ aws cloudtrail lookup-events \
--lookup-attributes 'AttributeKey=ResourceName,AttributeValue=ASIALXUWSRBXSAQZECAY' \
--query 'Events[*].Username'
[
"the.user#example.com"
]

How can I determine which role I've received after logging into AWS Cognito via JavaScript?

After I log in to AWS Cognito via my browser, I get an access key and a secret access key along w/a session token, but I can't see which role I've been assigned. I know which role I should be assigned, but is there a way to programmatically validate this?
I'm trying to use the role I've been assigned to access a restricted bucket, but am so far not having any success and one of the ways for me to trouble shoot this is to determine which role I've been assigned.
With sts.GetCallerIdentity.
cli example (js link above):
aws --profile XXXXXXXX sts get-caller-identity
{
"UserId": "AIDAIXXXXXXXXTHOVLM",
"Account": "123456789098",
"Arn": "arn:aws:iam::123456789098:user/dan"
}
It is indeed frustrating to debug without this, and it didn't used to exist, but now it does. Hurrah!

Creating AWS IAM user access key specifically for SES

I'm tracking how to send an Email Using the AWS SDK for Python (Boto).
At the AWS Developer Guide using-credentials page I read that:
For security best practice, use AWS Identity and Access Management (IAM) user access keys instead of AWS account access keys [emphasis added].
Then at the Managing Access Keys for IAM Users I am eventually led to this section and I duly confirm using
aws iam list-access-keys
that I have just created (in JSON form):
{
"AccessKeyMetadata": [
{
"UserName": "My_User_Name",
"Status": "Active",
"CreateDate": "2018-09-03T00:43:37Z",
"AccessKeyId": "JRUFKDHUWHE8DD495CHD"
}
]
}
but I lack clarity about whether this identity is the "AWS account access keys" that I was earlier warned does not fall in the "security best practice".
How do I create an IAM identity (user access + password) for sending email through SES and boto (while eliminating the chance I am exposing the entire AWS account)?
Ranting (and a constructive suggestion to AWS staff writers, if here): Specific branding would help. At Ikea I might order a chair or a table with the meaningless name Fjorstuvstok, but I know with certainty that I am ordering the chair I want.
The AWS account access keys are the ones owned by the root account user. To check what these are, you need to know your root account user name. This can be checked using the aws cli using the AWS root credentials, or loging in with your root account credentials to the AWS Console and clicking "My Security Credentials" under your username in the top right corner.
Assuming you use the cli, make sure you've configured the root credentials in ~/.aws/credentials. Then run:
aws iam get-user
{
"User": {
"UserName": "my_root_user_name",
"PasswordLastUsed": "2018-09-03T06:40:38Z",
"CreateDate": "2017-03-01T08:53:36Z",
"UserId": "9XXXXXXXXXXX",
"Arn": "arn:aws:iam::9XXXXXXXXXXX:root"
}
}
This will provide you with details of your root user. This username can then be used to query for access keys:
aws iam list-access-keys --user-name my_root_user_name
If any of the keys listed from this result are being used for SES, then that's bad news. AWS reccomends that you use Access Keys assigned to IAM Users (non-root).
The AWS account access keys mean the Root account access /secret keys of your AWS account. When you register yourself with aws using your email, the account created is Root account. There is key associated with that, which needs to be removed. (As this is Root account, it provides unrestricted access to all AWS services. Check AWS Account Root User Credentials vs. IAM User Credentials
The warning suggested to use IAM user access keys. So you can create IAM user in your aws account and create associated access key id and secret access key and configure that on your machine from where you are running your code. ( This is not good practice in higher deployment environment. If the machine gets compromised then access key will be exposed)
As its unclear how you are running your application code (from ECS or EC2 or AWS Lambda), You should create IAM role to grant access to SES from where you are going to run your code. This will avoid exposing IAM access key Id and Secret access key from your application code / machine.

How to test credentials for AWS Command Line Tools

Is there a command/subcommand that can be passed to the aws utility that can 1) verify that the credentials in the ~/.aws/credentials file are valid, and 2) give some indication which user the credentials belong to? I'm looking for something generic that doesn't make any assumptions about the user having permissions to IAM or any specific service.
The use case for this is a deploy-time sanity check to make sure that the credentials are good. Ideally there would be some way to check the return value and abort the deploy if there are invalid credentials.
Use GetCallerIdentity:
aws sts get-caller-identity
Unlike other API/CLI calls it will always work, regardless of your IAM permissions.
You will get output in the following format:
{
"Account": "123456789012",
"UserId": "AR#####:#####",
"Arn": "arn:aws:sts::123456789012:assumed-role/role-name/role-session-name"
}
Exact ARN format will depend on the type of credentials, but often includes the name of the (human) user.
It uses the standard AWS CLI error codes giving 0 on success and 255 if you have no credentials.
There is a straightforward way - aws iam get-user would tell the details about who you are (the current IAM User) - provided the user has iam privileges.
There are couple of CLI calls which support --dry-run flag like aws ec2 run-instances which you tell you whether you have necessary config / cred to perform the operation.
There is also --auth-dry-run which Checks whether you have the required permissions for the command, without actually running the command. If you have the required permissions, the command returns DryRunOperation; otherwise, it returns UnauthorizedOperation. [ From AWS Documentation - Common Options ]
You would be able to list the IAM Access Keys from Management Console which you can cross check to see who has been assigned which key.
The best way to understand which user / role has what privileges is make use of IAM Policy Simulator.
I was in need of the same so I wrote aws-role
I also wanted that the command outputs session time remains before logout:
I used it in many shell scripts to automate my AWS use -- worked well for me.
my script parse ~/.aws/credentials
PS: also thinking to enhance it to support JSON output