|
| 1 | +"""Class that applies permissions boundary to all the roles created within a Stack""" |
| 2 | +from typing import Union |
| 3 | + |
| 4 | +import jsii |
| 5 | +from aws_cdk import IAspect, aws_iam |
| 6 | +from constructs import IConstruct |
| 7 | +from jsii._reference_map import _refs |
| 8 | +from jsii._utils import Singleton |
| 9 | + |
| 10 | + |
| 11 | +@jsii.implements(IAspect) |
| 12 | +class PermissionsBoundaryAspect: |
| 13 | + """ |
| 14 | + This aspect finds all aws_iam.Role objects in a node (ie. CDK stack) and sets permissions boundary to the given ARN. |
| 15 | + """ |
| 16 | + |
| 17 | + def __init__(self, permissions_boundary: Union[aws_iam.ManagedPolicy, str]) -> None: |
| 18 | + """ |
| 19 | + :param permissions_boundary: Either aws_iam.ManagedPolicy object or managed policy's ARN string |
| 20 | + """ |
| 21 | + self.permissions_boundary = permissions_boundary |
| 22 | + |
| 23 | + def visit(self, construct_ref: IConstruct) -> None: |
| 24 | + """ |
| 25 | + construct_ref only contains a string reference to an object. To get the actual object, we need to resolve it using JSII mapping. |
| 26 | + :param construct_ref: ObjRef object with string reference to the actual object. |
| 27 | + :return: None |
| 28 | + """ |
| 29 | + if isinstance(construct_ref, jsii._kernel.ObjRef) and hasattr( |
| 30 | + construct_ref, "ref" |
| 31 | + ): |
| 32 | + kernel = Singleton._instances[ |
| 33 | + jsii._kernel.Kernel |
| 34 | + ] # The same object is available as: jsii.kernel |
| 35 | + resolve = _refs.resolve(kernel, construct_ref) |
| 36 | + else: |
| 37 | + resolve = construct_ref |
| 38 | + |
| 39 | + def _walk(obj): |
| 40 | + if isinstance(obj, aws_iam.Role): |
| 41 | + cfn_role = obj.node.find_child("Resource") |
| 42 | + policy_arn = ( |
| 43 | + self.permissions_boundary |
| 44 | + if isinstance(self.permissions_boundary, str) |
| 45 | + else self.permissions_boundary.managed_policy_arn |
| 46 | + ) |
| 47 | + cfn_role.add_property_override("PermissionsBoundary", policy_arn) |
| 48 | + else: |
| 49 | + if hasattr(obj, "permissions_node"): |
| 50 | + for c in obj.permissions_node.children: |
| 51 | + _walk(c) |
| 52 | + if hasattr(obj, "node") and obj.node.children: |
| 53 | + for c in obj.node.children: |
| 54 | + _walk(c) |
| 55 | + |
| 56 | + _walk(resolve) |
0 commit comments