@cloud-copilot/iam-lens 0.1.7 → 0.1.8

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 (90) hide show
  1. package/README.md +251 -1
  2. package/dist/cjs/cli.js +53 -5
  3. package/dist/cjs/cli.js.map +1 -1
  4. package/dist/cjs/collect/client.d.ts +37 -2
  5. package/dist/cjs/collect/client.d.ts.map +1 -1
  6. package/dist/cjs/collect/client.js +126 -27
  7. package/dist/cjs/collect/client.js.map +1 -1
  8. package/dist/cjs/principals.d.ts +0 -5
  9. package/dist/cjs/principals.d.ts.map +1 -1
  10. package/dist/cjs/principals.js +0 -9
  11. package/dist/cjs/principals.js.map +1 -1
  12. package/dist/cjs/resources.js +1 -1
  13. package/dist/cjs/resources.js.map +1 -1
  14. package/dist/cjs/{contextKeys.d.ts → simulate/contextKeys.d.ts} +1 -1
  15. package/dist/cjs/simulate/contextKeys.d.ts.map +1 -0
  16. package/dist/cjs/{contextKeys.js → simulate/contextKeys.js} +1 -1
  17. package/dist/cjs/simulate/contextKeys.js.map +1 -0
  18. package/dist/cjs/{simulate.d.ts → simulate/simulate.d.ts} +4 -2
  19. package/dist/cjs/simulate/simulate.d.ts.map +1 -0
  20. package/dist/cjs/{simulate.js → simulate/simulate.js} +38 -20
  21. package/dist/cjs/simulate/simulate.js.map +1 -0
  22. package/dist/cjs/test-datasets/testClient.d.ts +9 -0
  23. package/dist/cjs/test-datasets/testClient.d.ts.map +1 -0
  24. package/dist/cjs/test-datasets/testClient.js +28 -0
  25. package/dist/cjs/test-datasets/testClient.js.map +1 -0
  26. package/dist/cjs/utils/arn.d.ts +22 -0
  27. package/dist/cjs/utils/arn.d.ts.map +1 -0
  28. package/dist/cjs/utils/arn.js +49 -0
  29. package/dist/cjs/utils/arn.js.map +1 -0
  30. package/dist/cjs/utils/sts.d.ts +2 -0
  31. package/dist/cjs/utils/sts.d.ts.map +1 -0
  32. package/dist/cjs/utils/sts.js +9 -0
  33. package/dist/cjs/utils/sts.js.map +1 -0
  34. package/dist/cjs/whoCan/whoCan.d.ts +54 -0
  35. package/dist/cjs/whoCan/whoCan.d.ts.map +1 -0
  36. package/dist/cjs/whoCan/whoCan.js +320 -0
  37. package/dist/cjs/whoCan/whoCan.js.map +1 -0
  38. package/dist/esm/cli.js +53 -5
  39. package/dist/esm/cli.js.map +1 -1
  40. package/dist/esm/collect/client.d.ts +37 -2
  41. package/dist/esm/collect/client.d.ts.map +1 -1
  42. package/dist/esm/collect/client.js +125 -27
  43. package/dist/esm/collect/client.js.map +1 -1
  44. package/dist/esm/principals.d.ts +0 -5
  45. package/dist/esm/principals.d.ts.map +1 -1
  46. package/dist/esm/principals.js +0 -8
  47. package/dist/esm/principals.js.map +1 -1
  48. package/dist/esm/resources.js +1 -1
  49. package/dist/esm/resources.js.map +1 -1
  50. package/dist/esm/{contextKeys.d.ts → simulate/contextKeys.d.ts} +1 -1
  51. package/dist/esm/simulate/contextKeys.d.ts.map +1 -0
  52. package/dist/esm/{contextKeys.js → simulate/contextKeys.js} +1 -1
  53. package/dist/esm/simulate/contextKeys.js.map +1 -0
  54. package/dist/esm/{simulate.d.ts → simulate/simulate.d.ts} +4 -2
  55. package/dist/esm/simulate/simulate.d.ts.map +1 -0
  56. package/dist/esm/{simulate.js → simulate/simulate.js} +37 -20
  57. package/dist/esm/simulate/simulate.js.map +1 -0
  58. package/dist/esm/test-datasets/testClient.d.ts +9 -0
  59. package/dist/esm/test-datasets/testClient.d.ts.map +1 -0
  60. package/dist/esm/test-datasets/testClient.js +25 -0
  61. package/dist/esm/test-datasets/testClient.js.map +1 -0
  62. package/dist/esm/utils/arn.d.ts +22 -0
  63. package/dist/esm/utils/arn.d.ts.map +1 -0
  64. package/dist/esm/utils/arn.js +43 -0
  65. package/dist/esm/utils/arn.js.map +1 -0
  66. package/dist/esm/utils/sts.d.ts +2 -0
  67. package/dist/esm/utils/sts.d.ts.map +1 -0
  68. package/dist/esm/utils/sts.js +6 -0
  69. package/dist/esm/utils/sts.js.map +1 -0
  70. package/dist/esm/whoCan/whoCan.d.ts +54 -0
  71. package/dist/esm/whoCan/whoCan.d.ts.map +1 -0
  72. package/dist/esm/whoCan/whoCan.js +311 -0
  73. package/dist/esm/whoCan/whoCan.js.map +1 -0
  74. package/package.json +1 -1
  75. package/dist/cjs/accounts.d.ts +0 -3
  76. package/dist/cjs/accounts.d.ts.map +0 -1
  77. package/dist/cjs/accounts.js +0 -8
  78. package/dist/cjs/accounts.js.map +0 -1
  79. package/dist/cjs/contextKeys.d.ts.map +0 -1
  80. package/dist/cjs/contextKeys.js.map +0 -1
  81. package/dist/cjs/simulate.d.ts.map +0 -1
  82. package/dist/cjs/simulate.js.map +0 -1
  83. package/dist/esm/accounts.d.ts +0 -3
  84. package/dist/esm/accounts.d.ts.map +0 -1
  85. package/dist/esm/accounts.js +0 -5
  86. package/dist/esm/accounts.js.map +0 -1
  87. package/dist/esm/contextKeys.d.ts.map +0 -1
  88. package/dist/esm/contextKeys.js.map +0 -1
  89. package/dist/esm/simulate.d.ts.map +0 -1
  90. package/dist/esm/simulate.js.map +0 -1
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Arn = void 0;
4
+ const iam_utils_1 = require("@cloud-copilot/iam-utils");
5
+ class Arn {
6
+ arn;
7
+ parts;
8
+ constructor(arn) {
9
+ this.arn = arn;
10
+ this.parts = (0, iam_utils_1.splitArnParts)(arn);
11
+ }
12
+ get service() {
13
+ return this.parts.service;
14
+ }
15
+ get partition() {
16
+ return this.parts.partition;
17
+ }
18
+ get region() {
19
+ return this.parts.region;
20
+ }
21
+ get accountId() {
22
+ return this.parts.accountId;
23
+ }
24
+ get resourceType() {
25
+ return this.parts.resourceType;
26
+ }
27
+ get resourcePath() {
28
+ return this.parts.resourcePath;
29
+ }
30
+ get resource() {
31
+ return this.parts.resource || '';
32
+ }
33
+ get value() {
34
+ return this.arn;
35
+ }
36
+ /**
37
+ * Check
38
+ *
39
+ * @param parts
40
+ * @returns
41
+ */
42
+ matches(parts) {
43
+ return Object.entries(parts).every(([key, value]) => {
44
+ return this.parts[key] === value;
45
+ });
46
+ }
47
+ }
48
+ exports.Arn = Arn;
49
+ //# sourceMappingURL=arn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arn.js","sourceRoot":"","sources":["../../../src/utils/arn.ts"],"names":[],"mappings":";;;AAAA,wDAAkE;AAElE,MAAa,GAAG;IAGe;IAFZ,KAAK,CAAU;IAEhC,YAA6B,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;QACtC,IAAI,CAAC,KAAK,GAAG,IAAA,yBAAa,EAAC,GAAG,CAAC,CAAA;IACjC,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,OAAQ,CAAA;IAC5B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,SAAU,CAAA;IAC9B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAA;IAC1B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAA;IAC7B,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAA;IAChC,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAA;IAChC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAA;IAClC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,GAAG,CAAA;IACjB,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,KAAwB;QAC9B,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAqB,CAAC,KAAK,KAAK,CAAA;QACpD,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAlDD,kBAkDC"}
@@ -0,0 +1,2 @@
1
+ export declare const AssumeRoleActions: Set<string>;
2
+ //# sourceMappingURL=sts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sts.d.ts","sourceRoot":"","sources":["../../../src/utils/sts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,aAI5B,CAAA"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssumeRoleActions = void 0;
4
+ exports.AssumeRoleActions = new Set([
5
+ 'sts:assumerole',
6
+ 'sts:assumerolewithwebidentity',
7
+ 'sts:assumerolewithsaml'
8
+ ]);
9
+ //# sourceMappingURL=sts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sts.js","sourceRoot":"","sources":["../../../src/utils/sts.ts"],"names":[],"mappings":";;;AAAa,QAAA,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACvC,gBAAgB;IAChB,+BAA+B;IAC/B,wBAAwB;CACzB,CAAC,CAAA"}
@@ -0,0 +1,54 @@
1
+ import { ResourceType } from '@cloud-copilot/iam-data';
2
+ import { IamCollectClient } from '../collect/client.js';
3
+ export interface ResourceAccessRequest {
4
+ resource?: string;
5
+ resourceAccount?: string;
6
+ actions: string[];
7
+ }
8
+ export interface WhoCanAllowed {
9
+ principal: string;
10
+ service: string;
11
+ action: string;
12
+ }
13
+ export interface WhoCanResponse {
14
+ allowed: WhoCanAllowed[];
15
+ allAccountsChecked: boolean;
16
+ accountsNotFound: string[];
17
+ organizationsNotFound: string[];
18
+ organizationalUnitsNotFound: string[];
19
+ principalsNotFound: string[];
20
+ }
21
+ export declare function whoCan(collectClient: IamCollectClient, request: ResourceAccessRequest): Promise<WhoCanResponse>;
22
+ export declare function uniqueAccountsToCheck(collectClient: IamCollectClient, accountsToCheck: AccountsToCheck): Promise<{
23
+ accountsNotFound: string[];
24
+ organizationsNotFound: string[];
25
+ organizationalUnitsNotFound: string[];
26
+ accounts: string[];
27
+ }>;
28
+ export interface AccountsToCheck {
29
+ allAccounts: boolean;
30
+ specificAccounts: string[];
31
+ specificPrincipals: string[];
32
+ specificOrganizations: string[];
33
+ specificOrganizationalUnits: string[];
34
+ }
35
+ export declare function accountsToCheckBasedOnResourcePolicy(resourcePolicy: any, resourceAccount: string | undefined): Promise<AccountsToCheck>;
36
+ export declare function actionsForWhoCan(request: ResourceAccessRequest): Promise<string[]>;
37
+ /**
38
+ * Get the the possible resource types for an action and resource
39
+ *
40
+ * @param service the service the action belongs to
41
+ * @param action the action to get the resource type for
42
+ * @param resourceArn the resource type matching the action, if any
43
+ * @throws an error if the service or action does not exist, or if the action is a wildcard only action
44
+ */
45
+ export declare function lookupActionsForResourceArn(resourceArn: string): Promise<string[]>;
46
+ export declare function findResourceTypeForArn(resourceArn: string): Promise<[string, ResourceType]>;
47
+ /**
48
+ * Convert a resource pattern from iam-data to a regex pattern
49
+ *
50
+ * @param pattern the pattern to convert to a regex
51
+ * @returns the regex pattern
52
+ */
53
+ export declare function convertResourcePatternToRegex(pattern: string): string;
54
+ //# sourceMappingURL=whoCan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoCan.d.ts","sourceRoot":"","sources":["../../../src/whoCan/whoCan.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,YAAY,EACb,MAAM,yBAAyB,CAAA;AAShC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAMvD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,kBAAkB,EAAE,OAAO,CAAA;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,qBAAqB,EAAE,MAAM,EAAE,CAAA;IAC/B,2BAA2B,EAAE,MAAM,EAAE,CAAA;IACrC,kBAAkB,EAAE,MAAM,EAAE,CAAA;CAC7B;AAED,wBAAsB,MAAM,CAC1B,aAAa,EAAE,gBAAgB,EAC/B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,cAAc,CAAC,CAmGzB;AAkCD,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,gBAAgB,EAC/B,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC;IACT,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,qBAAqB,EAAE,MAAM,EAAE,CAAA;IAC/B,2BAA2B,EAAE,MAAM,EAAE,CAAA;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB,CAAC,CAiDD;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,OAAO,CAAA;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,kBAAkB,EAAE,MAAM,EAAE,CAAA;IAC5B,qBAAqB,EAAE,MAAM,EAAE,CAAA;IAC/B,2BAA2B,EAAE,MAAM,EAAE,CAAA;CACtC;AAED,wBAAsB,oCAAoC,CACxD,cAAc,EAAE,GAAG,EACnB,eAAe,EAAE,MAAM,GAAG,SAAS,GAClC,OAAO,CAAC,eAAe,CAAC,CA2E1B;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BxF;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsBxF;AAED,wBAAsB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAqBjG;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOrE"}
@@ -0,0 +1,320 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.whoCan = whoCan;
4
+ exports.uniqueAccountsToCheck = uniqueAccountsToCheck;
5
+ exports.accountsToCheckBasedOnResourcePolicy = accountsToCheckBasedOnResourcePolicy;
6
+ exports.actionsForWhoCan = actionsForWhoCan;
7
+ exports.lookupActionsForResourceArn = lookupActionsForResourceArn;
8
+ exports.findResourceTypeForArn = findResourceTypeForArn;
9
+ exports.convertResourcePatternToRegex = convertResourcePatternToRegex;
10
+ const iam_data_1 = require("@cloud-copilot/iam-data");
11
+ const iam_policy_1 = require("@cloud-copilot/iam-policy");
12
+ const iam_utils_1 = require("@cloud-copilot/iam-utils");
13
+ const resources_js_1 = require("../resources.js");
14
+ const simulate_js_1 = require("../simulate/simulate.js");
15
+ const arn_js_1 = require("../utils/arn.js");
16
+ const sts_js_1 = require("../utils/sts.js");
17
+ async function whoCan(collectClient, request) {
18
+ const { resource } = request;
19
+ if (!request.resourceAccount && !request.resource) {
20
+ throw new Error('Either resourceAccount or resource must be provided in the request.');
21
+ }
22
+ if (resource && !resource.startsWith('arn:')) {
23
+ throw new Error(`Invalid resource ARN: ${resource}. It must start with 'arn:'.`);
24
+ }
25
+ const resourceAccount = request.resourceAccount || (await (0, resources_js_1.getAccountIdForResource)(collectClient, resource));
26
+ if (!resourceAccount) {
27
+ throw new Error(`Could not determine account ID for resource ${resource}`);
28
+ }
29
+ const actions = await actionsForWhoCan(request);
30
+ if (!actions || actions.length === 0) {
31
+ throw new Error('No valid actions provided or found for the resource.');
32
+ }
33
+ let resourcePolicy = undefined;
34
+ if (resource) {
35
+ resourcePolicy = await (0, resources_js_1.getResourcePolicyForResource)(collectClient, resource);
36
+ const resourceArn = new arn_js_1.Arn(resource);
37
+ if ((resourceArn.matches({ service: 'iam', resourceType: 'role' }) ||
38
+ resourceArn.matches({ service: 'kms', resourceType: 'key' })) &&
39
+ !resourcePolicy) {
40
+ throw new Error(`Unable to find resource policy for ${resource}. Cannot determine who can access the resource.`);
41
+ }
42
+ }
43
+ const accountsToCheck = await accountsToCheckBasedOnResourcePolicy(resourcePolicy, resourceAccount);
44
+ const uniqueAccounts = await uniqueAccountsToCheck(collectClient, accountsToCheck);
45
+ const whoCanResults = [];
46
+ for (const account of uniqueAccounts.accounts) {
47
+ const principals = await collectClient.getAllPrincipalsInAccount(account);
48
+ for (const principal of principals) {
49
+ const principalResults = await runPrincipalForActions(collectClient, principal, resource, resourceAccount, actions);
50
+ whoCanResults.push(...principalResults);
51
+ }
52
+ }
53
+ const principalsNotFound = [];
54
+ for (const principal of accountsToCheck.specificPrincipals) {
55
+ if ((0, iam_utils_1.isServicePrincipal)(principal)) {
56
+ const principalResults = await runPrincipalForActions(collectClient, principal, resource, resourceAccount, actions);
57
+ whoCanResults.push(...principalResults);
58
+ }
59
+ else if ((0, iam_utils_1.isIamUserArn)(principal) || (0, iam_utils_1.isIamRoleArn)(principal) || (0, iam_utils_1.isAssumedRoleArn)(principal)) {
60
+ const principalExists = await collectClient.principalExists(principal);
61
+ if (!principalExists) {
62
+ principalsNotFound.push(principal);
63
+ }
64
+ else {
65
+ const principalResults = await runPrincipalForActions(collectClient, principal, resource, resourceAccount, actions);
66
+ whoCanResults.push(...principalResults);
67
+ }
68
+ }
69
+ else {
70
+ principalsNotFound.push(principal);
71
+ }
72
+ }
73
+ return {
74
+ allowed: whoCanResults,
75
+ allAccountsChecked: accountsToCheck.allAccounts,
76
+ accountsNotFound: uniqueAccounts.accountsNotFound,
77
+ organizationsNotFound: uniqueAccounts.organizationsNotFound,
78
+ organizationalUnitsNotFound: uniqueAccounts.organizationalUnitsNotFound,
79
+ principalsNotFound: principalsNotFound
80
+ };
81
+ }
82
+ async function runPrincipalForActions(collectClient, principal, resource, resourceAccount, actions) {
83
+ const results = [];
84
+ for (const action of actions) {
85
+ const result = await (0, simulate_js_1.simulateRequest)({
86
+ principal: principal,
87
+ resourceArn: resource,
88
+ resourceAccount,
89
+ action,
90
+ customContextKeys: {}
91
+ }, collectClient);
92
+ if (result.analysis?.result === 'Allowed') {
93
+ const [service, serviceAction] = action.split(':');
94
+ results.push({
95
+ principal,
96
+ service: service,
97
+ action: serviceAction
98
+ });
99
+ }
100
+ }
101
+ return results;
102
+ }
103
+ async function uniqueAccountsToCheck(collectClient, accountsToCheck) {
104
+ const returnValue = {
105
+ accountsNotFound: [],
106
+ organizationsNotFound: [],
107
+ organizationalUnitsNotFound: [],
108
+ accounts: []
109
+ };
110
+ if (accountsToCheck.allAccounts) {
111
+ returnValue.accounts = await collectClient.allAccounts();
112
+ return returnValue;
113
+ }
114
+ const uniqueAccounts = new Set();
115
+ for (const account of accountsToCheck.specificAccounts || []) {
116
+ const accountExists = await collectClient.accountExists(account);
117
+ if (accountExists) {
118
+ uniqueAccounts.add(account);
119
+ }
120
+ else {
121
+ returnValue.accountsNotFound.push(account);
122
+ }
123
+ }
124
+ for (const ouPath of accountsToCheck.specificOrganizationalUnits || []) {
125
+ const parts = ouPath.split('/');
126
+ const orgId = parts[0];
127
+ const pathParts = parts.slice(1);
128
+ const [found, accounts] = await collectClient.getAccountsForOrgPath(orgId, pathParts);
129
+ for (const account of accounts) {
130
+ uniqueAccounts.add(account);
131
+ }
132
+ if (!found) {
133
+ returnValue.organizationalUnitsNotFound.push(ouPath);
134
+ }
135
+ }
136
+ for (const orgId of accountsToCheck.specificOrganizations || []) {
137
+ const [found, accounts] = await collectClient.getAccountsForOrganization(orgId);
138
+ for (const account of accounts) {
139
+ uniqueAccounts.add(account);
140
+ }
141
+ if (!found) {
142
+ returnValue.organizationsNotFound.push(orgId);
143
+ }
144
+ }
145
+ returnValue.accounts = Array.from(uniqueAccounts);
146
+ return returnValue;
147
+ }
148
+ async function accountsToCheckBasedOnResourcePolicy(resourcePolicy, resourceAccount) {
149
+ const accountsToCheck = {
150
+ allAccounts: false,
151
+ specificAccounts: [],
152
+ specificPrincipals: [],
153
+ specificOrganizations: [],
154
+ specificOrganizationalUnits: []
155
+ };
156
+ if (resourceAccount) {
157
+ accountsToCheck.specificAccounts.push(resourceAccount);
158
+ }
159
+ if (!resourcePolicy) {
160
+ return accountsToCheck;
161
+ }
162
+ const policy = (0, iam_policy_1.loadPolicy)(resourcePolicy);
163
+ for (const statement of policy.statements()) {
164
+ if (statement.isAllow() && statement.isNotPrincipalStatement()) {
165
+ accountsToCheck.allAccounts = true;
166
+ }
167
+ if (statement.isAllow() && statement.isPrincipalStatement()) {
168
+ const principals = statement.principals();
169
+ let hasWildcardPrincipal = false;
170
+ for (const principal of principals) {
171
+ if (principal.isWildcardPrincipal()) {
172
+ hasWildcardPrincipal = true;
173
+ }
174
+ else if (principal.isAccountPrincipal()) {
175
+ accountsToCheck.specificAccounts.push(principal.accountId());
176
+ }
177
+ else {
178
+ accountsToCheck.specificPrincipals.push(principal.value());
179
+ }
180
+ }
181
+ if (hasWildcardPrincipal) {
182
+ const specificOrgs = [];
183
+ const specificOus = [];
184
+ const specificAccounts = [];
185
+ const conditions = statement.conditions();
186
+ for (const cond of conditions) {
187
+ if (cond.conditionKey().toLowerCase() === 'aws:principalorgid' &&
188
+ cond.operation().value().toLowerCase().startsWith('stringequals') &&
189
+ !cond.conditionValues().some((v) => v.includes('$')) // Ignore dynamic values for now
190
+ ) {
191
+ specificOrgs.push(...cond.conditionValues());
192
+ }
193
+ if (cond.conditionKey().toLowerCase() === 'aws:principalorgpaths' &&
194
+ cond.operation().baseOperator().toLowerCase().startsWith('stringequals') &&
195
+ !cond.conditionValues().some((v) => v.includes('$')) // Ignore dynamic values for now
196
+ ) {
197
+ specificOus.push(...cond.conditionValues());
198
+ }
199
+ if (cond.conditionKey().toLowerCase() === 'aws:principalaccount' &&
200
+ cond.operation().value().toLowerCase().startsWith('stringequals') &&
201
+ !cond.conditionValues().some((v) => v.includes('$')) // Ignore dynamic values for now
202
+ ) {
203
+ specificAccounts.push(...cond.conditionValues());
204
+ }
205
+ }
206
+ if (specificAccounts.length > 0) {
207
+ accountsToCheck.specificAccounts.push(...specificAccounts);
208
+ }
209
+ else if (specificOus.length > 0) {
210
+ accountsToCheck.specificOrganizationalUnits.push(...specificOus);
211
+ }
212
+ else if (specificOrgs.length > 0) {
213
+ accountsToCheck.specificOrganizations.push(...specificOrgs);
214
+ }
215
+ else {
216
+ accountsToCheck.allAccounts = true;
217
+ }
218
+ }
219
+ }
220
+ }
221
+ return accountsToCheck;
222
+ }
223
+ async function actionsForWhoCan(request) {
224
+ const { actions } = request;
225
+ if (actions && actions.length > 0) {
226
+ const validActions = [];
227
+ for (const action of actions) {
228
+ const parts = action.split(':');
229
+ if (parts.length !== 2) {
230
+ continue;
231
+ }
232
+ const [service, actionName] = parts;
233
+ const serviceExists = await (0, iam_data_1.iamServiceExists)(service);
234
+ if (!serviceExists) {
235
+ continue;
236
+ }
237
+ const actionExists = await (0, iam_data_1.iamActionExists)(service, actionName);
238
+ if (!actionExists) {
239
+ continue;
240
+ }
241
+ validActions.push(action);
242
+ }
243
+ return validActions;
244
+ }
245
+ if (!request.resource) {
246
+ return [];
247
+ }
248
+ return lookupActionsForResourceArn(request.resource);
249
+ }
250
+ /**
251
+ * Get the the possible resource types for an action and resource
252
+ *
253
+ * @param service the service the action belongs to
254
+ * @param action the action to get the resource type for
255
+ * @param resourceArn the resource type matching the action, if any
256
+ * @throws an error if the service or action does not exist, or if the action is a wildcard only action
257
+ */
258
+ async function lookupActionsForResourceArn(resourceArn) {
259
+ const [service, resourceType] = await findResourceTypeForArn(resourceArn);
260
+ const resourceTypeKey = resourceType.key;
261
+ const selectedActions = [];
262
+ const serviceActions = await (0, iam_data_1.iamActionsForService)(service);
263
+ for (const action of serviceActions) {
264
+ const actionDetails = await (0, iam_data_1.iamActionDetails)(service, action);
265
+ for (const rt of actionDetails.resourceTypes) {
266
+ if (rt.name == resourceTypeKey) {
267
+ selectedActions.push(`${service}:${action}`);
268
+ break; // No need to check other resource types for this action
269
+ }
270
+ }
271
+ }
272
+ const isRole = new arn_js_1.Arn(resourceArn).matches({ service: 'iam', resourceType: 'role' });
273
+ if (isRole) {
274
+ selectedActions.push(...sts_js_1.AssumeRoleActions.values());
275
+ }
276
+ return selectedActions;
277
+ }
278
+ async function findResourceTypeForArn(resourceArn) {
279
+ const arnParts = (0, iam_utils_1.splitArnParts)(resourceArn);
280
+ const service = arnParts.service.toLowerCase();
281
+ const serviceExists = await (0, iam_data_1.iamServiceExists)(service);
282
+ if (!serviceExists) {
283
+ throw new Error(`Unable to find service ${service} for resource ${resourceArn}`);
284
+ }
285
+ const sortedResourceTypes = await allResourceTypesByArnLength(service);
286
+ for (const rt of sortedResourceTypes) {
287
+ const pattern = convertResourcePatternToRegex(rt.arn);
288
+ const match = resourceArn.match(new RegExp(pattern));
289
+ if (match) {
290
+ return [service, rt];
291
+ }
292
+ }
293
+ throw new Error(`Unable to find resource type for service ${service} and resource ${resourceArn}.`);
294
+ }
295
+ /**
296
+ * Convert a resource pattern from iam-data to a regex pattern
297
+ *
298
+ * @param pattern the pattern to convert to a regex
299
+ * @returns the regex pattern
300
+ */
301
+ function convertResourcePatternToRegex(pattern) {
302
+ const regex = pattern.replace(/\$\{.*?\}/g, (match, position) => {
303
+ const name = match.substring(2, match.length - 1);
304
+ const camelName = name.at(0)?.toLowerCase() + name.substring(1);
305
+ return `(?<${camelName}>(.+?))`;
306
+ });
307
+ return `^${regex}$`;
308
+ }
309
+ async function allResourceTypesByArnLength(service) {
310
+ const resourceTypeKeys = await (0, iam_data_1.iamResourceTypesForService)(service);
311
+ const sortedResourceTypes = [];
312
+ for (const key of resourceTypeKeys) {
313
+ const details = await (0, iam_data_1.iamResourceTypeDetails)(service, key);
314
+ sortedResourceTypes.push(details);
315
+ }
316
+ return sortedResourceTypes.sort((a, b) => {
317
+ return b.arn.length - a.arn.length;
318
+ });
319
+ }
320
+ //# sourceMappingURL=whoCan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoCan.js","sourceRoot":"","sources":["../../../src/whoCan/whoCan.ts"],"names":[],"mappings":"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"}
package/dist/esm/cli.js CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { parseCliArguments } from '@cloud-copilot/cli';
3
3
  import { getCollectClient, loadCollectConfigs } from './collect/collect.js';
