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 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" | |
} | |
} | |
} | |
} | |
} |
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:
Principal
andNotPrincipal
are 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.