Examining the JSON Policy Structure
Start course
2h 58m

In this section of the AWS Certified: SAP on AWS Specialty learning path, we introduce you to the various Security services currently available in AWS that are relevant to the PAS-C01 exam.

Learning Objectives

  • Understand the purpose of AWS user and identity management
  • Identify resources and capabilities for AWS network security
  • Understand how to evaluate the security of an AWS environment
  • Describe AWS services used to create a comprehensive security solution for SAP deployments


The AWS Certified: SAP on AWS Specialty certification has been designed for anyone who has experience managing and operating SAP workloads. Ideally you’ll also have some exposure to the design and implementation of SAP workloads on AWS, including migrating these workloads from on-premises environments. Many exam questions will require a solutions architect level of knowledge for many AWS services, including AWS Security services. All of the AWS Cloud concepts introduced in this course will be explained and reinforced from the ground up.


In this lecture, I will be taking a deep look at the syntax and structure of IAM policies. For both identity-based and resource-based policies, the syntax is the same, but you might use slightly different parameters. If you've worked with IAM at all before, then I am sure you have come across an IAM policy. After all, it is the component that defines what an identity can or can't access. But what do these policies actually look like? IAM policies are formatted as JSON documents, JavaScript Object Notation, and each policy will have at least one statement where the structure may look like this example.

Let me break the structure of this policy down to allow you to understand each element. Version. This specifies the policy language version and specifies the language syntax used, and at the time of writing this course, the current policy version is 2012-10-17. Statement. This defines the main element of the policy, which will includes other sub-elements, including the Sid, Effect, Action, Resource, and Condition. These elements will identify the level of access granted or denied and to which resource. A policy must contain at least one statement, but it can also contain an array of statements. For each statement block, it must be enclosed within curly braces, but if you use an array of statements, then you must enclose the entire array within square brackets. And we shall look at an example of this during this lecture.

Sid. This is the statement ID, and it's an optional parameter that allows you to set a unique identifier within the statement. As you add more arrays within your policy, it can be a good idea to include a Sid for each one, allowing you to name them appropriately, making them more easily identifiable. For example, AllowGetObjectForS3. Without reading the rest of the statement, you can get a good idea of what the permissions in this statement allows.

Effect. This element can be set to either Allow or Deny, which either grant or restrict access for the actions defined in the statement. By default, all access to your resources are denied and so, therefore, if this is set to Allow, it replaces the default denied access. Similarly, if this was set to Deny, it would override any previous Allow. An explicit Deny in a policy will always take precedence over any Allow.

Principal. This parameter defines which principal the policy relates to. The Principal is only used for resource-based policies, for example, those policies attached to S3 Buckets. When using identity-based policies, this parameter is not required within the policy as the policy itself is associated with the principal and not a resource. As an alternative to the Principal parameter, this could be replaced with the NotPrincipal parameter, which would specify the user, role, or AWS account that is not allowed or denied access to the associated resource.

Action. This is the action that will either be allowed or denied, depending on the value entered for the Effect parameter. Actions are effectively API calls for different services. As a result, different actions are used for each service. For example the DeleteBucket action is available for S3 but not EC2, and likewise, the CreateKeyPair action is available for EC2 but not S3. The action is prefixed with the associated AWS service. This example defines two actions, CreateTrail and DeleteTrail, for the CloudTrail service. As another example, you can see this one here with the asterisk, and this acts as a wildcard which represents all actions for the CloudTrail service, essentially granting full access to the service.

Similarly, as we had with the Principal parameter, we could replace the Action parameter with the NotAction instead, and this could help you optimize your policy by creating a shorter version, listing just a limited set of actions that should not match instead of creating a longer policy listing all that actions that should. An example of using the NotAction is shown here. This policy essentially allows all actions for CloudTrail apart from the DeleteTrail API, and this is because the NotAction parameter is being used.

Resource. This element specifies the actual resource you wish the Action and Effect to be applied to. AWS uses identifiers known as ARNs, Amazon Resource Names, to specify specific resources. Typically, ARNs follow a syntax of, arn, partition, service, region, account-id, and then resource. So the Partition element, this relates to the partition that the resource is found in. For standard AWS regions, this would be AWS. Service. This reflects the specific AWS service, for example, S3 or EC2.

Region. This is the region where the resource is located. Some services do not need a region specified, so this can sometimes be left blank. Account-ID. This is your AWS Account ID, without hyphens. Again, some services do not need this information and so can be left blank. Resource. The value of this field will depend on the AWS service you are using. For example, if I were using the action, Action:s3:PutObject, then I could use the bucket name that I wanted those permissions to apply to. Again, we also have a NotResource parameter that can be used to explicitly match all other resources except those specified. For example, this policy will allow access to all S3 buckets other than those specified by the NotResource parameter.

Condition. This is an optional element that allows you to control when the permissions will be effective based upon set criteria. The element itself is made up of a condition and a key value pair and all elements of the condition must be met for the permissions to be active. Let's take a look at an example condition. In the example, the IP address is the condition itself, which the key value pair will be effective against. The aws:SourceIp is the Key and the is the value element of the key. So effectively, what this is saying is, if the Source IP address of the user who is requesting access via the policy is within the network range, then implement the permissions in the policy statement.

Now that I've gone through the core parameters of an IAM policy, let's take a look at a couple of examples to ensure we can understand the permissions that are being presented within the policy. As I mentioned previously, you can have multiple Sids within a statement, each granting a different level of access. The example below demonstrates this, and I have highlighted each a different color to show the separation.

So looking at this example policy, let's determine what access is being granted. So in StatementBlock1, this allows any resource full access to CloudTrail on the condition that their source IP address is within the network range. StatementBlock2. This allows full access to all RDS databases using all API calls except for that of the rds:DeleteDBInstance due to the NotAction parameter being used instead of the Action being used. And in StatementBlock3, this allows the creation and deletion of S3 Buckets within the cloudacademy bucket on S3.

Let's take a look at another example policy, this time, a resource-based policy, and in this instance, it's from an S3 bucket. So in this policy, it allows the user, Stuart, as highlighted by the Principal parameter, to create and delete buckets in addition to deleting the bucket policy. Stuart can also delete and put objects within the bucket, and the bucket that this policy refers to is the bucket named ca-bucket-uk, as defined by the Resource parameter. However, there is a condition bound to this policy that states that Stuart can only do this if he was authenticated via Multi-Factor Authentication, MFA. That should now give you more of an understanding of how JSON IAM policies work and what they look like.

About the Author
Learning Paths

Stuart has been working within the IT industry for two decades covering a huge range of topic areas and technologies, from data center and network infrastructure design, to cloud architecture and implementation.

To date, Stuart has created 150+ courses relating to Cloud reaching over 180,000 students, mostly within the AWS category and with a heavy focus on security and compliance.

Stuart is a member of the AWS Community Builders Program for his contributions towards AWS.

He is AWS certified and accredited in addition to being a published author covering topics across the AWS landscape.

In January 2016 Stuart was awarded ‘Expert of the Year Award 2015’ from Experts Exchange for his knowledge share within cloud services to the community.

Stuart enjoys writing about cloud technologies and you will find many of his articles within our blog pages.