AWS Identity and Access Management (IAM) controls who can access what in your AWS account. It handles authentication (who you are) and authorization (what you can do) for every API call, console login, and CLI operation across all AWS services. For production AWS environments, properly configured IAM users, groups, and policies are the foundation of your security posture.
This guide walks through managing AWS IAM users and groups entirely from the command line using the AWS CLI. We cover creating users, generating access keys, building groups with policy attachments, custom policies, password policies, MFA, auditing, and cleanup. Everything here works on any system with a configured AWS CLI – Linux, macOS, or Windows.
Prerequisites
Before starting, make sure you have the following in place:
- AWS CLI v2 installed and configured with credentials that have IAM administrative permissions. If you haven’t set it up yet, follow our guide on installing and using AWS CLI on Linux
- An AWS account with permissions to manage IAM resources (the
IAMFullAccessmanaged policy or equivalent) - Basic familiarity with JSON policy documents
Confirm your CLI is working and has IAM access:
aws sts get-caller-identity
This returns your account ID, user ARN, and user ID – confirming authentication is working:
{
"UserId": "AIDACKCEVSQ6C2EXAMPLE",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/admin"
}
Step 1: Create an IAM User
IAM users represent individual people or applications that interact with AWS. Each user gets unique credentials and can have permissions assigned directly or through group membership.
Create a new IAM user:
aws iam create-user --user-name developer01
AWS returns the new user’s details including the ARN and creation timestamp:
{
"User": {
"Path": "/",
"UserName": "developer01",
"UserId": "AIDACKCEVSQ6C2EXAMPLE",
"Arn": "arn:aws:iam::123456789012:user/developer01",
"CreateDate": "2026-03-22T10:15:30+00:00"
}
}
To create a user with a specific path (useful for organizing users by department or team):
aws iam create-user --user-name analyst01 --path /data-team/
If you need the user to access the AWS Management Console, create a login profile with a password:
aws iam create-login-profile --user-name developer01 --password 'TempP@ss2026!' --password-reset-required
The --password-reset-required flag forces the user to set a new password on first login – always use this for security.
Step 2: Create Access Keys for Programmatic Access
Access keys (an access key ID and secret access key pair) allow users to make API calls and use the AWS CLI. Each user can have up to two active access keys, which supports key rotation without downtime.
Generate an access key pair for the user:
aws iam create-access-key --user-name developer01
The output includes the secret access key – this is the only time it’s shown, so save it securely:
{
"AccessKey": {
"UserName": "developer01",
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"Status": "Active",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"CreateDate": "2026-03-22T10:20:00+00:00"
}
}
To list existing access keys for a user:
aws iam list-access-keys --user-name developer01
To deactivate an old key during rotation (before deleting it):
aws iam update-access-key --user-name developer01 --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive
For more details on managing access keys and SSH public keys, see our guide on allowing IAM users to create access keys and upload SSH public keys.
Step 3: Create IAM Groups
IAM groups let you manage permissions for multiple users at once. Instead of attaching policies to each user individually, attach them to a group and add users to it. When someone changes roles, move them to a different group rather than editing individual permissions.
Create groups for different teams or permission levels:
aws iam create-group --group-name Developers
AWS confirms the group creation with the group’s ARN:
{
"Group": {
"Path": "/",
"GroupName": "Developers",
"GroupId": "AGPACKCEVSQ6C2EXAMPLE",
"Arn": "arn:aws:iam::123456789012:group/Developers",
"CreateDate": "2026-03-22T10:25:00+00:00"
}
}
Create a few more groups to match typical team structures:
aws iam create-group --group-name DevOps
aws iam create-group --group-name ReadOnlyUsers
aws iam create-group --group-name DBAdmins
Verify the groups were created:
aws iam list-groups --query 'Groups[*].[GroupName,Arn]' --output table
The output lists all groups in your account with their ARNs:
---------------------------------------------------------------------
| ListGroups |
+----------------+--------------------------------------------------+
| DBAdmins | arn:aws:iam::123456789012:group/DBAdmins |
| Developers | arn:aws:iam::123456789012:group/Developers |
| DevOps | arn:aws:iam::123456789012:group/DevOps |
| ReadOnlyUsers | arn:aws:iam::123456789012:group/ReadOnlyUsers |
+----------------+--------------------------------------------------+
Step 4: Add Users to Groups
Once groups exist, add users to them. A user can belong to multiple groups, and their effective permissions are the union of all group policies plus any directly attached policies.
Add the developer user to the Developers group:
aws iam add-user-to-group --user-name developer01 --group-name Developers
This command produces no output on success. Verify the membership:
aws iam get-group --group-name Developers --query 'Users[*].UserName'
You should see the user listed in the group:
[
"developer01"
]
To check which groups a specific user belongs to:
aws iam list-groups-for-user --user-name developer01 --query 'Groups[*].GroupName'
To remove a user from a group:
aws iam remove-user-from-group --user-name developer01 --group-name Developers
Step 5: Attach Policies to Groups
AWS managed policies are pre-built permission sets maintained by AWS. They cover common use cases and are updated automatically when new services launch. Attaching policies to groups (not individual users) is the recommended approach.
Give the Developers group permission to work with EC2, S3, and CloudWatch:
aws iam attach-group-policy --group-name Developers --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess
aws iam attach-group-policy --group-name Developers --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
aws iam attach-group-policy --group-name Developers --policy-arn arn:aws:iam::aws:policy/CloudWatchFullAccess
Give the ReadOnlyUsers group view-only access across all services:
aws iam attach-group-policy --group-name ReadOnlyUsers --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
Give the DevOps group broader administrative access:
aws iam attach-group-policy --group-name DevOps --policy-arn arn:aws:iam::aws:policy/PowerUserAccess
List the policies attached to a group to confirm:
aws iam list-attached-group-policies --group-name Developers
The output shows each attached policy with its ARN:
{
"AttachedPolicies": [
{
"PolicyName": "AmazonEC2FullAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
},
{
"PolicyName": "AmazonS3FullAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonS3FullAccess"
},
{
"PolicyName": "CloudWatchFullAccess",
"PolicyArn": "arn:aws:iam::aws:policy/CloudWatchFullAccess"
}
]
}
Step 6: Create a Custom IAM Policy
AWS managed policies cover broad use cases, but production environments usually need custom policies that follow the principle of least privilege – granting only the exact permissions required for a specific task.
Create a policy file that allows read-only access to a specific S3 bucket and its objects:
vi /tmp/s3-readonly-policy.json
Add the following policy document:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3BucketListing",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::my-app-data-bucket"
},
{
"Sid": "AllowS3ObjectRead",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::my-app-data-bucket/*"
}
]
}
Create the policy in IAM:
aws iam create-policy --policy-name S3ReadOnlyAppData --policy-document file:///tmp/s3-readonly-policy.json --description "Read-only access to the my-app-data-bucket S3 bucket"
AWS returns the policy ARN, which you need for attaching it to groups or users:
{
"Policy": {
"PolicyName": "S3ReadOnlyAppData",
"PolicyId": "ANPACKCEVSQ6C2EXAMPLE",
"Arn": "arn:aws:iam::123456789012:policy/S3ReadOnlyAppData",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"CreateDate": "2026-03-22T10:35:00+00:00"
}
}
Attach the custom policy to a group:
aws iam attach-group-policy --group-name Developers --policy-arn arn:aws:iam::123456789012:policy/S3ReadOnlyAppData
To update an existing custom policy, create a new version and set it as default:
aws iam create-policy-version --policy-arn arn:aws:iam::123456789012:policy/S3ReadOnlyAppData --policy-document file:///tmp/s3-readonly-policy-v2.json --set-as-default
Each policy can have up to 5 versions. If you hit the limit, delete an old version first with aws iam delete-policy-version.
Step 7: Configure Account Password Policy
The account password policy applies to all IAM users with console access. Setting a strong policy prevents weak passwords across your organization. If you manage infrastructure with tools like Terraform for EKS deployments or Ansible for AWS automation, the IAM users driving those tools still need proper password policies for any console access.
Set a password policy with industry-standard requirements:
aws iam update-account-password-policy \
--minimum-password-length 14 \
--require-symbols \
--require-numbers \
--require-uppercase-characters \
--require-lowercase-characters \
--allow-users-to-change-password \
--max-password-age 90 \
--password-reuse-prevention 12 \
--hard-expiry
This enforces 14-character passwords with mixed character types, forces rotation every 90 days, prevents reusing the last 12 passwords, and locks the account (rather than prompting a reset) when passwords expire.
Verify the active policy:
aws iam get-account-password-policy
The output confirms all the settings are applied:
{
"PasswordPolicy": {
"MinimumPasswordLength": 14,
"RequireSymbols": true,
"RequireNumbers": true,
"RequireUppercaseCharacters": true,
"RequireLowercaseCharacters": true,
"AllowUsersToChangePassword": true,
"ExpirePasswords": true,
"MaxPasswordAge": 90,
"PasswordReusePrevention": 12,
"HardExpiry": true
}
}
Step 8: Enable MFA for IAM Users
Multi-factor authentication adds a second layer of security beyond passwords. Every IAM user with console access should have MFA enabled – this is a baseline security requirement for any production AWS account.
Create a virtual MFA device for the user:
aws iam create-virtual-mfa-device --virtual-mfa-device-name developer01-mfa --outfile /tmp/developer01-qr.png --bootstrap-method QRCodePNG
This generates a QR code PNG file that the user scans with their authenticator app (Google Authenticator, Authy, etc.). The command returns the MFA device serial number:
{
"VirtualMFADevice": {
"SerialNumber": "arn:aws:iam::123456789012:mfa/developer01-mfa"
}
}
After the user scans the QR code, they provide two consecutive codes from their authenticator app. Use those codes to activate the device:
aws iam enable-mfa-device \
--user-name developer01 \
--serial-number arn:aws:iam::123456789012:mfa/developer01-mfa \
--authentication-code1 123456 \
--authentication-code2 789012
Replace 123456 and 789012 with the two consecutive codes from the authenticator app. The codes must be generated 30 seconds apart.
Verify MFA is enabled for the user:
aws iam list-mfa-devices --user-name developer01
The output confirms the MFA device is attached and when it was enabled:
{
"MFADevices": [
{
"UserName": "developer01",
"SerialNumber": "arn:aws:iam::123456789012:mfa/developer01-mfa",
"EnableDate": "2026-03-22T10:45:00+00:00"
}
]
}
Step 9: List and Audit IAM Resources
Regular IAM auditing catches stale users, unused access keys, and overly permissive policies. These commands give you a quick overview of your IAM landscape.
List all IAM users in the account:
aws iam list-users --query 'Users[*].[UserName,CreateDate]' --output table
List all groups with their member count:
aws iam list-groups --query 'Groups[*].GroupName' --output table
Generate a full credentials report that shows password age, MFA status, and access key usage for every user:
aws iam generate-credential-report
Wait a few seconds for the report to generate, then download it:
aws iam get-credential-report --query 'Content' --output text | base64 --decode > /tmp/iam-credential-report.csv
The CSV file contains columns for each user including password_enabled, mfa_active, access_key_1_active, access_key_1_last_used_date, and more. Review this regularly to identify accounts that should be deactivated.
Find access keys that haven’t been used in over 90 days:
aws iam list-users --query 'Users[*].UserName' --output text | tr '\t' '\n' | while read user; do
aws iam list-access-keys --user-name "$user" --query 'AccessKeyMetadata[*].[UserName,AccessKeyId,Status,CreateDate]' --output text
done
Check the last used date for a specific access key:
aws iam get-access-key-last-used --access-key-id AKIAIOSFODNN7EXAMPLE
For CloudFormation-based infrastructure, validating your templates with tools like cfn-lint and cfn-nag helps catch IAM policy issues before deployment.
Step 10: Delete IAM Users and Groups
When employees leave or service accounts are retired, clean up their IAM resources completely. AWS requires removing all attached items before deleting a user or group.
To delete a user, first remove their dependencies in order:
aws iam delete-login-profile --user-name developer01
Delete any access keys the user has:
aws iam delete-access-key --user-name developer01 --access-key-id AKIAIOSFODNN7EXAMPLE
Deactivate and delete the MFA device:
aws iam deactivate-mfa-device --user-name developer01 --serial-number arn:aws:iam::123456789012:mfa/developer01-mfa
aws iam delete-virtual-mfa-device --serial-number arn:aws:iam::123456789012:mfa/developer01-mfa
Remove the user from all groups:
aws iam remove-user-from-group --user-name developer01 --group-name Developers
Detach any directly attached policies:
aws iam list-attached-user-policies --user-name developer01 --query 'AttachedPolicies[*].PolicyArn' --output text | tr '\t' '\n' | while read arn; do
aws iam detach-user-policy --user-name developer01 --policy-arn "$arn"
done
Now delete the user:
aws iam delete-user --user-name developer01
To delete a group, first detach all policies and remove all members:
aws iam list-attached-group-policies --group-name Developers --query 'AttachedPolicies[*].PolicyArn' --output text | tr '\t' '\n' | while read arn; do
aws iam detach-group-policy --group-name Developers --policy-arn "$arn"
done
Then delete the empty group:
aws iam delete-group --group-name Developers
AWS IAM CLI Command Reference
This table summarizes the most frequently used IAM CLI commands for quick reference.
| Command | Description |
|---|---|
aws iam create-user | Create a new IAM user |
aws iam delete-user | Delete an IAM user (remove dependencies first) |
aws iam create-login-profile | Set a console password for a user |
aws iam create-access-key | Generate access key pair for programmatic access |
aws iam delete-access-key | Delete an access key pair |
aws iam create-group | Create a new IAM group |
aws iam delete-group | Delete an IAM group (detach policies first) |
aws iam add-user-to-group | Add a user to a group |
aws iam remove-user-from-group | Remove a user from a group |
aws iam attach-group-policy | Attach a managed policy to a group |
aws iam detach-group-policy | Detach a managed policy from a group |
aws iam create-policy | Create a custom IAM policy from JSON |
aws iam list-users | List all IAM users in the account |
aws iam list-groups | List all IAM groups in the account |
aws iam get-group | Show group details and members |
aws iam generate-credential-report | Generate a CSV report of all credentials |
aws iam enable-mfa-device | Activate a virtual MFA device for a user |
aws iam update-account-password-policy | Set account-wide password requirements |
Conclusion
You now have a complete workflow for managing AWS IAM users and groups from the CLI – creating users, issuing credentials, organizing permissions through groups, writing custom least-privilege policies, enforcing password standards, and enabling MFA. These commands handle the full lifecycle from onboarding to offboarding.
For production accounts, enforce MFA on all human users, rotate access keys on a 90-day schedule, run credential reports weekly to catch unused accounts, and prefer group-based policies over direct user attachments. Consider enabling AWS CloudTrail to log every IAM API call for audit trails.