UNPKG

@k9securityio/k9-cdk

Version:

Provision strong AWS security policies easily using the AWS CDK.

92 lines 15.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SID_DENY_EVERYONE_ELSE = void 0; exports.makeResourcePolicy = makeResourcePolicy; exports.grantAccessViaResourcePolicy = grantAccessViaResourcePolicy; 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.WRITE_DATA); exports.SID_DENY_EVERYONE_ELSE = 'DenyEveryoneElse'; /** * Generate an EventBridge Bus resource policy from the provided props. * * @param props specifying desired access * @return a PolicyDocument that can be attached to an EventBridge event bus */ function makeResourcePolicy(props) { const policyFactory = new k9policy_1.K9PolicyFactory(); const policy = new iam.PolicyDocument(); const resourceArns = ['*']; (0, k9policy_1.validateAccessSpecs)(props.k9DesiredAccess); 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 EventBridge resources' + ' so the bus 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('EventBridge', SUPPORTED_CAPABILITIES, Array.from(accessSpecsByCapability.values()), resourceArns, true); policy.addStatements(...allowStatements); // DenyEveryoneElse — conditional on access pattern: // When wildcard + org constraint is used, skip DenyEveryoneElse because // putting "*" in the deny exception would exempt everyone. // The org constraint on the Allow side already limits access. if (!(0, k9policy_1.hasWildcardPrincipal)(props.k9DesiredAccess)) { const denyEveryoneElseStatement = new aws_iam_1.PolicyStatement({ sid: exports.SID_DENY_EVERYONE_ELSE, effect: aws_iam_1.Effect.DENY, principals: policyFactory.makeDenyEveryoneElsePrincipals(), actions: ['events:*'], 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('EventBridge', SUPPORTED_CAPABILITIES, accessSpecsByCapability, resourceArns); if (denyUntrustedOrgsStatement) { policy.addStatements(denyUntrustedOrgsStatement); } policy.validateForResourcePolicy(); return policy; } /** * Grant access to an event bus via resource policy using k9 IAccessSpec definitions. * * @param props specifying the event bus and desired access * * @return the results for adding each statement */ function grantAccessViaResourcePolicy(props) { const resourcePolicy = makeResourcePolicy(props); resourcePolicy.validateForResourcePolicy(); const policyJson = resourcePolicy.toJSON(); const k9Statements = policyJson.Statement; const bus = props.bus; const addToResourcePolicyResults = new Array(); for (let statement of k9Statements) { let addToResourcePolicyResult = bus.addToResourcePolicy(aws_iam_1.PolicyStatement.fromJson(statement)); addToResourcePolicyResults.push(addToResourcePolicyResult); } return addToResourcePolicyResults; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2V2ZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUF1Q0EsZ0RBdUVDO0FBU0Qsb0VBbUJDO0FBMUlELGlEQU02QjtBQUM3QiwyQ0FBMkM7QUFFM0MseUNBUW9CO0FBUXBCLElBQUksc0JBQXNCLEdBQUcsSUFBSSxLQUFLLENBQ3BDLDJCQUFnQixDQUFDLG1CQUFtQixFQUNwQywyQkFBZ0IsQ0FBQyxXQUFXLEVBQzVCLDJCQUFnQixDQUFDLFVBQVUsQ0FDNUIsQ0FBQztBQUVXLFFBQUEsc0JBQXNCLEdBQUcsa0JBQWtCLENBQUM7QUFFekQ7Ozs7O0dBS0c7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxLQUFvQztJQUNyRSxNQUFNLGFBQWEsR0FBRyxJQUFJLDBCQUFlLEVBQUUsQ0FBQztJQUM1QyxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUV4QyxNQUFNLFlBQVksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRTNCLElBQUEsOEJBQW1CLEVBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBRTNDLElBQUksMkJBQTJCLEdBQUcsYUFBYSxDQUFDLG1DQUFtQyxDQUFDLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNuSSxJQUFJLHVCQUF1QixHQUF1QyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTVFLEtBQUssSUFBSSxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLDJCQUEyQixDQUFDLEVBQUUsQ0FBQztRQUNwRix1QkFBdUIsQ0FBQyxHQUFHLENBQUMsSUFBQSx1Q0FBNEIsRUFBQyxhQUFhLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN2RixDQUFDO0lBRUQsSUFBSSxDQUFDLElBQUEsdUNBQTRCLEVBQUMsdUJBQXVCLENBQUMsRUFBRSxDQUFDO1FB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QUFDO1FBQ25DLElBQUkseUJBQXlCLEdBQUcsR0FBRyxDQUFDLG1CQUFtQixDQUNyRCx5QkFBZSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FDcEMsQ0FBQztRQUNGLDBCQUEwQixDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRCxPQUFPLDBCQUEwQixDQUFDO0FBQ3BDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBY2NvdW50Um9vdFByaW5jaXBhbCxcbiAgQWRkVG9SZXNvdXJjZVBvbGljeVJlc3VsdCxcbiAgRWZmZWN0LFxuICBQb2xpY3lEb2N1bWVudCxcbiAgUG9saWN5U3RhdGVtZW50LFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IEV2ZW50QnVzIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWV2ZW50cyc7XG5pbXBvcnQge1xuICBBY2Nlc3NDYXBhYmlsaXR5LFxuICBjYW5QcmluY2lwYWxzTWFuYWdlUmVzb3VyY2VzLFxuICBnZXRBY2Nlc3NDYXBhYmlsaXR5RnJvbVZhbHVlLFxuICBoYXNXaWxkY2FyZFByaW5jaXBhbCxcbiAgSUFjY2Vzc1NwZWMsXG4gIEs5UG9saWN5RmFjdG9yeSxcbiAgdmFsaWRhdGVBY2Nlc3NTcGVjcyxcbn0gZnJvbSAnLi9rOXBvbGljeSc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBLOUV2ZW50QnVzUmVzb3VyY2VQb2xpY3lQcm9wcyB7XG4gIHJlYWRvbmx5IGJ1czogRXZlbnRCdXM7XG4gIHJlYWRvbmx5IGs5RGVzaXJlZEFjY2VzczogQXJyYXk8SUFjY2Vzc1NwZWM+O1xufVxuXG5sZXQgU1VQUE9SVEVEX0NBUEFCSUxJVElFUyA9IG5ldyBBcnJheTxBY2Nlc3NDYXBhYmlsaXR5PihcbiAgQWNjZXNzQ2FwYWJpbGl0eS5BRE1JTklTVEVSX1JFU09VUkNFLFxuICBBY2Nlc3NDYXBhYmlsaXR5LlJFQURfQ09ORklHLFxuICBBY2Nlc3NDYXBhYmlsaXR5LldSSVRFX0RBVEEsXG4pO1xuXG5leHBvcnQgY29uc3QgU0lEX0RFTllfRVZFUllPTkVfRUxTRSA9ICdEZW55RXZlcnlvbmVFbHNlJztcblxuLyoqXG4gKiBHZW5lcmF0ZSBhbiBFdmVudEJyaWRnZSBCdXMgcmVzb3VyY2UgcG9saWN5IGZyb20gdGhlIHByb3ZpZGVkIHByb3BzLlxuICpcbiAqIEBwYXJhbSBwcm9wcyBzcGVjaWZ5aW5nIGRlc2lyZWQgYWNjZXNzXG4gKiBAcmV0dXJuIGEgUG9saWN5RG9jdW1lbnQgdGhhdCBjYW4gYmUgYXR0YWNoZWQgdG8gYW4gRXZlbnRCcmlkZ2UgZXZlbnQgYnVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlUmVzb3VyY2VQb2xpY3kocHJvcHM6IEs5RXZlbnRCdXNSZXNvdXJjZVBvbGljeVByb3BzKTogUG9saWN5RG9jdW1lbnQge1xuICBjb25zdCBwb2xpY3lGYWN0b3J5ID0gbmV3IEs5UG9saWN5RmFjdG9yeSgpO1xuICBjb25zdCBwb2xpY3kgPSBuZXcgaWFtLlBvbGljeURvY3VtZW50KCk7XG5cbiAgY29uc3QgcmVzb3VyY2VBcm5zID0gWycqJ107XG5cbiAgdmFsaWRhdGVBY2Nlc3NTcGVjcyhwcm9wcy5rOURlc2lyZWRBY2Nlc3MpO1xuXG4gIGxldCBhY2Nlc3NTcGVjc0J5Q2FwYWJpbGl0eVJlY3MgPSBwb2xpY3lGYWN0b3J5Lm1lcmdlRGVzaXJlZEFjY2Vzc1NwZWNzQnlDYXBhYmlsaXR5KFNVUFBPUlRFRF9DQVBBQklMSVRJRVMsIHByb3BzLms5RGVzaXJlZEFjY2Vzcyk7XG4gIGxldCBhY2Nlc3NTcGVjc0J5Q2FwYWJpbGl0eTogTWFwPEFjY2Vzc0NhcGFiaWxpdHksIElBY2Nlc3NTcGVjPiA9IG5ldyBNYXAoKTtcblxuICBmb3IgKGxldCBbY2FwYWJpbGl0eVN0ciwgYWNjZXNzU3BlY10gb2YgT2JqZWN0LmVudHJpZXMoYWNjZXNzU3BlY3NCeUNhcGFiaWxpdHlSZWNzKSkge1xuICAgIGFjY2Vzc1NwZWNzQnlDYXBhYmlsaXR5LnNldChnZXRBY2Nlc3NDYXBhYmlsaXR5RnJvbVZhbHVlKGNhcGFiaWxpdHlTdHIpLCBhY2Nlc3NTcGVjKTtcbiAgfVxuXG4gIGlmICghY2FuUHJpbmNpcGFsc01hbmFnZVJlc291cmNlcyhhY2Nlc3NTcGVjc0J5Q2FwYWJpbGl0eSkpIHtcbiAgICB0aHJvdyBFcnJvcignQXQgbGVhc3Qgb25lIHByaW5jaXBhbCBtdXN0IGJlIGFibGUgdG8gYWRtaW5pc3RlciBhbmQgcmVhZC1jb25maWcgZm9yIEV2ZW50QnJpZGdlIHJlc291cmNlcycgK1xuICAgICAgICAgICAgJyBzbyB0aGUgYnVzIHJlbWFpbnMgYWNjZXNzaWJsZTsgZm91bmQ6XFxuJyArXG4gICAgICAgICAgICBgYWRtaW5pc3Rlci1yZXNvdXJjZTogJyR7YWNjZXNzU3BlY3NCeUNhcGFiaWxpdHkuZ2V0KEFjY2Vzc0NhcGFiaWxpdHkuQURNSU5JU1RFUl9SRVNPVVJDRSk/LmFsbG93UHJpbmNpcGFsQXJuc30nXFxuYCArXG4gICAgICAgICAgICBgcmVhZC1jb25maWc6ICcke2FjY2Vzc1NwZWNzQnlDYXBhYmlsaXR5LmdldChBY2Nlc3NDYXBhYmlsaXR5LlJFQURfQ09ORklHKT8uYWxsb3dQcmluY2lwYWxBcm5zfSdgLFxuICAgICk7XG4gIH1cblxuICBjb25zdCBhbGxvd1N0YXRlbWVudHMgPSBwb2xpY3lGYWN0b3J5Lm1ha2VBbGxvd1N0YXRlbWVudHMoJ0V2ZW50QnJpZGdlJyxcbiAgICBTVVBQT1JURURfQ0FQQUJJTElUSUVTLFxuICAgIEFycmF5LmZyb20oYWNjZXNzU3BlY3NCeUNhcGFiaWxpdHkudmFsdWVzKCkpLFxuICAgIHJlc291cmNlQXJucyxcbiAgICB0cnVlKTtcbiAgcG9saWN5LmFkZFN0YXRlbWVudHMoLi4uYWxsb3dTdGF0ZW1lbnRzKTtcblxuICAvLyBEZW55RXZlcnlvbmVFbHNlIOKAlCBjb25kaXRpb25hbCBvbiBhY2Nlc3MgcGF0dGVybjpcbiAgLy8gV2hlbiB3aWxkY2FyZCArIG9yZyBjb25zdHJhaW50IGlzIHVzZWQsIHNraXAgRGVueUV2ZXJ5b25lRWxzZSBiZWNhdXNlXG4gIC8vIHB1dHRpbmcgXCIqXCIgaW4gdGhlIGRlbnkgZXhjZXB0aW9uIHdvdWxkIGV4ZW1wdCBldmVyeW9uZS5cbiAgLy8gVGhlIG9yZyBjb25zdHJhaW50IG9uIHRoZSBBbGxvdyBzaWRlIGFscmVhZHkgbGltaXRzIGFjY2Vzcy5cbiAgaWYgKCFoYXNXaWxkY2FyZFByaW5jaXBhbChwcm9wcy5rOURlc2lyZWRBY2Nlc3MpKSB7XG4gICAgY29uc3QgZGVueUV2ZXJ5b25lRWxzZVN0YXRlbWVudCA9IG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgc2lkOiBTSURfREVOWV9FVkVSWU9ORV9FTFNFLFxuICAgICAgZWZmZWN0OiBFZmZlY3QuREVOWSxcbiAgICAgIHByaW5jaXBhbHM6IHBvbGljeUZhY3RvcnkubWFrZURlbnlFdmVyeW9uZUVsc2VQcmluY2lwYWxzKCksXG4gICAgICBhY3Rpb25zOiBbJ2V2ZW50czoqJ10sXG4gICAgICByZXNvdXJjZXM6IHJlc291cmNlQXJucyxcbiAgICB9KTtcbiAgICBkZW55RXZlcnlvbmVFbHNlU3RhdGVtZW50LmFkZENvbmRpdGlvbignQm9vbCcsIHtcbiAgICAgICdhd3M6UHJpbmNpcGFsSXNBV1NTZXJ2aWNlJzogWydmYWxzZSddLFxuICAgIH0pO1xuICAgIGNvbnN0IGRlbnlFdmVyeW9uZUVsc2VUZXN0ID0gcG9saWN5RmFjdG9yeS53YXNMaWtlVXNlZChwcm9wcy5rOURlc2lyZWRBY2Nlc3MpID9cbiAgICAgICdBcm5Ob3RMaWtlJyA6XG4gICAgICAnQXJuTm90RXF1YWxzJztcbiAgICBjb25zdCBhbGxBbGxvd2VkUHJpbmNpcGFsQXJucyA9IHBvbGljeUZhY3RvcnkuZ2V0QWxsb3dlZFByaW5jaXBhbEFybnMocHJvcHMuazlEZXNpcmVkQWNjZXNzKTtcbiAgICBjb25zdCBhY2NvdW50Um9vdFByaW5jaXBhbCA9IG5ldyBBY2NvdW50Um9vdFByaW5jaXBhbCgpO1xuICAgIGRlbnlFdmVyeW9uZUVsc2VTdGF0ZW1lbnQuYWRkQ29uZGl0aW9uKGRlbnlFdmVyeW9uZUVsc2VUZXN0LCB7XG4gICAgICAnYXdzOlByaW5jaXBhbEFybic6IFtcbiAgICAgICAgLy8gUGxhY2UgUm9vdCBQcmluY2lwYWwgYXJuIGluIHN0YWJsZSwgcHJvbWluZW50IHBvc2l0aW9uO1xuICAgICAgICAvLyB3aWxsIHJlbmRlciBhcyBhbiBvYmplY3QgRm46OkpvaW4naW5nIFBhcnRpdGlvbiAmIEFjY291bnRJZFxuICAgICAgICBhY2NvdW50Um9vdFByaW5jaXBhbC5hcm4sXG4gICAgICAgIC4uLmFsbEFsbG93ZWRQcmluY2lwYWxBcm5zLFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIHBvbGljeS5hZGRTdGF0ZW1lbnRzKGRlbnlFdmVyeW9uZUVsc2VTdGF0ZW1lbnQpO1xuICB9XG5cbiAgY29uc3QgZGVueVVudHJ1c3RlZE9yZ3NTdGF0ZW1lbnQgPSBwb2xpY3lGYWN0b3J5Ll9tYWtlRGVueVVudHJ1c3RlZE9yZ3NTdGF0ZW1lbnQoXG4gICAgJ0V2ZW50QnJpZGdlJywgU1VQUE9SVEVEX0NBUEFCSUxJVElFUywgYWNjZXNzU3BlY3NCeUNhcGFiaWxpdHksIHJlc291cmNlQXJucyk7XG4gIGlmIChkZW55VW50cnVzdGVkT3Jnc1N0YXRlbWVudCkge1xuICAgIHBvbGljeS5hZGRTdGF0ZW1lbnRzKGRlbnlVbnRydXN0ZWRPcmdzU3RhdGVtZW50KTtcbiAgfVxuXG4gIHBvbGljeS52YWxpZGF0ZUZvclJlc291cmNlUG9saWN5KCk7XG5cbiAgcmV0dXJuIHBvbGljeTtcbn1cblxuLyoqXG4gKiBHcmFudCBhY2Nlc3MgdG8gYW4gZXZlbnQgYnVzIHZpYSByZXNvdXJjZSBwb2xpY3kgdXNpbmcgazkgSUFjY2Vzc1NwZWMgZGVmaW5pdGlvbnMuXG4gKlxuICogQHBhcmFtIHByb3BzIHNwZWNpZnlpbmcgdGhlIGV2ZW50IGJ1cyBhbmQgZGVzaXJlZCBhY2Nlc3NcbiAqXG4gKiBAcmV0dXJuIHRoZSByZXN1bHRzIGZvciBhZGRpbmcgZWFjaCBzdGF0ZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyYW50QWNjZXNzVmlhUmVzb3VyY2VQb2xpY3kocHJvcHM6IEs5RXZlbnRCdXNSZXNvdXJjZVBvbGljeVByb3BzKTpcbkFkZFRvUmVzb3VyY2VQb2xpY3lSZXN1bHRbXSB7XG4gIGNvbnN0IHJlc291cmNlUG9saWN5ID0gbWFrZVJlc291cmNlUG9saWN5KHByb3BzKTtcblxuICByZXNvdXJjZVBvbGljeS52YWxpZGF0ZUZvclJlc291cmNlUG9saWN5KCk7XG5cbiAgY29uc3QgcG9saWN5SnNvbiA9IHJlc291cmNlUG9saWN5LnRvSlNPTigpO1xuICBjb25zdCBrOVN0YXRlbWVudHMgPSBwb2xpY3lKc29uLlN0YXRlbWVudDtcbiAgY29uc3QgYnVzID0gcHJvcHMuYnVzO1xuICBjb25zdCBhZGRUb1Jlc291cmNlUG9saWN5UmVzdWx0cyA9IG5ldyBBcnJheTxBZGRUb1Jlc291cmNlUG9saWN5UmVzdWx0PigpO1xuXG4gIGZvciAobGV0IHN0YXRlbWVudCBvZiBrOVN0YXRlbWVudHMpIHtcbiAgICBsZXQgYWRkVG9SZXNvdXJjZVBvbGljeVJlc3VsdCA9IGJ1cy5hZGRUb1Jlc291cmNlUG9saWN5KFxuICAgICAgUG9saWN5U3RhdGVtZW50LmZyb21Kc29uKHN0YXRlbWVudCksXG4gICAgKTtcbiAgICBhZGRUb1Jlc291cmNlUG9saWN5UmVzdWx0cy5wdXNoKGFkZFRvUmVzb3VyY2VQb2xpY3lSZXN1bHQpO1xuICB9XG5cbiAgcmV0dXJuIGFkZFRvUmVzb3VyY2VQb2xpY3lSZXN1bHRzO1xufVxuIl19