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

  1. Master the JSON syntax structure of IAM policies
  2. Understand the usage of policy elements and attributes
  3. Learn condition blocks and condition operators
  4. Master policy variables and dynamic references
  5. 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:

  1. Basic Syntax: Mastered JSON policy document structure and usage of each element
  2. Condition System: Understood condition operators, modifiers, and complex condition combinations
  3. Policy Variables: Learned dynamic references and variable substitution for flexible permission control
  4. Evaluation Logic: Understood policy evaluation precedence and decision flow
  5. 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.