Esempio n. 1
0
 def trust_policy(self) -> PolicyDocument:
     """Return the trust policy for the role."""
     if isinstance(self.trust, Trust):
         return PolicyDocument(statements=[self.trust])
     elif isinstance(self.trust, PolicyDocument):
         return self.trust
     else:
         return PolicyDocument(
             statements=[AssumeRole(principal=self.trust)])
Esempio n. 2
0
class Role(Construct):
    """Define IAM role with an attached assume_role policy document.

    :param name: role name
    :param description: role description
    :param principal: principal which are allowed to assume this role
    :param managed_policy_arns: list of ARNs of IAM managed policies to attach
        to the role
    """

    name: str
    description: str
    principal: PrincipalType
    managed_policy_arns: List[str] = field(default_factory=list)

    _assume_role_policy_document: PolicyDocument = field(
        default=PolicyDocument([]), init=False
    )

    @property
    def assume_role_policy_document(self) -> PolicyDocument:
        """Return PolicyDocument to be attached to the bucket."""
        return PolicyDocument(statements=[AssumeRole(principal=self.principal)])

    @property
    def resources(self) -> List[AWSObject]:
        """Return troposphere objects defining the role."""
        attr = {
            "RoleName": self.name,
            "Description": self.description,
            "ManagedPolicyArns": self.managed_policy_arns,
            "AssumeRolePolicyDocument": self.assume_role_policy_document.as_dict,
        }
        return [iam.Role.from_dict(name_to_id(self.name), attr)]
Esempio n. 3
0
 def policy_document(self) -> PolicyDocument:
     """Return PolicyDocument to be attached to the bucket."""
     return PolicyDocument(statements=[
         DenyUnsecureTransport(bucket=self.name),
         DenyBadEncryptionHeader(bucket=self.name),
         DenyUnencryptedObjectUploads(bucket=self.name),
     ])
Esempio n. 4
0
    def cfn_policy_document(self, stack: Stack) -> PolicyDocument:
        statements = [
            PolicyStatement(
                action=[
                    # Needed by CloudFormation to handle the function lifecycle
                    "lambda:CreateFunction",
                    "lambda:GetFunction",
                    "lambda:DeleteFunction",
                    "lambda:UpdateFunctionCode",
                    "lambda:UpdateFunctionConfiguration",
                    # Needed by resources referencing the function
                    "lambda:GetFunctionConfiguration",
                ],
                effect="Allow",
                resource=f"arn:aws:lambda:::function:{self.name}*",
            )
        ]
        if isinstance(self.role, GetAtt):
            logger.warning(f"cannot compute needed iam:PassRole for lambda {self.name}")
        else:
            if isinstance(self.role, Role):
                role_arn = f"arn:aws:iam::%(account)s:policy/{self.role.name}"
            else:
                role_arn = self.role

            # Allow user to pass role to the lambda
            statements.append(
                PolicyStatement(
                    action=["iam:PassRole"], effect="Allow", resource=role_arn
                )
            )
        return PolicyDocument(statements=statements)
Esempio n. 5
0
    def cfn_policy_document(self) -> PolicyDocument:
        """Return stack necessary policy document for CloudFormation."""
        result = PolicyDocument([])
        for construct in self.constructs:
            if isinstance(construct, Construct):
                result += construct.cfn_policy_document(stack=self)

        return result
Esempio n. 6
0
 def cfn_policy_document(self, stack: Stack) -> PolicyDocument:
     """Get policy needed by CloudFormation."""
     return PolicyDocument([
         PolicyStatement(
             action=["logs:DescribeLogGroups", "logs:CreateLogGroup"],
             effect="Allow",
             resource=f"arn:aws:logs:::log-group:{self.name}",
         )
     ])
Esempio n. 7
0
 def resources(self, stack: Stack) -> list[AWSObject]:
     """Return troposphere objects defining the managed policy."""
     params = {
         "Description": self.description,
         "ManagedPolicyName": self.name,
         "PolicyDocument":
         PolicyDocument(statements=self.statements).as_dict,
         "Path": self.path,
     }
     return [iam.ManagedPolicy(name_to_id(self.name), **params)]
Esempio n. 8
0
 def s3_endpoint_policy_document(self) -> PolicyDocument:
     """Return policy document for S3 endpoint."""
     return PolicyDocument(statements=[
         PolicyStatement(
             action=["s3:GetObject", "s3:ListBucket"],
             effect="Allow",
             resource="*",
             principal="*",
         )
     ])
Esempio n. 9
0
 def cfn_policy_document(self, stack: Stack) -> PolicyDocument:
     return PolicyDocument(statements=[
         Allow(
             action=[
                 "iam:GetRole",
                 "iam:CreateRole",
                 "iam:AttachRolePolicy",
                 "iam:DetachRolePolicy",
                 "iam:DeleteRole",
             ],
             resource=f"arn:aws:iam::%(account)s:role/{self.name}",
         )
     ])
Esempio n. 10
0
 def ecr_endpoints_policy_document(self) -> PolicyDocument:
     """Return policy Document for ecr endpoint allowing only image pulls."""
     return PolicyDocument(statements=[
         PolicyStatement(
             action=[
                 "ecr:BatchGetImage",
                 "ecr:GetAuthorizationToken",
                 "ecr:GetDownloadUrlForLayer",
             ],
             effect="Allow",
             resource="*",
             principal="*",
         )
     ])
Esempio n. 11
0
 def cfn_policy_document(self, stack: Stack) -> PolicyDocument:
     return PolicyDocument(statements=[
         Allow(
             action=[
                 "iam:GetPolicy",
                 "iam:CreatePolicy",
                 "iam:ListPolicyVersions",
                 "iam:DeletePolicy",
                 "iam:CreatePolicyVersion",
                 "iam:DeletePolicyVersion",
             ],
             resource=f"arn:aws:iam::%(account)s:policy/{self.name}",
         )
     ])
