@cloud-copilot/iam-expand 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -22
- package/dist/cjs/cli.js +8 -2
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/expand_file.js +1 -1
- package/dist/cjs/expand_file.js.map +1 -1
- package/dist/esm/cli.js +9 -3
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/expand_file.js +1 -1
- package/dist/esm/expand_file.js.map +1 -1
- package/examples/README.md +3 -0
- package/examples/download-and-expand-authorization-details.sh +8 -0
- package/examples/download-and-expand-policies.sh +22 -0
- package/package.json +1 -1
- package/src/cli.ts +10 -3
- package/src/expand_file.test.ts +79 -0
- package/src/expand_file.ts +1 -1
package/README.md
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
# Expand IAM Actions
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Published in ESM and CommonJS and available as a [CLI](#cli).
|
|
2
|
+
Built in the Unix philosophy, this is a small tool that does one thing well: expand IAM actions with wildcards to their list of matching actions.
|
|
5
3
|
|
|
6
4
|
Use this to:
|
|
7
5
|
1) Expand out wildcards in actions when you are not allowed to use wildcards in your IAM policy.
|
|
8
6
|
2) Get an exhaustive list of actions that are included in a policy and quickly search it for interesting actions.
|
|
9
7
|
3) Investigate where dangerous or dubious actions are being used in your policies.
|
|
10
8
|
|
|
9
|
+
Published in ESM and CommonJS plus available as a [CLI](#cli).
|
|
10
|
+
|
|
11
|
+
All information is sourced from the [@cloud-copilot/iam-data](https://github.com/cloud-copilot/iam-data) which is updated daily.
|
|
12
|
+
|
|
11
13
|
## Installation
|
|
12
14
|
```bash
|
|
13
15
|
npm install -g @cloud-copilot/iam-expand
|
|
14
16
|
```
|
|
15
17
|
|
|
18
|
+
### AWS CloudShell Installation
|
|
19
|
+
The AWS CloudShell automatically has node and npm installed, so you can install this and run it straight from the console. You'll need to use sudo to install it globally.
|
|
20
|
+
```bash
|
|
21
|
+
sudo npm install -g @cloud-copilot/iam-expand
|
|
22
|
+
iam-expand
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Typescript/NodeJS Usage
|
|
16
26
|
```typescript
|
|
17
27
|
import { expandIamActions } from '@cloud-copilot/iam-expand';
|
|
18
28
|
|
|
@@ -50,7 +60,7 @@ expandIamActions(['s3:Get*Tagging', 's3:Put*Tagging'])
|
|
|
50
60
|
`expandIamActions` an optional second argument that is an object with the following options:
|
|
51
61
|
|
|
52
62
|
### `expandAsterisk`
|
|
53
|
-
By default, a single `*` not be expanded.
|
|
63
|
+
By default, a single `*` will not be expanded. If you want to expand a single `*` you can set this option to `true`.
|
|
54
64
|
|
|
55
65
|
```typescript
|
|
56
66
|
import { expandIamActions } from '@cloud-copilot/iam-expand';
|
|
@@ -126,7 +136,7 @@ expandIamActions(['s3:GetObject*','s3:Get*Tagging'],{distinct:true})
|
|
|
126
136
|
```
|
|
127
137
|
|
|
128
138
|
### `sort`
|
|
129
|
-
By default, the output will be sorted based on the order of the input. If you want the output to be sorted alphabetically you can set this option to `true`.
|
|
139
|
+
By default, the output will be sorted based on the order of the input. If you want the consolidated output to be sorted alphabetically you can set this option to `true`.
|
|
130
140
|
|
|
131
141
|
```typescript
|
|
132
142
|
import { expandIamActions } from '@cloud-copilot/iam-expand';
|
|
@@ -193,10 +203,36 @@ expandIamActions('r2:Get*Tagging', { errorOnMissingService: true })
|
|
|
193
203
|
//Uncaught Error: Service not found: r2
|
|
194
204
|
```
|
|
195
205
|
|
|
206
|
+
## `invalidActionBehavior`
|
|
207
|
+
By default, if an action is passed in that does not exist in the IAM data, it will be silently ignored and left out of the output. There are two options to override this behavior: `Error` and `Include`.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import { expandIamActions, InvalidActionBehavior } from '@cloud-copilot/iam-expand';
|
|
211
|
+
|
|
212
|
+
//Ignore invalid action by default
|
|
213
|
+
expandIamActions('ec2:DestroyAvailabilityZone')
|
|
214
|
+
[]
|
|
215
|
+
|
|
216
|
+
//Ignore invalid action explicitly
|
|
217
|
+
expandIamActions('ec2:DestroyAvailabilityZone', { invalidActionBehavior: InvalidActionBehavior.Remove })
|
|
218
|
+
[]
|
|
219
|
+
|
|
220
|
+
//Throw an error on invalid action
|
|
221
|
+
expandIamActions('ec2:DestroyAvailabilityZone', { invalidActionBehavior: InvalidActionBehavior.Error })
|
|
222
|
+
//Uncaught Error: Invalid action: ec2:DestroyAvailabilityZone
|
|
223
|
+
|
|
224
|
+
//Include invalid action
|
|
225
|
+
expandIamActions('ec2:DestroyAvailabilityZone', { invalidActionBehavior: InvalidActionBehavior.Include })
|
|
226
|
+
['ec2:DestroyAvailabilityZone']
|
|
227
|
+
```
|
|
228
|
+
|
|
196
229
|
## CLI
|
|
197
|
-
There is a CLI!
|
|
230
|
+
There is a CLI! The [examples folder](examples/README.md) has examples showing how to use the CLI to find interesting actions in your IAM policies.
|
|
231
|
+
|
|
232
|
+
### Installation
|
|
233
|
+
You can install it globally and use the command `iam-expand` or add it to a single project and use `npx`.
|
|
198
234
|
|
|
199
|
-
|
|
235
|
+
#### Install Globally
|
|
200
236
|
```bash
|
|
201
237
|
npm install -g @cloud-copilot/iam-expand
|
|
202
238
|
```
|
|
@@ -206,9 +242,14 @@ yarn global add @cloud-copilot/iam-data
|
|
|
206
242
|
yarn global add @cloud-copilot/iam-expand
|
|
207
243
|
```
|
|
208
244
|
|
|
209
|
-
|
|
245
|
+
The AWS CloudShell automatically has node and npm installed, so you can install this and run it straight from the console. You'll need to use sudo to install it globally.
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
sudo npm install -g @cloud-copilot/iam-expand
|
|
249
|
+
```
|
|
250
|
+
#### Install in a project
|
|
210
251
|
```bash
|
|
211
|
-
|
|
252
|
+
npm install @cloud-copilot/iam-expand
|
|
212
253
|
```
|
|
213
254
|
|
|
214
255
|
### Simple Usage
|
|
@@ -219,13 +260,13 @@ iam-expand s3:Get* s3:*Tag*
|
|
|
219
260
|
|
|
220
261
|
You can pass in all options available through the api as dash separated flags.
|
|
221
262
|
|
|
222
|
-
_Prints all matching actions for s3:Get*Tagging
|
|
263
|
+
_Prints all matching actions for `s3:Get*Tagging`, `s3:*Tag*`, and `ec2:*` in alphabetical order with duplicates removed:_
|
|
223
264
|
```bash
|
|
224
265
|
iam-expand s3:Get*Tagging s3:*Tag* ec2:* --expand-service-asterisk --distinct --sort
|
|
225
266
|
```
|
|
226
267
|
|
|
227
268
|
### Help
|
|
228
|
-
|
|
269
|
+
Run the command with no options to show usage:
|
|
229
270
|
```bash
|
|
230
271
|
iam-expand
|
|
231
272
|
```
|
|
@@ -234,8 +275,7 @@ iam-expand
|
|
|
234
275
|
If no actions are passed as arguments, the CLI will read from stdin.
|
|
235
276
|
|
|
236
277
|
#### Expanding JSON input
|
|
237
|
-
If the input is a valid json document, the CLI will find every instance of `Action` that is a string
|
|
238
|
-
or an array of strings and expand them. This is useful for finding all the actions in a policy document or set of documents.
|
|
278
|
+
If the input is a valid json document, the CLI will find every instance of `Action` and `NotAction` that is a string or an array of strings and expand them. This is useful for finding all the actions in a policy document or set of documents.
|
|
239
279
|
|
|
240
280
|
Given `policy.json`
|
|
241
281
|
```json
|
|
@@ -249,8 +289,8 @@ Given `policy.json`
|
|
|
249
289
|
"Resource": "*"
|
|
250
290
|
},
|
|
251
291
|
{
|
|
252
|
-
"Effect": "
|
|
253
|
-
"
|
|
292
|
+
"Effect": "Deny",
|
|
293
|
+
"NotAction": ["s3:Get*Tagging", "s3:Put*Tagging"],
|
|
254
294
|
"Resource": "*"
|
|
255
295
|
}
|
|
256
296
|
]
|
|
@@ -279,9 +319,9 @@ Gives this file in `expanded-policy.json`
|
|
|
279
319
|
"Resource": "*"
|
|
280
320
|
},
|
|
281
321
|
{
|
|
282
|
-
"Effect": "
|
|
322
|
+
"Effect": "Deny",
|
|
283
323
|
// Was ["s3:Get*Tagging", "s3:Put*Tagging"]
|
|
284
|
-
"
|
|
324
|
+
"NotAction": [
|
|
285
325
|
"s3:GetBucketTagging",
|
|
286
326
|
"s3:GetJobTagging",
|
|
287
327
|
"s3:GetObjectTagging",
|
|
@@ -301,14 +341,13 @@ Gives this file in `expanded-policy.json`
|
|
|
301
341
|
|
|
302
342
|
You can also use this to expand the actions from the output of commands.
|
|
303
343
|
```bash
|
|
304
|
-
aws iam get-account-authorization-details --output json | iam-expand --expand-service-asterisk --read-wait-time=20_000 > expanded-
|
|
344
|
+
aws iam get-account-authorization-details --output json | iam-expand --expand-service-asterisk --read-wait-time=20_000 > expanded-authorization-details.json
|
|
305
345
|
# Now you can search the output for actions you are interested in
|
|
306
|
-
grep "kms:DisableKey" expanded-inline-policies.json
|
|
346
|
+
grep -n "kms:DisableKey" expanded-inline-policies.json
|
|
307
347
|
```
|
|
308
|
-
_--expand-service-asterisk makes sure kms:* is expaneded out so you can find the DisableKey action. --read-wait-time=20_000 gives the cli command more time to return it's first byte of output_
|
|
309
348
|
|
|
310
349
|
#### Expanding arbitrary input
|
|
311
|
-
If the input from stdin is not json, the content is searched for actions
|
|
350
|
+
If the input from stdin is not json, the content is searched for IAM actions then expands them. Throw anything at it and it will find all the actions it can and expand them.
|
|
312
351
|
|
|
313
352
|
You can echo some content:
|
|
314
353
|
```bash
|
|
@@ -332,7 +371,7 @@ cat template.yaml | iam-expand
|
|
|
332
371
|
|
|
333
372
|
Or even some HTML:
|
|
334
373
|
```bash
|
|
335
|
-
curl "https://docs.aws.amazon.com/aws-managed-policy/latest/reference/
|
|
374
|
+
curl "https://docs.aws.amazon.com/aws-managed-policy/latest/reference/ReadOnlyAccess.html" | iam-expand
|
|
336
375
|
```
|
|
337
376
|
|
|
338
377
|
Or the output of any command.
|
package/dist/cjs/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ const iam_data_1 = require("@cloud-copilot/iam-data");
|
|
|
5
5
|
const cli_utils_js_1 = require("./cli_utils.js");
|
|
6
6
|
const expand_js_1 = require("./expand.js");
|
|
7
7
|
const commandName = 'iam-expand';
|
|
8
|
+
const dataPackage = '@cloud-copilot/iam-data';
|
|
8
9
|
async function expandAndPrint(actionStrings, options) {
|
|
9
10
|
try {
|
|
10
11
|
const result = await (0, expand_js_1.expandIamActions)(actionStrings, options);
|
|
@@ -35,7 +36,7 @@ function printUsage() {
|
|
|
35
36
|
console.log(' --invalid-action-behavior=error: Throw an error if an invalid action is encountered');
|
|
36
37
|
console.log('CLI Behavior Options:');
|
|
37
38
|
console.log(' --show-data-version: Print the version of the iam-data package being used and exit');
|
|
38
|
-
console.log(' --read-wait-time: Millisenconds to wait for
|
|
39
|
+
console.log(' --read-wait-time: Millisenconds to wait for the first byte from stdin before timing out.');
|
|
39
40
|
console.log(' Example: --read-wait-time=10_000');
|
|
40
41
|
process.exit(1);
|
|
41
42
|
}
|
|
@@ -53,7 +54,12 @@ for (const arg of args) {
|
|
|
53
54
|
async function run() {
|
|
54
55
|
const options = (0, cli_utils_js_1.convertOptions)(optionStrings);
|
|
55
56
|
if (options.showDataVersion) {
|
|
56
|
-
|
|
57
|
+
const version = await (0, iam_data_1.iamDataVersion)();
|
|
58
|
+
const updatedAt = console.log(`${dataPackage} version: ${version}`);
|
|
59
|
+
console.log(`Data last updated: ${await (0, iam_data_1.iamDataUpdatedAt)()}`);
|
|
60
|
+
console.log(`Update with either:`);
|
|
61
|
+
console.log(` npm update ${dataPackage}`);
|
|
62
|
+
console.log(` npm update -g ${dataPackage}`);
|
|
57
63
|
return;
|
|
58
64
|
}
|
|
59
65
|
if (actionStrings.length === 0) {
|
package/dist/cjs/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";;;AAEA,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/expand_file.js
CHANGED
|
@@ -11,7 +11,7 @@ const expand_js_1 = require("./expand.js");
|
|
|
11
11
|
* @returns the expanded JSON document
|
|
12
12
|
*/
|
|
13
13
|
async function expandJsonDocument(options, document, key) {
|
|
14
|
-
if (key === 'Action') {
|
|
14
|
+
if (key === 'Action' || key === 'NotAction') {
|
|
15
15
|
if (typeof document === 'string') {
|
|
16
16
|
return await (0, expand_js_1.expandIamActions)(document, options);
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expand_file.js","sourceRoot":"","sources":["../../src/expand_file.ts"],"names":[],"mappings":";;AAUA,gDA4BC;AAtCD,2CAAuE;AAEvE;;;;;;;GAOG;AACI,KAAK,UAAU,kBAAkB,CAAC,OAAyC,EAAE,QAAa,EAAE,GAAY;IAC7G,IAAG,GAAG,KAAK,QAAQ,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"expand_file.js","sourceRoot":"","sources":["../../src/expand_file.ts"],"names":[],"mappings":";;AAUA,gDA4BC;AAtCD,2CAAuE;AAEvE;;;;;;;GAOG;AACI,KAAK,UAAU,kBAAkB,CAAC,OAAyC,EAAE,QAAa,EAAE,GAAY;IAC7G,IAAG,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;QAC3C,IAAG,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,MAAM,IAAA,4BAAgB,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAClD,CAAC;QACD,IAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YACrF,MAAM,KAAK,GAAI,MAAM,IAAA,4BAAgB,EAAC,QAAQ,EAAE,EAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAA;YAC7E,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,IAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC7C,OAAO,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAC1C,CAAC,CAAC,CAAC,CAAA;IACL,CAAC;IAED,IAAG,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAClC,MAAM,SAAS,GAAQ,EAAE,CAAA;QACzB,KAAI,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;YAC3B,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
package/dist/esm/cli.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { iamDataVersion } from "@cloud-copilot/iam-data";
|
|
2
|
+
import { iamDataUpdatedAt, iamDataVersion } from "@cloud-copilot/iam-data";
|
|
3
3
|
import { convertOptions, parseStdIn } from "./cli_utils.js";
|
|
4
4
|
import { expandIamActions } from "./expand.js";
|
|
5
5
|
const commandName = 'iam-expand';
|
|
6
|
+
const dataPackage = '@cloud-copilot/iam-data';
|
|
6
7
|
async function expandAndPrint(actionStrings, options) {
|
|
7
8
|
try {
|
|
8
9
|
const result = await expandIamActions(actionStrings, options);
|
|
@@ -33,7 +34,7 @@ function printUsage() {
|
|
|
33
34
|
console.log(' --invalid-action-behavior=error: Throw an error if an invalid action is encountered');
|
|
34
35
|
console.log('CLI Behavior Options:');
|
|
35
36
|
console.log(' --show-data-version: Print the version of the iam-data package being used and exit');
|
|
36
|
-
console.log(' --read-wait-time: Millisenconds to wait for
|
|
37
|
+
console.log(' --read-wait-time: Millisenconds to wait for the first byte from stdin before timing out.');
|
|
37
38
|
console.log(' Example: --read-wait-time=10_000');
|
|
38
39
|
process.exit(1);
|
|
39
40
|
}
|
|
@@ -51,7 +52,12 @@ for (const arg of args) {
|
|
|
51
52
|
async function run() {
|
|
52
53
|
const options = convertOptions(optionStrings);
|
|
53
54
|
if (options.showDataVersion) {
|
|
54
|
-
|
|
55
|
+
const version = await iamDataVersion();
|
|
56
|
+
const updatedAt = console.log(`${dataPackage} version: ${version}`);
|
|
57
|
+
console.log(`Data last updated: ${await iamDataUpdatedAt()}`);
|
|
58
|
+
console.log(`Update with either:`);
|
|
59
|
+
console.log(` npm update ${dataPackage}`);
|
|
60
|
+
console.log(` npm update -g ${dataPackage}`);
|
|
55
61
|
return;
|
|
56
62
|
}
|
|
57
63
|
if (actionStrings.length === 0) {
|
package/dist/esm/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAA2B,MAAM,aAAa,CAAC;AAExE,MAAM,WAAW,GAAG,YAAY,CAAA;AAChC,MAAM,WAAW,GAAG,yBAAyB,CAAA;AAE7C,KAAK,UAAU,cAAc,CAAC,aAAuB,EAAE,OAAyC;IAC9F,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;QAC7D,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAA;IACzD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACrB,OAAO,CAAC,GAAG,CAAC,KAAK,WAAW,oCAAoC,CAAC,CAAA;IACjE,OAAO,CAAC,GAAG,CAAC,2BAA2B,WAAW,YAAY,CAAC,CAAA;IAC/D,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;IACxC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAA;IACrD,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;IACzC,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAA;IACtE,OAAO,CAAC,GAAG,CAAC,+EAA+E,CAAC,CAAA;IAC5F,OAAO,CAAC,GAAG,CAAC,wEAAwE,CAAC,CAAA;IACrF,OAAO,CAAC,GAAG,CAAC,+FAA+F,CAAC,CAAA;IAC5G,OAAO,CAAC,GAAG,CAAC,gFAAgF,CAAC,CAAA;IAC7F,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAA;IAC9E,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;IAChF,OAAO,CAAC,GAAG,CAAC,yFAAyF,CAAC,CAAA;IACtG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;IACpC,OAAO,CAAC,GAAG,CAAC,sFAAsF,CAAC,CAAA;IACnG,OAAO,CAAC,GAAG,CAAC,4FAA4F,CAAC,CAAA;IACzG,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAA;IACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,gCAAgC;AACpE,MAAM,aAAa,GAAa,EAAE,CAAA;AAClC,MAAM,aAAa,GAAa,EAAE,CAAA;AAElC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,IAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAAA;IAC7C,IAAG,OAAO,CAAC,eAAe,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAA;QACtC,MAAM,SAAS,GACf,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,aAAa,OAAO,EAAE,CAAC,CAAA;QACjD,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,gBAAgB,EAAE,EAAE,CAAC,CAAA;QAC7D,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;QAClC,OAAO,CAAC,GAAG,CAAC,gBAAgB,WAAW,EAAE,CAAC,CAAA;QAC1C,OAAO,CAAC,GAAG,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAA;QAC7C,OAAM;IACR,CAAC;IAED,IAAG,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,6CAA6C;QAC7C,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAA;QAC7C,IAAG,WAAW,CAAC,MAAM,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YACxD,OAAM;QACR,CAAC;aAAM,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,CAAA;YACxC,IAAG,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;gBACrD,OAAO,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAA;YAC/F,CAAC;YACD,aAAa,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,IAAG,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;QAC5C,OAAM;IACR,CAAC;IAED,UAAU,EAAE,CAAA;AACd,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IAChB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA"}
|
package/dist/esm/expand_file.js
CHANGED
|
@@ -8,7 +8,7 @@ import { expandIamActions } from "./expand.js";
|
|
|
8
8
|
* @returns the expanded JSON document
|
|
9
9
|
*/
|
|
10
10
|
export async function expandJsonDocument(options, document, key) {
|
|
11
|
-
if (key === 'Action') {
|
|
11
|
+
if (key === 'Action' || key === 'NotAction') {
|
|
12
12
|
if (typeof document === 'string') {
|
|
13
13
|
return await expandIamActions(document, options);
|
|
14
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expand_file.js","sourceRoot":"","sources":["../../src/expand_file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA2B,MAAM,aAAa,CAAA;AAEvE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAyC,EAAE,QAAa,EAAE,GAAY;IAC7G,IAAG,GAAG,KAAK,QAAQ,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"expand_file.js","sourceRoot":"","sources":["../../src/expand_file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA2B,MAAM,aAAa,CAAA;AAEvE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAyC,EAAE,QAAa,EAAE,GAAY;IAC7G,IAAG,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;QAC3C,IAAG,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,MAAM,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAClD,CAAC;QACD,IAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YACrF,MAAM,KAAK,GAAI,MAAM,gBAAgB,CAAC,QAAQ,EAAE,EAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAA;YAC7E,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,IAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC7C,OAAO,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAC1C,CAAC,CAAC,CAAC,CAAA;IACL,CAAC;IAED,IAAG,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAClC,MAAM,SAAS,GAAQ,EAAE,CAAA;QACzB,KAAI,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;YAC3B,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
: <<'END_COMMENT'
|
|
4
|
+
This script will download all the account authorization details which contains
|
|
5
|
+
inline policies and expand them then save them to a file.
|
|
6
|
+
END_COMMENT
|
|
7
|
+
|
|
8
|
+
aws iam get-account-authorization-details --output json | iam-expand --expand-service-asterisk --read-wait-time=20_000 > expanded-authorization-details.json
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
: <<'END_COMMENT'
|
|
4
|
+
This script will download all customer-managed policies in the account, expand them, and save them to files
|
|
5
|
+
in the `policies` directory. The file name will be the policy name with the path as a prefix.
|
|
6
|
+
END_COMMENT
|
|
7
|
+
|
|
8
|
+
mkdir -p policies
|
|
9
|
+
|
|
10
|
+
# List all managed policies that are attached to any entity
|
|
11
|
+
policies=$(aws iam list-policies --scope All --only-attached --query 'Policies[].{Arn:Arn,VersionId:DefaultVersionId,Path:Path,Name:PolicyName}' --output json)
|
|
12
|
+
|
|
13
|
+
# Loop through each policy to get the default version and save it
|
|
14
|
+
echo "$policies" | jq -c '.[]' | while read -r line; do
|
|
15
|
+
arn=$(echo "$line" | jq -r '.Arn')
|
|
16
|
+
version_id=$(echo "$line" | jq -r '.VersionId')
|
|
17
|
+
path=$(echo "$line" | jq -r '.Path' | tr '/' '_')
|
|
18
|
+
name=$(echo "$line" | jq -r '.Name')
|
|
19
|
+
|
|
20
|
+
file_name="policies/${path}${name}.json"
|
|
21
|
+
aws iam get-policy-version --policy-arn "$arn" --version-id "$version_id" --query 'PolicyVersion.Document' --output json 2>/dev/null | iam-expand --read-wait-time=10_000 > $file_name
|
|
22
|
+
done
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { iamDataVersion } from "@cloud-copilot/iam-data";
|
|
3
|
+
import { iamDataUpdatedAt, iamDataVersion } from "@cloud-copilot/iam-data";
|
|
4
4
|
import { convertOptions, parseStdIn } from "./cli_utils.js";
|
|
5
5
|
import { expandIamActions, ExpandIamActionsOptions } from "./expand.js";
|
|
6
6
|
|
|
7
7
|
const commandName = 'iam-expand'
|
|
8
|
+
const dataPackage = '@cloud-copilot/iam-data'
|
|
8
9
|
|
|
9
10
|
async function expandAndPrint(actionStrings: string[], options: Partial<ExpandIamActionsOptions>) {
|
|
10
11
|
try {
|
|
@@ -36,7 +37,7 @@ function printUsage() {
|
|
|
36
37
|
console.log(' --invalid-action-behavior=error: Throw an error if an invalid action is encountered')
|
|
37
38
|
console.log('CLI Behavior Options:')
|
|
38
39
|
console.log(' --show-data-version: Print the version of the iam-data package being used and exit')
|
|
39
|
-
console.log(' --read-wait-time: Millisenconds to wait for
|
|
40
|
+
console.log(' --read-wait-time: Millisenconds to wait for the first byte from stdin before timing out.')
|
|
40
41
|
console.log(' Example: --read-wait-time=10_000')
|
|
41
42
|
process.exit(1)
|
|
42
43
|
}
|
|
@@ -56,7 +57,13 @@ for (const arg of args) {
|
|
|
56
57
|
async function run() {
|
|
57
58
|
const options = convertOptions(optionStrings)
|
|
58
59
|
if(options.showDataVersion) {
|
|
59
|
-
|
|
60
|
+
const version = await iamDataVersion()
|
|
61
|
+
const updatedAt =
|
|
62
|
+
console.log(`${dataPackage} version: ${version}`)
|
|
63
|
+
console.log(`Data last updated: ${await iamDataUpdatedAt()}`)
|
|
64
|
+
console.log(`Update with either:`)
|
|
65
|
+
console.log(` npm update ${dataPackage}`)
|
|
66
|
+
console.log(` npm update -g ${dataPackage}`)
|
|
60
67
|
return
|
|
61
68
|
}
|
|
62
69
|
|
package/src/expand_file.test.ts
CHANGED
|
@@ -103,5 +103,84 @@ describe('expand_file', () => {
|
|
|
103
103
|
// Then the document should be returned as is
|
|
104
104
|
expect(result).toEqual(document)
|
|
105
105
|
})
|
|
106
|
+
|
|
107
|
+
it('should expand a string NotAction', async () => {
|
|
108
|
+
// Given a document with an action
|
|
109
|
+
const document = {
|
|
110
|
+
a: {
|
|
111
|
+
b: {
|
|
112
|
+
"NotAction": "s3:Get*"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
vi.mocked(expandIamActions).mockResolvedValue(["s3:GetObject", "s3:GetBucket"])
|
|
117
|
+
|
|
118
|
+
// When the document is expanded
|
|
119
|
+
const result = await expandJsonDocument({}, document)
|
|
120
|
+
|
|
121
|
+
// Then the action should be expanded
|
|
122
|
+
const expected = JSON.parse(JSON.stringify(document))
|
|
123
|
+
expected.a.b.NotAction = ["s3:GetObject", "s3:GetBucket"]
|
|
124
|
+
expect(result).toEqual(expected)
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it('should expand an array of string NotActions', async () => {
|
|
128
|
+
// Given a document with an action
|
|
129
|
+
const document = {
|
|
130
|
+
a: {
|
|
131
|
+
b: {
|
|
132
|
+
"NotAction": ["s3:Get*", "s3:Put*"]
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
vi.mocked(expandIamActions).mockImplementation(async (actions, options) =>{
|
|
137
|
+
expect(options?.distinct).toBe(true)
|
|
138
|
+
return ["s3:GetObject", "s3:GetBucket", "s3:PutObject", "s3:PutBucket"]
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// When the document is expanded
|
|
142
|
+
const result = await expandJsonDocument({}, document)
|
|
143
|
+
|
|
144
|
+
// Then the action should be expanded
|
|
145
|
+
const expected = JSON.parse(JSON.stringify(document))
|
|
146
|
+
expected.a.b.NotAction = ["s3:GetObject", "s3:GetBucket", "s3:PutObject", "s3:PutBucket"]
|
|
147
|
+
expect(result).toEqual(expected)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
it('should not expand a NotAction if it is an object', async () => {
|
|
151
|
+
// Given a document with an action
|
|
152
|
+
const document = {
|
|
153
|
+
a: {
|
|
154
|
+
b: {
|
|
155
|
+
"NotAction": {
|
|
156
|
+
"key": "value"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// When the document is expanded
|
|
163
|
+
const result = await expandJsonDocument({}, document)
|
|
164
|
+
|
|
165
|
+
// Then the document should be returned as is
|
|
166
|
+
expect(result).toEqual(document)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('should not expand a NotAction if it is an array of numbers', async () => {
|
|
170
|
+
// Given a document with an action
|
|
171
|
+
const document = {
|
|
172
|
+
a: {
|
|
173
|
+
b: {
|
|
174
|
+
"NotAction": [1, 2, 3]
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// When the document is expanded
|
|
180
|
+
const result = await expandJsonDocument({}, document)
|
|
181
|
+
|
|
182
|
+
// Then the document should be returned as is
|
|
183
|
+
expect(result).toEqual(document)
|
|
184
|
+
})
|
|
106
185
|
})
|
|
107
186
|
})
|
package/src/expand_file.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { expandIamActions, ExpandIamActionsOptions } from "./expand.js"
|
|
|
9
9
|
* @returns the expanded JSON document
|
|
10
10
|
*/
|
|
11
11
|
export async function expandJsonDocument(options: Partial<ExpandIamActionsOptions>, document: any, key?: string): Promise<any> {
|
|
12
|
-
if(key === 'Action') {
|
|
12
|
+
if(key === 'Action' || key === 'NotAction') {
|
|
13
13
|
if(typeof document === 'string') {
|
|
14
14
|
return await expandIamActions(document, options)
|
|
15
15
|
}
|