4
- import { simulateRequest } from './simulate.js';
4
+ import { resultMatchesExpectation, simulateRequest } from './simulate/simulate.js';
5
5
  import { iamLensVersion } from './utils/packageVersion.js';
6
+ import { whoCan } from './whoCan/whoCan.js';
6
7
  const main = async () => {
7
8
  const version = await iamLensVersion();
8
9
  const cli = parseCliArguments('iam-lens', {
@@ -22,12 +23,12 @@ const main = async () => {
22
23
  resourceAccountId: {
23
24
  type: 'string',
24
25
  values: 'single',
25
- description: 'The account ID of the resource, only required if it cannot be determined from the resource ARN. Ignore for wildcard actions'
26
+ description: 'The account ID of the resource, only required if it cannot be determined from the resource ARN.'
26
27
  },
27
28
  action: {
28
29
  type: 'string',
29
30
  values: 'single',
30
- description: 'The action to simulate; must be a valid IAM service and action such as `s3:GetObject`'
31
+ description: 'The action to simulate; must be a valid IAM service and action such as `s3:ListBucket`'
31
32
  },
32
33
  context: {
33
34
  type: 'string',
@@ -38,6 +39,32 @@ const main = async () => {
38
39
  type: 'boolean',
39
40
  description: 'Enable verbose output for the simulation',
40
41
  character: 'v'
42
+ },
43
+ expect: {
44
+ type: 'enum',
45
+ values: 'single',
46
+ validValues: ['Allowed', 'ImplicitlyDenied', 'ExplicitlyDenied', 'AnyDeny'],
47
+ description: 'The expected result of the simulation, if the result does not match the expected response a non-zero exit code will be returned'
48
+ }
49
+ }
50
+ },
51
+ 'who-can': {
52
+ description: 'Find who can perform an action on a resource',
53
+ options: {
54
+ resource: {
55
+ type: 'string',
56
+ values: 'single',
57
+ description: 'The ARN of the resource to check permissions for. Ignore for wildcard actions'
58
+ },
59
+ resourceAccount: {
60
+ type: 'string',
61
+ values: 'single',
62
+ description: 'The account ID of the resource, only required if it cannot be determined from the resource ARN. Required for wildcard actions'
63
+ },
64
+ actions: {
65
+ type: 'string',
66
+ values: 'multiple',
67
+ description: 'The action to check permissions for; must be a valid IAM service and action such as `s3:GetObject`'
41
68
  }
42
69
  }
43
70
  }
@@ -62,9 +89,9 @@ const main = async () => {
62
89
  cli.args.collectConfigs.push('./iam-collect.jsonc');
63
90
  }
64
91
  const thePartition = cli.args.partition || 'aws';
92
+ const collectConfigs = await loadCollectConfigs(cli.args.collectConfigs);
93
+ const collectClient = getCollectClient(collectConfigs, thePartition);
65
94
  if (cli.subcommand === 'simulate') {
66
- const collectConfigs = await loadCollectConfigs(cli.args.collectConfigs);
67
- const collectClient = getCollectClient(collectConfigs, thePartition);
68
95
  const { principal, resource, resourceAccountId, action, context } = cli.args;
69
96
  const contextKeys = convertContextKeysToMap(context);
70
97
  const result = await simulateRequest({
@@ -74,10 +101,31 @@ const main = async () => {
74
101
  action: action,
75
102
  customContextKeys: contextKeys
76
103
  }, collectClient);
104
+ if (result.errors) {
105
+ console.error('Simulation Errors:');
106
+ console.log(JSON.stringify(result.errors, null, 2));
107
+ process.exit(1);
108
+ }
77
109
  console.log(`Simulation Result: ${result.analysis?.result}`);
78
110
  if (cli.args.verbose) {
79
111
  console.log(JSON.stringify(result, null, 2));
80
112
  }
113
+ if (!resultMatchesExpectation(cli.args.expect, result.analysis?.result)) {
114
+ process.exit(1);
115
+ }
116
+ }
117
+ else if (cli.subcommand === 'who-can') {
118
+ const { resource, resourceAccount, actions } = cli.args;
119
+ if (!resourceAccount && !resource && actions.length === 0) {
120
+ console.error('Error: At least 1) resource or 2) resource-account and actions must be provided for who-can command');
121
+ process.exit(1);
122
+ }
123
+ const results = await whoCan(collectClient, {
124
+ resource: cli.args.resource,
125
+ actions: cli.args.actions,
126
+ resourceAccount: cli.args.resourceAccount
127
+ });
128
+ console.log(JSON.stringify(results, null, 2));
81
129
  }
82
130
  };
83
131
  main()
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE3E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAE1D,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;IACtB,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAA;IACtC,MAAM,GAAG,GAAG,iBAAiB,CAC3B,UAAU,EACV;QACE,QAAQ,EAAE;YACR,WAAW,EAAE,yBAAyB;YACtC,OAAO,EAAE;gBACP,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,QAAQ;oBAChB,WAAW,EAAE,yEAAyE;iBACvF;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,QAAQ;oBAChB,WAAW,EACT,4EAA4E;iBAC/E;gBACD,iBAAiB,EAAE;oBACjB,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,QAAQ;oBAChB,WAAW,EACT,6HAA6H;iBAChI;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,QAAQ;oBAChB,WAAW,EACT,uFAAuF;iBAC1F;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,UAAU;oBAClB,WAAW,EACT,oJAAoJ;iBACvJ;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,0CAA0C;oBACvD,SAAS,EAAE,GAAG;iBACf;aACF;SACF;KACF,EACD;QACE,cAAc,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,4CAA4C;YACzD,MAAM,EAAE,UAAU;SACnB;QACD,SAAS,EAAE;YACT,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,sEAAsE;YACnF,MAAM,EAAE,QAAQ;SACjB;KACF,EACD;QACE,SAAS,EAAE,UAAU;QACrB,gBAAgB,EAAE,IAAI;QACtB,iBAAiB,EAAE,IAAI;QACvB,OAAO;KACR,CACF,CAAA;IAED,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;IACrD,CAAC;IACD,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAA;IAEhD,IAAI,GAAG,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QAClC,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACxE,MAAM,aAAa,GAAG,gBAAgB,CAAC,cAAc,EAAE,YAAY,CAAC,CAAA;QAEpE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;QAC5E,MAAM,WAAW,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAA;QAEpD,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC;YACE,SAAS,EAAE,SAAU;YACrB,WAAW,EAAE,QAAS;YACtB,eAAe,EAAE,iBAAiB;YAClC,MAAM,EAAE,MAAO;YACf,iBAAiB,EAAE,WAAW;SAC/B,EACD,aAAa,CACd,CAAA;QAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;QAC5D,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED,IAAI,EAAE;KACH,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC;KACD,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;KACd,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;AAEpB;;;;;GAKG;AACH,SAAS,uBAAuB,CAAC,WAAqB;IACpD,MAAM,UAAU,GAAsC,EAAE,CAAA;IACxD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC/B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,CAAA;YAC9B,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}