IAM
Stands for Identity Access Management. There are several types of IAM identities. They are usually called “Principal”. This can be either a User or a Role. It can even be a service or an account. Users can assume Roles. Instance Profile is basically a separate IAM Role assumed by this particular instance.
IAM role. Some entity (principal in AWS language) that can be assumed by others (users, services, instances, accounts). However assumes the role, is provided with temporary credentials.
β As far as I know, principals (which I suppose is very close to the term entity) has an ID and probably a AccessKey as well.
Roles do not exist on their own. No, they are not ally cats πββ¬. Instead, when a principal (service, user, account etc) assumes a role, it is given temporary credentials that expire with time. These credentials, btw, are stored in the IMDS. That’s what it is for. AWS_ACCESS_KEY_ID
for temp creds starts with a ASIA
prefix.
β If some entity assumed some role, can these temp creds be used by other entity?
There are also ACLs (Access Control Lists), they have XML format and define which principals in other AWS accounts can access a resouce in question.
Nice diagram here showing how exactly AWS decides whether to grant access or not:
In order to understand what permissions something has, you need to add identity, resource policy + session restrictions.
IAM Policies
Policies consist of statements: Effect (ALLOW or DENY), Actions (What’s about to be done) and Resource (What’s it to be done to).
Policy created can be assigned to a user, a group, a resource, other principal.
There are several types of policies.
Organization Service Control Policy (SCP). This is one of the major. It specifies the maximum permissions that can be granted to IB or RB policies within the organization. Below is an example of such policy. It basically doesn’t allow IAM actions applied to any of the resources in case the request is not coming from eu-west-1 region.
{
"Version": "2022-08-06",
"Statement": [
{
"Sid": "SCP Policy",
"Effect": "Deny",
"NotAction": "iam:*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]
}
Resource-based. Describe principles that are allowed to touch this particular resource.
βοΈ Not all resources support RB policies.
Example:
{
"Version": "2022-08-06",
"Statement": [
{
"Sid": "my-ec2 Resource-based Policy",
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Principal": {
"AWS":[
"arn:aws:iam::123456789:role/my-ec2",
"arn:aws:iam::123456789:user/superadmin"
]
}
}
]
}
Identity-based. Specify resources that these identities are allowed to touch. Example:
{
"Version": "2022-08-06",
"Statement": [
{
"Sid": "my-ec2 Identity-based Policy",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": "*"
}
]
}
Session policy. Used when programmatically creating a session. Limits the permissions. First, one needs to create a session. Let’s say, Ezio is a product manager but needs to access some accounting information.aws sts assume-role --role-arn "arn:aws:iam::123456789:role/accountant" --role-session-name "accountant-alice-session" --policy file://policy.json
.
--role-arn arn:aws:iam::123456789:role/accountant
- it’s the IB policy. Resource policy is evaluated behind the scenes.
--policy file://policy.json
is our session policy (if any).
The example above basically says the following: “I am Ezio and I want to become an accountant for a day to access some resource. May I?”. Example of such policy:
{ "Version": "2022-06-08",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::accountinginfo"],
"Condition": { "StringLike":{ "s3:prefix":["ezio/*"] } } },
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::accountinginfo/ezio/*" }
]}
Permissions boundary. This is very close to the SCP in that it limits the maximum permissions that can be granted to a principal.
Access control lists. βοΈ XML. Basically, RB policies but for cross-account stuff.
Access Decision Tree
The official doc’s here [2].
- Search for “Deny” within the scope. If found, game over. Nothing is allowed.
- Review the SCP (if applicable). Deby if something is there prohibiting the request.
- Review the resource policy (if any). If this principal is not allowed - tell him to bugger off.
- If there are any permissions boundary, evaluate them first. If something the principal is requesting is prohibited, deny the request alltogether.
- If these are temp credentials, evaluate the session policy. If anything is wrong, deny.
- Evaluate all of the IB policies associated with the principal.
Instance profile
Instance profile is a container of a signle IAM role. For EC2 instances. It’s assigned to one IAM role, which has a number of managed or inline policy permissions. These credentials can be accessed via IMDSv1: curl βs "http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name"
.
For IMDSv2: TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token)
to retrieve the token and curl -H "X-aws-ec2-metadata-token: $TOKEN"http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name"
set the value of a X-aws-ec2-metadata-token
HTTP header to that retreived value.
β οΈ The above one didn’t work for me. Probably because of the well designed security restrictions.
Policy Types By Owner
AWS Managed Policies - shared between all AWS customers.
Customer Managed Policies - every customer withing AWS realm creates private policies that are managed by them.
Inline policies - owned by a principle and can’t be reused by other entities.
Login activity
For admin account go to IAM -> Credential report to see all the users and the following information:
- user name
- arn (acc N + username)
- user_creation_time
- password_enabled
- password_last_used
- password_last_changed
- password_next_rotation
- mfa_active
- access_key_1_active
- access_key_1_last_rotated
- access_key_1_last_used_date
- access_key_1_last_used_region
- access_key_1_last_used_service
- access_key_2_active
- access_key_2_last_rotated
- access_key_2_last_used_date
- access_key_2_last_used_region
- access_key_2_last_used_service
- cert_1_active
- cert_1_last_rotated
- cert_2_active
- cert_2_last_rotated
Tokens
On AWS there are several types of tokens.
IMDS
IMDSv2 tokens live for 6 hours, see here:
TheΒ
PUT
Β request must include a header that specifies the time to live (TTL) for the token, in seconds, up to a maximum of six hours (21,600 seconds).
IMDSv1 doesn’t have token at all.
Access Tokens
Tokens for users can be configired, see here:
The duration, in seconds, that the credentials should remain valid. Acceptable durations for IAM user sessions range from 900 seconds (15 minutes) to 129,600 seconds (36 hours), with 43,200 seconds (12 hours) as the default.
For this use get-session-token
with --duration-seconds
option. This is for temp credentials only. These creds can’t get to IAM info (if no MFA is also included) or STS API, aka Security Token Service (other than AssumeRole
or GetCallerIdentity
).
AWS_ACCESS_KEY_ID
for temp creds starts with a ASIA
prefix.
Service usage activity
Also, you can go to IAM -> username -> Access Advisor tab to see the services that this user has access to and when these were last used.
userIdentity
userIdentity
can be either AssumedRole
or IAMUser
.
An IAM administrator can configure AWS Security Token Service to require that users specify their identity when they use temporary credentials to assume roles.
AssumedRole
The user can either use their creds directly or use some role (policy instead). In this case, logs will also contain sessionContext
.
IAMUser
π BTFM
Login in via AWS CLI
Ensure you have AWS CLI installed.
export AWS_ACCESS_KEY_ID="ASIAJKJHASDKJHSDKJLA"
export AWS_SECRET_ACCESS_KEY="akljhdljkhljhewhjjkhsd/s"
export AWS_SESSION_TOKEN="kajsdhkjsaha" # optional. AWS_SESSION_TOKEN is required with temp creds only.
aws help
# You'll see all available options. For example, you can run aws ec2 to see what you can do to the EC2 instances from within the CLI
Retieve Metadata from EC2
# ssh into the machine in question
ssh user@machineIPorDNSname
# when promted for the password for user, enter it (in case public key encryption is not being used)
# The next two commands are issued from the EC2's console
# IMDSv1
curl βs "http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name"
# IMDSv2
# to retrieve the token
TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token)
# set X-aws-ec2-metadata-token header to that value
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name"
Root
It’s not recommended to use root
user for any activity on AWS unless it’s something that only root can done. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html
https://docs.aws.amazon.com/general/latest/gr/root-vs-iam.html#aws_tasks-that-require-root