Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Security Lake resource management service-linked role #289

Merged
merged 2 commits into from
Mar 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from aws_lambda_typing.context import Context
from aws_lambda_typing.events import CloudFormationCustomResourceEvent
from mypy_boto3_account import AccountClient
from mypy_boto3_account.type_defs import DeleteAlternateContactRequestRequestTypeDef, PutAlternateContactRequestRequestTypeDef
from mypy_boto3_account.type_defs import DeleteAlternateContactRequestTypeDef, PutAlternateContactRequestTypeDef
from mypy_boto3_organizations import OrganizationsClient
from mypy_boto3_organizations.type_defs import AccountTypeDef, DescribeAccountResponseTypeDef, TagTypeDef
from mypy_boto3_sns import SNSClient
Expand Down Expand Up @@ -156,7 +156,7 @@ def add_alternate_contact(
phone: Phone number for the alternate contact
title: Title for the alternate contact
"""
contact_parameters: PutAlternateContactRequestRequestTypeDef = {
contact_parameters: PutAlternateContactRequestTypeDef = {
"AlternateContactType": contact_type,
"EmailAddress": email,
"Name": name,
Expand All @@ -178,7 +178,7 @@ def delete_alternate_contact(
aws_account: AWS account to update
contact_type: Alternate contact type you want to update
"""
contact_parameters: DeleteAlternateContactRequestRequestTypeDef = {"AlternateContactType": contact_type}
contact_parameters: DeleteAlternateContactRequestTypeDef = {"AlternateContactType": contact_type}
try:
account_client.delete_alternate_contact(**contact_parameters)
LOGGER.info(f"Deleted {contact_type} Alternate Contact for account: {aws_account['Id']} ({aws_account['Name']})")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
BOTO3_CONFIG = Config(retries={"max_attempts": 10, "mode": "standard"})
UNEXPECTED = "Unexpected!"
SERVICE_NAME = "securitylake.amazonaws.com"
RESOURCE_MGMT_SERVICE_NAME = "resource-management.securitylake.amazonaws.com"
SLR_NAME = "AWSServiceRoleForSecurityLakeResourceManagement"
HOME_REGION = ssm.get_home_region()
AUDIT_ACCT_ID = ssm.get_security_acct()
AWS_LOG_SOURCES = ["ROUTE53", "VPC_FLOW", "SH_FINDINGS", "CLOUD_TRAIL_MGMT", "LAMBDA_EXECUTION", "S3_DATA", "EKS_AUDIT", "WAF"]
Expand Down Expand Up @@ -388,6 +390,14 @@ def add_log_sources(params: dict, regions: list, org_accounts: dict) -> None:
aws_log_sources.append(configurations)
if aws_log_sources:
security_lake.add_aws_log_source(sl_client, aws_log_sources)
for region in regions:
formatted_region = region.replace("-", "_")
lf_client = delegated_admin_session.client("lakeformation", region)
principal_identifier = (
f"arn:{PARTITION}:iam::{params['DELEGATED_ADMIN_ACCOUNT_ID']}:role/aws-service-role/{RESOURCE_MGMT_SERVICE_NAME}/{SLR_NAME}"
)
db_name = f"amazon_security_lake_glue_db_{formatted_region}"
security_lake.set_lake_formation_permissions_for_slr(lf_client, params["DELEGATED_ADMIN_ACCOUNT_ID"], principal_identifier, db_name)


def update_log_sources(params: dict, regions: list, org_accounts: dict) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,35 @@ def create_table_in_data_catalog(glue_client: GlueClient, shared_db_name: str, s
raise ValueError(f"Error calling glue:CreateTable {e}") from None


def set_lake_formation_permissions_for_slr(lf_client: LakeFormationClient, account: str, principal_identifier: str, db_name: str) -> None:
"""Set Lake Formation permissions.

Args:
lf_client: boto3 client
account: AWS account
principal_identifier: data lake principal identifier
db_name: database name

Raises:
ClientError: If there is an issue interacting with the AWS API

"""
LOGGER.info(f"Setting lakeformation permissions for '{db_name}'")
try:
resource: Union[ResourceTypeDef] = {
"Table": {"CatalogId": account, "DatabaseName": db_name, "TableWildcard": {}},
}
lf_client.grant_permissions(
CatalogId=account,
Principal={"DataLakePrincipalIdentifier": principal_identifier},
Resource=resource,
Permissions=["ALTER", "DESCRIBE"],
)
except ClientError as e:
LOGGER.error(f"Error calling GrantPermissions {e}.")
raise


def set_lake_formation_permissions(lf_client: LakeFormationClient, account: str, db_name: str) -> None:
"""Set Lake Formation permissions.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ Resources:
Condition:
StringLike:
ram:ResourceShareName: !Sub "*-${pAuditAccountQuerySubscriberExternalId}"
- PolicyName: sra-security-lake-org-policy-slr
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: AllowGrantPermissions
Effect: Allow
Action:
- lakeformation:GrantPermissions
- glue:GetDatabase
- glue:GetTable
Resource: "*"
Tags:
- Key: sra-solution
Value: !Ref pSRASolutionName
Original file line number Diff line number Diff line change
Expand Up @@ -472,17 +472,21 @@ Resources:
Resource: "*"
- Sid: AllowCreateServiceLinkedRole
Effect: Allow
Action: iam:CreateServiceLinkedRole
Action:
- iam:CreateServiceLinkedRole
- iam:GetRole
Condition:
StringLike:
iam:AWSServiceName: securitylake.amazonaws.com
iam:AWSServiceName:
- securitylake.amazonaws.com
- resource-management.securitylake.amazonaws.com
Resource: "*"
- Sid: SecurityLakeRemoveAdministratorAccess
Effect: Allow
Action:
- organizations:DeregisterDelegatedAdministrator
Resource: "*"
- PolicyName: sra-account-alternate-contacts-policy-organizations
- PolicyName: sra-security-lake-policy-organizations
PolicyDocument:
Version: 2012-10-17
Statement:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,19 @@ Resources:
- kms:Decrypt
Resource: '*'
- !Ref AWS::NoValue
- Sid: Allow SLR
Effect: Allow
Principal:
AWS: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/resource-management.securitylake.amazonaws.com/AWSServiceRoleForSecurityLakeResourceManagement'
Action:
- kms:Decrypt
- kms:GenerateDataKey*
Resource: '*'
Condition:
StringLike:
'kms:EncryptionContext:aws:s3:arn':
- !Sub 'arn:${AWS::Partition}:s3:::aws-security-data-lake-${AWS::Region}*'
'kms:ViaService': !Sub 's3.${AWS::Region}.amazonaws.com'
Tags:
- Key: sra-solution
Value: !Ref pSRASolutionName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Metadata:
- pDisableSecurityLake
- pControlTowerRegionsOnly
- pEnabledRegions
- pCreateAWSServiceRoleForSecurityLakeResourceManagementSlr
- pSecurityLakeOrgKeyAlias
- pSecurityLakeWarning
- pSRASecurityLakeMetaStoreManagerRoleName
Expand Down Expand Up @@ -93,6 +94,8 @@ Metadata:
default: CloudTrail - Lambda Data Events (recommended)
pCloudTrailS3DataEvents:
default: CloudTrail - S3 Data Events (high volume data)
pCreateAWSServiceRoleForSecurityLakeResourceManagementSlr:
default: Create AWS Service Role for Security Lake Resource Management.
pCustomerControlTowerRegions:
default: Customer Regions
pSecurityHubFindings:
Expand Down Expand Up @@ -167,6 +170,11 @@ Metadata:
default: Lambda Role Name

Parameters:
pCreateAWSServiceRoleForSecurityLakeResourceManagementSlr:
AllowedValues: ['true', 'false']
Default: 'true'
Description: Indicates whether to create a AWSServiceRoleForSecurityLakeResourceManagement service-linked role. Select True if this role does not exist in the Log Archive account
Type: String
pSecurityLakeOrgLambdaRoleName:
AllowedPattern: '^[\w+=,.@-]{1,64}$'
ConstraintDescription: Max 64 alphanumeric characters. Also special characters supported [+, =, ., @, -]
Expand Down Expand Up @@ -419,6 +427,9 @@ Conditions:
cCreateLakeFormationSlr: !Equals
- !Ref pCreateLakeFormationSlr
- 'true'
cAWSServiceRoleForSecurityLakeResourceManagement: !Equals
- !Ref pCreateAWSServiceRoleForSecurityLakeResourceManagementSlr
- 'true'

Rules:
VerifySecurityLakeDisclaimer:
Expand Down Expand Up @@ -598,9 +609,42 @@ Resources:
- Key: sra-solution
Value: !Ref pSRASolutionName


rAWSServiceRoleForSecurityLakeResourceManagementSLRStackSet:
Type: AWS::CloudFormation::StackSet
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Condition: cAWSServiceRoleForSecurityLakeResourceManagement
Properties:
StackSetName: sra-security-lake-resource-management-slr
AdministrationRoleARN: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${pStackSetAdminRole}
CallAs: SELF
Capabilities:
- CAPABILITY_NAMED_IAM
Description: !Sub ${pSRASolutionVersion} - Deploys AWS Lake Formation service-linked role via ${pSRASolutionName}
ExecutionRoleName: !Ref pStackExecutionRole
ManagedExecution:
Active: true
OperationPreferences:
FailureTolerancePercentage: 0
MaxConcurrentPercentage: 100
RegionConcurrencyType: PARALLEL
PermissionModel: SELF_MANAGED
StackInstancesGroup:
- DeploymentTargets:
Accounts:
- !Ref pLogArchiveAccountId
Regions:
- !Ref AWS::Region
TemplateURL: !Sub https://${pSRAStagingS3BucketName}.s3.${AWS::Region}.${AWS::URLSuffix}/${pSRASolutionName}/templates/sra-service-role-for-asl-resource-management.yaml
Tags:
- Key: sra-solution
Value: !Ref pSRASolutionName

rSecurityLakeKMSKeyStackSet:
Type: AWS::CloudFormation::StackSet
DependsOn: rSecurityLakeConfigurationIAMRoleStackSet
DependsOn:
- rSecurityLakeConfigurationIAMRoleStackSet
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
Expand Down Expand Up @@ -644,7 +688,7 @@ Resources:

rSecurityLakeMetaStoreManagerIAMRoleStackSet:
Type: AWS::CloudFormation::StackSet
DeletionPolicy: Delete
DeletionPolicy: Retain
UpdateReplacePolicy: Delete
Properties:
StackSetName: sra-security-lake-meta-store-manager-role
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
########################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
########################################################################
AWSTemplateFormatVersion: 2010-09-09
Description:
This template creates an IAM role to configure the delegated administrator account - - 'security_lake_org' solution in the repo,
https://github.com/aws-samples/aws-security-reference-architecture-examples (sra-1u3sd7f8p)

Metadata:
SRA:
Version: 1.0
Order: 2

Resources:
rAWSServiceRoleForSecurityLakeResourceManagementSLR:
Type: AWS::IAM::ServiceLinkedRole
Properties:
AWSServiceName: resource-management.securitylake.amazonaws.com