AWS Systems Architect Professional

AWS IAM JSON Policy Structure and API Actions

Purpose of This Lesson This lesson focuses on how AWS IAM policies are structured, how to read JSON-based permissions policies, and how IAM policies control access to AWS API actions. For the AWS Certified Solutions Architect – Professional SAP-C02 exam, IAM policy structure is foundational. Many scenario-based questions require you to understand whether access is […]

AWS Systems Architect ProfessionalAWS Systems Architect ProfessionalUpdated May 25, 2026
Study options
WatchComing later
ListenComing later
ReadAvailable
ReviewComing later

Study guide

Technical reference and lesson notes

Purpose of This Lesson

This lesson focuses on how AWS IAM policies are structured, how to read JSON-based permissions policies, and how IAM policies control access to AWS API actions.

For the AWS Certified Solutions Architect – Professional SAP-C02 exam, IAM policy structure is foundational. Many scenario-based questions require you to understand whether access is allowed, denied, scoped too broadly, or incorrectly applied to the wrong AWS resource type.

IAM policies are used to control who can perform which actions against which AWS resources. At the professional level, you need to understand not only what a policy does, but also whether it follows least privilege, whether the resources are correctly scoped, and whether wildcards introduce unnecessary risk.


Key Concepts

Everything in AWS Is an API Action

In AWS, almost every operation ultimately maps to an API call.

Whether you use:

  • AWS Management Console
  • AWS CLI
  • AWS SDK
  • Infrastructure as Code tools
  • Automation scripts

The action being performed behind the scenes is an AWS API operation.

For example:

User ActionAWS API Action
Launch an EC2 instanceec2:RunInstances
Stop an RDS databaserds:StopDBInstance
Perform an S3 operations3:<specific action>

This matters because IAM permissions are built around API actions. When you allow or deny access in IAM, you are really controlling which API calls a principal is allowed to make.

For the SAP-C02 exam, this is important because answer choices may describe user-friendly tasks, but the correct solution often depends on granting the correct API permissions.


IAM Policies Are Written in JSON

IAM policies use JSON, or JavaScript Object Notation.

A typical IAM policy includes:

  • Version
  • Statement
  • Effect
  • Action
  • Resource

A simplified IAM policy structure looks like this:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*",
"dynamodb:Describe*"
],
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*",
"arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTable"
]
}
]
}

JSON formatting matters. Missing commas, incorrect brackets, or invalid syntax can break the policy. In practice, AWS policy editors and code editors like Visual Studio Code can help identify formatting issues.


The Version Element

The Version field identifies the IAM policy language version.

Example:

"Version": "2012-10-17"

This value looks like a date, but it is not meant to represent the date the policy was created. It identifies the policy language version.

For most modern IAM policies, you will commonly see:

"2012-10-17"

For exam purposes, do not assume this date is wrong or outdated. It is expected.


The Statement Element

The Statement block contains one or more permission statements.

Each statement defines a specific rule that AWS evaluates. A policy can contain a single statement or multiple statements.

Each statement usually includes:

  • Effect
  • Action
  • Resource
  • Optionally, conditions or other policy elements

Example:

"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]

If there are multiple statements, AWS evaluates them together during authorization.


The Effect Element

The Effect field defines whether the policy statement allows or denies access.

Valid values are:

  • Allow
  • Deny

Example:

"Effect": "Allow"

or:

"Effect": "Deny"

IAM does not have a neutral “maybe” or “inherit” effect. A statement either allows something or explicitly denies it.

A key exam concept is that explicit deny overrides allow. Even if another policy allows an action, an explicit deny elsewhere will block it.


The Action Element

The Action element defines which AWS API operations the policy applies to.

Example:

"Action": "ec2:RunInstances"

This allows or denies the ability to launch EC2 instances, depending on the Effect.

Actions are written in this general format:

service-prefix:APIAction

Examples:

ec2:RunInstances
rds:StopDBInstance
s3:PutObject
dynamodb:DescribeTable

You can allow or deny very specific actions, or you can use wildcards to match multiple actions.


Using Wildcards in IAM Actions

A wildcard is represented by an asterisk:

*

Wildcards allow you to match multiple actions.

