You already understand that policies determine the permissions granted to an entity on AWS. Let's dive deeper into how they function. We'll explore different types of policies, examine their structure, and even create our own IAM policy.
Amazon Resource Names (ARNs)
Before diving into policies, let's look at Amazon Resource Names (ARNs). An ARN uniquely identifies AWS resources, users, groups, or roles across the entire AWS cloud. This allows you to accurately specify which resources or principals your IAM policies apply to. The general ARN formats are:
arn:partition:service:region:account-id:resource-type/resource-id
arn:partition:service:region:account-id:resource-idEach part of the ARN provides specific details:
partition— the resource's partition, for example, 'aws' for standard AWS regions.service— the service to which the resource belongs, for example, 's3' for Amazon S3.region— the region where the resource resides, for example, 'us-east-1'.account-id— the AWS account ID, for example, '123456789012'.resource-type— the type of the resource, for example, 'user', or 'role'.resource-id— the resource's name or path.
Let's review a few examples:
IAM user —
arn:aws:iam::123456789012:user/johnIAM role —
arn:aws:iam::123456789012:role/my-roleIAM group —
arn:aws:iam::123456789012:group/developersLambda Function —
arn:aws:lambda:us-west-2:123456789012:function:my-functionS3 bucket —
arn:aws:s3:::example-bucket
Types of policies
There are many types of IAM policies for different use cases. Here's a list of them:
Identity-based policies;
Resource-based policies;
Permission boundaries;
Organizational SCPs;
Session policies;
Let's start with identity-based policies. You attach these to a user, group, or role and determine the actions they can perform. They are further divided into managed and inline policies. Managed policies can be AWS-managed or customer-managed. AWS maintains AWS-managed policies and provides permissions for many use cases. However, you cannot modify them for more precise control as you can with customer-managed policies. For inline policies, you attach them directly to a single user, group, or role to manage that entity's access. Unlike managed policies, inline policies cannot be shared among multiple entities.
Next, we have resource-based policies. You attach these to AWS resources, such as S3 buckets or Lambda functions, to control who can access them and the actions they can perform on them. For instance, you can attach a resource-based policy to an S3 bucket to define who can access it and the actions (read, write, delete, etc.) they can perform.
Consider a user administrator initially limited to user management actions. They could decide to create a new, highly privileged user and log in as that user. This would allow them to perform any potentially malicious activities. Fortunately, we can define the maximum scope of actions that an entity can grant or delegate to other IAM entities using permission boundaries. They do not grant permissions; they only limit the permissions the IAM entity's policies can extend to others.
If you want to apply a consistent set of policies to all accounts in your organization, Service Control Policies (SCPs) can help. SCPs don't grant permissions but ensure that account-level policies stay within defined boundaries. They are handy for administrators to enforce compliance and security standards across an organization.
Session Policies are advanced policies you provide when you assume a role or federated user session. They further restrict permissions for the session, which is useful when you need temporary access to a resource with more restricted permissions than what your regular role allows. During that session, a session policy can limit the scope of access.
Structure of a policy
So, what goes into an IAM policy? Policies are created in a language known as JSON (JavaScript Object Notation). This might sound hard at first, but it is simply a way to describe things clearly to both humans and computers. An IAM policy contains the following elements:
Version — this is the policy's edition which usually is the date it was created;
Statement — this is the heart of the policy and contains everything that the policy does. A policy can contain one or more statements;
Sid (Optional) — an optional identifier to manage and identify individual statements, especially in multi-statement policies;
Effect — simply put, it's the 'Allow' or 'Deny' part. It's the decision of whether the door to a resource swings open or stays shut;
Action — these are the specific tasks you're allowing or denying, like 's3:ListBucket' to peek into an S3 bucket;
Principal — this dictates the account, user, or role, you'd like to allow or deny access. It is only required in resource-based policies and trust policies;
Resource — the AWS resource you're applying the permissions to. It's the 'what' of the policy and is also required in some cases;
Condition (Optional) — the cherry on top. Conditions define the circumstances under which the policy grants or denies permission;
Now that you know what goes into creating a policy, let's look at a simple example:
{
"Version": "2012-10-17",
"Statement": [
{
"SID": "StmtDenyS3BucketDeleteAccess",
"Effect": "Deny",
"Action": "s3:DeleteBucket",
"Resource": "arn:aws:s3:::hyper-bucket"
}
]
}In this snippet, we have an identity-based policy that denies an entity from deleting an S3 bucket named 'hyper-bucket.' As you can see, a policy consists of a few basic elements that determine what can or cannot be done. Even the most complex policies consist of these basic elements.
Crafting your first IAM policy
Now, let's get our hands dirty and create an IAM policy. Imagine we have two Amazon RDS databases that we'd like to safeguard. First, let's look at the entire policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:DescribeDBInstances",
"rds:StartDBInstance",
"rds:StopDBInstance",
"rds:DeleteDBInstance"
],
"Resource": [
"arn:aws:rds:us-east-1:123456789012:db:mysql-instance",
"arn:aws:rds:us-east-1:123456789012:db:postgres-instance"
],
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}It might look complex, but let's break it down. In this policy, the Version indicates that the policy's version is 2012-10-17, and the Statement contains the main part of the policy. We want to allow actions, so we use the "Allow" Effect:
"Effect": "Allow"Next, we list the actions we would like to allow on our resources. The Action section handles this. It defines the operations the policy allows or denies, using the format "service:action". You can specify individual actions, use wildcards (*) for multiple actions, or list several actions. Always use the principle of least privilege to only allow the necessary actions.
In our case, we want to allow listing, starting, stopping, or deleting our database instances:
"Action": [
"rds:DescribeDBInstances",
"rds:StartDBInstance",
"rds:StopDBInstance",
"rds:DeleteDBInstance"
],We want these actions to apply only to our MySQL and PostgreSQL database instances. So, we provide their unique identifiers (ARNs) in the Resource section. Here, we can also specify individual resources, use wildcards, or list several resources:
"Resource": [
"arn:aws:rds:us-east-1:123456789012:db:mysql-instance",
"arn:aws:rds:us-east-1:123456789012:db:postgres-instance"
],Finally, we want to perform these actions only if the entity has multi-factor authentication enabled. This extra layer of security is crucial for performing critical actions, like stopping or deleting database instances. To achieve this, we add a Condition section:
"Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}That's it, an entire policy supporting multiple actions on multiple database instances, with an added layer of security!
There are many other values you can specify as conditions. Review a full list of them in the AWS documentation.
Tools for working with policies
When working with policies, you will use various tools to author, analyze, and even troubleshoot them. Let's discuss some of them:
AWS Management Console — you can use this when creating policies. It is integrated with AWS's Policy Generator so you can select components from the interface and it will generate the policy for you;
IAM Policy Simulator — enables you to test the effects of your IAM policies to ensure they provide the desired permissions, which is crucial for understanding the impact of policy changes. It also aids in troubleshooting access errors;
AWS CLI — the CLI allows you to manage policies using commands in a terminal, which can be faster and more automated;
AWS IAM Access Analyzer — helps you validate your policies against best practices by analyzing permissions and identifying any resources that are shared with external entities;
Conclusion
Policies provide a straightforward yet effective way to manage the permissions of a principal. You can choose from different policies to meet various needs. Here's a recap of these policies:
Identity-based policies control a principal's permissions;
Resource-based policies manage resource actions;
Permission boundaries limit privilege escalation;
SCPs are a feature of AWS Organizations and apply to all accounts within an organization, restricting the permissions that can be granted within those accounts;
Session policies manage access during a session beyond what the assumed role's permissions already allow;
Policies can be managed by AWS or by you, the customer. When you create policies, you can customize them as much as needed to meet your specific requirements. To craft a policy, write a JSON document with elements like the effect, actions, principals, resources, and conditions of the policy. You can also start with an existing policy and modify it to fit your needs.