Skip to content

Commit c6b8148

Browse files
authored
Better iam policies (#3530)
1 parent 32545a7 commit c6b8148

File tree

5 files changed

+142
-89
lines changed

5 files changed

+142
-89
lines changed

src/cfnlint/data/schemas/other/iam/policy.json

+108-55
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,66 @@
33
"additionalProperties": false,
44
"definitions": {
55
"Action": {
6-
"anyOf": [
7-
{
8-
"$ref": "#/definitions/Wildcard"
9-
},
10-
{
11-
"$ref": "#/definitions/StringOrStringArray"
12-
}
13-
],
146
"cfnLint": [
157
"AWS::IAM::Policy/Properties/PolicyDocument/Statement/Action"
8+
],
9+
"items": {
10+
"type": "string"
11+
},
12+
"type": [
13+
"string",
14+
"array"
1615
]
1716
},
1817
"AwsArn": {
19-
"pattern": "(^arn:(aws|aws-cn|aws-us-gov):[^:]+:[^:]*(:(?:\\d{12}|\\*|aws)?:.+|)|\\*)$",
20-
"type": "string"
18+
"pattern": "(^arn:(aws|aws-cn|aws-us-gov):[^:]+:[^:]*(:(?:\\d{12}|\\*|aws)?:.+|)|\\*)$"
2119
},
2220
"AwsPrincipalArn": {
2321
"anyOf": [
2422
{
25-
"pattern": "^((arn:(aws|aws-cn|aws-us-gov):iam::\\d{12}:(?:root|user|group|role)|\\*)|\\d{12})"
23+
"const": "*"
24+
},
25+
{
26+
"pattern": "^\\d{12}$"
27+
},
28+
{
29+
"pattern": "^arn:(aws|aws-cn|aws-us-gov):iam::\\d{12}:(?:root|user|group|role)"
2630
},
2731
{
2832
"pattern": "^arn:(aws|aws-cn|aws-us-gov):iam::cloudfront:user/.+$"
2933
}
30-
],
31-
"type": "string"
34+
]
35+
},
36+
"Boolean": {
37+
"enum": [
38+
"true",
39+
"false",
40+
true,
41+
false
42+
]
43+
},
44+
"Booleans": {
45+
"if": {
46+
"type": [
47+
"string",
48+
"boolean"
49+
]
50+
},
51+
"items": {
52+
"$ref": "#/definitions/Boolean",
53+
"type": [
54+
"string",
55+
"boolean"
56+
]
57+
},
58+
"then": {
59+
"$ref": "#/definitions/Boolean"
60+
},
61+
"type": [
62+
"string",
63+
"array",
64+
"boolean"
65+
]
3266
},
3367
"Condition": {
3468
"patternProperties": {
@@ -114,14 +148,7 @@
114148
},
115149
"Null": {
116150
"additionalProperties": {
117-
"scalarOrArray": {
118-
"enum": [
119-
"true",
120-
"false",
121-
true,
122-
false
123-
]
124-
}
151+
"$ref": "#/definitions/Booleans"
125152
},
126153
"type": "object"
127154
}
@@ -130,22 +157,23 @@
130157
},
131158
"ConditionSetValue": {
132159
"additionalProperties": {
133-
"$ref": "#/definitions/StringArray"
160+
"items": {
161+
"type": "string"
162+
},
163+
"type": "array"
134164
},
135165
"type": "object"
136166
},
137167
"ConditionValue": {
138168
"additionalProperties": {
139-
"anyOf": [
140-
{
141-
"$ref": "#/definitions/StringOrStringArray"
142-
},
143-
{
144-
"type": "boolean"
145-
},
146-
{
147-
"type": "number"
148-
}
169+
"items": {
170+
"type": "string"
171+
},
172+
"type": [
173+
"boolean",
174+
"number",
175+
"string",
176+
"array"
149177
]
150178
},
151179
"type": "object"
@@ -156,20 +184,42 @@
156184
},
157185
"properties": {
158186
"AWS": {
159-
"scalarOrArray": {
160-
"$ref": "#/definitions/AwsPrincipalArn"
161-
}
187+
"$ref": "#/definitions/AwsPrincipalArn",
188+
"items": {
189+
"$ref": "#/definitions/AwsPrincipalArn",
190+
"type": "string"
191+
},
192+
"type": [
193+
"string",
194+
"array"
195+
]
162196
},
163197
"CanonicalUser": {
164-
"$ref": "#/definitions/StringOrStringArray"
198+
"items": {
199+
"type": "string"
200+
},
201+
"type": [
202+
"string",
203+
"array"
204+
]
165205
},
166206
"Federated": {
167-
"$ref": "#/definitions/StringOrStringArray"
207+
"items": {
208+
"type": "string"
209+
},
210+
"type": [
211+
"string",
212+
"array"
213+
]
168214
},
169215
"Service": {
170-
"scalarOrArray": {
216+
"items": {
171217
"type": "string"
172-
}
218+
},
219+
"type": [
220+
"string",
221+
"array"
222+
]
173223
}
174224
},
175225
"then": {
@@ -181,9 +231,15 @@
181231
]
182232
},
183233
"Resource": {
184-
"scalarOrArray": {
185-
"$ref": "#/definitions/AwsArn"
186-
}
234+
"$ref": "#/definitions/AwsArn",
235+
"items": {
236+
"$ref": "#/definitions/AwsArn",
237+
"type": "string"
238+
},
239+
"type": [
240+
"string",
241+
"array"
242+
]
187243
},
188244
"Statement": {
189245
"additionalProperties": false,
@@ -252,16 +308,7 @@
252308
},
253309
"required": [
254310
"Effect"
255-
],
256-
"type": "object"
257-
},
258-
"StringArray": {
259-
"type": "string"
260-
},
261-
"StringOrStringArray": {
262-
"scalarOrArray": {
263-
"$ref": "#/definitions/StringArray"
264-
}
311+
]
265312
},
266313
"Wildcard": {
267314
"const": "*"
@@ -272,9 +319,15 @@
272319
"type": "string"
273320
},
274321
"Statement": {
275-
"scalarOrArray": {
276-
"$ref": "#/definitions/Statement"
277-
}
322+
"$ref": "#/definitions/Statement",
323+
"items": {
324+
"$ref": "#/definitions/Statement",
325+
"type": "object"
326+
},
327+
"type": [
328+
"object",
329+
"array"
330+
]
278331
},
279332
"Version": {
280333
"cfnLint": [

src/cfnlint/data/schemas/other/iam/policy_identity.json

+10-5
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,23 @@
4545
"Sid": {
4646
"$ref": "policy#/definitions/Statement/properties/Sid"
4747
}
48-
},
49-
"type": "object"
48+
}
5049
}
5150
},
5251
"properties": {
5352
"Id": {
5453
"$ref": "policy#/properties/Id"
5554
},
5655
"Statement": {
57-
"scalarOrArray": {
58-
"$ref": "#/definitions/Statement"
59-
}
56+
"$ref": "#/definitions/Statement",
57+
"items": {
58+
"$ref": "#/definitions/Statement",
59+
"type": "object"
60+
},
61+
"type": [
62+
"object",
63+
"array"
64+
]
6065
},
6166
"Version": {
6267
"$ref": "policy#/properties/Version"

src/cfnlint/data/schemas/other/iam/policy_resource.json

+10-5
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,23 @@
5757
"Sid": {
5858
"$ref": "policy#/definitions/Statement/properties/Sid"
5959
}
60-
},
61-
"type": "object"
60+
}
6261
}
6362
},
6463
"properties": {
6564
"Id": {
6665
"$ref": "policy#/properties/Id"
6766
},
6867
"Statement": {
69-
"scalarOrArray": {
70-
"$ref": "#/definitions/Statement"
71-
}
68+
"$ref": "#/definitions/Statement",
69+
"items": {
70+
"$ref": "#/definitions/Statement",
71+
"type": "object"
72+
},
73+
"type": [
74+
"object",
75+
"array"
76+
]
7277
},
7378
"Version": {
7479
"$ref": "policy#/properties/Version"

src/cfnlint/data/schemas/other/iam/policy_resource_ecr.json

+10-5
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,23 @@
5151
"Sid": {
5252
"$ref": "policy#/definitions/Statement/properties/Sid"
5353
}
54-
},
55-
"type": "object"
54+
}
5655
}
5756
},
5857
"properties": {
5958
"Id": {
6059
"$ref": "policy#/properties/Id"
6160
},
6261
"Statement": {
63-
"scalarOrArray": {
64-
"$ref": "#/definitions/Statement"
65-
}
62+
"$ref": "#/definitions/Statement",
63+
"items": {
64+
"$ref": "#/definitions/Statement",
65+
"type": "object"
66+
},
67+
"type": [
68+
"object",
69+
"array"
70+
]
6671
},
6772
"Version": {
6873
"$ref": "policy#/properties/Version"

src/cfnlint/rules/resources/iam/Policy.py

+4-19
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,6 @@
1414
from cfnlint.schema.resolver import RefResolver
1515

1616

17-
# pylint: disable=unused-argument
18-
def _scalar_or_array(validator: Validator, subschema: Any, instance: Any, schema: Any):
19-
if validator.is_type(instance, "array"):
20-
for index, i in enumerate(instance):
21-
yield from validator.descend(i, subschema, path=index)
22-
else:
23-
yield from validator.descend(instance, subschema)
24-
25-
2617
class Policy(CfnLintJsonSchema):
2718
"""Check IAM policies"""
2819

@@ -61,28 +52,22 @@ def validate(
6152
# so we can run this now
6253
if validator.is_type(policy, "string"):
6354
try:
64-
iam_validator = validator.extend(
65-
validators={
66-
"scalarOrArray": _scalar_or_array,
67-
},
68-
)(schema=self.identity_schema).evolve(
55+
iam_validator = validator.evolve(
6956
context=validator.context.evolve(
7057
functions=[],
7158
),
7259
resolver=self.resolver,
60+
schema=self.identity_schema,
7361
)
7462
policy = json.loads(policy)
7563
except json.JSONDecodeError:
7664
return
7765
else:
78-
iam_validator = validator.extend(
79-
validators={
80-
"scalarOrArray": _scalar_or_array,
81-
},
82-
)(schema=self.identity_schema).evolve(
66+
iam_validator = validator.evolve(
8367
cfn=validator.cfn,
8468
context=validator.context,
8569
resolver=self.resolver,
70+
schema=self.identity_schema,
8671
)
8772

8873
for err in iam_validator.iter_errors(policy):

0 commit comments

Comments
 (0)