UNPKG

@k9securityio/k9-cdk

Version:

Provision strong AWS security policies easily using the AWS CDK.

65 lines 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SID_DENY_EVERYONE_ELSE = void 0; exports.makeResourcePolicy = makeResourcePolicy; const aws_iam_1 = require("aws-cdk-lib/aws-iam"); const iam = require("aws-cdk-lib/aws-iam"); const k9policy_1 = require("./k9policy"); let SUPPORTED_CAPABILITIES = new Array(k9policy_1.AccessCapability.ADMINISTER_RESOURCE, k9policy_1.AccessCapability.READ_CONFIG, k9policy_1.AccessCapability.READ_DATA, k9policy_1.AccessCapability.WRITE_DATA, k9policy_1.AccessCapability.DELETE_DATA); exports.SID_DENY_EVERYONE_ELSE = 'DenyEveryoneElse'; /** * Generate a DynamoDB resource policy from the provided props that can be attached to DynamoDB * resources, particularly tables & indices. * * @param props specifying desired access * @return a PolicyDocument that can be attached to DynamoDB resources */ function makeResourcePolicy(props) { const policyFactory = new k9policy_1.K9PolicyFactory(); const policy = new iam.PolicyDocument(); const resourceArns = ['*']; let accessSpecsByCapabilityRecs = policyFactory.mergeDesiredAccessSpecsByCapability(SUPPORTED_CAPABILITIES, props.k9DesiredAccess); let accessSpecsByCapability = new Map(); for (let [capabilityStr, accessSpec] of Object.entries(accessSpecsByCapabilityRecs)) { accessSpecsByCapability.set((0, k9policy_1.getAccessCapabilityFromValue)(capabilityStr), accessSpec); } if (!(0, k9policy_1.canPrincipalsManageResources)(accessSpecsByCapability)) { throw Error('At least one principal must be able to administer and read-config for DynamoDB resources' + ' so data data remains accessible; found:\n' + `administer-resource: '${accessSpecsByCapability.get(k9policy_1.AccessCapability.ADMINISTER_RESOURCE)?.allowPrincipalArns}'\n` + `read-config: '${accessSpecsByCapability.get(k9policy_1.AccessCapability.READ_CONFIG)?.allowPrincipalArns}'`); } const allowStatements = policyFactory.makeAllowStatements('DynamoDB', SUPPORTED_CAPABILITIES, Array.from(accessSpecsByCapability.values()), resourceArns, true); policy.addStatements(...allowStatements); const denyEveryoneElseStatement = new aws_iam_1.PolicyStatement({ sid: exports.SID_DENY_EVERYONE_ELSE, effect: aws_iam_1.Effect.DENY, principals: policyFactory.makeDenyEveryoneElsePrincipals(), actions: ['dynamodb:*'], resources: resourceArns, }); denyEveryoneElseStatement.addCondition('Bool', { 'aws:PrincipalIsAWSService': ['false'], }); const denyEveryoneElseTest = policyFactory.wasLikeUsed(props.k9DesiredAccess) ? 'ArnNotLike' : 'ArnNotEquals'; const allAllowedPrincipalArns = policyFactory.getAllowedPrincipalArns(props.k9DesiredAccess); const accountRootPrincipal = new aws_iam_1.AccountRootPrincipal(); denyEveryoneElseStatement.addCondition(denyEveryoneElseTest, { 'aws:PrincipalArn': [ // Place Root Principal arn in stable, prominent position; // will render as an object Fn::Join'ing Partition & AccountId accountRootPrincipal.arn, ...allAllowedPrincipalArns, ], }); policy.addStatements(denyEveryoneElseStatement); const denyUntrustedOrgsStatement = policyFactory._makeDenyUntrustedOrgsStatement('DynamoDB', SUPPORTED_CAPABILITIES, accessSpecsByCapability, resourceArns); if (denyUntrustedOrgsStatement) { policy.addStatements(denyUntrustedOrgsStatement); } policy.validateForResourcePolicy(); return policy; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1vZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZHluYW1vZGIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBZ0NBLGdEQWlFQztBQWpHRCxpREFBb0c7QUFDcEcsMkNBQTJDO0FBQzNDLHlDQU1vQjtBQU9wQixJQUFJLHNCQUFzQixHQUFHLElBQUksS0FBSyxDQUNwQywyQkFBZ0IsQ0FBQyxtQkFBbUIsRUFDcEMsMkJBQWdCLENBQUMsV0FBVyxFQUM1QiwyQkFBZ0IsQ0FBQyxTQUFTLEVBQzFCLDJCQUFnQixDQUFDLFVBQVUsRUFDM0IsMkJBQWdCLENBQUMsV0FBVyxDQUM3QixDQUFDO0FBRVcsUUFBQSxzQkFBc0IsR0FBRyxrQkFBa0IsQ0FBQztBQUV6RDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxLQUFvQztJQUNyRSxNQUFNLGFBQWEsR0FBRyxJQUFJLDBCQUFlLEVBQUUsQ0FBQztJQUM1QyxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUV4QyxNQUFNLFlBQVksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRTNCLElBQUksMkJBQTJCLEdBQUcsYUFBYSxDQUFDLG1DQUFtQyxDQUFDLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNuSSxJQUFJLHVCQUF1QixHQUF1QyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTVFLEtBQUssSUFBSSxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLDJCQUEyQixDQUFDLEVBQUUsQ0FBQztRQUNwRix1QkFBdUIsQ0FBQyxHQUFHLENBQUMsSUFBQSx1Q0FBNEIsRUFBQyxhQUFhLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN2RixDQUFDO0lBRUQsSUFBSSxDQUFDLElBQUEsdUNBQTRCLEVBQUMsdUJBQXVCLENBQUMsRUFBRSxDQUFDO1FBQzNELE1BQU0sS0FBSyxDQUFDLDBGQUEwRjtZQUM5Riw0Q0FBNEM7WUFDNUMseUJBQXlCLHVCQUF1QixDQUFDLEdBQUcsQ0FBQywyQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLGtCQUFrQixLQUFLO1lBQ25ILGlCQUFpQix1QkFBdUIsQ0FBQyxHQUFHLENBQUMsMkJBQWdCLENBQUMsV0FBVyxDQUFDLEVBQUUsa0JBQWtCLEdBQUcsQ0FDeEcsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLGVBQWUsR0FBRyxhQUFhLENBQUMsbUJBQW1CLENBQUMsVUFBVSxFQUNsRSxzQkFBc0IsRUFDdEIsS0FBSyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUM1QyxZQUFZLEVBQ1osSUFBSSxDQUFDLENBQUM7SUFDUixNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsZUFBZSxDQUFDLENBQUM7SUFFekMsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLHlCQUFlLENBQUM7UUFDcEQsR0FBRyxFQUFFLDhCQUFzQjtRQUMzQixNQUFNLEVBQUUsZ0JBQU0sQ0FBQyxJQUFJO1FBQ25CLFVBQVUsRUFBRSxhQUFhLENBQUMsOEJBQThCLEVBQUU7UUFDMUQsT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDO1FBQ3ZCLFNBQVMsRUFBRSxZQUFZO0tBQ3hCLENBQUMsQ0FBQztJQUNILHlCQUF5QixDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUU7UUFDN0MsMkJBQTJCLEVBQUUsQ0FBQyxPQUFPLENBQUM7S0FDdkMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxvQkFBb0IsR0FBRyxhQUFhLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1FBQzdFLFlBQVksQ0FBQyxDQUFDO1FBQ2QsY0FBYyxDQUFDO0lBQ2pCLE1BQU0sdUJBQXVCLEdBQUcsYUFBYSxDQUFDLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUM3RixNQUFNLG9CQUFvQixHQUFHLElBQUksOEJBQW9CLEVBQUUsQ0FBQztJQUN4RCx5QkFBeUIsQ0FBQyxZQUFZLENBQUMsb0JBQW9CLEVBQUU7UUFDM0Qsa0JBQWtCLEVBQUU7WUFDbEIsMERBQTBEO1lBQzFELDhEQUE4RDtZQUM5RCxvQkFBb0IsQ0FBQyxHQUFHO1lBQ3hCLEdBQUcsdUJBQXVCO1NBQzNCO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsTUFBTSxDQUFDLGFBQWEsQ0FDbEIseUJBQXlCLENBQzFCLENBQUM7SUFFRixNQUFNLDBCQUEwQixHQUFHLGFBQWEsQ0FBQywrQkFBK0IsQ0FDOUUsVUFBVSxFQUFFLHNCQUFzQixFQUFFLHVCQUF1QixFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQzdFLElBQUksMEJBQTBCLEVBQUUsQ0FBQztRQUMvQixNQUFNLENBQUMsYUFBYSxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO0lBRW5DLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2NvdW50Um9vdFByaW5jaXBhbCwgRWZmZWN0LCBQb2xpY3lEb2N1bWVudCwgUG9saWN5U3RhdGVtZW50IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQge1xuICBBY2Nlc3NDYXBhYmlsaXR5LFxuICBjYW5QcmluY2lwYWxzTWFuYWdlUmVzb3VyY2VzLFxuICBnZXRBY2Nlc3NDYXBhYmlsaXR5RnJvbVZhbHVlLFxuICBJQWNjZXNzU3BlYyxcbiAgSzlQb2xpY3lGYWN0b3J5LFxufSBmcm9tICcuL2s5cG9saWN5JztcblxuXG5leHBvcnQgaW50ZXJmYWNlIEs5RHluYW1vREJSZXNvdXJjZVBvbGljeVByb3BzIHtcbiAgcmVhZG9ubHkgazlEZXNpcmVkQWNjZXNzOiBBcnJheTxJQWNjZXNzU3BlYz47XG59XG5cbmxldCBTVVBQT1JURURfQ0FQQUJJTElUSUVTID0gbmV3IEFycmF5PEFjY2Vzc0NhcGFiaWxpdHk+KFxuICBBY2Nlc3NDYXBhYmlsaXR5LkFETUlOSVNURVJfUkVTT1VSQ0UsXG4gIEFjY2Vzc0NhcGFiaWxpdHkuUkVBRF9DT05GSUcsXG4gIEFjY2Vzc0NhcGFiaWxpdHkuUkVBRF9EQVRBLFxuICBBY2Nlc3NDYXBhYmlsaXR5LldSSVRFX0RBVEEsXG4gIEFjY2Vzc0NhcGFiaWxpdHkuREVMRVRFX0RBVEEsXG4pO1xuXG5leHBvcnQgY29uc3QgU0lEX0RFTllfRVZFUllPTkVfRUxTRSA9ICdEZW55RXZlcnlvbmVFbHNlJztcblxuLyoqXG4gKiBHZW5lcmF0ZSBhIER5bmFtb0RCIHJlc291cmNlIHBvbGljeSBmcm9tIHRoZSBwcm92aWRlZCBwcm9wcyB0aGF0IGNhbiBiZSBhdHRhY2hlZCB0byBEeW5hbW9EQlxuICogcmVzb3VyY2VzLCBwYXJ0aWN1bGFybHkgdGFibGVzICYgaW5kaWNlcy5cbiAqXG4gKiBAcGFyYW0gcHJvcHMgc3BlY2lmeWluZyBkZXNpcmVkIGFjY2Vzc1xuICogQHJldHVybiBhIFBvbGljeURvY3VtZW50IHRoYXQgY2FuIGJlIGF0dGFjaGVkIHRvIER5bmFtb0RCIHJlc291cmNlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWFrZVJlc291cmNlUG9saWN5KHByb3BzOiBLOUR5bmFtb0RCUmVzb3VyY2VQb2xpY3lQcm9wcyk6IFBvbGljeURvY3VtZW50IHtcbiAgY29uc3QgcG9saWN5RmFjdG9yeSA9IG5ldyBLOVBvbGljeUZhY3RvcnkoKTtcbiAgY29uc3QgcG9saWN5ID0gbmV3IGlhbS5Qb2xpY3lEb2N1bWVudCgpO1xuXG4gIGNvbnN0IHJlc291cmNlQXJucyA9IFsnKiddO1xuXG4gIGxldCBhY2Nlc3NTcGVjc0J5Q2FwYWJpbGl0eVJlY3MgPSBwb2xpY3lGYWN0b3J5Lm1lcmdlRGVzaXJlZEFjY2Vzc1NwZWNzQnlDYXBhYmlsaXR5KFNVUFBPUlRFRF9DQVBBQklMSVRJRVMsIHByb3BzLms5RGVzaXJlZEFjY2Vzcyk7XG4gIGxldCBhY2Nlc3NTcGVjc0J5Q2FwYWJpbGl0eTogTWFwPEFjY2Vzc0NhcGFiaWxpdHksIElBY2Nlc3NTcGVjPiA9IG5ldyBNYXAoKTtcblxuICBmb3IgKGxldCBbY2FwYWJpbGl0eVN0ciwgYWNjZXNzU3BlY10gb2YgT2JqZWN0LmVudHJpZXMoYWNjZXNzU3BlY3NCeUNhcGFiaWxpdHlSZWNzKSkge1xuICAgIGFjY2Vzc1NwZWNzQnlDYXBhYmlsaXR5LnNldChnZXRBY2Nlc3NDYXBhYmlsaXR5RnJvbVZhbHVlKGNhcGFiaWxpdHlTdHIpLCBhY2Nlc3NTcGVjKTtcbiAgfVxuXG4gIGlmICghY2FuUHJpbmNpcGFsc01hbmFnZVJlc291cmNlcyhhY2Nlc3NTcGVjc0J5Q2FwYWJpbGl0eSkpIHtcbiAgICB0aHJvdyBFcnJvcignQXQgbGVhc3Qgb25lIHByaW5jaXBhbCBtdXN0IGJlIGFibGUgdG8gYWRtaW5pc3RlciBhbmQgcmVhZC1jb25maWcgZm9yIER5bmFtb0RCIHJlc291cmNlcycgK1xuICAgICAgICAgICAgJyBzbyBkYXRhIGRhdGEgcmVtYWlucyBhY2Nlc3NpYmxlOyBmb3VuZDpcXG4nICtcbiAgICAgICAgICAgIGBhZG1pbmlzdGVyLXJlc291cmNlOiAnJHthY2Nlc3NTcGVjc0J5Q2FwYWJpbGl0eS5nZXQoQWNjZXNzQ2FwYWJpbGl0eS5BRE1JTklTVEVSX1JFU09VUkNFKT8uYWxsb3dQcmluY2lwYWxBcm5zfSdcXG5gICtcbiAgICAgICAgICAgIGByZWFkLWNvbmZpZzogJyR7YWNjZXNzU3BlY3NCeUNhcGFiaWxpdHkuZ2V0KEFjY2Vzc0NhcGFiaWxpdHkuUkVBRF9DT05GSUcpPy5hbGxvd1ByaW5jaXBhbEFybnN9J2AsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGFsbG93U3RhdGVtZW50cyA9IHBvbGljeUZhY3RvcnkubWFrZUFsbG93U3RhdGVtZW50cygnRHluYW1vREInLFxuICAgIFNVUFBPUlRFRF9DQVBBQklMSVRJRVMsXG4gICAgQXJyYXkuZnJvbShhY2Nlc3NTcGVjc0J5Q2FwYWJpbGl0eS52YWx1ZXMoKSksXG4gICAgcmVzb3VyY2VBcm5zLFxuICAgIHRydWUpO1xuICBwb2xpY3kuYWRkU3RhdGVtZW50cyguLi5hbGxvd1N0YXRlbWVudHMpO1xuXG4gIGNvbnN0IGRlbnlFdmVyeW9uZUVsc2VTdGF0ZW1lbnQgPSBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICBzaWQ6IFNJRF9ERU5ZX0VWRVJZT05FX0VMU0UsXG4gICAgZWZmZWN0OiBFZmZlY3QuREVOWSxcbiAgICBwcmluY2lwYWxzOiBwb2xpY3lGYWN0b3J5Lm1ha2VEZW55RXZlcnlvbmVFbHNlUHJpbmNpcGFscygpLFxuICAgIGFjdGlvbnM6IFsnZHluYW1vZGI6KiddLFxuICAgIHJlc291cmNlczogcmVzb3VyY2VBcm5zLFxuICB9KTtcbiAgZGVueUV2ZXJ5b25lRWxzZVN0YXRlbWVudC5hZGRDb25kaXRpb24oJ0Jvb2wnLCB7XG4gICAgJ2F3czpQcmluY2lwYWxJc0FXU1NlcnZpY2UnOiBbJ2ZhbHNlJ10sXG4gIH0pO1xuICBjb25zdCBkZW55RXZlcnlvbmVFbHNlVGVzdCA9IHBvbGljeUZhY3Rvcnkud2FzTGlrZVVzZWQocHJvcHMuazlEZXNpcmVkQWNjZXNzKSA/XG4gICAgJ0Fybk5vdExpa2UnIDpcbiAgICAnQXJuTm90RXF1YWxzJztcbiAgY29uc3QgYWxsQWxsb3dlZFByaW5jaXBhbEFybnMgPSBwb2xpY3lGYWN0b3J5LmdldEFsbG93ZWRQcmluY2lwYWxBcm5zKHByb3BzLms5RGVzaXJlZEFjY2Vzcyk7XG4gIGNvbnN0IGFjY291bnRSb290UHJpbmNpcGFsID0gbmV3IEFjY291bnRSb290UHJpbmNpcGFsKCk7XG4gIGRlbnlFdmVyeW9uZUVsc2VTdGF0ZW1lbnQuYWRkQ29uZGl0aW9uKGRlbnlFdmVyeW9uZUVsc2VUZXN0LCB7XG4gICAgJ2F3czpQcmluY2lwYWxBcm4nOiBbXG4gICAgICAvLyBQbGFjZSBSb290IFByaW5jaXBhbCBhcm4gaW4gc3RhYmxlLCBwcm9taW5lbnQgcG9zaXRpb247XG4gICAgICAvLyB3aWxsIHJlbmRlciBhcyBhbiBvYmplY3QgRm46OkpvaW4naW5nIFBhcnRpdGlvbiAmIEFjY291bnRJZFxuICAgICAgYWNjb3VudFJvb3RQcmluY2lwYWwuYXJuLFxuICAgICAgLi4uYWxsQWxsb3dlZFByaW5jaXBhbEFybnMsXG4gICAgXSxcbiAgfSk7XG5cbiAgcG9saWN5LmFkZFN0YXRlbWVudHMoXG4gICAgZGVueUV2ZXJ5b25lRWxzZVN0YXRlbWVudCxcbiAgKTtcblxuICBjb25zdCBkZW55VW50cnVzdGVkT3Jnc1N0YXRlbWVudCA9IHBvbGljeUZhY3RvcnkuX21ha2VEZW55VW50cnVzdGVkT3Jnc1N0YXRlbWVudChcbiAgICAnRHluYW1vREInLCBTVVBQT1JURURfQ0FQQUJJTElUSUVTLCBhY2Nlc3NTcGVjc0J5Q2FwYWJpbGl0eSwgcmVzb3VyY2VBcm5zKTtcbiAgaWYgKGRlbnlVbnRydXN0ZWRPcmdzU3RhdGVtZW50KSB7XG4gICAgcG9saWN5LmFkZFN0YXRlbWVudHMoZGVueVVudHJ1c3RlZE9yZ3NTdGF0ZW1lbnQpO1xuICB9XG5cbiAgcG9saWN5LnZhbGlkYXRlRm9yUmVzb3VyY2VQb2xpY3koKTtcblxuICByZXR1cm4gcG9saWN5O1xufVxuIl19