Chapter 04: In-Depth Guide to IAM Policies
Comprehensive study of AWS IAM policy syntax, structure, and advanced features including conditions, variables, and policy evaluation logic
Haiyue
73min
Chapter 04: In-Depth Guide to IAM Policies
Learning Objectives
- Master the JSON syntax structure of IAM policies
- Understand the usage of policy elements and attributes
- Learn condition blocks and condition operators
- Master policy variables and dynamic references
- Understand policy evaluation logic and precedence
IAM Policy System Architecture
🔄 正在渲染 Mermaid 图表...
4.1 IAM Policy Basic Syntax
4.1.1 Policy Document Structure
Policy Basic Structure
IAM policies use JSON format and include the following basic elements:
- Version: Policy language version
- Statement: Array of permission declarations
- Effect: Allow or Deny
- Action: Operations allowed or denied
- Resource: Resources the action applies to
- Condition: Optional conditional constraints
import boto3
import json
from datetime import datetime
def create_basic_policy_structure():
"""
Create basic IAM policy structure examples
"""
# Simplest policy structure
simple_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "*"
}
]
}
# Complete policy structure
complete_policy = {
"Version": "2012-10-17",
"Id": "ExamplePolicy123", # Optional policy ID
"Statement": [
{
"Sid": "AllowS3ReadAccess", # Optional statement ID
"Effect": "Allow",
"Principal": { # Only used in resource policies
"AWS": "arn:aws:iam::123456789012:user/ExampleUser"
},
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::example-bucket/*",
"arn:aws:s3:::another-bucket/*"
],
"Condition": {
"StringEquals": {
"s3:x-amz-server-side-encryption": "AES256"
},
"DateGreaterThan": {
"aws:CurrentTime": "2024-01-01T00:00:00Z"
}
}
}
]
}
print("Simple Policy Structure:")
print(json.dumps(simple_policy, indent=2))
print("\nComplete Policy Structure:")
print(json.dumps(complete_policy, indent=2))
return simple_policy, complete_policy
def validate_policy_syntax(policy_document):
"""
Validate IAM policy syntax correctness
"""
iam = boto3.client('iam')
try:
# Use AWS IAM service to validate policy syntax
response = iam.simulate_principal_policy(
PolicySourceArn='arn:aws:iam::123456789012:user/test-user',
ActionNames=['s3:GetObject'],
ResourceArns=['arn:aws:s3:::test-bucket/*'],
PolicyInputList=[json.dumps(policy_document)]
)
print("Policy syntax validation passed")
# Check simulation results
for result in response['EvaluationResults']:
decision = result['EvalDecision']
action = result['EvalActionName']
resource = result['EvalResourceName']
print(f" Action: {action}")
print(f" Resource: {resource}")
print(f" Decision: {decision}")
if 'MatchedStatements' in result:
print(f" Matched statements: {len(result['MatchedStatements'])}")
return True
except Exception as e:
print(f"Policy syntax validation failed: {str(e)}")
return False
# Create and validate policy examples
simple_policy, complete_policy = create_basic_policy_structure()
validate_policy_syntax(simple_policy)
4.1.2 Detailed Policy Elements
def demonstrate_policy_elements():
"""
Demonstrate the usage of various IAM policy elements
"""
# Version element
version_examples = {
"current": "2012-10-17", # Current version, recommended
"legacy": "2008-10-17" # Legacy version, not recommended
}
print("Version Description:")
for version_type, version_value in version_examples.items():
print(f" {version_type}: {version_value}")
# Effect element
effect_examples = {
"Allow": "Grant permissions",
"Deny": "Explicitly deny permissions (highest priority)"
}
print("\nEffect Types:")
for effect, description in effect_examples.items():
print(f" {effect}: {description}")
# Various formats of Action element
action_formats = {
"Single action": "s3:GetObject",
"Action list": ["s3:GetObject", "s3:PutObject"],
"Wildcard": "s3:*",
"Service wildcard": "*",
"Action family": "s3:Get*"
}
print("\nAction Formats:")
for format_type, example in action_formats.items():
print(f" {format_type}: {example}")
# Various formats of Resource element
resource_formats = {
"Specific resource": "arn:aws:s3:::my-bucket/file.txt",
"Bucket": "arn:aws:s3:::my-bucket",
"Bucket contents": "arn:aws:s3:::my-bucket/*",
"Resource list": [
"arn:aws:s3:::bucket1/*",
"arn:aws:s3:::bucket2/*"
],
"Wildcard": "*",
"Partial wildcard": "arn:aws:s3:::my-*"
}
print("\nResource Formats:")
for format_type, example in resource_formats.items():
print(f" {format_type}: {example}")
# Principal element (only used in resource policies)
principal_formats = {
"AWS account": "arn:aws:iam::123456789012:root",
"IAM user": "arn:aws:iam::123456789012:user/UserName",
"IAM role": "arn:aws:iam::123456789012:role/RoleName",
"AWS service": "lambda.amazonaws.com",
"Anonymous user": "*",
"Federated user": "arn:aws:sts::123456789012:federated-user/UserName"
}
print("\nPrincipal Types:")
for principal_type, example in principal_formats.items():
print(f" {principal_type}: {example}")
# Create comprehensive policy showing various elements
comprehensive_policy = {
"Version": "2012-10-17",
"Id": "ComprehensivePolicyExample",
"Statement": [
{
"Sid": "AllowS3ReadAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-data-bucket",
"arn:aws:s3:::my-data-bucket/*"
]
},
{
"Sid": "AllowS3WriteToSpecificPrefix",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::my-data-bucket/user-uploads/*"
},
{
"Sid": "DenyDeleteBucket",
"Effect": "Deny",
"Action": "s3:DeleteBucket",
"Resource": "*"
},
{
"Sid": "AllowEC2ReadOnly",
"Effect": "Allow",
"Action": "ec2:Describe*",
"Resource": "*"
}
]
}
print("\nComprehensive Policy Example:")
print(json.dumps(comprehensive_policy, indent=2))
return comprehensive_policy
# Demonstrate policy elements
comprehensive_policy = demonstrate_policy_elements()
4.2 Condition Blocks and Condition Operators
4.2.1 Detailed Condition Operators
def demonstrate_condition_operators():
"""
Demonstrate various condition operators in IAM policies
"""
# String condition operators
string_conditions = {
"StringEquals": {
"description": "Exact string match",
"example": {
"aws:PrincipalTag/Department": "Finance"
}
},
"StringNotEquals": {
"description": "String not equal",
"example": {
"aws:PrincipalTag/Department": "Temp"
}
},
"StringLike": {
"description": "Wildcard pattern matching",
"example": {
"s3:prefix": ["home/${aws:username}/*"]
}
},
"StringNotLike": {
"description": "Does not match wildcard pattern",
"example": {
"s3:prefix": ["restricted/*"]
}
}
}
# Numeric condition operators
numeric_conditions = {
"NumericEquals": {
"description": "Numeric equal to",
"example": {
"s3:max-keys": "10"
}
},
"NumericNotEquals": {
"description": "Numeric not equal to",
"example": {
"s3:max-keys": "100"
}
},
"NumericLessThan": {
"description": "Less than numeric value",
"example": {
"aws:MultiFactorAuthAge": "3600"
}
},
"NumericLessThanEquals": {
"description": "Less than or equal to numeric value",
"example": {
"s3:max-keys": "50"
}
},
"NumericGreaterThan": {
"description": "Greater than numeric value",
"example": {
"s3:object-size": "1024"
}
},
"NumericGreaterThanEquals": {
"description": "Greater than or equal to numeric value",
"example": {
"s3:object-size": "0"
}
}
}
# Date condition operators
date_conditions = {
"DateEquals": {
"description": "Date equals",
"example": {
"aws:CurrentTime": "2024-01-01T00:00:00Z"
}
},
"DateNotEquals": {
"description": "Date not equal",
"example": {
"aws:CurrentTime": "2024-12-25T00:00:00Z"
}
},
"DateLessThan": {
"description": "Date before",
"example": {
"aws:CurrentTime": "2024-12-31T23:59:59Z"
}
},
"DateGreaterThan": {
"description": "Date after",
"example": {
"aws:CurrentTime": "2024-01-01T00:00:00Z"
}
}
}
# Boolean condition operators
boolean_conditions = {
"Bool": {
"description": "Boolean value comparison",
"example": {
"aws:SecureTransport": "true",
"aws:MultiFactorAuthPresent": "true"
}
}
}
# IP address condition operators
ip_conditions = {
"IpAddress": {
"description": "IP address within range",
"example": {
"aws:SourceIp": ["203.0.113.0/24", "2001:DB8:1234:5678::/64"]
}
},
"NotIpAddress": {
"description": "IP address not within range",
"example": {
"aws:SourceIp": ["192.0.2.0/24"]
}
}
}
# ARN condition operators
arn_conditions = {
"ArnEquals": {
"description": "Exact ARN match",
"example": {
"aws:SourceArn": "arn:aws:s3:::my-bucket"
}
},
"ArnLike": {
"description": "ARN wildcard match",
"example": {
"aws:SourceArn": "arn:aws:s3:::my-*"
}
},
"ArnNotEquals": {
"description": "ARN not equal",
"example": {
"aws:SourceArn": "arn:aws:s3:::restricted-bucket"
}
},
"ArnNotLike": {
"description": "ARN does not match wildcard",
"example": {
"aws:SourceArn": "arn:aws:s3:::temp-*"
}
}
}
# Create comprehensive policy with various conditions
condition_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "StringConditions",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "*",
"Condition": {
"StringEquals": {
"s3:ExistingObjectTag/Environment": "Production"
},
"StringLike": {
"s3:prefix": ["home/${aws:username}/*"]
}
}
},
{
"Sid": "NumericConditions",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "*",
"Condition": {
"NumericLessThan": {
"s3:object-size": "10485760" # 10MB
},
"NumericGreaterThan": {
"s3:object-size": "0"
}
}
},
{
"Sid": "DateConditions",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "*",
"Condition": {
"DateGreaterThan": {
"aws:CurrentTime": "2024-01-01T00:00:00Z"
},
"DateLessThan": {
"aws:CurrentTime": "2024-12-31T23:59:59Z"
}
}
},
{
"Sid": "BooleanAndIPConditions",
"Effect": "Allow",
"Action": "iam:*",
"Resource": "*",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true",
"aws:SecureTransport": "true"
},
"IpAddress": {
"aws:SourceIp": ["203.0.113.0/24"]
}
}
},
{
"Sid": "ARNConditions",
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "*",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:::my-bucket/*"
}
}
}
]
}
print("Condition Operator Types:")
print("\nString Conditions:")
for op, details in string_conditions.items():
print(f" {op}: {details['description']}")
print("\nNumeric Conditions:")
for op, details in numeric_conditions.items():
print(f" {op}: {details['description']}")
print("\nDate Conditions:")
for op, details in date_conditions.items():
print(f" {op}: {details['description']}")
print("\nBoolean Conditions:")
for op, details in boolean_conditions.items():
print(f" {op}: {details['description']}")
print("\nIP Address Conditions:")
for op, details in ip_conditions.items():
print(f" {op}: {details['description']}")
print("\nARN Conditions:")
for op, details in arn_conditions.items():
print(f" {op}: {details['description']}")
print("\nComprehensive Condition Policy Example:")
print(json.dumps(condition_policy, indent=2))
return condition_policy
# Demonstrate condition operators
condition_policy = demonstrate_condition_operators()
4.2.2 Condition Modifiers and Set Operations
def demonstrate_condition_modifiers():
"""
Demonstrate IAM condition modifiers and set operations
"""
# Condition modifiers
modifier_examples = {
"IfExists": {
"description": "Only check condition if key exists",
"use_case": "Handle optional fields",
"example": {
"StringEqualsIfExists": {
"s3:ExistingObjectTag/Environment": "Production"
}
}
},
"ForAllValues": {
"description": "All values in request must match condition",
"use_case": "Restrict all values of multi-value field",
"example": {
"ForAllValues:StringEquals": {
"dynamodb:Attributes": ["UserId", "Email", "Name"]
}
}
},
"ForAnyValue": {
"description": "At least one value in request matches condition",
"use_case": "Allow any value in multi-value field",
"example": {
"ForAnyValue:StringEquals": {
"aws:PrincipalTag/Department": ["Finance", "HR", "IT"]
}
}
}
}
# Create policy demonstrating modifiers
modifier_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "IfExistsModifier",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "*",
"Condition": {
"StringEqualsIfExists": {
"s3:ExistingObjectTag/Classification": "Public"
},
"StringEquals": {
"s3:ExistingObjectTag/Environment": "Production"
}
}
},
{
"Sid": "ForAllValuesModifier",
"Effect": "Allow",
"Action": "dynamodb:GetItem",
"Resource": "arn:aws:dynamodb:*:*:table/UserProfiles",
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:Attributes": [
"UserId",
"Email",
"FirstName",
"LastName"
]
}
}
},
{
"Sid": "ForAnyValueModifier",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::company-data/*",
"Condition": {
"ForAnyValue:StringEquals": {
"aws:PrincipalTag/Department": [
"Engineering",
"DevOps",
"QA"
]
}
}
}
]
}
print("Condition Modifier Descriptions:")
for modifier, details in modifier_examples.items():
print(f"\n{modifier}:")
print(f" Description: {details['description']}")
print(f" Use case: {details['use_case']}")
print(f" Example: {json.dumps(details['example'], indent=4)}")
print("\nModifier Policy Example:")
print(json.dumps(modifier_policy, indent=2))
# Create complex condition combination example
complex_condition_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ComplexS3Access",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::sensitive-data/*",
"Condition": {
"Bool": {
"aws:SecureTransport": "true",
"aws:MultiFactorAuthPresent": "true"
},
"StringEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
},
"StringLike": {
"s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:*:*:key/*"
},
"NumericLessThan": {
"aws:MultiFactorAuthAge": "1800" # MFA within 30 minutes
},
"IpAddress": {
"aws:SourceIp": [
"203.0.113.0/24", # Office network
"198.51.100.0/24" # VPN network
]
},
"DateGreaterThan": {
"aws:CurrentTime": "2024-01-01T00:00:00Z"
},
"ForAllValues:StringEquals": {
"aws:TagKeys": [
"Environment",
"Project",
"Owner"
]
}
}
}
]
}
print("\nComplex Condition Combination Policy:")
print(json.dumps(complex_condition_policy, indent=2))
return modifier_policy, complex_condition_policy
# Demonstrate condition modifiers
modifier_policy, complex_policy = demonstrate_condition_modifiers()
4.3 Policy Variables and Dynamic References
4.3.1 AWS Policy Variables
def demonstrate_policy_variables():
"""
Demonstrate the use of variables in IAM policies
"""
# AWS global variables
global_variables = {
"aws:CurrentTime": "Current timestamp",
"aws:EpochTime": "Unix timestamp",
"aws:PrincipalType": "Principal type (User, Role, Account, etc.)",
"aws:SecureTransport": "Whether using HTTPS",
"aws:SourceIp": "Source IP address of request",
"aws:UserAgent": "HTTP User-Agent header",
"aws:userid": "AWS user ID",
"aws:username": "Username",
"aws:PrincipalArn": "Principal's ARN",
"aws:RequestedRegion": "Requested AWS region",
"aws:RequestTag/key": "Tag value in request",
"aws:PrincipalTag/key": "Principal's tag value"
}
# Service-specific variables
service_variables = {
"s3": {
"s3:prefix": "S3 object prefix",
"s3:delimiter": "S3 delimiter",
"s3:max-keys": "Maximum number of objects to list",
"s3:ExistingObjectTag/key": "Existing object's tag value",
"s3:x-amz-content-sha256": "Content SHA256 hash",
"s3:x-amz-server-side-encryption": "Server-side encryption type"
},
"ec2": {
"ec2:InstanceType": "EC2 instance type",
"ec2:Region": "EC2 region",
"ec2:ResourceTag/key": "EC2 resource tag",
"ec2:Subnet": "Subnet ID"
},
"dynamodb": {
"dynamodb:Attributes": "DynamoDB attribute list",
"dynamodb:LeadingKeys": "DynamoDB primary key values",
"dynamodb:Encrypt": "Whether encryption enabled"
}
}
# Create policy examples using variables
variable_policies = {
"user_home_directory": {
"description": "Users can only access their own home directory",
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::user-home-directories/${aws:username}/*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::user-home-directories",
"Condition": {
"StringLike": {
"s3:prefix": "${aws:username}/*"
}
}
}
]
}
},
"time_based_access": {
"description": "Time-based access control",
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"DateGreaterThan": {
"aws:CurrentTime": "2024-01-01T00:00:00Z"
},
"DateLessThan": {
"aws:CurrentTime": "2024-12-31T23:59:59Z"
},
"IpAddress": {
"aws:SourceIp": "203.0.113.0/24"
}
}
}
]
}
},
"tag_based_access": {
"description": "Tag-based access control",
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RebootInstances"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Owner": "${aws:username}",
"ec2:ResourceTag/Department": "${aws:PrincipalTag/Department}"
}
}
},
{
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedTag/Owner": "${aws:username}",
"aws:RequestedTag/Department": "${aws:PrincipalTag/Department}"
}
}
}
]
}
},
"dynamodb_row_level": {
"description": "DynamoDB row-level access control",
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/UserProfiles",
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${aws:username}"]
}
}
}
]
}
}
}
print("AWS Global Variables:")
for var, description in global_variables.items():
print(f" ${{{var}}}: {description}")
print("\nService-Specific Variables:")
for service, variables in service_variables.items():
print(f"\n {service.upper()} Service:")
for var, description in variables.items():
print(f" ${{{var}}}: {description}")
print("\nPolicy Variable Usage Examples:")
for policy_name, policy_info in variable_policies.items():
print(f"\n{policy_name}:")
print(f" Description: {policy_info['description']}")
print(f" Policy: {json.dumps(policy_info['policy'], indent=2)}")
return variable_policies
def create_dynamic_policy_generator():
"""
Create dynamic policy generator
"""
class DynamicPolicyGenerator:
def __init__(self):
self.base_templates = {}
def register_template(self, name, template):
"""Register policy template"""
self.base_templates[name] = template
def generate_user_specific_policy(self, username, department, resources):
"""Generate user-specific policy"""
user_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowUserSpecificS3Access",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": f"arn:aws:s3:::user-data/{username}/*"
},
{
"Sid": "AllowDepartmentSharedAccess",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": f"arn:aws:s3:::shared-data/{department.lower()}/*"
}
]
}
# Add resource-specific permissions
if resources:
for resource in resources:
if resource['type'] == 'ec2':
user_policy['Statement'].append({
"Sid": f"AllowEC2Access{resource['name']}",
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RebootInstances"
],
"Resource": resource['arn'],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Owner": username
}
}
})
return user_policy
def generate_role_specific_policy(self, service_name, permissions_level):
"""Generate role-specific policy"""
service_policies = {
"lambda": {
"basic": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
},
"s3_access": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::lambda-data/*"
}
]
}
}
}
return service_policies.get(service_name, {}).get(permissions_level, {})
def apply_security_constraints(self, policy, constraints):
"""Apply security constraints to policy"""
enhanced_policy = policy.copy()
# Add common security conditions
security_conditions = {
"Bool": {
"aws:SecureTransport": "true"
}
}
if constraints.get('require_mfa'):
security_conditions["Bool"]["aws:MultiFactorAuthPresent"] = "true"
security_conditions["NumericLessThan"] = {
"aws:MultiFactorAuthAge": str(constraints.get('mfa_max_age', 3600))
}
if constraints.get('ip_restriction'):
security_conditions["IpAddress"] = {
"aws:SourceIp": constraints['ip_restriction']
}
if constraints.get('time_restriction'):
if 'start_time' in constraints['time_restriction']:
security_conditions["DateGreaterThan"] = {
"aws:CurrentTime": constraints['time_restriction']['start_time']
}
if 'end_time' in constraints['time_restriction']:
security_conditions["DateLessThan"] = {
"aws:CurrentTime": constraints['time_restriction']['end_time']
}
# Apply security conditions to all statements
for statement in enhanced_policy.get('Statement', []):
if 'Condition' not in statement:
statement['Condition'] = {}
# Merge conditions
for condition_type, condition_value in security_conditions.items():
if condition_type not in statement['Condition']:
statement['Condition'][condition_type] = {}
statement['Condition'][condition_type].update(condition_value)
return enhanced_policy
return DynamicPolicyGenerator()
# Demonstrate policy variables
variable_policies = demonstrate_policy_variables()
# Create and use dynamic policy generator
policy_generator = create_dynamic_policy_generator()
# Generate user-specific policy
user_policy = policy_generator.generate_user_specific_policy(
username="john.doe",
department="Engineering",
resources=[
{
"type": "ec2",
"name": "DevServer",
"arn": "arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0"
}
]
)
print("\nDynamically Generated User Policy:")
print(json.dumps(user_policy, indent=2))
# Apply security constraints
constraints = {
"require_mfa": True,
"mfa_max_age": 1800, # 30 minutes
"ip_restriction": ["203.0.113.0/24"],
"time_restriction": {
"start_time": "2024-01-01T00:00:00Z",
"end_time": "2024-12-31T23:59:59Z"
}
}
secured_policy = policy_generator.apply_security_constraints(user_policy, constraints)
print("\nPolicy After Applying Security Constraints:")
print(json.dumps(secured_policy, indent=2))
4.4 Policy Evaluation Logic
4.4.1 Policy Evaluation Order
def demonstrate_policy_evaluation_logic():
"""
Demonstrate IAM policy evaluation logic and precedence
"""
# Policy evaluation order
evaluation_order = {
1: {
"step": "Explicit Deny Check",
"description": "Check if there's an explicit Deny statement in any policy",
"result": "If matching Deny found, immediately deny request"
},
2: {
"step": "Organization SCP Check",
"description": "Check AWS Organizations service control policies",
"result": "If SCP doesn't allow, deny request"
},
3: {
"step": "Resource Policy Check",
"description": "Check resource-based policies on the resource",
"result": "If resource policy allows, may allow request"
},
4: {
"step": "Permissions Boundary Check",
"description": "Check IAM entity's permissions boundary",
"result": "Permissions boundary limits maximum permissions"
},
5: {
"step": "Identity Policy Check",
"description": "Check identity policies of user, group, and role",
"result": "If identity policy allows, may allow request"
},
6: {
"step": "Session Policy Check",
"description": "Check session policy provided during AssumeRole",
"result": "Session policy further limits permissions"
},
7: {
"step": "Default Deny",
"description": "If no explicit allow, default deny",
"result": "Deny request"
}
}
print("IAM Policy Evaluation Order:")
for step_num, step_info in evaluation_order.items():
print(f"\n{step_num}. {step_info['step']}")
print(f" Description: {step_info['description']}")
print(f" Result: {step_info['result']}")
# Create policy evaluation examples
evaluation_examples = {
"explicit_deny_wins": {
"scenario": "Explicit deny has highest precedence",
"policies": {
"identity_policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
},
"resource_policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:DeleteObject",
"Resource": "arn:aws:s3:::critical-data/*"
}
]
}
},
"result": "DeleteObject action is denied because explicit deny has highest precedence"
},
"permissions_boundary_limitation": {
"scenario": "Permissions boundary limitation",
"policies": {
"identity_policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
},
"permissions_boundary": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
},
"result": "Only S3 operations allowed, other service operations blocked by permissions boundary"
},
"session_policy_restriction": {
"scenario": "Session policy further restricts",
"policies": {
"role_policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
},
"session_policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::specific-bucket/*"
}
]
}
},
"result": "Only allowed to read objects from specific bucket, other S3 operations restricted by session policy"
}
}
print("\nPolicy Evaluation Examples:")
for example_name, example_info in evaluation_examples.items():
print(f"\n{example_name}:")
print(f" Scenario: {example_info['scenario']}")
print(f" Result: {example_info['result']}")
for policy_type, policy_content in example_info['policies'].items():
print(f"\n {policy_type}:")
print(f" {json.dumps(policy_content, indent=2)}")
return evaluation_order, evaluation_examples
def create_policy_evaluation_simulator():
"""
Create policy evaluation simulator
"""
class PolicyEvaluationSimulator:
def __init__(self):
self.policies = {
'identity_policies': [],
'resource_policies': [],
'permissions_boundaries': [],
'session_policies': [],
'scp_policies': []
}
def add_policy(self, policy_type, policy_document):
"""Add policy to simulator"""
if policy_type in self.policies:
self.policies[policy_type].append(policy_document)
def evaluate_request(self, action, resource, principal=None, conditions=None):
"""Simulate policy evaluation process"""
evaluation_result = {
'action': action,
'resource': resource,
'principal': principal,
'conditions': conditions or {},
'decision': 'Deny', # Default deny
'evaluation_steps': []
}
# Step 1: Check explicit deny
explicit_deny = self._check_explicit_deny(action, resource, conditions)
evaluation_result['evaluation_steps'].append({
'step': 1,
'name': 'Explicit Deny Check',
'result': 'Deny' if explicit_deny else 'No explicit deny found',
'decision': 'Deny' if explicit_deny else 'Continue'
})
if explicit_deny:
evaluation_result['decision'] = 'Deny'
evaluation_result['reason'] = 'Explicit deny found'
return evaluation_result
# Step 2: Check organization SCP (simulated)
scp_allow = self._check_scp_policies(action, resource)
evaluation_result['evaluation_steps'].append({
'step': 2,
'name': 'Organization SCP Check',
'result': 'Allow' if scp_allow else 'Deny',
'decision': 'Continue' if scp_allow else 'Deny'
})
if not scp_allow:
evaluation_result['decision'] = 'Deny'
evaluation_result['reason'] = 'Organization SCP denies'
return evaluation_result
# Step 3: Check resource policy
resource_policy_allow = self._check_resource_policies(action, resource, principal)
evaluation_result['evaluation_steps'].append({
'step': 3,
'name': 'Resource Policy Check',
'result': 'Allow' if resource_policy_allow else 'No explicit allow',
'decision': 'Continue'
})
# Step 4: Check permissions boundary
permissions_boundary_allow = self._check_permissions_boundaries(action, resource)
evaluation_result['evaluation_steps'].append({
'step': 4,
'name': 'Permissions Boundary Check',
'result': 'Allow' if permissions_boundary_allow else 'Deny',
'decision': 'Continue' if permissions_boundary_allow else 'Deny'
})
if not permissions_boundary_allow:
evaluation_result['decision'] = 'Deny'
evaluation_result['reason'] = 'Permissions boundary denies'
return evaluation_result
# Step 5: Check identity policy
identity_policy_allow = self._check_identity_policies(action, resource, conditions)
evaluation_result['evaluation_steps'].append({
'step': 5,
'name': 'Identity Policy Check',
'result': 'Allow' if identity_policy_allow else 'No explicit allow',
'decision': 'Continue' if identity_policy_allow else 'Deny'
})
# Step 6: Check session policy
session_policy_allow = self._check_session_policies(action, resource)
evaluation_result['evaluation_steps'].append({
'step': 6,
'name': 'Session Policy Check',
'result': 'Allow' if session_policy_allow else 'No restriction',
'decision': 'Continue'
})
# Final decision
if (resource_policy_allow or identity_policy_allow) and session_policy_allow:
evaluation_result['decision'] = 'Allow'
evaluation_result['reason'] = 'Request allowed by policies'
else:
evaluation_result['decision'] = 'Deny'
evaluation_result['reason'] = 'No explicit allow found (implicit deny)'
return evaluation_result
def _check_explicit_deny(self, action, resource, conditions):
"""Check if there's an explicit deny"""
all_policies = (
self.policies['identity_policies'] +
self.policies['resource_policies'] +
self.policies['session_policies']
)
for policy in all_policies:
for statement in policy.get('Statement', []):
if (statement.get('Effect') == 'Deny' and
self._action_matches(action, statement.get('Action', [])) and
self._resource_matches(resource, statement.get('Resource', []))):
return True
return False
def _check_scp_policies(self, action, resource):
"""Check organization SCP policies"""
if not self.policies['scp_policies']:
return True # No SCP policies, allow
for policy in self.policies['scp_policies']:
for statement in policy.get('Statement', []):
if (statement.get('Effect') == 'Allow' and
self._action_matches(action, statement.get('Action', [])) and
self._resource_matches(resource, statement.get('Resource', []))):
return True
return False
def _check_resource_policies(self, action, resource, principal):
"""Check resource policies"""
for policy in self.policies['resource_policies']:
for statement in policy.get('Statement', []):
if (statement.get('Effect') == 'Allow' and
self._action_matches(action, statement.get('Action', [])) and
self._resource_matches(resource, statement.get('Resource', [])) and
self._principal_matches(principal, statement.get('Principal', {}))):
return True
return False
def _check_permissions_boundaries(self, action, resource):
"""Check permissions boundaries"""
if not self.policies['permissions_boundaries']:
return True # No permissions boundary, no restriction
for policy in self.policies['permissions_boundaries']:
for statement in policy.get('Statement', []):
if (statement.get('Effect') == 'Allow' and
self._action_matches(action, statement.get('Action', [])) and
self._resource_matches(resource, statement.get('Resource', []))):
return True
return False
def _check_identity_policies(self, action, resource, conditions):
"""Check identity policies"""
for policy in self.policies['identity_policies']:
for statement in policy.get('Statement', []):
if (statement.get('Effect') == 'Allow' and
self._action_matches(action, statement.get('Action', [])) and
self._resource_matches(resource, statement.get('Resource', []))):
return True
return False
def _check_session_policies(self, action, resource):
"""Check session policies"""
if not self.policies['session_policies']:
return True # No session policy, no restriction
for policy in self.policies['session_policies']:
for statement in policy.get('Statement', []):
if (statement.get('Effect') == 'Allow' and
self._action_matches(action, statement.get('Action', [])) and
self._resource_matches(resource, statement.get('Resource', []))):
return True
return False
def _action_matches(self, requested_action, policy_actions):
"""Check if action matches"""
if isinstance(policy_actions, str):
policy_actions = [policy_actions]
for policy_action in policy_actions:
if policy_action == '*' or policy_action == requested_action:
return True
if policy_action.endswith('*'):
prefix = policy_action[:-1]
if requested_action.startswith(prefix):
return True
return False
def _resource_matches(self, requested_resource, policy_resources):
"""Check if resource matches"""
if isinstance(policy_resources, str):
policy_resources = [policy_resources]
for policy_resource in policy_resources:
if policy_resource == '*' or policy_resource == requested_resource:
return True
if policy_resource.endswith('*'):
prefix = policy_resource[:-1]
if requested_resource.startswith(prefix):
return True
return False
def _principal_matches(self, requested_principal, policy_principal):
"""Check if principal matches"""
if not policy_principal:
return True
if policy_principal == '*':
return True
# Simplified principal matching logic
return True
return PolicyEvaluationSimulator()
# Demonstrate policy evaluation logic
evaluation_order, evaluation_examples = demonstrate_policy_evaluation_logic()
# Create and use policy evaluation simulator
simulator = create_policy_evaluation_simulator()
# Add example policies
identity_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
deny_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "s3:DeleteObject",
"Resource": "*"
}
]
}
simulator.add_policy('identity_policies', identity_policy)
simulator.add_policy('identity_policies', deny_policy)
# Simulate policy evaluation
result1 = simulator.evaluate_request(
action='s3:GetObject',
resource='arn:aws:s3:::my-bucket/file.txt',
principal='arn:aws:iam::123456789012:user/testuser'
)
result2 = simulator.evaluate_request(
action='s3:DeleteObject',
resource='arn:aws:s3:::my-bucket/file.txt',
principal='arn:aws:iam::123456789012:user/testuser'
)
print("\nPolicy Evaluation Simulation Results:")
print("\nAllowed GetObject request:")
print(json.dumps(result1, indent=2, default=str))
print("\nDenied DeleteObject request:")
print(json.dumps(result2, indent=2, default=str))
4.5 Policy Types and Use Cases
4.5.1 Different Types of Policies
def demonstrate_policy_types():
"""
Demonstrate different types of IAM policies and their use cases
"""
policy_types = {
"identity_based_policies": {
"description": "Policies attached to IAM identities (users, groups, roles)",
"types": {
"managed_policies": {
"aws_managed": "Pre-defined policies provided by AWS",
"customer_managed": "Policies created and managed by customer"
},
"inline_policies": "Policies embedded directly into a single identity"
},
"use_cases": [
"Define permissions for users, groups, or roles",
"Share same permissions across multiple identities",
"Provide baseline permission sets"
]
},
"resource_based_policies": {
"description": "Policies attached to AWS resources",
"examples": ["S3 bucket policies", "SQS queue policies", "KMS key policies", "Lambda resource policies"],
"use_cases": [
"Define who can access specific resources",
"Cross-account resource sharing",
"Resource-level access control"
]
},
"permissions_boundaries": {
"description": "Define maximum permissions boundary for IAM entity",
"use_cases": [
"Limit developer's maximum permissions",
"Implement permission delegation",
"Enterprise governance and compliance"
]
},
"organization_scps": {
"description": "AWS Organizations service control policies",
"use_cases": [
"Limit service usage at organization level",
"Prevent accidental high-cost operations",
"Enforce compliance requirements"
]
},
"session_policies": {
"description": "Temporary policies provided during AssumeRole",
"use_cases": [
"Further limit role permissions",
"Provide temporary fine-grained control",
"Dynamic permission adjustment"
]
}
}
# Create examples of different policy types
policy_examples = {
"identity_based_managed": {
"name": "S3ReadOnlyAccess-Custom",
"description": "Custom S3 read-only access policy",
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetBucketVersioning"
],
"Resource": [
"arn:aws:s3:::company-data-*",
"arn:aws:s3:::company-data-*/*"
]
}
]
}
},
"resource_based_s3": {
"name": "S3BucketCrossAccountPolicy",
"description": "Allow cross-account access to S3 bucket",
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountRead",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111122223333:root",
"arn:aws:iam::444455556666:user/trusted-user"
]
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::shared-bucket",
"arn:aws:s3:::shared-bucket/*"
],
"Condition": {
"StringEquals": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
}
]
}
},
"permissions_boundary": {
"name": "DeveloperPermissionsBoundary",
"description": "Developer permissions boundary",
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*",
"dynamodb:*",
"lambda:*",
"ec2:Describe*",
"ec2:RunInstances",
"ec2:StopInstances",
"ec2:StartInstances"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"iam:*",
"organizations:*",
"account:*",
"billing:*"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": "ec2:TerminateInstances",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"ec2:ResourceTag/Environment": ["Dev", "Test"]
}
}
}
]
}
},
"organization_scp": {
"name": "PreventHighCostServices",
"description": "SCP to prevent using high-cost services",
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"sagemaker:*",
"redshift:*",
"emr:*"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "*",
"Condition": {
"ForAnyValue:StringNotEquals": {
"ec2:InstanceType": [
"t2.micro",
"t2.small",
"t3.micro",
"t3.small"
]
}
}
}
]
}
},
"session_policy": {
"name": "TemporaryReadOnlyAccess",
"description": "Temporary read-only access session policy",
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket",
"ec2:Describe*",
"cloudwatch:Get*",
"cloudwatch:List*",
"cloudwatch:Describe*"
],
"Resource": "*"
}
]
}
}
}
print("IAM Policy Type Descriptions:")
for policy_type, info in policy_types.items():
print(f"\n{policy_type.replace('_', ' ').title()}:")
print(f" Description: {info['description']}")
if 'types' in info:
print(" Subtypes:")
for subtype, subdesc in info['types'].items():
if isinstance(subdesc, dict):
print(f" {subtype}:")
for k, v in subdesc.items():
print(f" - {k}: {v}")
else:
print(f" - {subtype}: {subdesc}")
if 'examples' in info:
print(f" Examples: {', '.join(info['examples'])}")
print(" Use cases:")
for use_case in info['use_cases']:
print(f" - {use_case}")
print("\nPolicy Examples:")
for example_name, example_info in policy_examples.items():
print(f"\n{example_name}:")
print(f" Name: {example_info['name']}")
print(f" Description: {example_info['description']}")
print(f" Policy content:")
print(json.dumps(example_info['policy'], indent=4))
return policy_types, policy_examples
def create_policy_management_system():
"""
Create policy management system
"""
class PolicyManagementSystem:
def __init__(self):
self.iam = boto3.client('iam')
self.policy_templates = {}
self.policy_versions = {}
def create_managed_policy(self, policy_name, policy_document, description=""):
"""Create managed policy"""
try:
response = self.iam.create_policy(
PolicyName=policy_name,
PolicyDocument=json.dumps(policy_document),
Description=description,
Tags=[
{
'Key': 'ManagedBy',
'Value': 'PolicyManagementSystem'
},
{
'Key': 'CreatedDate',
'Value': datetime.now().strftime('%Y-%m-%d')
}
]
)
policy_arn = response['Policy']['Arn']
print(f"Managed policy created successfully: {policy_arn}")
return policy_arn
except Exception as e:
print(f"Failed to create managed policy: {str(e)}")
return None
def create_policy_version(self, policy_arn, new_policy_document):
"""Create new policy version"""
try:
# Get current version information
policy = self.iam.get_policy(PolicyArn=policy_arn)
current_versions = self.iam.list_policy_versions(PolicyArn=policy_arn)
# Check version count limit (max 5 versions)
if len(current_versions['Versions']) >= 5:
# Delete oldest non-default version
oldest_version = None
for version in current_versions['Versions']:
if not version['IsDefaultVersion']:
if oldest_version is None or version['CreateDate'] < oldest_version['CreateDate']:
oldest_version = version
if oldest_version:
self.iam.delete_policy_version(
PolicyArn=policy_arn,
VersionId=oldest_version['VersionId']
)
print(f"Deleted old version: {oldest_version['VersionId']}")
# Create new version
response = self.iam.create_policy_version(
PolicyArn=policy_arn,
PolicyDocument=json.dumps(new_policy_document),
SetAsDefault=True
)
version_id = response['PolicyVersion']['VersionId']
print(f"New policy version created successfully: {version_id}")
return version_id
except Exception as e:
print(f"Failed to create policy version: {str(e)}")
return None
def attach_policy_to_entity(self, policy_arn, entity_type, entity_name):
"""Attach policy to IAM entity"""
try:
if entity_type == 'user':
self.iam.attach_user_policy(
UserName=entity_name,
PolicyArn=policy_arn
)
elif entity_type == 'role':
self.iam.attach_role_policy(
RoleName=entity_name,
PolicyArn=policy_arn
)
elif entity_type == 'group':
self.iam.attach_group_policy(
GroupName=entity_name,
PolicyArn=policy_arn
)
else:
raise ValueError(f"Unsupported entity type: {entity_type}")
print(f"Policy attached to {entity_type}: {entity_name}")
return True
except Exception as e:
print(f"Failed to attach policy: {str(e)}")
return False
def set_permissions_boundary(self, entity_type, entity_name, boundary_policy_arn):
"""Set permissions boundary"""
try:
if entity_type == 'user':
self.iam.put_user_permissions_boundary(
UserName=entity_name,
PermissionsBoundary=boundary_policy_arn
)
elif entity_type == 'role':
self.iam.put_role_permissions_boundary(
RoleName=entity_name,
PermissionsBoundary=boundary_policy_arn
)
else:
raise ValueError(f"Permissions boundary not supported for entity type: {entity_type}")
print(f"Permissions boundary set for {entity_type}: {entity_name}")
return True
except Exception as e:
print(f"Failed to set permissions boundary: {str(e)}")
return False
def validate_policy_permissions(self, policy_arn, test_cases):
"""Validate policy permissions"""
try:
validation_results = []
for test_case in test_cases:
response = self.iam.simulate_principal_policy(
PolicySourceArn=policy_arn,
ActionNames=[test_case['action']],
ResourceArns=[test_case['resource']],
ContextEntries=test_case.get('context', [])
)
for result in response['EvaluationResults']:
validation_results.append({
'action': result['EvalActionName'],
'resource': result['EvalResourceName'],
'decision': result['EvalDecision'],
'expected': test_case.get('expected', 'Allow'),
'passed': result['EvalDecision'] == test_case.get('expected', 'Allow')
})
print("Policy Validation Results:")
for result in validation_results:
status = "Pass" if result['passed'] else "Fail"
print(f" {status} {result['action']} on {result['resource']}: "
f"{result['decision']} (expected: {result['expected']})")
return validation_results
except Exception as e:
print(f"Policy validation failed: {str(e)}")
return []
def generate_policy_report(self, policy_arn):
"""Generate policy report"""
try:
# Get policy details
policy = self.iam.get_policy(PolicyArn=policy_arn)
policy_version = self.iam.get_policy_version(
PolicyArn=policy_arn,
VersionId=policy['Policy']['DefaultVersionId']
)
# Get policy usage
entities = self.iam.list_entities_for_policy(PolicyArn=policy_arn)
report = {
'policy_name': policy['Policy']['PolicyName'],
'policy_arn': policy_arn,
'created_date': policy['Policy']['CreateDate'],
'updated_date': policy['Policy']['UpdateDate'],
'description': policy['Policy']['Description'],
'default_version': policy['Policy']['DefaultVersionId'],
'attached_to': {
'users': [user['UserName'] for user in entities['PolicyUsers']],
'groups': [group['GroupName'] for group in entities['PolicyGroups']],
'roles': [role['RoleName'] for role in entities['PolicyRoles']]
},
'policy_document': policy_version['PolicyVersion']['Document']
}
print("Policy Report:")
print(f" Policy name: {report['policy_name']}")
print(f" Created date: {report['created_date']}")
print(f" Updated date: {report['updated_date']}")
print(f" Description: {report['description']}")
print(f" Current version: {report['default_version']}")
print(f" Attached to users: {len(report['attached_to']['users'])}")
print(f" Attached to groups: {len(report['attached_to']['groups'])}")
print(f" Attached to roles: {len(report['attached_to']['roles'])}")
return report
except Exception as e:
print(f"Failed to generate policy report: {str(e)}")
return None
return PolicyManagementSystem()
# Demonstrate policy types
policy_types, policy_examples = demonstrate_policy_types()
# Create policy management system
policy_mgmt = create_policy_management_system()
# Example: create and manage policies
example_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-app-bucket/*",
"Condition": {
"StringEquals": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
}
]
}
# Note: Actual execution requires valid AWS credentials
print("\nPolicy Management System Example:")
print("Ready for creating managed policies, version control, attaching policies, and other functions")
Summary
This chapter provided in-depth coverage of AWS IAM policies:
- Basic Syntax: Mastered JSON policy document structure and usage of each element
- Condition System: Understood condition operators, modifiers, and complex condition combinations
- Policy Variables: Learned dynamic references and variable substitution for flexible permission control
- Evaluation Logic: Understood policy evaluation precedence and decision flow
- Policy Types: Mastered characteristics and applicable scenarios of different policy types
Through this chapter, you should be able to:
- Write IAM policies following best practices
- Use conditions and variables to implement fine-grained permission control
- Understand policy evaluation mechanism and debug permission issues
- Manage different types of policies to meet various business needs
- Implement policy version control and permission auditing
The next chapter will cover advanced applications of permissions boundaries and service control policies.