AWS CLI First #3: Crafting Granular JSON Policies, Boundaries & Policy Simulator
Master AWS Least Privilege from the terminal. Learn how to write fine-grained JSON IAM policies, evaluate permissions using the IAM Policy Simulator CLI, enforce permission boundaries against privilege escalation, and implement account guardrails.
AWS with CLI: The Terminal-First Mastery Path
Part of the CLI-first comprehensive learning path from foundational setup to production cloud architectures.
In Part 1 and Part 2, we set up our CLI environment, configured MFA-enforced role assumption, and simulated our zero-privilege engineer (engineer-bob).
However, in both previous parts, we relied on coarse AWS-managed policies like AdministratorAccess and AmazonEC2FullAccess.
In production cloud security, relying on broad managed policies violates the Principle of Least Privilege:
- Excessive Blast Radius:
AmazonEC2FullAccessallows an engineer to delete production VPC gateways, wipe snapshot backups, or launch expensive GPU instances. - No Tag-Based Scoping: AWS-managed policies cannot restrict access to specific environments (e.g. allowing deployments in
Stagingwhile strictly blocking modifications inProduction). - No Dynamic Variable Interpolation: Managed policies cannot dynamically isolate users to their own private storage folders or credentials.
In this guide, we master Custom JSON Permission Engineering entirely from the terminal.
By the end of this guide, you will:
- Master the 5 structural primitives of an IAM policy document.
- Understand the 3-way policy evaluation matrix (Implicit Deny vs Explicit Allow vs Explicit Deny).
- Use Policy Variables (
${aws:username}) to build automated self-service credentials management. - Craft fine-grained infrastructure policies scoped by resource tags (
aws:ResourceTag/Environment). - Test and debug permissions before deployment using the AWS IAM Policy Simulator CLI.
- Enforce Permissions Boundaries to prevent junior developers from escalating their own privileges.
- Manage policy lifecycle, revisions, and instant rollbacks using IAM Policy Versioning.
💰 Estimated Lab Cost
| Component | Usage in Lab | AWS Cost |
|---|---|---|
| Custom Customer Managed Policies | JSON Policy Creation & Versioning | $0.00 (100% Free) |
| IAM Policy Simulator API | Permission Dry-Run Evaluation | $0.00 (100% Free) |
| Permissions Boundaries | Guardrail Enforcement | $0.00 (100% Free) |
| Total Estimated Cost | Complete Hands-On Session | $0.00 (100% Free) |
Core Concept: Anatomy of an IAM Policy JSON
Every IAM policy document in AWS is a JSON structure containing one or more Statements. Each Statement is constructed from 5 foundational building blocks:
+-------------------------------------------------------------------------------+
| IAM Policy Document JSON |
+-------------------------------------------------------------------------------+
| |
| { |
| "Version": "2012-10-17", |
| "Statement": [ |
| { |
| "Sid": "AllowStagingEC2Ops", <-- Statement Identifier |
| "Effect": "Allow", <-- Allow or Deny |
| "Action": [ <-- API verbs to permit/block |
| "ec2:StartInstances", |
| "ec2:StopInstances" |
| ], |
| "Resource": "arn:aws:ec2:*:*:instance/*", <-- Target ARN |
| "Condition": { <-- Contextual constraints |
| "StringEquals": { |
| "aws:ResourceTag/Environment": "Staging" |
| } |
| } |
| } |
| ] |
| } |
+-------------------------------------------------------------------------------+
The 5 Policy Primitives Explained:
Sid(Statement ID): An optional human-readable label (e.g.AllowStagingEC2Ops) to document the purpose of the statement.Effect: Must be either"Allow"or"Deny".Action: Specifies the exact API operations. You can use wildcards (e.g.ec2:Describe*) or exact API verbs (e.g.s3:GetObject).Resource: The Amazon Resource Name (ARN) of the target assets. For actions that do not support resource-level permissions (likeec2:DescribeInstances), this must be"*".Condition: Fine-grained contextual rules (e.g. IP CIDR whitelists, MFA presence, request timestamps, or resource tags).
Core Concept: The 3-Way Policy Evaluation Matrix
How does AWS decide whether to permit or reject an API request when multiple policies are attached?
AWS evaluates authorization through a strict, deterministic evaluation chain:
[ Incoming AWS API Request ]
|
v
+-------------------------------+
| Is there an EXPLICIT DENY? | -- YES --> [ 403 ACCESS DENIED ]
+-------------------------------+ (Overrides everything!)
|
NO
|
v
+-------------------------------+
| Is there an EXPLICIT ALLOW? | -- YES --> [ 200 ALLOWED ]
+-------------------------------+
|
NO
|
v
[ IMPLICIT DENY ]
(Default safe state:
403 Access Denied)
The Golden Rules of IAM Evaluation:
- Default is Always Deny (Implicit Deny): By default, all requests are blocked until an explicit
Allowstatement grants access. - Explicit Allow Grants Access: If a policy statement matches the action and resource with
"Effect": "Allow", the request is authorized. - Explicit Deny TRUMPS EVERYTHING: If any matching statement contains
"Effect": "Deny", the request is immediately blocked, regardless of how manyAllowpolicies are attached.
Core Concept: Dynamic Policy Variables (${aws:username})
Writing separate policies for every individual developer (alice-policy.json, bob-policy.json) does not scale.
AWS IAM solves this with Policy Variables. When an API request is made, AWS automatically substitutes ${aws:username} with the caller’s actual identity:
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::company-engineering-vault/${aws:username}/*"
}
- When Alice calls
s3:GetObject, the ARN resolves to:company-engineering-vault/alice/* - When Bob calls
s3:GetObject, the ARN resolves to:company-engineering-vault/engineer-bob/*
This single policy dynamically creates private home directories for thousands of engineers without authoring separate documents.
Core Concept: The Defense-in-Depth Hierarchy
In enterprise cloud security, multiple guardrails operate together:
| Policy Layer | Attached To | Purpose | Can it grant permissions? |
|---|---|---|---|
| Identity-Based Policy | IAM User / Role / Group | Grants specific permissions to callers | Yes |
| Resource-Based Policy | S3 Bucket, SQS Queue, KMS Key | Dictates who can access this specific resource | Yes |
| Permissions Boundary | IAM User / Role | Sets the maximum ceiling of allowed permissions | No (Limits only) |
| Service Control Policy (SCP) | AWS Account / Organizational Unit | Account-wide guardrails across AWS Organizations | No (Limits only) |
Phase 1: Crafting the Developer Self-Service MFA Policy
Let’s begin by authoring a reusable, enterprise-grade policy named DeveloperSelfManageMFA using policy variables.
This policy allows developers to manage their own passwords, access keys, and MFA devices without granting them permission to modify any other team member’s credentials.
Step 1: Create self-manage-mfa-policy.json
Run the following command in your terminal to generate the policy definition:
cat <<'EOF' > self-manage-mfa-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowViewAccountInfo",
"Effect": "Allow",
"Action": [
"iam:GetAccountSummary",
"iam:ListAccountAliases",
"iam:ListUsers"
],
"Resource": "*"
},
{
"Sid": "AllowSelfManageCredentials",
"Effect": "Allow",
"Action": [
"iam:ChangePassword",
"iam:GetUser",
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowSelfManageMFA",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice",
"iam:DeleteVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ResyncMFADevice",
"iam:ListMFADevices"
],
"Resource": [
"arn:aws:iam::*:mfa/${aws:username}-mfa",
"arn:aws:iam::*:user/${aws:username}"
]
}
]
}
EOF
Step 2: Create the Customer Managed Policy via CLI
Using your administrator profile (cloud-dev-admin), publish this policy to your AWS account:
aws iam create-policy \
--policy-name DeveloperSelfManageMFA \
--policy-document file://self-manage-mfa-policy.json \
--description "Allows developers to manage their own keys and MFA devices" \
--profile cloud-dev-admin
JSON Output:
{
"Policy": {
"PolicyName": "DeveloperSelfManageMFA",
"PolicyId": "ANPAEXAMPLEPOLICYID",
"Arn": "arn:aws:iam::123456789012:policy/DeveloperSelfManageMFA",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"IsAttachable": true,
"CreateDate": "2026-08-29T01:00:00+00:00"
}
}
Step 3: Attach the Policy to the Developers Group
Instead of attaching the policy directly to Bob’s individual user account, we attach it to the Developers IAM Group we created in Part 2:
ACCOUNT_ID=$(aws sts get-caller-identity --profile cloud-dev-admin --query "Account" --output text)
aws iam attach-group-policy \
--group-name Developers \
--policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/DeveloperSelfManageMFA" \
--profile cloud-dev-admin
[!TIP] Why Group + Policy Variables is Enterprise Magic: Because the policy uses
arn:aws:iam::*:user/${aws:username}, attaching it toDevelopersgrants self-service permissions to all current and future engineers in the group.
- When
engineer-bobrunsiam:CreateAccessKey,${aws:username}evaluates toengineer-bob.- When
engineer-alicejoins next month, adding her toDevelopersgives her an isolated credential sandbox with zero additional policy authoring!
Clean up the local file:
rm -f self-manage-mfa-policy.json
Phase 2: Crafting Scoped Infrastructure Policies with Resource Tags
Now let’s author a scoped operational policy for staging environments: StagingEC2OperatorPolicy.
The Security Requirements:
- The engineer can query EC2 instances globally (
ec2:Describe*). - The engineer can
Start,Stop, andRebootinstances only if the instance has the tagEnvironment: Staging. - The engineer is explicitly denied from terminating (
ec2:TerminateInstances) any instance under all circumstances.
Step 1: Create staging-ec2-operator-policy.json
cat <<'EOF' > staging-ec2-operator-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowGlobalReadAndDiscovery",
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ec2:Get*",
"ec2:List*"
],
"Resource": "*"
},
{
"Sid": "AllowControlStagingInstancesOnly",
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RebootInstances"
],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Environment": "Staging"
}
}
},
{
"Sid": "ExplicitlyDenyTerminationEverywhere",
"Effect": "Deny",
"Action": [
"ec2:TerminateInstances"
],
"Resource": "*"
}
]
}
EOF
Step 2: Publish the Policy via CLI
aws iam create-policy \
--policy-name StagingEC2OperatorPolicy \
--policy-document file://staging-ec2-operator-policy.json \
--description "Scoped control for staging EC2 instances with termination block" \
--profile cloud-dev-admin
Step 3: Attach the Policy to the Developers Group
Attach this policy directly to the Developers group so Bob (and all developers) inherit it:
ACCOUNT_ID=$(aws sts get-caller-identity --profile cloud-dev-admin --query "Account" --output text)
aws iam attach-group-policy \
--group-name Developers \
--policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/StagingEC2OperatorPolicy" \
--profile cloud-dev-admin
Phase 3: Testing Policies with the AWS IAM Policy Simulator CLI
Before letting engineers run commands on live infrastructure, how do you verify that your JSON tag conditions work as expected?
The AWS CLI provides two powerful simulation commands:
simulate-principal-policy(Recommended): Tests the live, effective permissions of a real User or Role (including all policies inherited from their groups).simulate-custom-policy: Tests a raw offline JSON file before you attach or publish it.
Step 1: Test 1 - Simulating Allowed Action on Staging Instance
Let’s simulate Bob attempting to start an EC2 instance tagged with Environment: Staging:
aws iam simulate-principal-policy \
--policy-source-arn "arn:aws:iam::${ACCOUNT_ID}:user/engineer-bob" \
--action-names "ec2:StartInstances" \
--resource-arns "arn:aws:ec2:ap-southeast-1:${ACCOUNT_ID}:instance/i-0123456789abcdef0" \
--context-entries "ContextKeyName='aws:ResourceTag/Environment',ContextKeyValues='Staging',ContextKeyType='string'" \
--profile cloud-dev-admin \
--query "EvaluationResults[0].[EvalActionName, EvalDecision]" \
--output table
[!TIP] Simulating Raw JSON Files with
simulate-custom-policy: If you want to test the JSON file directly before attaching it, run:aws iam simulate-custom-policy \ --policy-input-list file://staging-ec2-operator-policy.json \ --action-names "ec2:StartInstances" \ --resource-arns "arn:aws:ec2:ap-southeast-1:${ACCOUNT_ID}:instance/i-0123456789abcdef0" \ --context-entries "ContextKeyName='aws:ResourceTag/Environment',ContextKeyValues='Staging',ContextKeyType='string'" \ --profile cloud-dev-admin \ --query "EvaluationResults[0].[EvalActionName, EvalDecision]" \ --output table
Simulator Output:
---------------------------------
| SimulatePrincipalPolicy |
+---------------------+---------+
| ec2:StartInstances | allowed|
+---------------------+---------+
Step 2: Test 2 - Simulating Blocked Action on Production Instance
What happens if Bob attempts to stop a Production instance (Environment: Production)?
aws iam simulate-principal-policy \
--policy-source-arn "arn:aws:iam::${ACCOUNT_ID}:user/engineer-bob" \
--action-names "ec2:StopInstances" \
--resource-arns "arn:aws:ec2:ap-southeast-1:${ACCOUNT_ID}:instance/i-0123456789abcdef0" \
--context-entries "ContextKeyName='aws:ResourceTag/Environment',ContextKeyValues='Production',ContextKeyType='string'" \
--profile cloud-dev-admin \
--query "EvaluationResults[0].[EvalActionName, EvalDecision]" \
--output table
Simulator Output:
---------------------------------
| SimulatePrincipalPolicy |
+-------------------+-----------+
| ec2:StopInstances| implicitDeny|
+-------------------+-----------+
Result: implicitDeny! The condition failed because the tag was Production, so the action was safely blocked.
Step 3: Test 3 - Simulating Explicit Deny (ec2:TerminateInstances)
What if Bob tries to terminate an instance, even one tagged as Staging?
aws iam simulate-principal-policy \
--policy-source-arn "arn:aws:iam::${ACCOUNT_ID}:user/engineer-bob" \
--action-names "ec2:TerminateInstances" \
--resource-arns "arn:aws:ec2:ap-southeast-1:${ACCOUNT_ID}:instance/i-0123456789abcdef0" \
--context-entries "ContextKeyName='aws:ResourceTag/Environment',ContextKeyValues='Staging',ContextKeyType='string'" \
--profile cloud-dev-admin \
--query "EvaluationResults[0].[EvalActionName, EvalDecision]" \
--output table
Simulator Output:
-------------------------------------
| SimulatePrincipalPolicy |
+------------------------+----------+
| ec2:TerminateInstances| explicitDeny|
+------------------------+----------+
Result: explicitDeny! The explicit Deny statement overrode all conditions.
Clean up the local file:
rm -f staging-ec2-operator-policy.json
Phase 4: Enforcing Permissions Boundaries (Preventing Privilege Escalation)
In many engineering organizations, developers need permissions to create IAM Roles for their serverless workloads (e.g. AWS Lambda functions, ECS task roles).
The Privilege Escalation Threat:
If developer Bob has iam:CreateRole and iam:AttachRolePolicy, Bob could create a new IAM role, attach AdministratorAccess to it, and assume the role—instantly escalating himself to full cloud root!
The Solution: Permissions Boundary
A Permissions Boundary is an advanced IAM feature that acts as a maximum ceiling. Even if Bob attaches AdministratorAccess to a role, the role can never perform actions outside the boundary.
+-------------------------------------------------------------------------------+
| Effective Permission Calculation |
+-------------------------------------------------------------------------------+
| |
| [ Identity Permission Policy ] [ Permissions Boundary ] |
| (e.g. AdministratorAccess) ∩ (e.g. S3 & CloudWatch Logs Only) |
| |
| = |
| |
| [ EFFECTIVE PERMISSION ] |
| (Only S3 & CloudWatch Logs!) |
| |
+-------------------------------------------------------------------------------+
Step 1: Create developer-boundary-policy.json
Let’s create a boundary policy that caps all operations strictly to EC2, S3, and CloudWatch:
cat <<'EOF' > developer-boundary-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowedServicesCeiling",
"Effect": "Allow",
"Action": [
"ec2:*",
"s3:*",
"logs:*",
"cloudwatch:*"
],
"Resource": "*"
},
{
"Sid": "BlockIAMModifications",
"Effect": "Deny",
"Action": [
"iam:*",
"organizations:*",
"account:*"
],
"Resource": "*"
}
]
}
EOF
Step 2: Publish the Boundary Policy via CLI
aws iam create-policy \
--policy-name DeveloperBoundaryCeiling \
--policy-document file://developer-boundary-policy.json \
--description "Maximum permission boundary ceiling for engineering users" \
--profile cloud-dev-admin
Step 3: Attach the Boundary to engineer-bob
Apply the boundary to Bob using aws iam put-user-permissions-boundary:
aws iam put-user-permissions-boundary \
--user-name engineer-bob \
--permissions-boundary "arn:aws:iam::${ACCOUNT_ID}:policy/DeveloperBoundaryCeiling" \
--profile cloud-dev-admin
Verify that Bob now has an active boundary:
aws iam get-user --user-name engineer-bob --profile cloud-dev-admin --query "User.PermissionsBoundary" --output json
Output:
{
"PermissionsBoundaryType": "Policy",
"PermissionsBoundaryArn": "arn:aws:iam::123456789012:policy/DeveloperBoundaryCeiling"
}
Now, even if an administrator accidentally attaches AdministratorAccess directly to Bob, Bob is mathematically barred from modifying IAM, billing, or organization settings because the boundary caps his maximum permissions!
Clean up the local file:
rm -f developer-boundary-policy.json
Phase 5: Policy Versioning & Instant Rollbacks via CLI
Unlike code repositories where Git handles history, AWS IAM has native policy versioning built into the API.
Each customer-managed policy retains up to 5 versions (v1, v2, v3, v4, v5). You can modify, inspect, and instantly roll back policies from the command line.
Step 1: Create a New Policy Version (v2)
Let’s say we want to update DeveloperSelfManageMFA to also allow developers to inspect STS caller identities:
cat <<'EOF' > updated-self-mfa.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSelfManageCredentialsAndSTS",
"Effect": "Allow",
"Action": [
"iam:ChangePassword",
"iam:GetUser",
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:ListAccessKeys",
"sts:GetCallerIdentity"
],
"Resource": "*"
}
]
}
EOF
# Create version 2 and set it as the active default
aws iam create-policy-version \
--policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/DeveloperSelfManageMFA" \
--policy-document file://updated-self-mfa.json \
--set-as-default \
--profile cloud-dev-admin
Step 2: List All Policy Versions
aws iam list-policy-versions \
--policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/DeveloperSelfManageMFA" \
--profile cloud-dev-admin \
--output table
Output:
-------------------------------------------------------------------------
| ListPolicyVersions |
+------------------+------------+---------------------------------------+
| CreateDate | IsDefault | VersionId |
+------------------+------------+---------------------------------------+
| 2026-08-29T... | True | v2 |
| 2026-08-29T... | False | v1 |
+------------------+------------+---------------------------------------+
Step 3: Instant Rollback to v1
If a new policy version causes unexpected permission errors in production, you can instantly revert to v1 with a single command:
aws iam set-default-policy-version \
--policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/DeveloperSelfManageMFA" \
--version-id v1 \
--profile cloud-dev-admin
No re-uploading JSON or modifying user attachments required—the policy rollback takes effect across all attached users within milliseconds.
Clean up the local file:
rm -f updated-self-mfa.json
Phase 6: Multi-Account Guardrails with Service Control Policies (SCPs)
When operating multiple AWS accounts within an AWS Organization, IAM policies alone are not enough.
A rogue administrator in a child account could create an IAM user with AdministratorAccess and bypass local rules. To prevent this, organizations enforce Service Control Policies (SCPs) at the AWS Organization root.
+-------------------------------------------------------------------------------+
| AWS Organizations SCP Architecture |
+-------------------------------------------------------------------------------+
| |
| [ AWS Organization Root ] |
| | |
| +-- [ Service Control Policy: Region Restriction SCP ] |
| | |
| +--> [ Staging Account (111122223333) ] |
| | -> Enforces: All APIs outside ap-southeast-1 are DENIED |
| | |
| +--> [ Production Account (444455556666) ] |
| -> Enforces: Even ROOT cannot delete CloudTrail logs |
| |
+-------------------------------------------------------------------------------+
Real-World Example: Region-Locking SCP JSON
The following SCP denies all AWS infrastructure actions in any region other than Singapore (ap-southeast-1), protecting the company from expensive accidental deployments or cryptocurrency mining in unauthorized regions:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllOutsideSingapore",
"Effect": "Deny",
"NotAction": [
"iam:*",
"organizations:*",
"route53:*",
"cloudfront:*",
"support:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"ap-southeast-1"
]
}
}
}
]
}
[!TIP] Notice the
NotActionblock: global services like IAM, Route53, and CloudFront must be exempted because their APIs do not run in specific geographical regions.
Phase 7: Security Auditing & Compliance with IAM Credential Reports
How do security teams and compliance auditors (SOC2, ISO 27001, PCI-DSS) verify that all users have MFA enabled and that no stale access keys exist?
AWS provides the IAM Credential Report API, which generates an account-wide security audit table.
Step 1: Request Credential Report Generation
aws iam generate-credential-report --profile cloud-dev-admin
Output:
{
"State": "COMPLETE",
"Description": "No report exists. Generating a new report."
}
Step 2: Download and Inspect the Audit CSV
The report content is returned as a Base64-encoded CSV string. We can decode and format it directly in the terminal:
aws iam get-credential-report \
--profile cloud-dev-admin \
--query "Content" \
--output text | base64 -d | cut -d',' -f1,4,8,9,11,16 | column -s, -t
Formatted Audit Output:
user password_enabled mfa_active access_key_1_active access_key_1_last_rotated access_key_2_active
<root_account> not_supported true false N/A false
cloud-dev-admin false false true 2026-08-27T11:20:00+00:00 false
engineer-bob false true true 2026-08-28T04:00:00+00:00 false
What Auditors Check in This Report:
mfa_active == true: Confirms that all users and the root account have multi-factor authentication enforced.access_key_last_rotated < 90 days: Verifies that static access keys are routinely rotated.access_key_last_used_date: Detects unused or abandoned credentials that should be deactivated.
Quick Reference: Essential Policy & Boundary CLI Commands
| Action | CLI Command |
|---|---|
| Create Custom Policy | aws iam create-policy --policy-name <name> --policy-document file://policy.json |
| Attach Policy to Group | aws iam attach-group-policy --group-name <group> --policy-arn <arn> |
| Attach Policy to User | aws iam attach-user-policy --user-name <user> --policy-arn <arn> |
| Attach Policy to Role | aws iam attach-role-policy --role-name <role> --policy-arn <arn> |
| Simulate Custom Policy | aws iam simulate-custom-policy --policy-input-list file://policy.json --action-names <action> |
| Simulate Principal Policy | aws iam simulate-principal-policy --policy-source-arn <user-arn> --action-names <action> |
| Set Permissions Boundary | aws iam put-user-permissions-boundary --user-name <user> --permissions-boundary <arn> |
| Create Policy Version | aws iam create-policy-version --policy-arn <arn> --policy-document file://new.json --set-as-default |
| List Policy Versions | aws iam list-policy-versions --policy-arn <arn> |
| Rollback Policy Version | aws iam set-default-policy-version --policy-arn <arn> --version-id <version> |
| Generate Credential Report | aws iam generate-credential-report |
| Get Credential Report | aws iam get-credential-report --query "Content" --output text | base64 -d |
Summary & What’s Next
In this third installment of AWS with CLI, we moved to mastery of cloud authorization:
- We broke down the 5 structural primitives of IAM policies and the 3-way evaluation matrix.
- We used
${aws:username}policy variables to provision an automated self-service MFA policy attached to theDevelopersgroup. - We authored tag-scoped infrastructure policies using
aws:ResourceTag/Environmentconditions. - We verified permissions without touching live servers using the AWS IAM Policy Simulator CLI.
- We enforced Permissions Boundaries to eliminate privilege escalation vectors.
- We leveraged native IAM Policy Versioning for instant, zero-downtime rollbacks.
- We audited account credential hygiene and compliance using IAM Credential Reports.
Now that our identity, security, and authorization foundation is impenetrable, we are ready to move into the physical cloud.
In Part 4, we begin Module 2: Global Infrastructure & VPC Networking, mastering AWS Regions, Availability Zones, physical ZoneId mapping, and opt-in region management from the CLI!