Esempio n. 12
0
 def allow_service_to_write(
         self,
         service: str,
         name_suffix: str,
         condition: Optional[ConditionType] = None) -> sqs.QueuePolicy:
     """Enable a given service to send a message."""
     return sqs.QueuePolicy(
         name_to_id(f"{self.name}Policy{name_suffix}"),
         Queues=[self.ref],
         PolicyDocument=PolicyDocument(statements=[
             Allow(
                 action="sqs:SendMessage",
                 resource=self.arn,
                 principal={"Service": f"{service}.amazonaws.com"},
                 condition=condition,
             )
         ]).as_dict,
     )
Esempio n. 13
0
 def cfn_policy_document(self, stack: Stack) -> PolicyDocument:
     return PolicyDocument(
         [
             PolicyStatement(
                 action=[
                     "s3:CreateBucket",
                     "s3:DeleteBucket",
                     "s3:DeleteBucketPolicy",
                     "s3:GetBucketPolicy",
                     "s3:PutBucketPolicy",
                     "s3:PutEncryptionConfiguration",
                     "s3:GetEncryptionConfiguration",
                     "s3:PutBucketVersioning",
                     "s3:GetBucketVersioning",
                     "s3:PutBucketPublicAccessBlock",
                     "s3:GetBucketPublicAccessBlock",
                 ],
                 effect="Allow",
                 resource=self.arn,
             )
         ]
     )
Esempio n. 14
0
    def allow_publish_policy(
            self,
            service: str,
            name_suffix: str,
            condition: Optional[ConditionType] = None) -> sns.TopicPolicy:
        """Return a policy allowing a service to publish to the topic.

        :param service: service allowed to publish
        :param name_suffix: a suffix used in the object name
        :param condition: condition to be able to publish
        """
        return sns.TopicPolicy(
            name_to_id(f"{self.name}Policy{name_suffix}"),
            Topics=[self.ref],
            PolicyDocument=PolicyDocument(statements=[
                Allow(
                    action="sns:Publish",
                    resource=self.ref,
                    principal={"Service": f"{service}.amazonaws.com"},
                    condition=condition,
                )
            ]).as_dict,
        )
Esempio n. 15
0
 def policy_document(self) -> PolicyDocument:
     """Return PolicyDocument to be attached to the bucket."""
     return super().policy_document + PolicyDocument(statements=[
         AWSConfigBucketPermissionsCheck(bucket=self.name),
         AWSConfigBucketDelivery(bucket=self.name),
     ])
Esempio n. 16
0
    def cfn_policy_document(self, stack: Stack) -> PolicyDocument:
        """Return the IAM policy needed by CloudFormation to manage the stack.

        :param stack: the stack that contains the construct
        """
        return PolicyDocument([])
Esempio n. 17
0
 def policy_document(self) -> PolicyDocument:
     """Return PolicyDocument to be attached to the managed policy."""
     return PolicyDocument(
         statements=[AllowAccess(buckets=self.buckets, action=self.action)])
Esempio n. 18
0
 def policy_document(self) -> PolicyDocument:
     """Return PolicyDocument to be attached to the bucket."""
     return PolicyDocument(statements=self.policy_statements)
Esempio n. 19
0
def test_vpc(stack: Stack) -> None:
    """Test VPC creation."""
    ecr_endpoint_pd = PolicyDocument(
        statements=[
            Allow(
                action=[
                    "ecr:BatchGetImage",
                    "ecr:GetAuthorizationToken",
                    "ecr:GetDownloadUrlForLayer",
                ],
                resource="*",
                principal="*",
            )
        ]
    )
    s3_endpoint_pd = PolicyDocument(
        statements=[
            Allow(action=["s3:PutObject", "s3:GetObject"], resource="*", principal="*"),
            Allow(action="s3:ListBucket", resource="*", principal="*"),
        ]
    )
    cloudwatch_endpoint_pd = PolicyDocument(
        statements=[
            Allow(
                action=[
                    "logs:CreateLogStream",
                    "logs:CreateLogGroup",
                    "logs:PutLogEvents",
                ],
                resource="*",
                principal="*",
            )
        ]
    )
    sm_endpoint_pd = PolicyDocument(
        statements=[
            Allow(
                action=[
                    "secretsmanager:GetResourcePolicy",
                    "secretsmanager:GetSecretValue",
                    "secretsmanager:DescribeSecret",
                    "secretsmanager:ListSecretVersionIds",
                ],
                resource=["this_is_a_secret_arn"],
                principal="*",
            )
        ]
    )
    stack.add(
        VPC(
            name="TestVPC",
            region="eu-west-1",
            internet_gateway=True,
            nat_gateway=True,
            s3_endpoint_policy_document=s3_endpoint_pd,
            interface_endpoints=[
                ("logs", cloudwatch_endpoint_pd),
                ("ecr.api", ecr_endpoint_pd),
                ("ecr.dkr", ecr_endpoint_pd),
                ("sts", None),
                ("secretsmanager", sm_endpoint_pd),
            ],
        )
    )
    with open(os.path.join(TEST_DIR, "vpc.json")) as fd:
        expected_template = json.load(fd)

    assert stack.export()["Resources"] == expected_template
Esempio n. 20
0
 def assume_role_policy_document(self) -> PolicyDocument:
     """Return PolicyDocument to be attached to the bucket."""
     return PolicyDocument(statements=[AssumeRole(principal=self.principal)])