@cloud-copilot/iam-shrink 0.1.0

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.
Files changed (85) hide show
  1. package/LICENSE.txt +674 -0
  2. package/README.md +187 -0
  3. package/dist/cjs/cli.d.ts +2 -0
  4. package/dist/cjs/cli.d.ts.map +1 -0
  5. package/dist/cjs/cli.js +78 -0
  6. package/dist/cjs/cli.js.map +1 -0
  7. package/dist/cjs/cli_utils.d.ts +30 -0
  8. package/dist/cjs/cli_utils.d.ts.map +1 -0
  9. package/dist/cjs/cli_utils.js +75 -0
  10. package/dist/cjs/cli_utils.js.map +1 -0
  11. package/dist/cjs/errors.d.ts +13 -0
  12. package/dist/cjs/errors.d.ts.map +1 -0
  13. package/dist/cjs/errors.js +56 -0
  14. package/dist/cjs/errors.js.map +1 -0
  15. package/dist/cjs/index.d.ts +3 -0
  16. package/dist/cjs/index.d.ts.map +1 -0
  17. package/dist/cjs/index.js +8 -0
  18. package/dist/cjs/index.js.map +1 -0
  19. package/dist/cjs/package.json +3 -0
  20. package/dist/cjs/shrink.d.ts +131 -0
  21. package/dist/cjs/shrink.d.ts.map +1 -0
  22. package/dist/cjs/shrink.js +358 -0
  23. package/dist/cjs/shrink.js.map +1 -0
  24. package/dist/cjs/shrink_file.d.ts +12 -0
  25. package/dist/cjs/shrink_file.d.ts.map +1 -0
  26. package/dist/cjs/shrink_file.js +38 -0
  27. package/dist/cjs/shrink_file.js.map +1 -0
  28. package/dist/cjs/stdin.d.ts +7 -0
  29. package/dist/cjs/stdin.d.ts.map +1 -0
  30. package/dist/cjs/stdin.js +34 -0
  31. package/dist/cjs/stdin.js.map +1 -0
  32. package/dist/cjs/validate.d.ts +11 -0
  33. package/dist/cjs/validate.d.ts.map +1 -0
  34. package/dist/cjs/validate.js +30 -0
  35. package/dist/cjs/validate.js.map +1 -0
  36. package/dist/esm/cli.d.ts +2 -0
  37. package/dist/esm/cli.d.ts.map +1 -0
  38. package/dist/esm/cli.js +76 -0
  39. package/dist/esm/cli.js.map +1 -0
  40. package/dist/esm/cli_utils.d.ts +30 -0
  41. package/dist/esm/cli_utils.d.ts.map +1 -0
  42. package/dist/esm/cli_utils.js +69 -0
  43. package/dist/esm/cli_utils.js.map +1 -0
  44. package/dist/esm/errors.d.ts +13 -0
  45. package/dist/esm/errors.d.ts.map +1 -0
  46. package/dist/esm/errors.js +50 -0
  47. package/dist/esm/errors.js.map +1 -0
  48. package/dist/esm/index.d.ts +3 -0
  49. package/dist/esm/index.d.ts.map +1 -0
  50. package/dist/esm/index.js +3 -0
  51. package/dist/esm/index.js.map +1 -0
  52. package/dist/esm/package.json +3 -0
  53. package/dist/esm/shrink.d.ts +131 -0
  54. package/dist/esm/shrink.d.ts.map +1 -0
  55. package/dist/esm/shrink.js +343 -0
  56. package/dist/esm/shrink.js.map +1 -0
  57. package/dist/esm/shrink_file.d.ts +12 -0
  58. package/dist/esm/shrink_file.d.ts.map +1 -0
  59. package/dist/esm/shrink_file.js +35 -0
  60. package/dist/esm/shrink_file.js.map +1 -0
  61. package/dist/esm/stdin.d.ts +7 -0
  62. package/dist/esm/stdin.d.ts.map +1 -0
  63. package/dist/esm/stdin.js +31 -0
  64. package/dist/esm/stdin.js.map +1 -0
  65. package/dist/esm/validate.d.ts +11 -0
  66. package/dist/esm/validate.d.ts.map +1 -0
  67. package/dist/esm/validate.js +27 -0
  68. package/dist/esm/validate.js.map +1 -0
  69. package/package.json +43 -0
  70. package/postbuild.sh +13 -0
  71. package/src/cli.ts +83 -0
  72. package/src/cli_utils.test.ts +117 -0
  73. package/src/cli_utils.ts +82 -0
  74. package/src/errors.ts +52 -0
  75. package/src/index.ts +3 -0
  76. package/src/shrink.test.ts +594 -0
  77. package/src/shrink.ts +385 -0
  78. package/src/shrink_file.test.ts +72 -0
  79. package/src/shrink_file.ts +38 -0
  80. package/src/stdin.ts +34 -0
  81. package/src/validate.test.ts +55 -0
  82. package/src/validate.ts +29 -0
  83. package/tsconfig.cjs.json +12 -0
  84. package/tsconfig.esm.json +15 -0
  85. package/tsconfig.json +23 -0
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # Shrink IAM Actions
2
+
3
+ Built in the Unix philosophy, this is a small tool with two goals:
4
+ 1. Shrink IAM actions lists by creating patterns that match only the actions specified and no others.
5
+ 2. Do #1 in a way that won't make your coworkers hate you.
6
+
7
+ Using Action Wildcards is not recommended, sometimes there are [IAM Limits](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) you can't get around. This tool helps you stay within those limits.
8
+
9
+ ## Getting Small While Staying Sane
10
+ IAM Actions are camel cased into a number of words. For example:
11
+ * `s3:GetObject` -> "Get" "Object"
12
+ * `s3:GetObjectTagging` -> "Get" "Object" "Tagging"
13
+
14
+ IAM Shrink will only replace one word at a time and will never replace part of a word. So for instance `s3:GetObject` will never get shrunk to something like `s3:*et*`. This is to balance size reduction with readability.
15
+
16
+ ## Use in Browser
17
+ [https://iam.cloudcopilot.io/tools/iam-shrink](https://iam.cloudcopilot.io/tools/iam-shrink)
18
+
19
+ ## Use in CLI
20
+
21
+ ### Installation
22
+ You can install it globally. This also works in the default AWS CloudShell!
23
+ ```bash
24
+ npm install -g @cloud-copilot/iam-shrink
25
+ ```
26
+ *Depending on your configuration sudo may be required to install globally.*
27
+
28
+ ### Help
29
+
30
+ ```bash
31
+ iam-shrink --help
32
+ ```
33
+
34
+ ### Shrink IAM Actions
35
+
36
+ #### Pass in Argument
37
+ It's unlikely that you will pass in on the CLI a number of actions after the command name, but you can. You'll need a large number of actions for it to be pracitical, so it's mostly for automation.
38
+
39
+ ```bash
40
+ Usage: iam-shrink s3:GetBucketTagging s3:GetJobTagging s3:GetObjectTagging s3:GetObjectVersionTagging s3:GetStorageLensConfigurationTagging
41
+ # Output
42
+ s3:Get*Tagging
43
+ ```
44
+
45
+ #### Read from stdin
46
+ If no actions are passed as arguments, the CLI will read from stdin.
47
+
48
+ ```bash
49
+ cat "s3:GetBucketTagging s3:GetJobTagging s3:GetObjectTagging s3:GetObjectVersionTagging s3:GetStorageLensConfigurationTagging" | iam-shrink
50
+ # Output
51
+ s3:Get*Tagging
52
+ ```
53
+
54
+ #### Shrink JSON input
55
+ If the input is a valid json document, the CLI will find every instance of `Action` and `NotAction` that is an array of strings and shrink them.
56
+
57
+ Given `policy.json`
58
+ ```json
59
+ {
60
+ "Version": "2012-10-17",
61
+ "Statement": [
62
+ {
63
+ "Effect": "Allow",
64
+ "Action": [
65
+ "groundstation:GetAgentConfiguration",
66
+ "groundstation:GetConfig",
67
+ "groundstation:GetDataflowEndpointGroup",
68
+ "groundstation:GetMinuteUsage",
69
+ "groundstation:GetMissionProfile",
70
+ "groundstation:GetSatellite",
71
+ "groundstation:ListConfigs",
72
+ "groundstation:ListContacts",
73
+ "groundstation:ListDataflowEndpointGroups",
74
+ "groundstation:ListEphemerides",
75
+ "groundstation:ListGroundStations",
76
+ "groundstation:ListMissionProfiles",
77
+ "groundstation:ListSatellites",
78
+ "groundstation:ListTagsForResource",
79
+ "s3:GetBucketTagging",
80
+ "s3:GetJobTagging",
81
+ "s3:GetObjectTagging",
82
+ "s3:GetObjectVersionTagging",
83
+ "s3:GetStorageLensConfigurationTagging"
84
+ ],
85
+ "Resource": "*"
86
+ },
87
+ {
88
+ "Effect": "Deny",
89
+ "NotAction": [
90
+ "organizations:DeleteOrganization",
91
+ "organizations:DeleteOrganizationalUnit",
92
+ "organizations:DeletePolicy",
93
+ "organizations:DeleteResourcePolicy",
94
+ "organizations:LeaveOrganization"
95
+ ],
96
+ "Resource": "*"
97
+ }
98
+ ]
99
+ }
100
+ ```
101
+
102
+ ```bash
103
+ cat policy.json | iam-shrink > smaller-policy.json
104
+ ```
105
+
106
+ Gives this file in `smaller-policy.json`
107
+ ```json
108
+ {
109
+ "Version": "2012-10-17",
110
+ "Statement": [
111
+ {
112
+ "Effect": "Allow",
113
+ "Action": [
114
+ "groundstation:List*",
115
+ "groundstation:Get*",
116
+ "s3:Get*Tagging"
117
+ ],
118
+ "Resource": "*"
119
+ },
120
+ {
121
+ "Effect": "Deny",
122
+ "NotAction": [
123
+ "organizations:Delete*",
124
+ "organizations:Leave*"
125
+ ],
126
+ "Resource": "*"
127
+ }
128
+ ]
129
+ }
130
+ ```
131
+
132
+ ### Configuring iterations
133
+ By default, the CLI will do two iterations of shrinking. This generally does a good balance between reducing size and maintaining readability. This can be adjusted with the `--iterations` flag.
134
+
135
+ Assuming the [AWS Read Only policy](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/ReadOnlyAccess.html) is in `readonly.json`
136
+
137
+ ```bash
138
+ You can change this with the `--iterations` flag.
139
+
140
+ ```bash
141
+ # Default two iterations
142
+ cat readonly.json | iam-shrink | wc -m
143
+ # 61305 characters
144
+
145
+ # Increasing iterations
146
+ cat readonly.json | iam-shrink --iterations=3 | wc -m
147
+ # 45983 characters
148
+ cat readonly.json | iam-shrink --iterations=4 | wc -m
149
+ # 43654 characters
150
+ cat readonly.json | iam-shrink --iterations=5 | wc -m
151
+ # 43336 characters
152
+
153
+ # Unlimited iterations until the policy cannot be further reduced
154
+ cat readonly.json | iam-shrink --iterations=0 | wc -m
155
+ # 43281 characters
156
+ ```
157
+
158
+ If you want to shrink the policy as much as possible, you can use `--iterations=0`. This will keep shrinking the policy until it can't be reduced any further.
159
+
160
+ ## Use in TypeScript/Node
161
+
162
+ You can use the shrink function in your own code.
163
+ ```typescript
164
+ import { shrink } from '@cloud-copilot/iam-shrink';
165
+
166
+ const actions = [
167
+ "s3:GetBucketTagging",
168
+ "s3:GetJobTagging",
169
+ "s3:GetObjectTagging",
170
+ "s3:GetObjectVersionTagging",
171
+ "s3:GetStorageLensConfigurationTagging"
172
+ ];
173
+
174
+ const shrunk = await shrink(actions);
175
+ console.log(shrunk);
176
+ // [ s3:Get*Tagging ]
177
+ ```
178
+
179
+ You can specify the number of iterations as well.
180
+ ```typescript
181
+ import { shrink } from '@cloud-copilot/iam-shrink';
182
+
183
+ const bigListOfActions = getBigListOfActions();
184
+
185
+ const smallerList = await shrink(bigListOfActions, { iterations: 3 });
186
+ console.log(shrunk);
187
+ ```
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const iam_data_1 = require("@cloud-copilot/iam-data");
4
+ const cli_utils_js_1 = require("./cli_utils.js");
5
+ const shrink_js_1 = require("./shrink.js");
6
+ const commandName = 'iam-shrink';
7
+ const dataPackage = '@cloud-copilot/iam-data';
8
+ async function shrinkAandPrint(actions, shrinkOptions) {
9
+ try {
10
+ const result = await (0, shrink_js_1.shrink)(actions, shrinkOptions);
11
+ for (const action of result) {
12
+ console.log(action);
13
+ }
14
+ }
15
+ catch (e) {
16
+ console.error(e.message);
17
+ process.exit(1);
18
+ }
19
+ }
20
+ function printUsage() {
21
+ console.log('No arguments provided or input from stdin');
22
+ console.log('Usage:');
23
+ console.log(` ${commandName} [options] [action1] [action2] ...`);
24
+ console.log(` <input from stdout> | ${commandName} [options]`);
25
+ console.log('Shrink ActionOptions:');
26
+ console.log(' --iterations: How many iterations of shrinking should be executed, defaults to 2; zero or less means no limit');
27
+ console.log(' Example: --iterations=5');
28
+ console.log(' Example: --iterations=-1');
29
+ console.log('CLI Behavior Options:');
30
+ console.log(' --show-data-version: Print the version of the iam-data package being used and exit');
31
+ console.log(' --read-wait-ms: Millisenconds to wait for the first byte from stdin before timing out.');
32
+ console.log(' Example: --read-wait-ms=10_000');
33
+ process.exit(1);
34
+ }
35
+ const args = process.argv.slice(2); // Ignore the first two elements
36
+ const actionStrings = [];
37
+ const optionStrings = [];
38
+ for (const arg of args) {
39
+ if (arg.startsWith('--')) {
40
+ optionStrings.push(arg);
41
+ }
42
+ else {
43
+ actionStrings.push(arg);
44
+ }
45
+ }
46
+ async function run() {
47
+ const options = (0, cli_utils_js_1.convertOptions)(optionStrings);
48
+ if (options.showDataVersion) {
49
+ const version = await (0, iam_data_1.iamDataVersion)();
50
+ console.log(`${dataPackage} version: ${version}`);
51
+ console.log(`Data last updated: ${await (0, iam_data_1.iamDataUpdatedAt)()}`);
52
+ console.log(`Update with either:`);
53
+ console.log(` npm update ${dataPackage}`);
54
+ console.log(` npm update -g ${dataPackage}`);
55
+ return;
56
+ }
57
+ if (actionStrings.length === 0) {
58
+ //If no actions are provided, read from stdin
59
+ const stdInResult = await (0, cli_utils_js_1.parseStdIn)(options);
60
+ if (stdInResult.object) {
61
+ console.log(JSON.stringify(stdInResult.object, null, 2));
62
+ return;
63
+ }
64
+ else if (stdInResult.strings) {
65
+ actionStrings.push(...stdInResult.strings);
66
+ }
67
+ }
68
+ if (actionStrings.length > 0) {
69
+ await shrinkAandPrint(actionStrings, options);
70
+ return;
71
+ }
72
+ printUsage();
73
+ }
74
+ run().catch((e) => {
75
+ console.error(e);
76
+ process.exit(1);
77
+ }).then(() => process.exit(0)).finally(() => { });
78
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { ShrinkOptions } from "./shrink.js";
2
+ interface CliOptions extends ShrinkOptions {
3
+ showDataVersion: boolean;
4
+ readWaitMs: string;
5
+ }
6
+ /**
7
+ * Convert a dash-case string to camelCase
8
+ * @param str the string to convert
9
+ * @returns the camelCase string
10
+ */
11
+ export declare function dashToCamelCase(str: string): string;
12
+ /**
13
+ * Convert an array of option strings to an object
14
+ *
15
+ * @param optionArgs the array of option strings to convert
16
+ * @returns the object representation of the options
17
+ */
18
+ export declare function convertOptions(optionArgs: string[]): Partial<CliOptions>;
19
+ export declare function extractActionsFromLineOfInput(line: string): string[];
20
+ /**
21
+ * Parse the actions from stdin
22
+ *
23
+ * @returns an array of strings from stdin
24
+ */
25
+ export declare function parseStdIn(options: Partial<CliOptions>): Promise<{
26
+ strings?: string[];
27
+ object?: any;
28
+ }>;
29
+ export {};
30
+ //# sourceMappingURL=cli_utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli_utils.d.ts","sourceRoot":"","sources":["../../src/cli_utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5C,UAAU,UAAW,SAAQ,aAAa;IACxC,eAAe,EAAE,OAAO,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAwBxE;AAGD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMpE;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAC,CAAC,CAgB1G"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dashToCamelCase = dashToCamelCase;
4
+ exports.convertOptions = convertOptions;
5
+ exports.extractActionsFromLineOfInput = extractActionsFromLineOfInput;
6
+ exports.parseStdIn = parseStdIn;
7
+ const shrink_file_js_1 = require("./shrink_file.js");
8
+ const stdin_js_1 = require("./stdin.js");
9
+ /**
10
+ * Convert a dash-case string to camelCase
11
+ * @param str the string to convert
12
+ * @returns the camelCase string
13
+ */
14
+ function dashToCamelCase(str) {
15
+ str = str.substring(2);
16
+ return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
17
+ }
18
+ /**
19
+ * Convert an array of option strings to an object
20
+ *
21
+ * @param optionArgs the array of option strings to convert
22
+ * @returns the object representation of the options
23
+ */
24
+ function convertOptions(optionArgs) {
25
+ const options = {};
26
+ for (const option of optionArgs) {
27
+ let key = option;
28
+ let value = true;
29
+ if (option.includes('=')) {
30
+ [key, value] = option.split('=');
31
+ }
32
+ options[dashToCamelCase(key)] = value;
33
+ }
34
+ if (options.iterations) {
35
+ const iterationNumber = parseInt(options.iterations);
36
+ if (isNaN(iterationNumber)) {
37
+ delete options.iterations;
38
+ }
39
+ else if (iterationNumber <= 0) {
40
+ options.iterations = Infinity;
41
+ }
42
+ else {
43
+ options.iterations = iterationNumber;
44
+ }
45
+ }
46
+ return options;
47
+ }
48
+ const actionPattern = /\:?([a-zA-Z0-9-]+:[a-zA-Z0-9*]+)/g;
49
+ function extractActionsFromLineOfInput(line) {
50
+ const matches = line.matchAll(actionPattern);
51
+ return Array.from(matches)
52
+ .filter((match) => !match[0].startsWith('arn:') && !match[0].startsWith(':'))
53
+ .map((match) => match[1]);
54
+ }
55
+ /**
56
+ * Parse the actions from stdin
57
+ *
58
+ * @returns an array of strings from stdin
59
+ */
60
+ async function parseStdIn(options) {
61
+ const delay = options.readWaitMs ? parseInt(options.readWaitMs.replaceAll(/\D/g, '')) : undefined;
62
+ const data = await (0, stdin_js_1.readStdin)(delay);
63
+ if (data.length === 0) {
64
+ return {};
65
+ }
66
+ try {
67
+ const object = await (0, shrink_file_js_1.shrinkJsonDocument)(options, JSON.parse(data));
68
+ return { object };
69
+ }
70
+ catch (err) { }
71
+ const lines = data.split('\n');
72
+ const actions = lines.flatMap(line => extractActionsFromLineOfInput(line));
73
+ return { strings: actions };
74
+ }
75
+ //# sourceMappingURL=cli_utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli_utils.js","sourceRoot":"","sources":["../../src/cli_utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export declare class ShrinkValidationError extends Error {
2
+ readonly desiredPatterns: string[];
3
+ readonly errorMatch: string;
4
+ /**
5
+ * Capture a validation error from a shrink operation
6
+ *
7
+ * @param desiredPatterns the patterns the user wanted to shrink
8
+ * @param excludedPatterns the patterns the user wanted to exclude
9
+ * @param errorMatch the undesired match that triggered the bug
10
+ */
11
+ constructor(desiredPatterns: string[], errorMatch: string);
12
+ }
13
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAmCA,qBAAa,qBAAsB,SAAQ,KAAK;aAQlB,eAAe,EAAE,MAAM,EAAE;aAAkB,UAAU,EAAE,MAAM;IAPzF;;;;;;OAMG;gBACyB,eAAe,EAAE,MAAM,EAAE,EAAkB,UAAU,EAAE,MAAM;CAO1F"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ShrinkValidationError = void 0;
4
+ const bugBaseUrl = 'https://github.com/cloud-copilot/iam-shrink/issues/new';
5
+ /**
6
+ * The title of the bug report
7
+ * @param errorMatch The undesired match
8
+ * @returns the title of the bug report
9
+ */
10
+ function bugTitle(errorMatch) {
11
+ return `Bug: ShrinkValidationError. ${errorMatch}`;
12
+ }
13
+ /**
14
+ * The body of the bug report
15
+ *
16
+ * @param errorMatch The undesired match
17
+ * @param desiredPatterns The desired patterns
18
+ * @param excludedPatterns The excluded patterns
19
+ * @returns the body of the bug report
20
+ */
21
+ function bugBody(errorMatch, desiredPatterns) {
22
+ return `${errorMatch} while shrinking patterns ${JSON.stringify(desiredPatterns)}`;
23
+ }
24
+ /**
25
+ * Get the full url of the full bug report
26
+ *
27
+ * @param desiredPatterns The desired patterns
28
+ * @param excludedPatterns The excluded patterns
29
+ * @param errorMatch The undesired match that caused the bug
30
+ * @returns the full url to create a new bug report
31
+ */
32
+ function bugUrl(desiredPatterns, errorMatch) {
33
+ return `${bugBaseUrl}?labels=bug&title=${encodeURIComponent(bugTitle(errorMatch))}&body=${encodeURIComponent(bugBody(errorMatch, desiredPatterns))}`;
34
+ }
35
+ class ShrinkValidationError extends Error {
36
+ desiredPatterns;
37
+ errorMatch;
38
+ /**
39
+ * Capture a validation error from a shrink operation
40
+ *
41
+ * @param desiredPatterns the patterns the user wanted to shrink
42
+ * @param excludedPatterns the patterns the user wanted to exclude
43
+ * @param errorMatch the undesired match that triggered the bug
44
+ */
45
+ constructor(desiredPatterns, errorMatch) {
46
+ super([
47
+ `@cloud-copilot/iam-shrink has failed validation and this is a bug.`,
48
+ `Please file a bug at ${bugUrl(desiredPatterns, errorMatch)}`,
49
+ ].join("\n"));
50
+ this.desiredPatterns = desiredPatterns;
51
+ this.errorMatch = errorMatch;
52
+ this.name = "ShrinkValidationError"; // Set the name of the error
53
+ }
54
+ }
55
+ exports.ShrinkValidationError = ShrinkValidationError;
56
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAAA,MAAM,UAAU,GAAG,wDAAwD,CAAA;AAE3E;;;;GAIG;AACH,SAAS,QAAQ,CAAC,UAAkB;IAClC,OAAO,+BAA+B,UAAU,EAAE,CAAC;AACrD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,OAAO,CAAC,UAAkB,EAAE,eAAyB;IAC5D,OAAO,GAAG,UAAU,6BAA6B,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,CAAC;AACrF,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,MAAM,CAAC,eAAyB,EAAE,UAAkB;IAC3D,OAAO,GAAG,UAAU,qBAAqB,kBAAkB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,SAAS,kBAAkB,CAAC,OAAO,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;AACvJ,CAAC;AAED,MAAa,qBAAsB,SAAQ,KAAK;IAQlB;IAA2C;IAPvE;;;;;;OAMG;IACH,YAA4B,eAAyB,EAAkB,UAAkB;QACvF,KAAK,CAAC;YACJ,oEAAoE;YACpE,wBAAwB,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC,EAAE;SAC9D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAJY,oBAAe,GAAf,eAAe,CAAU;QAAkB,eAAU,GAAV,UAAU,CAAQ;QAKvF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC,CAAC,4BAA4B;IACnE,CAAC;CACF;AAfD,sDAeC"}
@@ -0,0 +1,3 @@
1
+ export { shrink } from './shrink.js';
2
+ export { shrinkJsonDocument } from './shrink_file.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shrinkJsonDocument = exports.shrink = void 0;
4
+ var shrink_js_1 = require("./shrink.js");
5
+ Object.defineProperty(exports, "shrink", { enumerable: true, get: function () { return shrink_js_1.shrink; } });
6
+ var shrink_file_js_1 = require("./shrink_file.js");
7
+ Object.defineProperty(exports, "shrinkJsonDocument", { enumerable: true, get: function () { return shrink_file_js_1.shrinkJsonDocument; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AACf,mDAAsD;AAA7C,oHAAA,kBAAkB,OAAA"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,131 @@
1
+ export interface ShrinkOptions {
2
+ iterations: number;
3
+ }
4
+ /**
5
+ * Shrink the list of desired patterns minus the excluded patterns to the smallest list of patterns
6
+ * that still includes the actions you want and only the actions you want.
7
+ *
8
+ * This will create a Target Set of actions that match the patterns in {@link desiredPatterns}, and do
9
+ * not match any pattern in {@link excludedPatterns}.
10
+ *
11
+ * It will then derive the list of wildcard patterns that match the Target Set and no other actions.
12
+ *
13
+ * @param desiredPatterns the list of patterns you want to include, e.g. ['s3:Get*', 's3:PutObject', 's3:*Tag*']
14
+ * @param iterations the number of iterations to run the shrink operations
15
+ * @returns the smallest list of patterns that will match only the actions specified by desiredPatterns and not match any of the excludedPatterns or any actions not specified by desiredPatterns.
16
+ */
17
+ export declare function shrink(desiredPatterns: string[], shrinkOptions?: Partial<ShrinkOptions>): Promise<string[]>;
18
+ /**
19
+ * Map an array of service:action strings to just the action
20
+ *
21
+ * @param actions the array of service:action strings such as ['s3:GetObject', 'ec2:DescribeInstances']
22
+ * @returns an array of just the action strings such as ['GetObject', 'DescribeInstances']
23
+ */
24
+ export declare function mapActions(actions: string[]): string[];
25
+ /**
26
+ * Groups an array of service:action strings by service
27
+ *
28
+ * Returns a map of service to an object with two arrays: withService and withoutService
29
+ * * withService contains the full service:action strings
30
+ * * withoutService contains just the action strings
31
+ *
32
+ * @param actions the array of service:action strings such as ['s3:GetObject', 'ec2:DescribeInstances']
33
+ * @returns a map of service to an object with two arrays: withService and withoutService
34
+ */
35
+ export declare function groupActionsByService(actions: string[]): Map<string, {
36
+ withService: string[];
37
+ withoutService: string[];
38
+ }>;
39
+ /**
40
+ * Shrink a list of desired actions to the smallest number of patterns that match the desired actions
41
+ * from the possible actions and no other actions.
42
+ *
43
+ * @param desiredActions the list of actions you want to include
44
+ * @param possibleActions the list of actions that are possible
45
+ * @param iterations the number of iterations to run the shrink operations
46
+ * @returns the smallest list of patterns that when compared to possibleActions will match only the desiredActions and no others
47
+ */
48
+ export declare function shrinkResolvedList(desiredActions: string[], possibleActions: string[], iterations: number): string[];
49
+ /**
50
+ * Shrink the list of desired actions for while excluding the undesired actions
51
+ *
52
+ * @param desiredActions the list of actions you want to include, can be a mix of full actions and wildcards
53
+ * @param undesiredActions the list of actions you want to exclude no matter what
54
+ * @param deep if true, will shrink based on all common sequences, otherwise will only shrink based on the most common sequence
55
+ * @returns the smallest list of actions that will match only the desiredActions and not match any of the undesiredActions or any actions not specified by desiredActions.
56
+ */
57
+ export declare function shrinkIteration(desiredActions: string[], undesiredActions: string[], deep: boolean): string[];
58
+ /**
59
+ * Reduces a singele action into a smaller number of parts by replace one part at a time with an asterisk
60
+ * and validating that there are no undesired actions that match the new action
61
+ *
62
+ * @param desiredAction the action to reduce
63
+ * @param sequence the sequence to reduce the action by
64
+ * @param undesiredActions the list of actions that should not match the reduced action
65
+ * @returns the reduced action with as many parts replaced with asterisks as possible while still matching the desired actions and not matching any of the undesired actions
66
+ */
67
+ export declare function reduceAction(desiredAction: string, sequence: string, undesiredActions: string[]): string;
68
+ /**
69
+ * Consolidate multile consecutive asterisks into a single asterisk
70
+ *
71
+ * @param wildcardAction the action to collapse
72
+ * @returns the action with consecutive asterisks collapsed into a single asterisk
73
+ */
74
+ export declare function collapseAsterisks(wildcardAction: string): string;
75
+ /**
76
+ * Convert a wildcard action into a regular expression
77
+ *
78
+ * @param wildcardAction the wildcard action to convert
79
+ * @returns a regular expression that will match the wildcard action
80
+ */
81
+ export declare function regexForWildcardAction(wildcardAction: string): RegExp;
82
+ /**
83
+ * Checks to see if a wildcard action matches any of the strings in a list
84
+ *
85
+ * @param wildcardAction the wildcard action to check
86
+ * @param strings the list of strings to check against
87
+ * @returns true if the wildcard action matches any of the strings
88
+ */
89
+ export declare function wildcardActionMatchesAnyString(wildcardAction: string, strings: string[]): boolean;
90
+ /**
91
+ * Split an IAM Action into parts based on capital letters and asterisks
92
+ * For a new part to start there must be a transition from a lowercase letter to an uppercase letter or an asterisk
93
+ * For example :
94
+ * * "CreateAccessPointForObjectLambda" would be split into ["Create", "Access", "Point", "For", "Object", "Lambda"]
95
+ * * "*ObjectTagging*" would be split into ["*", "Object", "Tagging", "*"]
96
+ *
97
+ * @param input the IAM Action to split
98
+ * @returns the parts of the IAM Action
99
+ */
100
+ export declare function splitActionIntoParts(input: string): string[];
101
+ /**
102
+ * Given a list of strings and a list of strings those parts are in, count the number of times each part appears in the strings
103
+ *
104
+ * @param substrings the sub strings to count
105
+ * @param actions the list of strings to count the substrings in
106
+ * @returns Returns a map of the substring to the number of times it appears in the actions
107
+ */
108
+ export declare function countSubstrings(substrings: string[], actions: string[]): Map<string, number>;
109
+ /**
110
+ * Finds all the the common sequences in a list of actions strings and counts their frequency and length.
111
+ *
112
+ * @param actions the list of actions to find common sequences in
113
+ * @returns an array of objects with the sequence, frequency, and length of the common sequences
114
+ */
115
+ export declare function findCommonSequences(actions: string[]): {
116
+ sequence: string;
117
+ frequency: number;
118
+ length: number;
119
+ }[];
120
+ /**
121
+ * Consolidates overlapping wildcards into their most general form
122
+ *
123
+ * For example:
124
+ * ['*Object', 'Object*', '*Object*'] will be consolidated into ['*Object*']
125
+ * ['Get*', '*Get*'] will be consolidated into ['*Get*']
126
+ *
127
+ * @param patterns the list of patterns to consolidate
128
+ * @returns the consolidated list of patterns
129
+ */
130
+ export declare function consolidateWildcardPatterns(patterns: string[]): string[];
131
+ //# sourceMappingURL=shrink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shrink.d.ts","sourceRoot":"","sources":["../../src/shrink.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAA;CACnB;AAQD;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BjH;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE;IAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,EAAE,CAAA;CAAC,CAAC,CAYvH;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAkCpH;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CAmB7G;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,GAAG,MAAM,CAqExG;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAIrE;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAQjG;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAK5D;AAGD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAc5F;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,CAchH;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAkBxE"}