Identity and Access Management
https://docs.aws.amazon.com/iam/index.html
FAQs: https://aws.amazon.com/iam/faqs/
Security best practices in IAM - https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html
Enable IAM Access Analyzer
See some use cases at Security best practices in IAM
It can generate policies - see below
Note that this is a paid service.
A vault for securely storing and accessing AWS credentials in development environments - https://github.com/99designs/aws-vault
Cloudsplaining is an AWS IAM Security Assessment tool that identifies violations of least privilege and generates a risk-prioritized report - https://github.com/salesforce/cloudsplaining
A tool for quickly evaluating IAM permissions in AWS - https://github.com/nccgroup/PMapper
Refining permissions in AWS using last accessed information - https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html
AWS Vault - https://github.com/99designs/aws-vault - Stores IAM credentials in your operating system's secure keystore
IAM is a global service. Notice you cannot select any region at the top-right dropdown. Any user, group, role etc. can be used on all regions, all around the world.
Summary
- User: an individual, system or application running outside of AWS requiring access to AWS services.
- Group: collection of users with the same permissions. A user can be in many groups.
- Role: set of permissions. Used to authenticate AWS entities such as EC2 instances.
- Policy: JSON file. Permissions assigned to a user, group or role.
- Principal: user, account, service, or other entity that is allowed or denied access to a resource. Can be (source):
- AWS account and root user
- IAM roles
- Role sessions
- IAM users
- Federated user sessions
- AWS services
- All principals
Nice summary - https://blog.awsfundamentals.com/aws-iam-roles-terms-concepts-and-examples
Cheatsheet - https://digitalcloud.training/aws-iam/
User
By default users have no permissions, thus they can't do anything. You give them permissions using groups and policies.
Each user has a username (Account name), used to log in.
Authentication options:
- Web console: username and password + optionally MFA.
- To log in at the console use the URL
https:/ /$accountId.signin.aws.amazon.com/console
orhttps:/ /$accountAlias.signin.aws.amazon.com/console
. Useaws sts get-caller-identity
to get the account ID.
- To log in at the console use the URL
- CLI & API: access key ID and secret access key. You can also have MFA too.
- Only a user can have access keys (not a group, role or policy).
- Best practice: use roles for applications that run on EC2 instances or lambda functions. See Require workloads to use temporary credentials with IAM roles to access AWS
You should set up a unique IAM user for every person who needs access to the AWS account, and grant access only to the resources each person needs, following the least-privilege principle.
Service account
An IAM user for a service or application.
IAM roles for service accounts provide the ability to manage credentials for your applications, similar to the way that Amazon EC2 instance profiles provide credentials to Amazon EC2 instances. source
Group
A collection of users with the same permissions.
A way of organizing users and applying permissions to them through a policy.
A user can be a member of zero, one or multiple groups.
Is not an identity, thus it cannot be used at the a Principal
field of a policy. See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html:
You cannot identify a user group as a principal in a policy (such as a resource-based policy) because groups relate to permissions, not authentication, and principals are authenticated IAM entities.
Role
A way to delegate permissions without using permanent credentials. Is an identity. Roles are assumed by users, applications and services (the trusted entities).
When you assume a role you loose any other permissions. Eg if you are an admin but you assume a role, you loose the admin permissions. Thus, the permissions assigned to a role need to include everything required to complete the task.
- Is an AWS identity with permissions that determine what can and can't do.
- Can be assigned an identity policy for permissions.
- Users, applications and services can assume roles.
- Does not have long term credentials/passwords/access keys. Instead, if a user is assigned a role, access keys are created dynamically and provided to the user temporarily.
- Can be used to delegate access to users, applications or services that don't normally have access to your AWS resources.
- A user who assumes a role temporarily gives up his other own permissions and instead takes on the permissions of the role.
- Eg we can give an EC2 instance a IAM role to temporarily access a S3 bucket using an instance profile.
- Roles remove the need to modify a user's policy each time a change is required.
https://stackoverflow.com/questions/46199680/difference-between-iam-role-and-iam-user-in-aws
We recommend using IAM roles for human users and workloads that access your AWS resources so that they use temporary credentials (instead of IAM users) source
A role is an identity in AWS that doesn't have its own credentials (as a user does) source
Root vs User vs Role
From AWS in Action, page 144.
Root user | User | Role | |
---|---|---|---|
Can have a password to log in to the web console | Must | Yes | No |
Can have access keys to send requests to the API with the CLI or SDKs | Yes, but not recommended | Yes | No |
Can belong to a group | No | Yes | No |
Can be associated with an EC2 instance, Lambda function, ECS container | No | No | Yes |
By default, users and roles can't do anything. You need an identity policy to allow them to perform actions. Users and roles use identity policies.
sts:AssumeRole
The API call used to assume a role.
On a trust policy the Action
is sts:AssumeRole
.
https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/assume-role.html
https://stackoverflow.com/questions/63241009/aws-sts-assume-role-in-one-command
EC2 instance profile
Never copy a user’s access keys to an EC2 instance; use IAM roles instead!
Whenever you need to authenticate AWS resources like EC2 instancesI, instead of using an IAM user for authentication, you should use an IAM role. When using an IAM role, your access keys are injected into your EC2 instance automatically.
(AWS in Action p. 148)
A way to attach a role to an EC2 instance, for example to access other services like S3.
If you want to connect to an EC2 instance using Session Manager, you need to attach an instance profile role with the permission policy AmazonSSMManagedInstanceCore
to the EC2 instance.
In addition to the permission policies, the role needs a trust policy with sts:AssumeRole
to allow the EC2 instance to assume the role.
To create an instance profile role do:
- Go to IAM → Roles, and click 'Create role'.
- At the 'Trusted entity type' choose 'AWS service', and at the 'Use case' drop-down list select EC2 (under 'Commonly used services'). This is the trust policy.
- Click 'Next' and select the Permissions policies.
Once the role is created, you can see the trust policy at the role's 'Trust relationship' tab, where the trusted entities is:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
The permissions policy (an inline identity policy) can be anything. For example, if we've given S3 read access with AmazonS3ReadOnlyAccess
, it will be:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*",
"s3:Describe*",
"s3-object-lambda:Get*",
"s3-object-lambda:List*"
],
"Resource": "* "
}
]
}
To attach the role to the EC2 instance, when creating an instance, select the role at the 'IAM instance profile' dropdown. And if the instance is already running, go to the EC2 console → Instances, open the instance, and on the Actions drop-down menu (top right) do Security → Modify IAM role. Select the role and click 'Update IAM role'.
Policy
JSON file. Permissions assigned to a user, group or role.
{
"Sid": "AllowManageOwnSSHPublicKeys", // Who/what is authorized
"Effect": "Allow", // Or "Deny"
"Action": [
// Which task(s) are allowed/denied. It's an API action
"iam:GetSSHPublicKey",
"iam:ListSSHPublicKeys"
],
"Condition": {
// Which condition(s) need to be met for authorization
},
// Resources to which authorized tasks are performed. An ARN or *
"Resource": "arn:aws:iam::*:user/${aws:username}"
}
List of all Action
s available for a service: Actions, resources, and condition keys for AWS services
. You need to click on a service.
Not all API operations that are defined by a service can be used as an action in an IAM policy. Some services include permission-only actions that don't directly correspond to an API operation. These actions are indicated with [permission only]. Use this list to determine which actions you can use in an IAM policy.
Console: https://console.aws.amazon.com/iamv2/home?#/policies
Policy Simulator: https://policysim.aws.amazon.com
Policy types - https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#access_policy-types
AWS managed policies - https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies
AWS IAM Policies in a Nutshell - https://start.jcolemorrison.com/aws-iam-policies-in-a-nutshell/
AWS IAM policy linting library - https://github.com/duo-labs/parliament
EAR
A policy needs to have an EAR to listen what is going to do: Effect, Action and Resource.
Allow and Deny
All permissions are implicitly denied by default. Thus, nothing is allowed unless there's an explicit Allow.
Any explicit Deny overrides any explicit Allows. Thus, if there's multiple policies with conflicting statements, the most restrictive policy is applied.
Note that the root user has full access.
See 'Policy evaluation logic' - https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html
Examples
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html
AdministratorAccess policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
Allows all actions on all resources.
Deny operations to resource if it's not authenticated using MFA
For an S3 bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"Null": {
"aws:MultiFactorAuthAge": "true"
}
}
}
]
}
More specific:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::238267638199:user/Albert"
},
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"],
"Condition": {
"Null": {
"aws:MultiFactorAuthAge": "true"
}
}
}
]
}
Permissions policy and trust policy (role)
See https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/
Trust policy: who
Permissions policy: what
Permissions policy
Defines the permissions (Allow or Deny) that the user of the role is able to perform (or is denied from performing), and on which resources. Is an identity-based policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:Describe*",
"Resource": "*"
}
]
}
Trust policy
Who is allowed to assume the role, and under which conditions. Is a resource-based policy.
The IAM service supports only one type of resource-based policy called a role trust policy, which is attached to an IAM role. source
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "sts:AssumeRole"
}
]
}
For example to allow the S3 service to replicate two buckets we create a Role with this custom trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Identity-based vs resource-based policy
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_identity-vs-resource.html
Identity-based policy
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_id-based
Examples: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html
Attached to users, groups and roles (permissions policy). Can be attached in various ways:
- Inline policy: a policy that only applies to single, specific user, group or role. It cannot be reused. If you delete the user, the policy is also deleted.
- An EC2 instance profile role is an inline identity policy. See AWS in Action p. 149.
- Managed policy: either created by you (customer managed) or AWS (AWS managed). Can be reused (standalone, it can be applied to multiple entities).
With CloudFormation, it’s easy to maintain inline identity policies; that’s why we use inline identity policies most of the time in this book. (AWS in Action p. 147)
Using managed policies can often conflict with following the least-privilege principal. Managed policies usually set the Resource
property to *
. That’s why we attach our own inline policies to IAM roles or users.
(AWS in Action p. 147)
Does not have a Principal
.
Example: Allows access to a specific DynamoDB table (source)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListAndDescribe",
"Effect": "Allow",
"Action": [
"dynamodb:List*",
"dynamodb:DescribeReservedCapacity*",
"dynamodb:DescribeLimits",
"dynamodb:DescribeTimeToLive"
],
"Resource": "*"
},
{
"Sid": "SpecificTable",
"Effect": "Allow",
"Action": [
"dynamodb:BatchGet*",
"dynamodb:DescribeStream",
"dynamodb:DescribeTable",
"dynamodb:Get*",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchWrite*",
"dynamodb:CreateTable",
"dynamodb:Delete*",
"dynamodb:Update*",
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/MyTable"
}
]
}
Resource-based policy
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_resource-based
Attached to a resource like an S3 bucket, a DynamoDB table or a SQS queue. Defines permissions for a principal accessing the resource.
Resource-based policies are inline policies. There are no managed resource-based policies. source
If a policy has a Principal
, it is a resource policy.
On the JSON there's a Principal
which defines who gets permission to perform the Action
to a specific Resource
only.
Not all resources support resource-based policies, only a few of them do, see the table at https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html.
Example (source):
{
"Version": "2012-10-17",
"Id": "BucketPolicy",
"Statement": [
{
"Sid": "AllAccess",
"Action": "s3:*",
"Effect": "Allow",
"Principal": "*", // Who is allowed to perform the action
"Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"]
}
]
}
Can be applied to a role too: a trust policy.
Note that when the Action applies to an object, like s3:GetObject
, the Resource needs to have /*
appended, otherwise the permission applies to the S3 bucket and it doesn't work:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublicAccessToS3Objects",
"Principal": "*",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-static-website-bucket/*" // <- We need '/*' here!
}
]
}
Session policy
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
Limit the permissions of a role when you use the STS AssumeRole action using the CLI or API.
A session policy is a permissions policy which you can optionally pass during an AssumeRole operation. This enables you to place further restrictions on a role's permissions for that session. source