In many AWS environments, IAM users need the ability to manage their own access keys and upload SSH public keys for services like CodeCommit – without involving an administrator for every request. This guide covers creating an IAM policy for self-service key management, attaching it properly, and implementing security best practices. We also cover IAM Identity Center as the modern alternative to long-lived access keys.
Prerequisites
- An AWS account with IAM administrative access
- AWS CLI v2 installed and configured, or access to the AWS Management Console
- Basic understanding of IAM policies and JSON policy syntax
IAM Policy for Self-Service Access Key Management
The following policy allows IAM users to create, list, update, and delete their own access keys. It uses the ${aws:username} variable to scope permissions to the authenticated user only, preventing them from managing other users’ keys.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ManageOwnAccessKeys",
"Effect": "Allow",
"Action": [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:GetAccessKeyLastUsed",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "ViewAccountInfo",
"Effect": "Allow",
"Action": [
"iam:GetAccountSummary",
"iam:ListAccountAliases"
],
"Resource": "*"
}
]
}
The first statement grants key management actions scoped to the user’s own IAM path. The second statement provides read-only account information that the console needs to display the credentials page properly.
Create the Policy via AWS CLI
Save the above JSON to a file called self-manage-keys.json, then create the policy:
aws iam create-policy \
--policy-name SelfManageAccessKeys \
--policy-document file://self-manage-keys.json \
--description "Allows users to manage their own access keys"
Note the policy ARN from the output – you will need it to attach the policy.
Attach the Policy to a User or Group
Attaching to a group is the recommended approach, as it scales better than per-user attachments:
# Create a group (if it doesn't exist)
aws iam create-group --group-name Developers
# Attach the policy to the group
aws iam attach-group-policy \
--group-name Developers \
--policy-arn arn:aws:iam::123456789012:policy/SelfManageAccessKeys
# Add a user to the group
aws iam add-user-to-group --group-name Developers --user-name jdoe
To attach directly to a user instead:
aws iam attach-user-policy \
--user-name jdoe \
--policy-arn arn:aws:iam::123456789012:policy/SelfManageAccessKeys
Verify the policy is attached:
aws iam list-attached-group-policies --group-name Developers
SSH Public Key Upload for CodeCommit
AWS CodeCommit uses SSH keys associated with IAM users for Git authentication. Users need permission to upload and manage their own SSH public keys.
Add these actions to the policy (or create a separate policy):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ManageOwnSSHKeys",
"Effect": "Allow",
"Action": [
"iam:UploadSSHPublicKey",
"iam:DeleteSSHPublicKey",
"iam:GetSSHPublicKey",
"iam:ListSSHPublicKeys",
"iam:UpdateSSHPublicKey"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
}
]
}
Once the policy is in place, users can upload their SSH key through the CLI:
aws iam upload-ssh-public-key \
--user-name jdoe \
--ssh-public-key-body file://~/.ssh/id_rsa.pub
Or through the console: navigate to IAM – Users – select the user – Security credentials tab – SSH keys for AWS CodeCommit – Upload SSH public key.
The output includes an SSHPublicKeyId which the user will use as their SSH username when connecting to CodeCommit. Verify by listing uploaded keys:
aws iam list-ssh-public-keys --user-name jdoe
Combined Policy: Access Keys and SSH Keys
For convenience, here is a combined policy that covers both access key management and SSH key management in a single document:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ManageOwnAccessKeys",
"Effect": "Allow",
"Action": [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:GetAccessKeyLastUsed",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "ManageOwnSSHKeys",
"Effect": "Allow",
"Action": [
"iam:UploadSSHPublicKey",
"iam:DeleteSSHPublicKey",
"iam:GetSSHPublicKey",
"iam:ListSSHPublicKeys",
"iam:UpdateSSHPublicKey"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "ViewAccountInfo",
"Effect": "Allow",
"Action": [
"iam:GetAccountSummary",
"iam:ListAccountAliases",
"iam:GetLoginProfile",
"iam:ListMFADevices"
],
"Resource": "*"
}
]
}
IAM Identity Center (SSO) as a Modern Alternative
Long-lived IAM access keys are a security liability. AWS IAM Identity Center (formerly AWS SSO) is the recommended approach for most organizations. Instead of permanent keys, users authenticate through a central portal and receive temporary credentials that expire automatically.
Why IAM Identity Center is Better
- Temporary credentials – Session tokens expire after a configurable period (default 1 hour, up to 12 hours). No permanent keys to leak or forget about.
- Centralized access – Manage access to multiple AWS accounts from one place. Users see a portal listing all accounts and roles they can assume.
- Integration with identity providers – Connect to Active Directory, Okta, Azure AD, or any SAML 2.0 provider. Users authenticate with their existing corporate credentials.
- MFA enforcement – Require multi-factor authentication at the identity provider level.
- Audit trail – All access is logged in CloudTrail with the federated user identity.
Using IAM Identity Center with the AWS CLI
Configure SSO in the AWS CLI:
aws configure sso
# Follow the prompts to set:
# SSO session name
# SSO start URL (your Identity Center portal URL)
# SSO Region
# SSO registration scopes
After configuration, log in:
aws sso login --profile my-sso-profile
This opens a browser for authentication. Once authenticated, the CLI receives temporary credentials automatically. You can then run any AWS command using the SSO profile:
aws s3 ls --profile my-sso-profile
Security Best Practices
Whether you use IAM access keys or Identity Center, follow these practices to keep your AWS environment secure.
Rotate Access Keys Regularly
AWS recommends rotating access keys every 90 days. Check the age of existing keys:
aws iam list-access-keys --user-name jdoe --query 'AccessKeyMetadata[*].{KeyId:AccessKeyId,Created:CreateDate,Status:Status}'
The rotation process: create a new key, update all applications that use the old key, verify everything works with the new key, then deactivate and delete the old key:
# Create new key
aws iam create-access-key --user-name jdoe
# After updating applications, deactivate the old key
aws iam update-access-key --user-name jdoe --access-key-id AKIAIOSFODNN7OLD --status Inactive
# After confirming nothing breaks, delete it
aws iam delete-access-key --user-name jdoe --access-key-id AKIAIOSFODNN7OLD
Use IAM Roles Instead of Keys Where Possible
EC2 instances, Lambda functions, ECS tasks, and other AWS services should use IAM roles rather than access keys. Roles provide temporary credentials that rotate automatically:
- Attach an instance profile to EC2 instances instead of storing keys in
~/.aws/credentials. - Use execution roles for Lambda functions.
- Use task roles for ECS containers.
Enforce MFA for Sensitive Actions
Add an MFA condition to the self-service policy if you want to require MFA before users can create or delete keys:
{
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
Add this condition block to the statements that grant CreateAccessKey and DeleteAccessKey.
Monitor Key Usage
Use the credential report to find unused or old keys across all IAM users:
aws iam generate-credential-report
aws iam get-credential-report --query 'Content' --output text | base64 --decode
The report includes the last time each access key was used and the last time the key was rotated. Keys that have not been used in 90+ days should be investigated and likely deactivated.
You can also check individual key usage:
aws iam get-access-key-last-used --access-key-id AKIAIOSFODNN7EXAMPLE
Conclusion
Giving IAM users self-service access to their own keys reduces administrative overhead while keeping things secure through scoped policies. The ${aws:username} variable is the key ingredient – it ensures users can only touch their own credentials. For CodeCommit, adding SSH key management actions to the same policy gives developers everything they need. That said, if you are starting fresh or planning a security improvement, IAM Identity Center with temporary credentials is the stronger path. It eliminates the risk of leaked long-lived keys and simplifies access management across multiple accounts.