Mastering AWS Custom Policies & The Principle of Least Privilege
Construct custom policies that meet the principle of least privilege
Mastering AWS Custom Policies & The Principle of Least Privilege
This guide focuses on the critical security task of constructing IAM policies that provide only the necessary access required for a specific function, reducing the "blast radius" of potential security incidents.
Learning Objectives
After studying this guide, you should be able to:
- Define the Principle of Least Privilege and its importance in AWS security.
- Distinguish between AWS-managed, Customer-managed, and Inline policies.
- Construct a JSON policy document that restricts access by specific Actions and Resource ARNs.
- Explain the role of Permission Boundaries in limiting the maximum permissions of an IAM principal.
- Identify best practices for securing the AWS Root user and managing administrative access.
Key Terms & Glossary
- Principle of Least Privilege (PoLP): The practice of granting only the minimum permissions required to perform a task.
- IAM Policy: A JSON document that defines permissions by associating "Effect", "Action", "Resource", and "Condition".
- ARN (Amazon Resource Name): A standardized string used to uniquely identify an AWS resource (e.g.,
arn:aws:s3:::my-bucket). - IAM Role: An identity with specific permissions that can be assumed by users, applications, or AWS services; it does not have long-term credentials like a password.
- Permission Boundary: An advanced feature where you use a managed policy to set the maximum permissions that an identity-based policy can grant to an IAM entity.
The "Big Idea"
In AWS, security is "Job Zero." The core of this security is Authorization. By moving away from broad, "FullAccess" managed policies toward granular, Customer-managed policies, you ensure that if a credential is compromised, the attacker is limited to a very narrow set of actions on specific resources. It is the difference between giving a contractor a master key to a building versus a keycard that only opens one specific door during business hours.
Formula / Concept Box
The Anatomy of an IAM Policy Statement
Every statement in a custom policy generally follows this structure:
| Element | Description | Example |
|---|---|---|
| Effect | Whether the statement allows or denies access. | "Allow" or "Deny" |
| Action | The specific API calls/operations allowed. | "s3:GetObject" |
| Resource | The specific AWS resources the actions apply to. | "arn:aws:s3:::my-data-bucket/*" |
| Condition | (Optional) When the policy is in effect. | "StringEquals": {"aws:SourceVpce": "vpce-123"} |
Visual Anchors
Policy Evaluation Logic
This flowchart illustrates how AWS determines if a request is allowed when both an identity-based policy and a permission boundary exist.
Permission Intersection (Venn Diagram)
The following diagram represents the "Effective Permissions" of a user. An action is only allowed if it exists within the overlap of the Assigned Policy and the Permission Boundary.
\begin{tikzpicture} \draw[fill=blue!20, opacity=0.5] (0,0) circle (1.5cm) node[left=0.5cm] {\shortstack{Identity-Based\Policy}}; \draw[fill=red!20, opacity=0.5] (1.5,0) circle (1.5cm) node[right=0.5cm] {\shortstack{Permission\Boundary}}; \begin{scope} \clip (0,0) circle (1.5cm); \fill[purple!40] (1.5,0) circle (1.5cm); \end{scope} \node at (0.75,0) [font=\bfseries] {Effective}; \end{tikzpicture}
Hierarchical Outline
- IAM Policy Types
- AWS Managed Policies: Created/maintained by AWS (e.g.,
AdministratorAccess). Broad and easy but often violate least privilege. - Customer Managed Policies: Reusable, standalone policies created by you. Best practice for granular control.
- Inline Policies: Embedded directly in a single user/role. Not reusable; harder to manage at scale.
- AWS Managed Policies: Created/maintained by AWS (e.g.,
- Role Variants
- Service Role: Assumed by an AWS service to perform actions on your behalf.
- Service-Linked Role (SLR): Predefined by the service; you cannot modify permissions. Not recommended for production data access if custom roles are an option.
- Governance Best Practices
- Use IAM Access Analyzer to refine broad policies based on actual usage.
- Implement MFA for all users, especially those with administrative power.
- Use IAM Identity Center (formerly SSO) for centralized access management across multiple accounts.
Definition-Example Pairs
- Resource-Level Permissions: Specifying an ARN instead of a wildcard (
*).- Example: Instead of
"Resource": "*"for S3, use"Resource": "arn:aws:s3:::customer-billing-data/*"to limit the user to one specific bucket.
- Example: Instead of
- Action-Level Permissions: Specifying exact API calls.
- Example: Instead of
"Action": "s3:*", use"Action": ["s3:GetObject", "s3:ListBucket"]to prevent the user from deleting files.
- Example: Instead of
Worked Examples
Constructing a Least-Privilege S3 Policy
Scenario: A data engineer needs to read files from a specific folder in an S3 bucket but should not be able to delete anything or access other buckets.
The Custom JSON Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::my-company-data-lake"]
},
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::my-company-data-lake/processed-logs/*"]
}
]
}[!NOTE] Notice that
s3:ListBucketis applied to the bucket ARN, whiles3:GetObjectis applied to the object path ARN (with/*).
Comparison Tables
Policy Comparison Matrix
| Feature | AWS Managed | Customer Managed | Inline |
|---|---|---|---|
| Created By | AWS | You | You |
| Editable? | No | Yes | Yes |
| Reusable? | Yes | Yes | No |
| Recommended? | For general use | Yes (Least Privilege) | Rarely |
Service Role vs. Service-Linked Role
| Aspect | Service Role | Service-Linked Role |
|---|---|---|
| Ownership | You own and manage it | The AWS Service owns it |
| Customization | Full control over policies | Permissions are fixed/pre-defined |
| Use Case | Custom app on EC2 accessing S3 | Auto Scaling creating EC2 instances |
Checkpoint Questions
- Why is a Customer-managed policy preferred over an AWS-managed policy for production data access?
- What happens if an Identity Policy allows
s3:PutObjectbut the Permission Boundary only allowss3:GetObject? - True or False: Inline policies are the recommended way to share permissions across multiple IAM roles.
- Which IAM tool helps you identify unused permissions to help you transition to a least-privilege model?
▶Click for Answers
- Customer-managed policies allow you to specify exact ARNs and actions, whereas AWS-managed policies are often too broad.
- The action is Denied. For an action to be allowed, it must be present in both the Identity Policy AND the Permission Boundary.
- False. Customer-managed policies are recommended for reuse.
- AWS IAM Access Analyzer.
Muddy Points & Cross-Refs
- Permission Boundary vs. Policy: A common point of confusion is thinking a boundary grants permissions. It does not. It only limits them. Think of the boundary as a ceiling; no matter how high the user's policy tries to go, they can never exceed the ceiling set by the boundary.
- Service-Linked Roles in Production: As noted in the source material, avoid using Lake Formation service-linked roles in production because they may not meet the specific least-privilege requirements of your organization.
- Root User: Never use the root user for daily tasks. Create a "Primary Admin" user with the
AdministratorAccessmanaged policy instead.