IAM is used any time you want to access a service like EC2, DynamoDB or S3. IAM building blocks are;
- IAM User
- IAM Role
- IAM Group
- IAM Policy
API / CLI access is through key & secret: AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Action": "*"
"Resource": "*"
aws iam list-users will give us user arn.
Console access is through username / password with optional MFA
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Action": "*"
"Resource": "*"
"Condition":
"Bool":
"aws:MultiFactorAuthPresent": "true"
Now we need to use AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY to get a session token (which has an expiration date)
aws sts get-session-token –serial-number arn:aws:iam::007:mfa/AdminUser –token-code 007007
which will return AWS_SESSION_TOKEN and a new set of AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY. With these temporary credentials we can request,
aws iam list-users
Servers can be whitelisted through specifying their ip to whitelist
Console access is through username / password with optional MFA
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Action": "s3:*Object"
"Resource": "*"
"Condition":
"IpAddress":
"aws:SourceIp":
- "1.2.3.4/32"
Now server with ip 1.2.3.4 can do anything to s3 objects on any resource
IAM Users
- can have long lived credentials
- can be external users and systems
- may have optional security like mfa or conditions (mfa enabled & ip whitelisting)
It would be very bad idea to take AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY and store them in EC2 instance.
IAM Role
- are used by native resources (EC2 instance, RDS instance, CodeBuild, CloudFormation)
- resources assume role
- role has policies attached
1. EC2 instance will assume an IAM role, IAM role has policy attached to it
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Action": "s3:*Object"
"Resource": "*"
2. IAM Role will return temporary credentials to EC2 instance
3. Then EC2 instance can use these temporary credentials to access resource (S3)
EC2 instance has security credentials automatically which are rotated every few hours.
curl http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
aws sts get-caller-identity
IAM Role Trust Policies
Users can also have escalated priviledges through assume role.
An IAM user assumes IAM Role
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Action": "sts:AssumeRole"
"Resource": "*"
which has Policy that allow access to bucket
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Action":
- "s3:*"
"Resource":
- "arn:aws:s3:::my-bucket-iam"
- "arn:aws:s3:::my-bucket-iam/*"
IAM Role returns temporary credentials, where IAM user can access to corresponding S3
We are able to do that because the role has the following trust policy
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Principal":
"AWS": "arn:aws:iam::007:root"
"Action": "sts:AssumeRole"
"Resource": "*"
any iam user or role in this account is allowed to use assume this role, so EC2 instance and IAM user are both allowed to assume this role. As comparison, the following policy only allows EC2 instances to assume the role
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Principal":
"Service": "ec2.amazon.com"
"Action": "sts:AssumeRole"
"Resource": "*"
any IAM user will get access denied when they try
aws sts assume-role –role-arn arn:aws:iam:007:role/ec2-iam-ss-role –role-session-name elevated
IAM Role Trust Policy
- defines who is trusted to assume the role
- does not grant an explicit allow
IAM Federation
Used by OpenID Connect identity providers
Used by external directories with SAML 2.0
How it works
1. My device will login to amazon / facebook / twitter / active directory
2. My device will request AssumeRole WithWebIdentity from AWS STS. AWS sts that has policy
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Action":
- "s3:*"
"Resource":
- "arn:aws:s3:::my-bucket-iam"
- "arn:aws:s3:::my-bucket-iam/*"
3. AWS STS will provide temporary credentials for the role.
4. Now device can access to corresponding resource (S3)
The trust policy has to be defined that says external resources are allowed to assume this role.
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Principal":
"Federated": "www.amazon.com"
"Action": "sts:AssumeRoleWithWebIdentity"
"Condition":
"StringEquals":
"www.amazon.com:app_id": "amzn1.app.007"
"Resource": "*"
any app with name can use this trust policy.
IAM Role
- is used by AWS resources
- can be used for federation
- provides temporary credentials
- trust policies define who is allowed to assume the role.
IAM Users |
IAM Roles |
Stored credentials |
Generated credentials |
Long term credentials |
Temporary credentials |
External systems and users |
AWS resources and federation |
Less secure |
More secure |
MFA optional |
|
IAM Policies
Defines what Users and Roles can specifically do. They can be applied to Users, roles and Groups. Policies can be Inline or Managed policies.
Inline Policies are attached directly to users or groups. Managed policies are separate entities and can be attached to more than one User, Role or Groups. This allows policy reusability.
API / CLI access is through key & secret: AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY
In figure, User A will have access to EC2, DynamoDB and S3, but User B will only have group policy, access to s3.
If a User does not have a policy, or only have empty policy, it will have DENY. To do anything with service, we need explicit ALLOW. There can be managed group policy which is allowing corresponding resource usage. In IAM policy, explicit DENY has higher priority then explicit ALLOW.
Permission boundaries for users and roles
- They define the maximum allowed permissions
- If a permission boundary is enabled, only explicitly allowed actions are permitted, and denied actions are denied
- Permission boundaries never grant permissions
Permission boundaries enforce that, even the user assumes roles that may have more freedom, he can not use these due to permission boundaries. If a permission boundary is enabled for a specific user, only actions explicitly listed in permission boundary is possible for that user.
Up to now policies are identity attached policies, which are policies attached to identities or roles. There can also be policies attached to resources.
Resource-based Policies
- They are attached to a resource.
- They define which identities can / cannot access the resource
An example bucket policy that allows any object operation is allowed for user avarel on daltons-bucket.
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Principal":
"AWS": "arn:aws:iam::007:user/avarel"
"Action": "s3:*Object*"
"Resource": "arn:aws:s3:::daltons-bucket"
So, in order to reach a resource, user may have a managed policy allowing him to access this resource, or resource may have a policy allowing this user to have access to him. If these is an explicit DENY somewhere, it will override the rest.
Service Control Policies (SCP)
Much like permission boundaries, they define the maximum boundaries for account.
It uses AWS organizations which have master account and child accounts. Master account should have “all featured enabled” for this AWS organization. If all features are enabled, we can specify service control policy for the child accounts.
If Service control Policies are enables,
- only explicitly allowed actions are permitted, and denied actions are denied.
- SCPs newer grant permissions
Overall Allow / Deny decision will be due to
Sample case 1. There is an S3 bucket BucketA, where its resource policy has AllowS3Access. A user, UserA having permission boundary of Allow* + DenyS3AccessToBucketA. Can UserA access to BucketA?
Yes, because resource policies have higher priority then user permission boundaries.
Sample case 2. There is an IAM user UserA in an AWS Account AccountA. AccountA has a organization service control policy of Allow* + DenyS3:DeleteBucket. UserA has managed policy AllowAssumeRole, and permission boundary Allow* + DenyS3AccessBucketA. IAM Role has trust policy of AllowAssumeByIAM User, and managed policy of AllowAllS3Access.
Is this user is allowed to create EC2 instances?
There is no explicit Allow, so we have an implicit Deny.
Is the user allowed to assume the role?
As the user has a policy to assume the role, and as the role has trust policy that lets user to assume role, yes he can.
Is the user allowed to delete BucketB?
As service control policy says DenyS3DeleteBucket, he can not
Is the user allowed to access BucketA?
No because permission boundaries for this specific user can not let him to access BucketA
Is this user allowed to access BucketB?
Yes he can, there is not an explicit Deny, but there is an explicit Allow in managed policy.
The structure of an IAM Policy has
- version
- statement
- effect
- action
- resource
- principle determines who this statement applies to. used in trust policies & resource based policies. In identity based policy, the principle is always owner, so there is no need to specify
Valid principles are
- AWS account and root user “AWS”: “arn:aws:iam::007:root” (it specifies every iam user & role in this account)
- IAM users
- Federated users (using web identity or SAML federation) “Federated”: “www.amazon.com”, in conditions we can specify the actual application.
- IAM roles
- Assumed-role sessions
- AWS services
- Anonymous users (which is not recommended)
Conditions determine when the actions are valid.
Global condition keys are
- aws:MultiFactorAuthPresent key has value Bool
- aws:SourceIp has value IP address (Ipaddress / NotIpAddress)
Service-specific condition keys are
- s3:x-amz-storage-class has value String (StringEquals / StringNotEqualsIgnoreCase)
- sts:RoleSessionName
- sc2:Encrypted
Null Operator checks if a key is present. Useful for
- assumed roles
- MFA (check weather MFA key is set)
- encryption (if you do not case which encryption key there is and only want to check weather an encryption key is there)
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Action": "ec2:*"
"Resource": "*"
"Condition":
"Null":
"aws:TokenIssueTime": "true"
By default, users don’t have permission to describe, start, stop, or terminate the instances. A way to grant the users such permissions is to attach a tag to instances, and then create a statement that enables them to manage instances with that tag.
The following policy allows users to launch instances using only the AMIs that have the specified tag, “env=dev”. The users can’t launch instances using other AMIs because of the condition element associated to AMI resource. The users also can’t launch into a subnet, as the policy does not grant permissions for the subnet and network interface resources. However, they are allowed to launch EC2 with instance resources, and requires users to specify the key pair project_secret and the security group sg-007. Users are still able to launch instances without a key pair.
"Version": "2012-10-17"
"Statement":
- "Effect": "Allow"
"Action": "ec2:RunInstances"
"Resource":
- "arn:aws:ec2:region::image/ami-*"
"Condition":
"StringEquals":
"ec2:ResourceTag/env": "dev"
- "Effect": "Allow"
"Action": "ec2:RunInstances"
"Resource":
- "arn:aws:ec2:region:account:instance/*"
- "arn:aws:ec2:region:account:volume/*"
- "arn:aws:ec2:region:account:key-pair/project_secret"
- "arn:aws:ec2:region:account:security-group/sg-007"
References
IAM best practices
IAM for AWS Solutions Architect