Every interaction you have with the cloud is through APIs. When you make an API request to AWS, it goes through several layers of authentication and authorization checks to verify your identity and assess your permissions. This process involves confirming 'you are who you say you are' and evaluating the request context against various predefined policies.
To understand the journey properly, you need to understand different terminologies so that you can clearly understand everything.
IAM Principals
In AWS, the term "principal" refers to an entity that can make requests to perform actions and access resources. Principals are a fundamental part of IAM and play a crucial role in managing security and access control within your AWS environment.
Types of IAM principals that make requests:
AWS Account
A principal can be an entire AWS account identified by its unique AWS account ID.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "123456789012" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example-bucket/*" } ] }
The above JSON object is a policy allows any entity/service in the AWS account with ID
123456789012
to perform thes3:GetObject
action on all objects within the S3 bucket namedexample-bucket
.IAM Role
Temporarily gives specific permissions to identities. You can create an IAM role with specific permissions and attach it to a service/user to give a certain level of privilege.
For giving temporary permission to services/users outside the AWS environment (for example, on-prem cloud), an IAM Role Anywhere service can be used.
IAM User
Specific individuals or services within an AWS account, identified by their IAM username. It is used for long-term credential access to the account. By default, an IAM user doesn't have any permission. To allocate permission, the best practice is to put users in a group and then attach a policy to that group, or attach a role to a user.
Federated User
External users authenticated through identity providers (IdPs) like SAML, OpenID Connect, or AWS Cognito. This principal gets credential by using the
sts:GetFederationToken
API. This is not a user that is Federated by way of an identity provider. Most customers won't use this type of Federated user often.Anonymous User
Makes unauthenticated requests to AWS. An anonymous principal refers to any entity that is accessing your AWS resources without any authenticated identity. Essentially, this means access is being granted to the general public, without requiring them to sign in or provide any credentials. This is often used in scenarios where you want to make certain resources publicly accessible, such as a public website or shared documents.
Root User
User with full access to AWS account.
Every principal has an ARN, which uniquely identifies the principal within AWS. For example, an IAM user ARN might look like arn:aws:iam::123456789012:user/JohnDoe
. It is used to specify principal in your policy statement.
AWS Policy
What is AWS Policy?
AWS Policy is a document that defines what actions a principal can perform on which resources within your AWS environment. It is written in JSON using the IAM JSON Policy Language (except Access Control List).
We can devide all the policies into two categories:
Policies associated with IAM Entity (IAM Role, User, Group)
Policies associated with AWS Resource
Policies that defines the permissions of IAM Entity are:
Identity-base Policy
Grants permission to identities (Users, Groups, Roles). This policy can be managed or inline.
Organization's Service Control Policy (SCP)
Limits maximum permissions for account members of an organization or organizational unit (OU).
Permission Boundary
Limits how much permission Identity-based policy can give to an entity (user/role). It can only be used as managed policy.
Session Policy
Limits permissions that role or user's identity-based policies grant to the session.
Policies that defines the permission of AWS Resource are:
Resource-base Policy
Grants permission to principals of same account or different account. It is attached with resources like S3, EC2, etc and also the principal is specified in this policy statment. There are some special type of resource-based policies. Some of them we will talk in this blog are:
Trust Policy
The trust policy defines which principals can assume the IAM Role, and under which conditions.
VPC Endpoint Policy
It is used to control which AWS principals can use the endpoint to access an AWS service. An endpoint policy does not override or replace identity-based policies or resource-based policies.
Access Control List (ACL)
Grants permission to principals of same or different accounts. It doesn't use JSON format and few AWS service support this policy.
Following two mindmap screenshots are from my notes:
To learn more about AWS Policy, you can have a look in AWS documentation.
Statement: Building block of AWS Policy
An AWS Policy Statement is a component of an AWS Policy that specifies the permissions for a particular action or set of actions on specific resources. Each policy can have multiple statements, each providing detailed control over permissions. Lets analyze the following Identity-based policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*"
]
},
{
"Effect": "Allow",
"Action": "ec2:StartInstances",
"Resource": "arn:aws:ec2:us-west-2:123456789012:instance/*"
},
{
"Effect": "Deny",
"Action": "s3:DeleteObject",
"Resource": "arn:aws:s3:::example-bucket/*"
}
]
}
This policy grants specific permissions and denies one particular action within AWS. It allows the identity to list the contents of and retrieve objects from the S3 bucket named example-bucket
, as well as start any EC2 instances in the us-west-2
region under the account 123456789012
. However, the policy explicitly denies the ability to delete objects from the example-bucket
S3 bucket.
How is a Policy Evaluated?
A policy can have multiple statements. But to pass through the policy, only one allow statement and no deny statement is required. For an incoming request, the request context is evaluated against the policies. To authorize the request against a policy,
At least one statement with an effect of allow must match for a request to be allowed.
A matching statement with an effect of deny takes precedence over a matching statement with an effect of allow.
This process will be repeated for all the policies in the policy chain. (Be aware that, based on scenario, different set of policies are evaluated in different order. We will learn about this in later part of this blog.)
Based on the policy evaluation, AWS decides whether to allow or deny the request. The decision is logged in AWS CloudTrail for auditing purposes.
Tools and Resources for AWS Policies
AWS Policy Visualizer
Using this tool you can visualize AWS Policies and can manually debug the policy to check if has appropriate permissions. Great tool for writing and debugging effective policies.Policy Simulator
Using this you can simulate how policy will work before adding/using the policy. You need an AWS account to use it (because it will use your IAM user to simulate).-
Use this website to generate policy in easy way.
Actions, resources, and condition keys for AWS services
If you are someone who write AWS policies, then this page should be bookmarked. You will get all everything to write policies for all services in AWS.
Request Journey
Now let’s break down the journey from the moment a request is made by an AWS principal until it’s authorized or denied. For simplicity we will focus on only one principal, AWS Role.
1. Making the API Request
You can only interact with AWS through API. For that, there are 3 ways — Console, CLI, and SDK.
AWS Management Console: When you perform an action using the AWS Management Console, the console makes API calls on your behalf.
AWS CLI: You can run commands directly in your terminal or write a script to interact with AWS services.
AWS SDKs: When you are building a software and need to interact with AWS programmatically, you will use libraries that is build and maintained by AWS. Boto3 for python3 is such an example.
(You can also interact with AWS as an anonymous user. But for this scenario, I am not considering this.)
2. Authentication
Before interacting with AWS, you have to authenticate yourself - so that AWS can recognize who you are.
In case of console, the authentication process complete when you signin using account ID, IAM username, password and MFS.
When you are interacting with AWS programmatically using SDK and CLI, you need to use appropriate access key and secret key to authenticate yourself.
In case of IAM Role, it authenticates with temporary credentials, which are given by AWS Security Token Service (STS). This service by default runs in every AWS region. Its job is to produce short time credentials to use by an IAM Role.
An IAM Role needs two resource-based policies when it is created. Trust Policy and Role Policy.
Trust Relationship Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
For Lambda functions, you need to grant this permission to the Lambda service itself. The Principal element with Service set to lambda.amazonaws.com indicates that the AWS Lambda service is trusted to assume this role. The Action element with sts:AssumeRole
specifies the action that is allowed. This setup ensures that only AWS Lambda can use this role, adding another layer of security by preventing other AWS services or users from assuming this role and accessing its permissions.
IAM Role Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::example-bucket/*"
}
]
}
The IAM Role Policy defines what actions the Lambda function is allowed to perform. In this example, the policy allows the Lambda function to read from and write to an specific S3 bucket.
In case of anonymous user, no authentication is required.
3. Building Request Context
Every request to AWS contains unique properties that is be provided along with an authorization request to make more granular authorization decisions. Till of this date there are total 18types of request context parameters — account ID, authorizer principal ID, source IP, user aget, etc are such examples. IAM then compares this authorization context with to your IAM policies to determine which policy statements match.
In case you are curious and want to know more, read the AWS documentation on request context.
4. Evaluate Policies
Before understanding evaluaton process of the policies, its crucial to understand what is Root account and Organization Unit in AWS Organization.
AWS Organization
In a large organization, there might be multiple (sometimes hundreds/thousands) of AWS accounts for different use cases. For proper security, resource, and bill management, AWS offers the AWS Organization service. This service allows you to centrally manage and govern multiple AWS accounts. It simplifies billing by consolidating payments for all accounts under a single master account, known as the Root Account. AWS Organizations also enhance security and compliance by enabling you to apply Service Control Policies (SCPs) that define the services and actions each account can use. Additionally, it helps streamline workflows by allowing you to create Organizational Units (OUs), which are groupings of accounts that can be managed collectively based on similar requirements or functions. This hierarchical structure facilitates efficient resource management, policy enforcement, and cost tracking across the entire organization.
For the example shown above, you can attach SCP policies directly to the Root Account, which will apply to all accounts under it. You can also attach SCP policies to a group of accounts by attaching it to OU. Additionally, it is possible to attach SCP policies to individual accounts.
For the simplicity of explanation and demonstration, we will abstract all the SCP policies into one.
Policy Evaluation: IAM Role
Now lets get to our IAM Role. An IAM role by itself does not make requests without a session. A role always has a corresponding session which is the principal that actually makes request.
The request is first evaluated against the SCPs defined at the organizational level. SCPs apply to all principals (users, roles, etc.) within the organization. These policies determine the upper limit of what actions are allowed or denied within the organization. The account context comes into play next, where the request is evaluated based on the policies specific to the account in which the resource resides.
Here when a request is invoked by a AWS Role Session, the role need to be allowed by multiple policies startign from organization's SCPs. If the role need to access a resource inside the same account then one of the following three policy chain will be evaluated accourding to the principal that is specified in the Resource-based Policy statment.
If the resource-based policy statement specifies principal for Accout, Role or Session then the policy evaluation path will be taken the followign 1, 2 or 3 respectively.
If the request doesn't access any resource then the following policy chain will be evaluated.
When the requested Role session originates from one account and the requested resource is in different account, then all the policies need to approved to access the resource.
Policy Evaluation: IAM User
Till now we have understood the policy chain evaluation in case of AWS Role. But for other principals, the evaluation chain is different. For the completeness of the article, let's consider the AWS User principal in the following scenario.
For request approval of an AWS User, all three session need to be evaluated. Note that the order of evaluation chain is different. It is evaluating Permission boundary policies before Identity-based policy. Rest of the structure is same as IAM Role.
Policy Evaluation with VPC Endpoint
In the previous examples, we assumed that there is no VPC endpoint service attached. If there is any VPC endpoint service, then the evaluation process of VPC endpoint policy will be after SCP, before getting access to the Account.
Conclusion
Every API request in AWS is a multi-step journey involving authentication, building request context, collection, and evaluation of various policies. By understanding how each type of policy contributes to the final authorization decision for each type of principal, you can better manage and troubleshoot access controls in your AWS environment.