UNPKG

@cloud-copilot/iam-lens

Version:

Visibility in IAM in and across AWS accounts

58 lines 3.17 kB
import { loadPolicy } from '@cloud-copilot/iam-policy'; import { shrinkJsonDocument } from '@cloud-copilot/iam-shrink'; import { getAllPoliciesForPrincipal } from '../principals.js'; import { addPoliciesToPermissionSet, buildPermissionSetFromPolicies, toPolicyStatements } from './permissionSet.js'; export async function canWhat(collectClient, input) { const { principal } = input; if (!principal) { throw new Error('Principal must be provided for can-what command'); } const principalPolicies = await getAllPoliciesForPrincipal(collectClient, principal); const identityPolicies = [ ...principalPolicies.managedPolicies, ...principalPolicies.inlinePolicies, ...(principalPolicies.groupPolicies?.map((group) => group.managedPolicies).flat() || []), ...(principalPolicies.groupPolicies?.map((group) => group.inlinePolicies).flat() || []) ].map((policy) => loadPolicy(policy.policy)); const allowedPermissions = await buildPermissionSetFromPolicies('Allow', identityPolicies); const identityDenyPermissions = await buildPermissionSetFromPolicies('Deny', identityPolicies); let finalPermissions = allowedPermissions; if (principalPolicies.permissionBoundary) { const boundaryPolicy = loadPolicy(principalPolicies.permissionBoundary.policy); const boundaryPermissions = await buildPermissionSetFromPolicies('Allow', [boundaryPolicy]); finalPermissions = allowedPermissions.intersection(boundaryPermissions); } const scpAllowsByLevel = []; const rcpAllowsByLevel = []; for (const level of principalPolicies.scps) { const scpPolicies = level.policies.map((scp) => loadPolicy(scp.policy)); scpAllowsByLevel.push(await buildPermissionSetFromPolicies('Allow', scpPolicies)); await addPoliciesToPermissionSet(identityDenyPermissions, 'Deny', scpPolicies); } const principalAccountDenyPermissions = identityDenyPermissions.clone(); for (const level of principalPolicies.rcps) { const rcpPolicies = level.policies.map((rcp) => loadPolicy(rcp.policy)); rcpAllowsByLevel.push(await buildPermissionSetFromPolicies('Allow', rcpPolicies)); await addPoliciesToPermissionSet(principalAccountDenyPermissions, 'Deny', rcpPolicies); } for (const scpAllow of scpAllowsByLevel) { finalPermissions = finalPermissions.intersection(scpAllow); } for (const rcpAllow of rcpAllowsByLevel) { finalPermissions = finalPermissions.intersection(rcpAllow); } const permissionsAfterDeny = finalPermissions.subtract(principalAccountDenyPermissions); finalPermissions = permissionsAfterDeny.allow; const deniedPermissions = permissionsAfterDeny.deny; const allowStatements = toPolicyStatements(finalPermissions); const denyStatements = toPolicyStatements(deniedPermissions); const policyDocument = { Version: '2012-10-17', Statement: [...allowStatements, ...denyStatements] }; if (input.shrinkActionLists) { await shrinkJsonDocument({ iterations: 0 }, policyDocument); } return policyDocument; } //# sourceMappingURL=canWhat.js.map