@cloud-copilot/iam-lens 0.1.11 → 0.1.13
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/dist/cjs/canWhat/canWhat.d.ts +10 -0
- package/dist/cjs/canWhat/canWhat.d.ts.map +1 -0
- package/dist/cjs/canWhat/canWhat.js +61 -0
- package/dist/cjs/canWhat/canWhat.js.map +1 -0
- package/dist/cjs/canWhat/permission.d.ts +54 -0
- package/dist/cjs/canWhat/permission.d.ts.map +1 -0
- package/dist/cjs/canWhat/permission.js +749 -0
- package/dist/cjs/canWhat/permission.js.map +1 -0
- package/dist/cjs/canWhat/permissionSet.d.ts +59 -0
- package/dist/cjs/canWhat/permissionSet.d.ts.map +1 -0
- package/dist/cjs/canWhat/permissionSet.js +296 -0
- package/dist/cjs/canWhat/permissionSet.js.map +1 -0
- package/dist/cjs/cli.js +28 -0
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/collect/client.js +1 -1
- package/dist/cjs/collect/client.js.map +1 -1
- package/dist/esm/canWhat/canWhat.d.ts +10 -0
- package/dist/esm/canWhat/canWhat.d.ts.map +1 -0
- package/dist/esm/canWhat/canWhat.js +58 -0
- package/dist/esm/canWhat/canWhat.js.map +1 -0
- package/dist/esm/canWhat/permission.d.ts +54 -0
- package/dist/esm/canWhat/permission.d.ts.map +1 -0
- package/dist/esm/canWhat/permission.js +737 -0
- package/dist/esm/canWhat/permission.js.map +1 -0
- package/dist/esm/canWhat/permissionSet.d.ts +59 -0
- package/dist/esm/canWhat/permissionSet.d.ts.map +1 -0
- package/dist/esm/canWhat/permissionSet.js +288 -0
- package/dist/esm/canWhat/permissionSet.js.map +1 -0
- package/dist/esm/cli.js +28 -0
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/collect/client.js +1 -1
- package/dist/esm/collect/client.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IamCollectClient } from '../collect/client.js';
|
|
2
|
+
export interface CanWhatInput {
|
|
3
|
+
principal: string;
|
|
4
|
+
shrinkActionLists: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function canWhat(collectClient: IamCollectClient, input: CanWhatInput): Promise<{
|
|
7
|
+
Version: string;
|
|
8
|
+
Statement: any[];
|
|
9
|
+
}>;
|
|
10
|
+
//# sourceMappingURL=canWhat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canWhat.d.ts","sourceRoot":"","sources":["../../../src/canWhat/canWhat.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AASvD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,iBAAiB,EAAE,OAAO,CAAA;CAC3B;AAED,wBAAsB,OAAO,CAAC,aAAa,EAAE,gBAAgB,EAAE,KAAK,EAAE,YAAY;;;GAoEjF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.canWhat = canWhat;
|
|
4
|
+
const iam_policy_1 = require("@cloud-copilot/iam-policy");
|
|
5
|
+
const iam_shrink_1 = require("@cloud-copilot/iam-shrink");
|
|
6
|
+
const principals_js_1 = require("../principals.js");
|
|
7
|
+
const permissionSet_js_1 = require("./permissionSet.js");
|
|
8
|
+
async function canWhat(collectClient, input) {
|
|
9
|
+
const { principal } = input;
|
|
10
|
+
if (!principal) {
|
|
11
|
+
throw new Error('Principal must be provided for can-what command');
|
|
12
|
+
}
|
|
13
|
+
const principalPolicies = await (0, principals_js_1.getAllPoliciesForPrincipal)(collectClient, principal);
|
|
14
|
+
const identityPolicies = [
|
|
15
|
+
...principalPolicies.managedPolicies,
|
|
16
|
+
...principalPolicies.inlinePolicies,
|
|
17
|
+
...(principalPolicies.groupPolicies?.map((group) => group.managedPolicies).flat() || []),
|
|
18
|
+
...(principalPolicies.groupPolicies?.map((group) => group.inlinePolicies).flat() || [])
|
|
19
|
+
].map((policy) => (0, iam_policy_1.loadPolicy)(policy.policy));
|
|
20
|
+
const allowedPermissions = await (0, permissionSet_js_1.buildPermissionSetFromPolicies)('Allow', identityPolicies);
|
|
21
|
+
const identityDenyPermissions = await (0, permissionSet_js_1.buildPermissionSetFromPolicies)('Deny', identityPolicies);
|
|
22
|
+
let finalPermissions = allowedPermissions;
|
|
23
|
+
if (principalPolicies.permissionBoundary) {
|
|
24
|
+
const boundaryPolicy = (0, iam_policy_1.loadPolicy)(principalPolicies.permissionBoundary.policy);
|
|
25
|
+
const boundaryPermissions = await (0, permissionSet_js_1.buildPermissionSetFromPolicies)('Allow', [boundaryPolicy]);
|
|
26
|
+
finalPermissions = allowedPermissions.intersection(boundaryPermissions);
|
|
27
|
+
}
|
|
28
|
+
const scpAllowsByLevel = [];
|
|
29
|
+
const rcpAllowsByLevel = [];
|
|
30
|
+
for (const level of principalPolicies.scps) {
|
|
31
|
+
const scpPolicies = level.policies.map((scp) => (0, iam_policy_1.loadPolicy)(scp.policy));
|
|
32
|
+
scpAllowsByLevel.push(await (0, permissionSet_js_1.buildPermissionSetFromPolicies)('Allow', scpPolicies));
|
|
33
|
+
await (0, permissionSet_js_1.addPoliciesToPermissionSet)(identityDenyPermissions, 'Deny', scpPolicies);
|
|
34
|
+
}
|
|
35
|
+
const principalAccountDenyPermissions = identityDenyPermissions.clone();
|
|
36
|
+
for (const level of principalPolicies.rcps) {
|
|
37
|
+
const rcpPolicies = level.policies.map((rcp) => (0, iam_policy_1.loadPolicy)(rcp.policy));
|
|
38
|
+
rcpAllowsByLevel.push(await (0, permissionSet_js_1.buildPermissionSetFromPolicies)('Allow', rcpPolicies));
|
|
39
|
+
await (0, permissionSet_js_1.addPoliciesToPermissionSet)(principalAccountDenyPermissions, 'Deny', rcpPolicies);
|
|
40
|
+
}
|
|
41
|
+
for (const scpAllow of scpAllowsByLevel) {
|
|
42
|
+
finalPermissions = finalPermissions.intersection(scpAllow);
|
|
43
|
+
}
|
|
44
|
+
for (const rcpAllow of rcpAllowsByLevel) {
|
|
45
|
+
finalPermissions = finalPermissions.intersection(rcpAllow);
|
|
46
|
+
}
|
|
47
|
+
const permissionsAfterDeny = finalPermissions.subtract(principalAccountDenyPermissions);
|
|
48
|
+
finalPermissions = permissionsAfterDeny.allow;
|
|
49
|
+
const deniedPermissions = permissionsAfterDeny.deny;
|
|
50
|
+
const allowStatements = (0, permissionSet_js_1.toPolicyStatements)(finalPermissions);
|
|
51
|
+
const denyStatements = (0, permissionSet_js_1.toPolicyStatements)(deniedPermissions);
|
|
52
|
+
const policyDocument = {
|
|
53
|
+
Version: '2012-10-17',
|
|
54
|
+
Statement: [...allowStatements, ...denyStatements]
|
|
55
|
+
};
|
|
56
|
+
if (input.shrinkActionLists) {
|
|
57
|
+
await (0, iam_shrink_1.shrinkJsonDocument)({ iterations: 0 }, policyDocument);
|
|
58
|
+
}
|
|
59
|
+
return policyDocument;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=canWhat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canWhat.js","sourceRoot":"","sources":["../../../src/canWhat/canWhat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type PermissionEffect = 'Allow' | 'Deny';
|
|
2
|
+
export type PermissionConditions = Record<string, Record<string, string[]>>;
|
|
3
|
+
/**
|
|
4
|
+
* An immutable representation of a single permission for a specific action.
|
|
5
|
+
*
|
|
6
|
+
* This will eventually have methods like "merge with another permission",
|
|
7
|
+
* "check if overlaps with another permission", "subtract a deny permission",
|
|
8
|
+
* etc and those will all return a new Permission instance.
|
|
9
|
+
*/
|
|
10
|
+
export declare class Permission {
|
|
11
|
+
readonly effect: PermissionEffect;
|
|
12
|
+
readonly service: string;
|
|
13
|
+
readonly action: string;
|
|
14
|
+
readonly resource: string[] | undefined;
|
|
15
|
+
readonly notResource: string[] | undefined;
|
|
16
|
+
readonly conditions: Record<string, Record<string, string[]>> | undefined;
|
|
17
|
+
constructor(effect: PermissionEffect, service: string, action: string, resource: string[] | undefined, notResource: string[] | undefined, conditions: Record<string, Record<string, string[]>> | undefined);
|
|
18
|
+
/**
|
|
19
|
+
* Returns true if this Permission completely includes the other Permission.
|
|
20
|
+
* Only supports merging of "Allow" permissions (same effect, service, action).
|
|
21
|
+
*/
|
|
22
|
+
includes(other: Permission): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Returns the union of this Permission with another.
|
|
25
|
+
* If one includes the other, return the including Permission.
|
|
26
|
+
* Otherwise, attempt to merge conditions and resource/notResource.
|
|
27
|
+
* If merge yields a single Permission, return it; else return both.
|
|
28
|
+
*/
|
|
29
|
+
union(other: Permission): Permission[];
|
|
30
|
+
/**
|
|
31
|
+
* Returns the intersection of this Permission with another.
|
|
32
|
+
* Always returns exactly one Permission. If there is no overlap,
|
|
33
|
+
* returns undefined.
|
|
34
|
+
*/
|
|
35
|
+
intersection(other: Permission): Permission | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Subtract a Deny permission from this Allow permission.
|
|
38
|
+
* Returns an array of resulting Allow permissions (may be empty if fully denied).
|
|
39
|
+
*/
|
|
40
|
+
subtract(other: Permission): Permission[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns a new PermissionConditions object with all operator and context keys lowercased.
|
|
44
|
+
*/
|
|
45
|
+
export declare function normalizeConditionKeys(conds: PermissionConditions): PermissionConditions;
|
|
46
|
+
/**
|
|
47
|
+
* Invert a set of IAM condition clauses for Deny → allow inversion.
|
|
48
|
+
* Preserves ForAllValues:/ForAnyValue: prefixes and IfExists suffixes.
|
|
49
|
+
*
|
|
50
|
+
* @param conds the condition clauses to invert
|
|
51
|
+
* @return a new set of inverted conditions
|
|
52
|
+
*/
|
|
53
|
+
export declare function invertConditions(conds: Record<string, Record<string, string[]>>): Record<string, Record<string, string[]>>;
|
|
54
|
+
//# sourceMappingURL=permission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../../src/canWhat/permission.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAA;AAE/C,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;AAU3E;;;;;;GAMG;AACH,qBAAa,UAAU;aAEH,MAAM,EAAE,gBAAgB;aACxB,OAAO,EAAE,MAAM;aACf,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS;aAC9B,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS;aACjC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS;gBALhE,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,EAC9B,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,EACjC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS;IASlF;;;OAGG;IACI,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;IAyH3C;;;;;OAKG;IACI,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,EAAE;IAiE7C;;;;OAIG;IACI,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS;IAkL9D;;;OAGG;IACI,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,EAAE;CA6HjD;AAmKD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,oBAAoB,GAAG,oBAAoB,CAWxF;AA+BD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,GAC9C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAqB1C"}
|