Last active
August 8, 2024 04:23
-
-
Save jstewmon/ee5d4b7ec0d8d60cbc303cb515272f8a to your computer and use it in GitHub Desktop.
AWS IAM Policy JSON Schema
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "type": "object", | |
| "required": ["Statement"], | |
| "additionalProperties": false, | |
| "properties": { | |
| "Version": { | |
| "type": "string", | |
| "enum": ["2008-10-17", "2012-10-17"] | |
| }, | |
| "Id": { | |
| "type": "string" | |
| }, | |
| "Statement": { | |
| "oneOf": [ | |
| { | |
| "$ref": "#/definitions/Statement" | |
| }, | |
| { | |
| "type": "array", | |
| "items": { | |
| "$ref": "#/definitions/Statement" | |
| } | |
| } | |
| ] | |
| } | |
| }, | |
| "definitions": { | |
| "aws-arn": { | |
| "type": "string", | |
| "pattern": "^arn:aws:[^:]+:[^:]*:(?:\\d{12}|\\*)?:.+$" | |
| }, | |
| "aws-principal-arn": { | |
| "type": "string", | |
| "pattern": "^arn:aws:iam::\\d{12}:(?:root|user|group|role)" | |
| }, | |
| "string-array": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| } | |
| }, | |
| "string-or-string-array": { | |
| "anyOf": [ | |
| { | |
| "type": "string" | |
| }, | |
| { | |
| "$ref": "#/definitions/string-array" | |
| } | |
| ] | |
| }, | |
| "wildcard": { | |
| "const": "*" | |
| }, | |
| "condition-set-value": { | |
| "type": "object", | |
| "additionalProperties": { | |
| "$ref": "#/definitions/string-array" | |
| } | |
| }, | |
| "condition-value": { | |
| "type": "object", | |
| "additionalProperties": { | |
| "anyOf": [ | |
| { "$ref": "#/definitions/string-or-string-array" }, | |
| { "type": "boolean" }, | |
| { "type": "number" } | |
| ] | |
| } | |
| }, | |
| "Statement": { | |
| "allOf": [ | |
| { | |
| "oneOf": [{ "required": ["Action"] }, { "required": ["NotAction"] }] | |
| }, | |
| { | |
| "oneOf": [ | |
| { "required": ["Resource"] }, | |
| { "required": ["NotResource"] } | |
| ] | |
| }, | |
| { | |
| "type": "object", | |
| "required": ["Effect"], | |
| "additionalProperties": false, | |
| "properties": { | |
| "Sid": { | |
| "type": "string" | |
| }, | |
| "Effect": { | |
| "type": "string", | |
| "enum": ["Allow", "Deny"] | |
| }, | |
| "Action": { | |
| "$ref": "#/definitions/Action" | |
| }, | |
| "NotAction": { | |
| "$ref": "#/definitions/Action" | |
| }, | |
| "Principal": { | |
| "$ref": "#/definitions/Principal" | |
| }, | |
| "NotPrincipal": { | |
| "$ref": "#/definitions/Principal" | |
| }, | |
| "Resource": { | |
| "$ref": "#/definitions/Resource" | |
| }, | |
| "NotResource": { | |
| "$ref": "#/definitions/Resource" | |
| }, | |
| "Condition": { | |
| "$ref": "#/definitions/Condition" | |
| } | |
| } | |
| } | |
| ] | |
| }, | |
| "Action": { | |
| "anyOf": [ | |
| { | |
| "$ref": "#/definitions/wildcard" | |
| }, | |
| { | |
| "$ref": "#/definitions/string-or-string-array" | |
| } | |
| ] | |
| }, | |
| "Principal": { | |
| "anyOf": [ | |
| { | |
| "$ref": "#/definitions/wildcard" | |
| }, | |
| { | |
| "type": "object", | |
| "properties": { | |
| "AWS": { | |
| "anyOf": [ | |
| { | |
| "$ref": "#/definitions/wildcard" | |
| }, | |
| { | |
| "$ref": "#/definitions/aws-principal-arn" | |
| }, | |
| { | |
| "type": "array", | |
| "items": { | |
| "$ref": "#/definitions/aws-principal-arn" | |
| } | |
| } | |
| ] | |
| }, | |
| "Federated": { | |
| "$ref": "#/definitions/string-or-string-array" | |
| }, | |
| "CanonicalUser": { | |
| "$ref": "#/definitions/string-or-string-array" | |
| } | |
| } | |
| } | |
| ] | |
| }, | |
| "Resource": { | |
| "anyOf": [ | |
| { | |
| "$ref": "#/definitions/wildcard" | |
| }, | |
| { | |
| "$ref": "#/definitions/aws-arn" | |
| }, | |
| { | |
| "type": "array", | |
| "items": { | |
| "$ref": "#/definitions/aws-arn" | |
| } | |
| } | |
| ] | |
| }, | |
| "Condition": { | |
| "type": "object", | |
| "properties": { | |
| "Null": { | |
| "type": "object", | |
| "additionalProperties": { | |
| "enum": ["true", "false", true, false] | |
| } | |
| }, | |
| "StringEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringNotEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringEqualsIgnoreCase": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringNotEqualsIgnoreCase": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringLike": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringNotLike": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericNotEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericLessThan": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericLessThanEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericGreaterThan": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericGreaterThanEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateNotEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateLessThan": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateLessThanEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateGreaterThan": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateGreaterThanEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "Bool": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "BinaryEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "IpAddress": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NotIpAddress": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "ArnEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "ArnNotEquals": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "ArnLike": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "ArnNotLike": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringNotEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringEqualsIgnoreCaseIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringNotEqualsIgnoreCaseIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringLikeIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "StringNotLikeIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericNotEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericLessThanIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericLessThanEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericGreaterThanIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NumericGreaterThanEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateNotEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateLessThanIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateLessThanEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateGreaterThanIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "DateGreaterThanEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "BoolIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "BinaryEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "IpAddressIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "NotIpAddressIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "ArnEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "ArnNotEqualsIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "ArnLikeIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "ArnNotLikeIfExists": { | |
| "$ref": "#/definitions/condition-value" | |
| }, | |
| "ForAllValues:StringEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:StringNotEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:StringEqualsIgnoreCase": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:StringNotEqualsIgnoreCase": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:StringLike": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:StringNotLike": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:NumericEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:NumericNotEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:NumericLessThan": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:NumericLessThanEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:NumericGreaterThan": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:NumericGreaterThanEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:DateEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:DateNotEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:DateLessThan": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:DateLessThanEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:DateGreaterThan": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:DateGreaterThanEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:Bool": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:BinaryEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:IpAddress": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:NotIpAddress": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:ArnEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:ArnNotEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:ArnLike": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAllValues:ArnNotLike": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:StringEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:StringNotEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:StringEqualsIgnoreCase": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:StringNotEqualsIgnoreCase": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:StringLike": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:StringNotLike": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:NumericEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:NumericNotEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:NumericLessThan": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:NumericLessThanEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:NumericGreaterThan": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:NumericGreaterThanEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:DateEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:DateNotEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:DateLessThan": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:DateLessThanEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:DateGreaterThan": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:DateGreaterThanEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:Bool": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:BinaryEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:IpAddress": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:NotIpAddress": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:ArnEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:ArnNotEquals": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:ArnLike": { | |
| "$ref": "#/definitions/condition-set-value" | |
| }, | |
| "ForAnyValues:ArnNotLike": { | |
| "$ref": "#/definitions/condition-set-value" | |
| } | |
| } | |
| } | |
| } | |
| } |
Author
I have come up against an issue in that if you use the Action of sts:AssumeRole the schema causes failure due there being no Resource present.
e.g. from https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_policy-examples.html
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"elasticmapreduce.amazonaws.com",
"datapipeline.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
I've posted a gist which fixes this over at https://gist.github.com/LeePorte/16825880f7eac126555b9aa3bda1cf22
It adds in the ability to have a Service as a principal which validates against the pattern of .+.amazonaws.com$ and has some if else logic as to weather to apply
"oneOf": [
{ "required": ["Resource"] },
{ "required": ["NotResource"] }
]
based on if the Action is sts:AssumeRole
This is why I love open source :) :)
Hi! The schema is awesome. Wanted to mention this:
PrincipalandNotPrincipalare also mutually exclusive, so i would add:
"oneOf": [
{ "required": ["Principal"] },
{ "required": ["NotPrincipal"] }
]- Seems like the array of statements cant be empty, so i'd add
"minLength": 1
"Statement": {
"oneOf": [
{
"$ref": "#/definitions/Statement"
},
{
"type": "array",
"minLength": 1,
"items": {
"$ref": "#/definitions/Statement"
}
}
]
}Thanks a lot for the schema, it saved me some time :D
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the feedback! I updated the gist accordingly.
n.b. I did some cursory testing, but I'm not using this schema myself, so no warranties, etc.