How to delete / deactivate a rogue MFA device in AWS? - amazon-web-services

I introduced a policy that requires the users in a group to enable MFA. After enabling the policy I logged into an user account (user-foo) to try it out and apparently created a kind of a rogue MFA device when I aborted the setup of a virtual MFA device.
This led to the following error when the user tried to connect his MFA device:
Here is a list of the MFA devices. For comparison I added the output of user-bar with a correctly initialized MFA device.
$ aws iam list-virtual-mfa-devices
{
"VirtualMFADevices": [
{
"SerialNumber": "arn:aws:iam::123456789010:mfa/user-foo"
},
{
"SerialNumber": "arn:aws:iam::123456789010:mfa/user-bar",
"User": {
"Path": "/",
"UserName": "user-bar",
"UserId": "ABCDEFGHIJKLMNOPQRSTU",
"Arn": "arn:aws:iam::123456789010:user/user-bar",
"CreateDate": "2020-07-02T09:45:21Z",
"PasswordLastUsed": "2020-07-03T08:56:47Z"
},
"EnableDate": "2020-07-02T11:07:07Z"
}
]
}
As you can see, only the serial number for the MFA device of user-foo shows up. To delete the entry on the CLI also the user name is required. So I logged in as admin and assigned my phone as MFA device. Now the device showed up properly, but after deleting it with:
$ deactivate-mfa-device --user-name user-foo --serial-number arn:aws:iam::123456789010:mfa/user-foo
It appears again with its serial number without the user:
$ aws iam list-virtual-mfa-devices
{
"VirtualMFADevices": [
{
"SerialNumber": "arn:aws:iam::123456789010:mfa/user-foo"
},
[...]
]
}
Does anyone have an idea how to fix this?

Okay, pretty easy solution: It works if the MFA device is deleted in the console. For some reason this is not possible from the command line.

When you start the process and end it it creates that error and creates a disabled unassigned MFA device. Even though it has the user name in the arn, it is still assigned. It is possible to delete the MFA device from the command line.
aws iam delete-virtual-mfa-device --serial-number arn:aws:iam::123456789010:mfa/user-foo
If the device were enabled you would have to disable it prior to being able to delete it. The completion of setting up an MFA device needs to be done in one pass or will create this error.

Related

How to know user created in AWS has what access

I Have users created in AWS, but I am not able to locate if they have been only given programmatic access or console access or they have been provided with both.
is there a way to check , edit, or know what type of access is being used by a user.
In the console, you can see it in the Security Credentials Tab of the User in IAM:
If the list of Access keys is not empty and at least one entry is active, it means they have programmatic access.
From the CLI you can also get this information. Erik showed you the command to list the access keys for a user to check if they have programmatic access.
$ aws iam list-access-keys --user-name raspi --no-cli-pager
{
"AccessKeyMetadata": [
{
"UserName": "raspi",
"AccessKeyId": "AKIA2BFBC12345KHW4",
"Status": "Active",
"CreateDate": "2021-07-07T07:42:37+00:00"
}
]
}
To figure out if a user can log in to the console, you need to check if they have a login profile:
$ # This user can login
$ aws iam get-login-profile --user-name raspi --no-cli-pager
{
"LoginProfile": {
"UserName": "raspi",
"CreateDate": "2021-07-07T07:42:37+00:00",
"PasswordResetRequired": false
}
}
$ # This user can't login to the console
$ aws iam get-login-profile --user-name ses-demo-sender --no-cli-pager
An error occurred (NoSuchEntity) when calling the GetLoginProfile operation: Login Profile for User ses-demo-sender cannot be found.
You can check If a user has access keys. If a user has programatic access it needs access keys.
Here is a Cli command:
aws iam list-access-keys --user-name Bob

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.

Web Interface for AWS Cognito Identity Pool Not Saving Changes For Authenticated Provider Role Selection

In an identity pool in AWS Cognito I am trying to make users assume an IAM Role based on the group that they belong to in an user pool. Whenever I select Edit Identity Pool > Authentication Providers > "Choose Role From Token" and then click save changes, I get a banner at the top of my screen saying changes saved successfully, but if I go back and look at the settings they have returned to "Use Default Role" instead of "Choose Role From Token". Is this a bug, do I have something configured wrong where that is an invalid option, or another potential issue?
Here is an image of what settings I select and want to take effect
Here is the state that it currently is and what it returns to after I press save changes
AWS CLI Command for Setting Identity Pool Role with Option "Choose Role From Token"
aws cognito-identity set-identity-pool-roles --identity-pool-id "IDENTITY POOL ID" --roles authenticated="Auth IAM Role ARN",unauthenticated="UnAuth IAM Role ARN" --role-mappings cognito-idp.<<AWS REGION>>.amazonaws.com/<<USER POOL ID>>:<< APP CLIENT ID>>="{Type="Token", AmbiguousRoleResolution="Deny"}"
I am confident that this must be a bug with the AWS web console and not a fault of my own. After trouble shooting as much as I could, I set up the AWS CLI and ran the necessary commands from there and it worked on the first try. After revisiting the page in the AWS web console the changes were reflected properly and my authentication now works properly.
I had same problem with UI, thanks for this post, I tried the CLI.
identity_roles.json
{
"IdentityPoolId": "us-east-1:pool_id",
"Roles": {
"unauthenticated": "arn:aws:iam::account_id:role/UnAuthDefaultRole",
"authenticated": "arn:aws:iam::account_id:role/AuthDefaultRole"
},
"RoleMappings": {
"cognito-idp.us-east-1.amazonaws.com/user-pool-id:app-id": {
"Type": "Token",
"AmbiguousRoleResolution": "AuthenticatedRole"
}
}
}
aws cognito-identity get-identity-pool-roles --identity-pool-id us-east-1:identity_pool_id
aws cognito-identity set-identity-pool-roles --cli-input-json file://pwd/identity_roles.json

AWS Access keys without accessing the console

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.

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!