@cloud-copilot/iam-lens
Version:
Visibility in IAM in and across AWS accounts
105 lines • 4.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.makePrincipalIndex = makePrincipalIndex;
const bitset_1 = require("bitset");
const bitset_js_1 = require("../utils/bitset.js");
/**
* Make a principal index for all principals in the collect client
*
* @param collectClient the collect client to use
*/
async function makePrincipalIndex(collectClient) {
const principalIndex = {
prefix: 'arn:aws:iam::',
principals: [],
accounts: {},
action: {},
notAction: {}
};
const allAccounts = await collectClient.allAccounts();
let globalIndex = 0;
for (const accountId of allAccounts) {
const accountBitSet = new bitset_1.default();
const principals = await collectClient.getAllPrincipalsInAccount(accountId);
const accountStart = globalIndex;
for (const principalArn of principals) {
principalIndex.principals.push((0, bitset_js_1.compressPrincipalString)(principalArn));
accountBitSet.set(globalIndex, 1);
const allowPolicies = await collectClient.getAllowPoliciesForPrincipal(principalArn);
addPoliciesToCache(allowPolicies, principalIndex, globalIndex);
globalIndex++;
}
const accountEnd = globalIndex - 1;
principalIndex.accounts[accountId] = [accountStart, accountEnd];
}
for (const type of ['action', 'notAction']) {
for (const [, actions] of Object.entries(principalIndex[type])) {
for (const [action, bitset] of Object.entries(actions)) {
actions[action] = (0, bitset_js_1.encodeBitSet)(bitset);
}
}
}
delete principalIndex.notAction['*'];
await collectClient.savePrincipalIndex('principals', {
principals: principalIndex.principals,
prefix: principalIndex.prefix
});
await collectClient.savePrincipalIndex('accounts', principalIndex.accounts);
await collectClient.savePrincipalIndex('not-actions', principalIndex.notAction);
for (const [service, serviceIndex] of Object.entries(principalIndex.action)) {
const serviceKey = service === '*' ? 'wildcard' : service;
await collectClient.savePrincipalIndex(`actions-${serviceKey}`, serviceIndex);
}
}
/**
* Add policies to the existing cache
*
* @param policies the policies to add
* @param existingCache the existing cache
* @param principalIndex the index of the principal to add
*/
function addPoliciesToCache(policies, existingCache, principalIndex) {
for (const policy of policies) {
for (const statement of policy.statements()) {
if (statement.isAllow()) {
if (statement.isActionStatement()) {
for (const action of statement.actions()) {
setCacheAction(existingCache.action, action, principalIndex);
}
}
else if (statement.isNotActionStatement()) {
for (const action of statement.notActions()) {
setCacheAction(existingCache.notAction, action, principalIndex);
}
}
}
}
}
}
/**
* Sets an action for a principal in a cache.
*
* @param cache The cache to update.
* @param action The action to set.
* @param principalIndex The index of the principal.
*/
function setCacheAction(cache, action, principalIndex) {
if (action.isWildcardAction()) {
if (!cache['*']) {
cache['*'] = { '*': new bitset_1.default() };
}
cache['*']['*'].set(principalIndex, 1);
}
else if (action.isServiceAction()) {
const service = action.service().toLowerCase();
const serviceAction = action.action().toLowerCase();
if (!cache[service]) {
cache[service] = {};
}
if (!cache[service][serviceAction]) {
cache[service][serviceAction] = new bitset_1.default();
}
cache[service][serviceAction].set(principalIndex, 1);
}
}
//# sourceMappingURL=makePrincipalIndex.js.map