Example:

"Action": "s3:*"

This means all Amazon S3 API actions.

Another example:

"Action": "dynamodb:Describe*"

This means all DynamoDB actions that begin with Describe.

This might include actions such as:

dynamodb:DescribeTable
dynamodb:DescribeBackup
dynamodb:DescribeLimits

Wildcards are powerful, but they can also create overly broad permissions. For the SAP-C02 exam, broad wildcards may be incorrect if the question emphasizes least privilege.


The Resource Element

The Resource element defines which AWS resources the policy applies to.

Resources are usually identified by Amazon Resource Names, or ARNs.

Example:

"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTable"

An ARN uniquely identifies a resource in AWS.

A typical ARN includes:

arn:partition:service:region:account-id:resource

For example:

arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTable

This identifies a DynamoDB table named ExampleTable in the us-east-1 Region in account 123456789012.


S3 Bucket-Level and Object-Level Resources

Amazon S3 is a common exam area because bucket-level and object-level permissions are scoped differently.

For S3, a bucket ARN looks like this:

arn:aws:s3:::example-bucket

Objects inside that bucket use a separate ARN pattern:

arn:aws:s3:::example-bucket/*

These are not the same thing.

Resource ARNApplies To
arn:aws:s3:::example-bucketThe bucket itself
arn:aws:s3:::example-bucket/*Objects inside the bucket

This matters because some S3 actions apply to the bucket, while others apply to objects.

For example:

S3 Permission TypeExample Resource Scope
Bucket-level actionsarn:aws:s3:::example-bucket
Object-level actionsarn:aws:s3:::example-bucket/*

If a policy grants object-level access but omits the bucket ARN, some bucket-level operations may fail.

If a policy grants bucket-level access but omits the object ARN, object operations may fail.

For exam questions involving S3 permissions, always check whether the policy includes the correct resource scope.


Broad Permissions vs Granular Permissions

IAM policies can be broad or very specific.

A broad policy might allow:

"Action": "s3:*"

A more specific policy might allow only:

"Action": [
"s3:GetObject",
"s3:PutObject"
]

Broad permissions are easier to configure, but they may violate least privilege.

Granular permissions are more secure, but require better understanding of the exact API calls required by the workload.

For SAP-C02, AWS usually expects designs that follow least privilege unless there is a strong operational reason for broader access.


Multiple Actions and Multiple Resources

An IAM statement can include multiple actions and multiple resources.

Example:

"Action": [
"s3:*",
"dynamodb:Describe*"
],
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*",
"arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTable"
]

This statement allows all S3 actions against the specified bucket and objects, and DynamoDB describe actions against the specified table.

When reading policies, pay attention to whether the action and resource combinations actually make sense together. Some actions only support specific resource types, and some may require Resource: "*" depending on the AWS service and API.


Exam-Relevant Takeaways

For the SAP-C02 exam, remember these key points:

IAM policies control access to AWS API actions. Even console actions map to API calls behind the scenes.

Policies are written in JSON and must be syntactically valid.

The Version value 2012-10-17 is normal and expected. It is the IAM policy language version, not the creation date of the policy.

Each policy contains one or more Statement blocks.

The Effect is either Allow or Deny.

The Action identifies the API operation, such as ec2:RunInstances or rds:StopDBInstance.

Wildcards can be used, such as s3:* for all S3 actions or dynamodb:Describe* for all DynamoDB describe actions.

The Resource element scopes the permissions to specific AWS resources using ARNs.

For S3, bucket-level and object-level permissions require different ARNs.

Least privilege is a major exam theme. Avoid broad wildcards unless the scenario requires them.

Explicit deny overrides allow.


Architecture Decision Guide

ScenarioBest AWS ChoiceWhy
Allow a user to launch EC2 instances onlyGrant ec2:RunInstancesIAM actions map directly to AWS API operations.
Allow all S3 operations on a specific bucket and its objectsUse s3:* with both bucket and object ARNsS3 has separate bucket-level and object-level resource scopes.
Allow read-only metadata access to DynamoDB resourcesUse actions like dynamodb:Describe*Wildcarding the action prefix can allow a controlled group of related API calls.
Restrict permissions to one DynamoDB tableUse the specific DynamoDB table ARNResource-level scoping supports least privilege.
Grant access to objects inside an S3 bucketUse arn:aws:s3:::bucket-name/*Object-level access requires the object ARN pattern.
Grant access to the S3 bucket itselfUse arn:aws:s3:::bucket-nameBucket-level actions require the bucket ARN without /*.
Create a policy for production workloadsPrefer specific actions and resourcesThis reduces blast radius and supports least privilege.
Quickly test permissions in a lab environmentTemporarily use broader permissions, then refineBroad permissions may speed up testing but should not become the final design.

Common Exam Traps

Confusing the IAM Policy Version with a Creation Date

The policy version:

"Version": "2012-10-17"

is not the date the policy was created. It is the IAM policy language version.

Do not select an answer that suggests changing this value simply because it looks old.


Forgetting That Console Actions Are API Calls

The AWS Console is not separate from IAM authorization. Console actions still call AWS APIs.

If a user cannot perform an operation in the console, the issue may still be missing IAM permissions for the underlying API action.


Using Only the S3 Bucket ARN When Object Access Is Required

This is a common mistake.

This ARN applies to the bucket:

arn:aws:s3:::example-bucket

This ARN applies to objects in the bucket:

arn:aws:s3:::example-bucket/*

If the policy needs object access, the object ARN must be included.


Assuming s3:* Automatically Applies to All Buckets

The action controls what can be done. The resource controls where it can be done.

This allows all S3 actions only against the specified resources:

"Action": "s3:*",
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*"
]

It does not automatically grant access to every S3 bucket unless the resource scope allows it.


Overusing Wildcards

Wildcards are convenient but can violate least privilege.

For example:

"Action": "*"

or:

"Resource": "*"

may be too broad for a secure production design.

On the exam, broad permissions are often wrong when a more specific policy would meet the requirement.


Missing Commas or Incorrect JSON Syntax

IAM policies are JSON documents. Syntax matters.

Common formatting issues include:

  • Missing commas between elements
  • Incorrect brackets
  • Incorrect quotation marks
  • Invalid nesting
  • Trailing commas where not allowed

In real environments, use IAM Access Analyzer, AWS policy validation, or a code editor to catch errors before deployment.


Real-World Engineer Notes

In a real AWS environment, IAM policy structure matters for security, operations, troubleshooting, and governance.

From an infrastructure engineering perspective, the most important habit is to map the business or technical requirement back to the required API actions. For example, “user needs to start and stop EC2 instances” should become a defined set of EC2 actions, not a broad ec2:* permission unless there is a valid reason.

S3 permissions deserve extra attention because bucket-level and object-level access are separate. Many real-world access issues come from granting permissions to the bucket but forgetting the object path, or granting object permissions but forgetting a bucket-level permission needed to list or inspect the bucket.

In production environments, broad wildcards should be treated carefully. They may be acceptable during early testing, but they should be refined before deployment. Overly broad IAM policies increase the blast radius if credentials are compromised.

When troubleshooting IAM issues, engineers should check:

  • Which principal is making the request
  • Which API action is being called
  • Whether the policy allows that action
  • Whether the resource ARN matches the target resource
  • Whether an explicit deny exists elsewhere
  • Whether the action supports resource-level permissions
  • Whether bucket-level and object-level ARNs are both required

For governance, IAM policies should be reviewed regularly. Over time, policies tend to accumulate permissions that are no longer needed. Least privilege is not a one-time setup; it requires ongoing cleanup and validation.


Quick Reference Summary

IAM policies are JSON documents that define permissions for AWS API actions.

Core elements:

Policy ElementPurpose
VersionDefines the IAM policy language version
StatementContains one or more permission rules
EffectSpecifies Allow or Deny
ActionDefines the AWS API operations
ResourceDefines the AWS resources the policy applies to

Important examples:

ec2:RunInstances
rds:StopDBInstance
s3:*
dynamodb:Describe*

S3 ARN patterns:

arn:aws:s3:::bucket-name
arn:aws:s3:::bucket-name/*

Remember:

  • AWS actions are API calls.
  • IAM policies are JSON.
  • Wildcards can broaden access.
  • S3 bucket and object permissions are different.
  • Least privilege is preferred.
  • Explicit deny overrides allow.

Flashcards

Q: What format are IAM policies written in?
A: IAM policies are written in JSON.

Q: What does the IAM policy Version value 2012-10-17 represent?
A: It represents the IAM policy language version, not the policy creation date.

Q: What are the only valid values for the Effect element in an IAM policy?
A: Allow and Deny.

Q: What does the Action element define in an IAM policy?
A: It defines the AWS API operations that the policy allows or denies.

Q: What does s3:* mean in an IAM policy?
A: It means all Amazon S3 API actions.

Q: What does dynamodb:Describe* mean?
A: It matches all DynamoDB API actions that begin with Describe.

Q: What does the Resource element define?
A: It defines the AWS resources that the policy statement applies to.

Q: What is an ARN?
A: An Amazon Resource Name is a unique identifier for an AWS resource.

Q: What is the difference between arn:aws:s3:::my-bucket and arn:aws:s3:::my-bucket/*?
A: The first applies to the bucket itself; the second applies to objects inside the bucket.

Q: Why might an S3 policy require two resource ARNs?
A: Because some actions apply to the bucket and others apply to objects within the bucket.

Q: What happens if an IAM policy has invalid JSON syntax?
A: The policy cannot be properly saved or evaluated until the syntax is corrected.

Q: Why should wildcards be used carefully in IAM policies?
A: They can grant broader access than intended and may violate least privilege.

Q: What does ec2:RunInstances allow?
A: It allows the API action used to launch EC2 instances.

Q: What does rds:StopDBInstance allow?
A: It allows the API action used to stop an RDS database instance.

Q: What IAM design principle is heavily tested on the SAP-C02 exam?
A: Least privilege.


Practice Questions

Question 1:
A solutions architect is reviewing an IAM policy that includes the following action:

"Action": "s3:*"

What does this action allow if paired with an Allow effect?

A. All AWS service actions
B. All S3 API actions
C. Only S3 object read actions
D. Only S3 bucket creation actions

Correct Answer:
B. All S3 API actions

Explanation:
The wildcard after s3: means all API actions for the Amazon S3 service. The actual resources affected still depend on the Resource element.


Question 2:
An IAM policy grants access to the following resource only:

arn:aws:s3:::company-data

A user still cannot access objects inside the bucket. What is the most likely issue?

A. The policy version is outdated
B. The policy needs an explicit deny
C. The object-level ARN is missing
D. S3 does not support IAM policies

Correct Answer:
C. The object-level ARN is missing

Explanation:
The ARN arn:aws:s3:::company-data applies to the bucket itself. Object-level access requires an ARN such as arn:aws:s3:::company-data/*.


Question 3:
A policy includes this action:

"Action": "dynamodb:Describe*"

What does this most likely allow?

A. All DynamoDB actions
B. Only the DescribeTable action
C. DynamoDB actions that begin with Describe
D. All actions against all AWS database services

Correct Answer:
C. DynamoDB actions that begin with Describe

Explanation:
The wildcard matches all DynamoDB API actions beginning with Describe, such as describe-style metadata operations.


Question 4:
A developer says the IAM policy must be invalid because it contains this line:

"Version": "2012-10-17"

What should you tell them?

A. The policy is invalid because the version is too old
B. The value represents the IAM policy language version and is expected
C. The date must be changed to today’s date
D. The version field should always be removed

Correct Answer:
B. The value represents the IAM policy language version and is expected

Explanation:
2012-10-17 is the current commonly used IAM policy language version. It is not the date the policy was created.


Question 5:
A team wants to follow least privilege when allowing users to launch EC2 instances. Which approach is best?

A. Allow *:* on all resources
B. Allow ec2:* on all resources
C. Allow the required EC2 API actions, such as ec2:RunInstances, scoped as tightly as possible
D. Give the users administrator access temporarily and remove it later

Correct Answer:
C. Allow the required EC2 API actions, such as ec2:RunInstances, scoped as tightly as possible

Explanation:
Least privilege means granting only the actions and resources required. Broad wildcards may work, but they increase security risk and are usually not the preferred exam answer.