diff --git a/Dome9.CloudGuardOnboarding.Orchestrator/AwsCloudFormation/StackConfig/ServerlessStackConfig.cs b/Dome9.CloudGuardOnboarding.Orchestrator/AwsCloudFormation/StackConfig/ServerlessStackConfig.cs index d738a05..4386aa3 100644 --- a/Dome9.CloudGuardOnboarding.Orchestrator/AwsCloudFormation/StackConfig/ServerlessStackConfig.cs +++ b/Dome9.CloudGuardOnboarding.Orchestrator/AwsCloudFormation/StackConfig/ServerlessStackConfig.cs @@ -4,14 +4,24 @@ namespace Dome9.CloudGuardOnboarding.Orchestrator { public class ServerlessStackConfig : OnboardingStackConfig { + public string CloudGuardAwsAccountId { get; set; } + public string ServerlessStage { get; set; } + public string ServerlessRegion { get; set; } + public ServerlessStackConfig( string templateS3Url, string stackName, string onboardingId, string uniqueSuffix, - int executionTimeoutMinutes) + int executionTimeoutMinutes, + string cloudGuardAwsAccountId, + string serverlessStage, + string serverlessRegion) : base(onboardingId, templateS3Url, stackName, uniqueSuffix, executionTimeoutMinutes) { + CloudGuardAwsAccountId = cloudGuardAwsAccountId; + ServerlessStage = serverlessStage; + ServerlessRegion = serverlessRegion; } } } diff --git a/Dome9.CloudGuardOnboarding.Orchestrator/AwsCloudFormation/StackWrapper/ServerlessStackWrapper.cs b/Dome9.CloudGuardOnboarding.Orchestrator/AwsCloudFormation/StackWrapper/ServerlessStackWrapper.cs index a7511ca..35efe24 100644 --- a/Dome9.CloudGuardOnboarding.Orchestrator/AwsCloudFormation/StackWrapper/ServerlessStackWrapper.cs +++ b/Dome9.CloudGuardOnboarding.Orchestrator/AwsCloudFormation/StackWrapper/ServerlessStackWrapper.cs @@ -1,4 +1,7 @@ -namespace Dome9.CloudGuardOnboarding.Orchestrator +using System; +using System.Collections.Generic; + +namespace Dome9.CloudGuardOnboarding.Orchestrator { public class ServerlessStackWrapper : StackWrapperBase { @@ -7,5 +10,23 @@ public ServerlessStackWrapper(ICloudGuardApiWrapper apiProvider, IRetryAndBackof } protected override Enums.Feature Feature => Enums.Feature.ServerlessProtection; + + protected override Dictionary GetParameters(OnboardingStackConfig onboardingStackConfig) + { + Console.WriteLine($"[INFO] [GetParameters] {onboardingStackConfig.GetType().Name}=[{onboardingStackConfig}]"); + if (!(onboardingStackConfig is ServerlessStackConfig)) + { + throw new ArgumentException($"{nameof(onboardingStackConfig)} is not of type {nameof(ServerlessStackConfig)}"); + } + + var permissionsStackConfig = onboardingStackConfig as ServerlessStackConfig; + return new Dictionary + { + { "CloudGuardAwsAccountId", permissionsStackConfig.CloudGuardAwsAccountId }, + { "ServerlessStage", permissionsStackConfig.ServerlessStage }, + { "TimeStamp", DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString() }, + { "ServerlessRegion", permissionsStackConfig.ServerlessRegion } + }; + } } } diff --git a/Dome9.CloudGuardOnboarding.Orchestrator/CloudGuardApi/Model/Response/ConfigurationResponseModel.cs b/Dome9.CloudGuardOnboarding.Orchestrator/CloudGuardApi/Model/Response/ConfigurationResponseModel.cs index de3cb4c..e59a700 100644 --- a/Dome9.CloudGuardOnboarding.Orchestrator/CloudGuardApi/Model/Response/ConfigurationResponseModel.cs +++ b/Dome9.CloudGuardOnboarding.Orchestrator/CloudGuardApi/Model/Response/ConfigurationResponseModel.cs @@ -9,6 +9,7 @@ public class ConfigurationResponseModel public string ServerlessTemplateS3Path { get; set; } public bool ServerlessProtectionEnabled { get; set; } public string ServerlessCftRegion { get; set; } + public string ServerlessStage { get; set; } public string IntelligenceStackName { get; set; } public string IntelligenceTemplateS3Path { get; set; } public bool IntelligenceEnabled { get; set; } @@ -25,6 +26,7 @@ public override string ToString() $"{nameof(PermissionsTemplateS3Path)}='{PermissionsTemplateS3Path}', " + $"{nameof(ServerlessProtectionEnabled)}='{ServerlessProtectionEnabled}', " + $"{nameof(ServerlessCftRegion)}='{ServerlessCftRegion}', " + + $"{nameof(ServerlessStage)}='{ServerlessStage}', " + $"{nameof(IntelligenceStackName)}='{IntelligenceStackName}', " + $"{nameof(IntelligenceTemplateS3Path)}='{IntelligenceTemplateS3Path}', " + $"{nameof(IntelligenceEnabled)}='{IntelligenceEnabled}', " + diff --git a/Dome9.CloudGuardOnboarding.Orchestrator/Steps/ServerlessStackCreationStep.cs b/Dome9.CloudGuardOnboarding.Orchestrator/Steps/ServerlessStackCreationStep.cs index 34ead7e..b86b58d 100644 --- a/Dome9.CloudGuardOnboarding.Orchestrator/Steps/ServerlessStackCreationStep.cs +++ b/Dome9.CloudGuardOnboarding.Orchestrator/Steps/ServerlessStackCreationStep.cs @@ -6,21 +6,21 @@ namespace Dome9.CloudGuardOnboarding.Orchestrator.Steps { public class ServerlessStackCreationStep : StepBase { - private readonly string _awsAccountId; private readonly string _onboardingId; private readonly ServerlessStackWrapper _awsStackWrapper; private readonly ServerlessStackConfig _stackConfig; - private readonly StackOperation _stackOperation; - public ServerlessStackCreationStep(ICloudGuardApiWrapper apiProvider, IRetryAndBackoffService retryAndBackoffService, string awsAccountId, string onboardingId, string serverlessStackS3Url, string serverlessStackName, string uniqueSuffix, StackOperation stackOperation = StackOperation.Create) + public ServerlessStackCreationStep(ICloudGuardApiWrapper apiProvider, IRetryAndBackoffService retryAndBackoffService, + string cftS3Buckets, string region, + string onboardingId, string templateS3Path, string serverlessStackName, string uniqueSuffix, + string cloudGuardAwsAccountId, string serverlessStage, string serverlessRegion) { _apiProvider = apiProvider; _retryAndBackoffService = retryAndBackoffService; - _awsAccountId = awsAccountId; _onboardingId = onboardingId; _awsStackWrapper = new ServerlessStackWrapper(apiProvider, retryAndBackoffService); - _stackConfig = new ServerlessStackConfig(serverlessStackS3Url, serverlessStackName, onboardingId, uniqueSuffix, 30); - _stackOperation = stackOperation; + var s3Url = $"https://{cftS3Buckets}.s3.{region}.amazonaws.com/{templateS3Path}"; + _stackConfig = new ServerlessStackConfig(s3Url, serverlessStackName, onboardingId, uniqueSuffix, 30, cloudGuardAwsAccountId, serverlessStage, serverlessRegion); } public override Task Cleanup() @@ -34,7 +34,7 @@ public async override Task Execute() Console.WriteLine($"[INFO] About to add serverless protection"); await _retryAndBackoffService.RunAsync(() => _apiProvider.UpdateOnboardingStatus(new StatusModel(_onboardingId, Enums.Feature.ServerlessProtection, Enums.Status.PENDING, "Adding serverless protection", null, null, null))); Console.WriteLine($"[INFO][{nameof(ServerlessStackCreationStep)}.{nameof(Execute)}] RunStackAsync starting"); - await _awsStackWrapper.RunStackAsync(_stackConfig, _stackOperation); + await _awsStackWrapper.RunStackAsync(_stackConfig, StackOperation.Create); Console.WriteLine($"[INFO][{nameof(ServerlessStackCreationStep)}.{nameof(Execute)}] RunStackAsync finished"); await _retryAndBackoffService.RunAsync(() => _apiProvider.UpdateOnboardingStatus(new StatusModel(_onboardingId, Enums.Feature.ServerlessProtection, Enums.Status.ACTIVE, "Added serverless protection successfully", null, null, null))); Console.WriteLine($"[INFO] Successfully added serverless protection"); diff --git a/Dome9.CloudGuardOnboarding.Orchestrator/Workflow/OnboardingWorkflow.cs b/Dome9.CloudGuardOnboarding.Orchestrator/Workflow/OnboardingWorkflow.cs index 45759f2..c0c8b46 100644 --- a/Dome9.CloudGuardOnboarding.Orchestrator/Workflow/OnboardingWorkflow.cs +++ b/Dome9.CloudGuardOnboarding.Orchestrator/Workflow/OnboardingWorkflow.cs @@ -70,7 +70,7 @@ public override async Task RunAsync(OnboardingRequest request, LambdaCustomResou await ExecuteStep(new ServerlessAddAccountStep(_apiProvider, _retryAndBackoffService, request.AwsAccountId, request.OnboardingId)); // 8. create serverless protection stack if enabled - await ExecuteStep(new ServerlessStackCreationStep(_apiProvider, _retryAndBackoffService, request.AwsAccountId, request.OnboardingId, configuration.ServerlessTemplateS3Path, configuration.ServerlessStackName, request.UniqueSuffix)); + await ExecuteStep(new ServerlessStackCreationStep(_apiProvider, _retryAndBackoffService, request.S3BucketName, request.AwsAccountRegion, request.OnboardingId, configuration.ServerlessTemplateS3Path, configuration.ServerlessStackName, request.UniqueSuffix, configuration.CloudGuardAwsAccountId, configuration.ServerlessStage, configuration.ServerlessCftRegion)); } } else diff --git a/cft/cft-replacer/replacer.js b/cft/cft-replacer/replacer.js index 089e929..807154a 100644 --- a/cft/cft-replacer/replacer.js +++ b/cft/cft-replacer/replacer.js @@ -38,15 +38,22 @@ let replacer = function () { const readonlyPolicy = yamlParse(fs.readFileSync(__dirname + '/../replacements/readonly_policy.yml', 'utf8')) const readwritePolicy = yamlParse(fs.readFileSync(__dirname + '/../replacements/readwrite_policy.yml', 'utf8')) const stackModifyPolicyStatements = yamlParse(fs.readFileSync(__dirname + '/../replacements/stack_modify_policy_statements.yml', 'utf8')) + const metadata = yamlParse(fs.readFileSync(__dirname + '/../replacements/metadata.yml', 'utf8')) + const userBasedOrchestratorRolePolicies = yamlParse(fs.readFileSync(__dirname + '/../replacements/user_based_orchestrator_role_policy_statements.yml', 'utf8')) + const roleBasedOrchestratorRolePolicies = yamlParse(fs.readFileSync(__dirname + '/../replacements/role_based_orchestrator_role_policy_statements.yml', 'utf8')) writToFile('/generated/templates/policies/readonly_policy.json', JSON.stringify(readonlyPolicy, null, 4)) writToFile('/generated/templates/policies/readwrite_policy.json', JSON.stringify(readwritePolicy, null, 4)) // role based onboarding + let orchestratorRole = yamlParse(fs.readFileSync(__dirname + '/../replacements/orchestartor_role.yml', 'utf8')) let onboardingJson = yamlParse(fs.readFileSync(__dirname + '/../role_based/onboarding.yml', 'utf8')) replaceObjectByPlaceholders(onboardingJson, [ + {key: 'REPLACEMENT_METADATA', value: metadata}, {key: 'REPLACEMENT_PARAMETERS', value: parameters}, {key: 'REPLACEMENT_SATCK_MODIFY_POLICY_STATEMENT', value: stackModifyPolicyStatements}, + {key: 'REPLACEMENT_ORCHESTRATOR_ROLE', value: orchestratorRole}, + {key: 'REPLACEMENT_ORCHESTRATOR_ROLE_POLICY_STATEMENTS', value: roleBasedOrchestratorRolePolicies}, {key: 'REPLACEMENT_ORCHESTRATOR', value: orchestrator}, {key: 'REPLACEMENT_ORCHESTRATOR_INVOKE_PROPERTIES', value: orchestratorInvokeProperties}, {key: 'REPLACEMENT_BUCKET_SUFFIX', value: bucketSuffix}, @@ -75,12 +82,24 @@ let replacer = function () { let intelligence = fs.readFileSync(__dirname + '/../role_based/intelligence_cft.yml', 'utf8') writToFile('/generated/templates/role_based/intelligence_cft.yml', intelligence) + // role based serverless + let serverlessJson = yamlParse(fs.readFileSync(__dirname + '/../role_based/serverless_cft.yml', 'utf8')) + replaceObjectByPlaceholders(serverlessJson, [ + {key: 'REPLACEMENT_METADATA', value: metadata}, + ]); + let serverlessYml = yamlDump(serverlessJson) + writToFile('/generated/templates/role_based/serverless_cft.yml', serverlessYml) + // user based onboarding + orchestratorRole = yamlParse(fs.readFileSync(__dirname + '/../replacements/orchestartor_role.yml', 'utf8')) onboardingJson = yamlParse(fs.readFileSync(__dirname + '/../user_based/onboarding.yml', 'utf8')) replaceObjectByPlaceholders(onboardingJson, [ + {key: 'REPLACEMENT_METADATA', value: metadata}, {key: 'REPLACEMENT_PARAMETERS', value: parameters}, {key: 'REPLACEMENT_SATCK_MODIFY_POLICY_STATEMENT', value: stackModifyPolicyStatements}, + {key: 'REPLACEMENT_ORCHESTRATOR_ROLE', value: orchestratorRole}, + {key: 'REPLACEMENT_ORCHESTRATOR_ROLE_POLICY_STATEMENTS', value: userBasedOrchestratorRolePolicies}, {key: 'REPLACEMENT_ORCHESTRATOR', value: orchestrator}, {key: 'REPLACEMENT_ORCHESTRATOR_INVOKE_PROPERTIES', value: orchestratorInvokeProperties}, {key: 'REPLACEMENT_BUCKET_SUFFIX', value: bucketSuffix}, @@ -151,6 +170,10 @@ function replaceObjectByPlaceholder(element, replacementKey, replacementValue) { element[key] = value.replace(replacementKey, replacementValue) } else if (Array.isArray(element)) { element.splice(Number(key), 1); + if (replacementValue == null) + { + continue; + } if (Array.isArray(replacementValue)) { element.push(...replacementValue); } else { diff --git a/cft/generated/templates/role_based/onboarding.yml b/cft/generated/templates/role_based/onboarding.yml index 60e148b..a8c004c 100644 --- a/cft/generated/templates/role_based/onboarding.yml +++ b/cft/generated/templates/role_based/onboarding.yml @@ -1,7 +1,7 @@ AWSTemplateFormatVersion: 2010-09-09 Description: Check Point CloudGuard Dome9 unified onboarding Metadata: - Version: 2.0.0 + Version: 2.6.0 Parameters: S3BucketName: Description: The S3 Bucket @@ -42,6 +42,9 @@ Parameters: CloudGuardAwsAccountNumber: Description: The CloudGuard AWS account number Type: String + ServerlessStage: + Description: The Serverless stage name + Type: String Conditions: RemoteStackModifyEnabled: !Equals - !Ref EnableRemoteStackModify @@ -97,8 +100,9 @@ Resources: - iam:DeleteRole - iam:DetachRolePolicy - iam:DeleteRolePolicy + - iam:PutRolePolicy Resource: !Sub >- - arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Lambda-CloudFormation-role${UniqueSuffix} + arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Onboarding-Orchestrator-role${UniqueSuffix} - Sid: LambdaRemovePermission Effect: Allow Action: lambda:RemovePermission @@ -115,7 +119,7 @@ Resources: Type: AWS::CloudFormation::WaitConditionHandle Waiter: Type: AWS::CloudFormation::WaitConditionHandle - StackModifyRoleIfEnabledWaitCondition: + StackModifyIfEnabledWaitCondition: Type: AWS::CloudFormation::WaitCondition Properties: Handle: !If @@ -124,11 +128,11 @@ Resources: - !Ref Waiter Timeout: '1' Count: 0 - CloudGuardLambdaStackCreationRole: + CloudGuardOrchestratorRole: Type: AWS::IAM::Role - DependsOn: StackModifyRoleIfEnabledWaitCondition + DependsOn: StackModifyIfEnabledWaitCondition Properties: - RoleName: !Sub CloudGuard-Lambda-CloudFormation-role${UniqueSuffix} + RoleName: !Sub CloudGuard-Onboarding-Orchestrator-role${UniqueSuffix} AssumeRolePolicyDocument: Version: 2012-10-17 Statement: @@ -139,15 +143,161 @@ Resources: Action: - sts:AssumeRole Policies: - - PolicyName: !Sub CloudGuard-Lambda-CloudFormation-policy${UniqueSuffix} + - PolicyName: !Sub CloudGuard-Onboarding-Orchestrator-policy${UniqueSuffix} PolicyDocument: Version: 2012-10-17 Statement: - - Sid: CloudGuardLambdaCloudFormation + - Sid: CloudGuardOnboardingOrchestratorCloudformation + Action: + - cloudformation:CreateStack + - cloudformation:DescribeStacks + - cloudformation:DeleteStack + - cloudformation:CreateChangeSet + - cloudformation:ExecuteChangeSet + - cloudformation:DeleteChangeSet + - cloudformation:DescribeChangeSet + Effect: Allow + Resource: + - !Sub >- + arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/CloudGuard-Onboarding* + - Sid: CloudGuardOnboardingOrchestratorCloudformationList + Action: + - cloudformation:ListStacks + Effect: Allow + Resource: !Sub >- + arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/*/* + - Sid: CloudGuardOnboardingOrchestratorIamListAccount + Action: + - iam:ListAccountAliases + Effect: Allow + Resource: '*' + - Sid: CloudGuardOnboardingOrchestratorIam + Action: + - iam:GetRole + - iam:CreateRole + - iam:DeleteRole + - iam:PutRolePolicy + - iam:DetachRolePolicy + - iam:AttachRolePolicy + - iam:DeleteRolePolicy + - iam:getRolePolicy + - iam:UpdateRole + - iam:TagRole + - iam:UntagRole + - iam:DeleteRolePolicy + - iam:PassRole + Effect: Allow + Resource: + - !Sub >- + arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Connect-RO-role${UniqueSuffix} + - !Sub >- + arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Connect-RW-role${UniqueSuffix} + - !Sub >- + arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuardFSPLogsSenderRole + - !Sub >- + arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuardServerlessCrossAccountRole + - !Sub >- + arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuardServerlessCodeAnalysisLambdaExecutionRole + - !Sub >- + arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuardServerlessFSPInjectorLambdaExecutionRole + - Sid: CloudGuardOnboardingOrchestratorIntelligenceCloudtrail + Action: + - cloudtrail:DescribeTrails + Effect: Allow + Resource: '*' + - Sid: CloudGuardOnboardingOrchestratorIntelligenceS3 Action: - - '*' + - s3:GetBucketLocation + - s3:GetBucketNotification + - s3:PutBucketNotification Effect: Allow Resource: '*' + - Sid: CloudGuardOnboardingOrchestratorServelessLambda + Action: + - lambda:GetFunction + - lambda:GetFunctionConfiguration + - lambda:TagResource + - lambda:UntagResource + - lambda:CreateFunction + - lambda:DeleteFunction + - lambda:UpdateFunctionCode + - lambda:UpdateFunctionConfiguration + - lambda:GetFunctionConfiguration + Effect: Allow + Resource: + - !Sub >- + arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardNode14CodeAnalysis + - !Sub >- + arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardJavaCodeAnalysis + - !Sub >- + arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardPy3CodeAnalysis + - !Sub >- + arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardCsCodeAnalysis + - !Sub >- + arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardFSPInjector + - Sid: CloudGuardOnboardingOrchestratorServelessLambdaTp + Action: + - lambda:GetLayerVersion + Effect: Allow + Resource: + - !Sub arn:aws:lambda:${AWS::Region}:553035198032:layer:nodejs12:21 + - !Sub >- + arn:aws:lambda:${AWS::Region}:985618988812:layer:aws-lambda-layer-csharp:* + - !Sub >- + arn:aws:lambda:${AWS::Region}:985618988812:layer:aws-lambda-layer-java:* + - Sid: CloudGuardOnboardingOrchestratorServelessLogs + Action: + - logs:DescribeLogGroups + - logs:CreateLogGroup + - logs:DeleteLogGroup + - logs:CreateLogStream + - logs:PutRetentionPolicy + Effect: Allow + Resource: + - !Sub >- + arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardNode14CodeAnalysis:log-stream:* + - !Sub >- + arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardJavaCodeAnalysis:log-stream:* + - !Sub >- + arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardPy3CodeAnalysis:log-stream:* + - !Sub >- + arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardCsCodeAnalysis:log-stream:* + - !Sub >- + arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardFSPInjector:log-stream:* + - Sid: CloudGuardOnboardingOrchestratorLogsDescribe + Action: + - logs:DescribeLogGroups + Effect: Allow + Resource: !Sub 'arn:aws:logs:*:${AWS::AccountId}:log-group:*:' + - Sid: CloudGuardOnboardingOrchestratorServelessProtegoS3 + Action: + - s3:GetObject + Effect: Allow + Resource: + - !Sub >- + arn:aws:s3:::${ServerlessStage}-protego/code_analysis_functions/* + - Sid: CloudGuardOnboardingOrchestratorServelessS3 + Action: + - s3:GetBucketPolicy + - s3:CreateBucket + - s3:PutObject + - s3:PutBucketPolicy + - s3:DeleteObject + - s3:DeleteBucketPolicy + - s3:DeleteBucket + - s3:PutEncryptionConfiguration + - s3:PutBucketPublicAccessBlock + Effect: Allow + Resource: + - !Sub arn:aws:s3:::protego-fsp-${AWS::AccountId} + - !Sub arn:aws:s3:::protego-fsp-${AWS::AccountId}/* + - Sid: CloudGuardOnboardingOrchestratorServelessSns + Action: + - sns:Publish + Effect: Allow + Resource: + - !Sub >- + arn:aws:sns:${AWS::Region}:${CloudGuardAwsAccountNumber}:${ServerlessStage}-${AWS::AccountId}-notifications ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole CloudGuardOnboardingOrchestrator: @@ -155,7 +305,7 @@ Resources: Properties: FunctionName: !Sub CloudGuardOnboardingOrchestrator${UniqueSuffix} Runtime: dotnetcore3.1 - Role: !GetAtt CloudGuardLambdaStackCreationRole.Arn + Role: !GetAtt CloudGuardOrchestratorRole.Arn Handler: >- Dome9.CloudGuardOnboarding.Orchestrator::Dome9.CloudGuardOnboarding.Orchestrator.Function::FunctionHandler Timeout: 900 diff --git a/cft/generated/templates/role_based/serverless_cft.yml b/cft/generated/templates/role_based/serverless_cft.yml new file mode 100644 index 0000000..8e9a017 --- /dev/null +++ b/cft/generated/templates/role_based/serverless_cft.yml @@ -0,0 +1,489 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Create a cross account role that authorizes access for Cloudguard BE. +Metadata: + Version: 2.6.0 +Parameters: + CloudGuardAwsAccountId: + Description: CloudGuard instance AWS AccountId that is requiring external trust + Type: String + ServerlessStage: + Description: The Serverless stage name + Type: String + TimeStamp: + Description: The current TimeStamp running TimeStamp + Type: String + ServerlessRegion: + Description: The Serverless region + Type: String +Conditions: + IsProtegoRegionCondition: !Equals + - !Sub ${AWS::Region} + - !Ref ServerlessRegion +Resources: + CrossAccountRole: + Type: AWS::IAM::Role + Properties: + RoleName: CloudGuardServerlessCrossAccountRole + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + AWS: + - !Ref CloudGuardAwsAccountId + Action: sts:AssumeRole + Condition: + StringEquals: + sts:ExternalId: !Base64 + Fn::Sub: ${AWS::AccountId} + ManagedPolicyArns: + - arn:aws:iam::aws:policy/ReadOnlyAccess + Policies: + - PolicyName: CrossAccountCustomerRO + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - lambda:InvokeFunction + - lambda:GetFunction + - lambda:GetLayerVersion + - lambda:UpdateFunctionConfiguration + - lambda:TagResource + - lambda:ListTags + - lambda:UntagResource + Resource: + - !GetAtt ProtegoNode14CodeAnalysisFunction.Arn + - !GetAtt ProtegoJavaCodeAnalysisFunction.Arn + - !GetAtt ProtegoPython3CodeAnalysisFunction.Arn + - !GetAtt ProtegoCSharpCodeAnalysisFunction.Arn + - !GetAtt ProtegoFSPInjectorFunction.Arn + - Effect: Allow + Action: + - lambda:UpdateFunctionCode + - lambda:UpdateFunctionConfiguration + Resource: + - !Join + - ':' + - - !GetAtt ProtegoNode14CodeAnalysisFunction.Arn + - '*' + - !Join + - ':' + - - !GetAtt ProtegoJavaCodeAnalysisFunction.Arn + - '*' + - !Join + - ':' + - - !GetAtt ProtegoPython3CodeAnalysisFunction.Arn + - '*' + - !Join + - ':' + - - !GetAtt ProtegoCSharpCodeAnalysisFunction.Arn + - '*' + - !Join + - ':' + - - !GetAtt ProtegoFSPInjectorFunction.Arn + - '*' + - !Sub >- + arn:aws:lambda:*:${AWS::AccountId}:function:CloudGuardFSPLogsSender* + - !Sub >- + arn:aws:lambda:*:${AWS::AccountId}:function:ProtegoFSPLogsSender* + ProtegoPython3CodeAnalysisLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: /aws/lambda/CloudGuardPy3CodeAnalysis + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + ProtegoJavaCodeAnalysisLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: /aws/lambda/CloudGuardJavaCodeAnalysis + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + ProtegoNode14CodeAnalysisLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: /aws/lambda/CloudGuardNode14CodeAnalysis + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + ProtegoCSharpCodeAnalysisLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: /aws/lambda/CloudGuardCsCodeAnalysis + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + ProtegoFSPInjectorLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: /aws/lambda/CloudGuardFSPInjector + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + CodeAnalysisLambdaExecutionRole: + Type: AWS::IAM::Role + Properties: + RoleName: CloudGuardServerlessCodeAnalysisLambdaExecutionRole + Path: / + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: CodeAnalysisLambdaExecutionPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !GetAtt ProtegoPython3CodeAnalysisLogGroup.Arn + - !GetAtt ProtegoJavaCodeAnalysisLogGroup.Arn + - !GetAtt ProtegoNode14CodeAnalysisLogGroup.Arn + - !GetAtt ProtegoCSharpCodeAnalysisLogGroup.Arn + - Effect: Allow + Action: + - lambda:GetFunction + - lambda:ListLayers + - lambda:GetLayerVersion + - lambda:ListLayerVersions + Resource: '*' + FSPInjectorLambdaExecutionRole: + Type: AWS::IAM::Role + Properties: + RoleName: CloudGuardServerlessFSPInjectorLambdaExecutionRole + Path: / + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: FSPInjectorLambdaExecutionPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !GetAtt ProtegoFSPInjectorLogGroup.Arn + - Effect: Allow + Action: + - lambda:GetFunction + - lambda:GetFunctionConfiguration + - lambda:ListLayers + - lambda:GetLayerVersion + - lambda:ListLayerVersions + - lambda:UpdateFunctionConfiguration + - lambda:UpdateFunctionCode + Resource: '*' + ProtegoPython3CodeAnalysisFunction: + Type: AWS::Lambda::Function + Properties: + Handler: function_code_analysis_python.lambda_handler + FunctionName: CloudGuardPy3CodeAnalysis + Role: !GetAtt CodeAnalysisLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: !Sub >- + code_analysis_functions/${ServerlessStage}_function_code_analysis_python3.zip + MemorySize: 3008 + Description: Statically analyze Python code + Runtime: python3.8 + Timeout: 860 + Tags: + - Key: Owner + Value: Cloudguard Serverless Security + DependsOn: + - CodeAnalysisLambdaExecutionRole + ProtegoJavaCodeAnalysisFunction: + Type: AWS::Lambda::Function + Properties: + Handler: io.protego.lambda.Handler + FunctionName: CloudGuardJavaCodeAnalysis + Role: !GetAtt CodeAnalysisLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: code_analysis_functions/function_api_usage_java-1.0.jar + MemorySize: 3008 + Description: Statically analyze Java code + Runtime: java11 + Timeout: 860 + Tags: + - Key: Owner + Value: Cloudguard Serverless Security + DependsOn: + - CodeAnalysisLambdaExecutionRole + ProtegoNode14CodeAnalysisFunction: + Type: AWS::Lambda::Function + Properties: + Handler: index.handler + FunctionName: CloudGuardNode14CodeAnalysis + Role: !GetAtt CodeAnalysisLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: !Sub >- + code_analysis_functions/${ServerlessStage}_function_code_analysis_node.zip + MemorySize: 4096 + Description: Statically analyze NodeJs code + Runtime: nodejs14.x + Timeout: 860 + Tags: + - Key: Owner + Value: Cloudguard Serverless Security + Layers: + - !Sub >- + arn:aws:lambda:${AWS::Region}:985618988812:layer:aws-lambda-layer-java:1 + DependsOn: + - CodeAnalysisLambdaExecutionRole + ProtegoCSharpCodeAnalysisFunction: + Type: AWS::Lambda::Function + Properties: + Handler: >- + function_api_usage_c_sharp::function_api_usage_c_sharp.Handler::HandleRequest + FunctionName: CloudGuardCsCodeAnalysis + Role: !GetAtt CodeAnalysisLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: code_analysis_functions/function_api_usage_c_sharp.zip + MemorySize: 1024 + Description: Statically analyze C# code + Runtime: dotnetcore3.1 + Timeout: 860 + Tags: + - Key: Owner + Value: Cloudguard Serverless Security + DependsOn: + - CodeAnalysisLambdaExecutionRole + ProtegoFSPInjectorFunction: + Type: AWS::Lambda::Function + Properties: + Handler: cloudguard.fspinjector.Handler::handleRequest + FunctionName: CloudGuardFSPInjector + Role: !GetAtt FSPInjectorLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: !Sub >- + code_analysis_functions/${ServerlessStage}_fsp_injector_min_template_v9.zip + MemorySize: 3008 + Description: FSP injector, add FSP runtime protection to functions + Runtime: java11 + Layers: + - !Sub arn:aws:lambda:${AWS::Region}:553035198032:layer:nodejs12:21 + - !Sub >- + arn:aws:lambda:${AWS::Region}:985618988812:layer:aws-lambda-layer-csharp:1 + Timeout: 860 + Tags: + - Key: Owner + Value: Cloudguard Serverless Security + DependsOn: + - FSPInjectorLambdaExecutionRole + ProtegoAgentBucket: + Type: AWS::S3::Bucket + Condition: IsProtegoRegionCondition + Properties: + BucketName: !Sub protego-fsp-${AWS::AccountId} + BucketEncryption: + ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: AES256 + PublicAccessBlockConfiguration: + BlockPublicAcls: true + BlockPublicPolicy: true + RestrictPublicBuckets: true + IgnorePublicAcls: true + DependsOn: + - PreDeployPhoneHomeCustomResource + ProtegoAgentBucketPolicy: + Type: AWS::S3::BucketPolicy + Properties: + Bucket: !Ref ProtegoAgentBucket + PolicyDocument: + Statement: + - Sid: ProtegoOnlySecureTransport + Effect: Deny + Principal: '*' + Action: '*' + Resource: !Sub arn:aws:s3:::${ProtegoAgentBucket}/* + Condition: + Bool: + aws:SecureTransport: 'false' + - Sid: ProtegoPermissions + Effect: Allow + Principal: '*' + Action: + - s3:ListBucket + - s3:GetObject + Resource: + - !Sub arn:aws:s3:::${ProtegoAgentBucket} + - !Sub arn:aws:s3:::${ProtegoAgentBucket}/* + Condition: + StringEquals: + aws:PrincipalAccount: !Ref AWS::AccountId + ProtegoAgentPolicy: + Type: AWS::IAM::Policy + Properties: + PolicyName: CloudguardFSPPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - s3:GetBucketPolicy + - s3:ListBucket + - s3:PutBucketPolicy + - s3:DeleteBucketPolicy + Resource: !Sub arn:aws:s3:::${ProtegoAgentBucket} + - Effect: Allow + Action: + - s3:DeleteObject + - s3:GetObject + - s3:PutObject + Resource: !Sub arn:aws:s3:::${ProtegoAgentBucket}/* + - Effect: Allow + Action: + - logs:PutSubscriptionFilter + - logs:DeleteSubscriptionFilter + - logs:DescribeSubscriptionFilters + - logs:DescribeLogGroups + Resource: !Sub 'arn:aws:logs:*:${AWS::AccountId}:log-group:*:' + Roles: + - !Ref CrossAccountRole + ProtegoFSPLogsPolicy: + Type: AWS::IAM::Policy + Properties: + PolicyName: CloudguardFSPLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - lambda:CreateFunction + - lambda:DeleteFunction + - lambda:AddPermission + Resource: + - !Sub >- + arn:aws:lambda:*:${AWS::AccountId}:function:CloudGuardFSPLogsSender* + - !Sub >- + arn:aws:lambda:*:${AWS::AccountId}:function:ProtegoFSPLogsSender* + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:PutRetentionPolicy + - logs:DeleteLogGroup + Resource: + - !Sub >- + arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardFSPLogsSender*:* + - !Sub >- + arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/ProtegoFSPLogsSender*:* + - Effect: Allow + Action: + - iam:PassRole + Resource: !GetAtt ProtegoFSPLogsSenderRole.Arn + Roles: + - !Ref CrossAccountRole + ProtegoFSPLogsSenderRole: + Type: AWS::IAM::Role + Properties: + RoleName: CloudGuardFSPLogsSenderRole + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: ProtegoFSPLogsSenderPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub >- + arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardFSPLogsSender*:* + - !Sub >- + arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/ProtegoFSPLogsSender*:* + - Effect: Allow + Action: + - sqs:GetQueueUrl + - sqs:SendMessage + Resource: !Sub >- + arn:aws:sqs:${AWS::Region}:${CloudGuardAwsAccountId}:${ServerlessStage}_customer_fsp_logs_queue* + DependsOn: + - PreDeployPhoneHomeCustomResource + PreDeployPhoneHomeCustomResource: + Type: Custom::PhoneHomeCustomResource + Condition: IsProtegoRegionCondition + Version: '1.0' + Properties: + ServiceToken: !Sub >- + arn:aws:sns:${AWS::Region}:${CloudGuardAwsAccountId}:${ServerlessStage}-${AWS::AccountId}-notifications + AccountID: !Ref AWS::AccountId + TimeStamp: !Ref TimeStamp + CFTemplateVersion: 23 + PhoneHomeCustomResourceNew: + Type: Custom::PhoneHomeCustomResource + Version: '1.0' + DependsOn: + - CrossAccountRole + - ProtegoAgentPolicy + - ProtegoFSPLogsPolicy + - ProtegoFSPLogsSenderRole + - ProtegoAgentBucketPolicy + Properties: + ServiceToken: !Sub >- + arn:aws:sns:${AWS::Region}:${CloudGuardAwsAccountId}:${ServerlessStage}-${AWS::AccountId}-notifications + RoleArn: !GetAtt CrossAccountRole.Arn + AccountID: !Ref AWS::AccountId + TimeStamp: !Ref TimeStamp + CFTemplateVersion: 23 + ProtegoFSPLambdaRoleARN: !GetAtt ProtegoFSPLogsSenderRole.Arn + Features: + ProtegoBase: true + ProtegoFSP: true + ProtegoFSPInjector: true + Python3CodeAnalysisFunc: !GetAtt ProtegoPython3CodeAnalysisFunction.Arn + JavaCodeAnalysisFunc: !GetAtt ProtegoJavaCodeAnalysisFunction.Arn + NodeCodeAnalysisFunc: !GetAtt ProtegoNode14CodeAnalysisFunction.Arn + CSharpCodeAnalysisFunc: !GetAtt ProtegoCSharpCodeAnalysisFunction.Arn + FSPInjectorFunc: !GetAtt ProtegoFSPInjectorFunction.Arn +Outputs: + RoleARN: + Description: The ARN of the role that can be assumed by the other account. + Value: !GetAtt CrossAccountRole.Arn + ProtegoFSPLambdaRoleARN: + Description: >- + The ARN of the role that can be used by protego fsp logs sender lambda in + customer account. + Value: !GetAtt ProtegoFSPLogsSenderRole.Arn + FSPInjectorLambdaRoleARN: + Description: >- + The ARN of the role that is used by fsp injector lambda in customer + account. + Value: !GetAtt FSPInjectorLambdaExecutionRole.Arn + CodeAnalysisLambdaRoleARN: + Description: >- + The ARN of the role that is used by all code analysis lambdas in customer + account. + Value: !GetAtt CodeAnalysisLambdaExecutionRole.Arn diff --git a/cft/generated/templates/user_based/onboarding.yml b/cft/generated/templates/user_based/onboarding.yml index 1dfb8cc..5bfcedf 100644 --- a/cft/generated/templates/user_based/onboarding.yml +++ b/cft/generated/templates/user_based/onboarding.yml @@ -1,7 +1,7 @@ AWSTemplateFormatVersion: 2010-09-09 Description: Check Point CloudGuard Dome9 unified onboarding Metadata: - Version: 2.0.0 + Version: 2.6.0 Parameters: S3BucketName: Description: The S3 Bucket @@ -89,8 +89,9 @@ Resources: - iam:DeleteRole - iam:DetachRolePolicy - iam:DeleteRolePolicy + - iam:PutRolePolicy Resource: !Sub >- - arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Lambda-CloudFormation-role${UniqueSuffix} + arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Onboarding-Orchestrator-role${UniqueSuffix} - Sid: LambdaRemovePermission Effect: Allow Action: lambda:RemovePermission @@ -120,7 +121,7 @@ Resources: Type: AWS::CloudFormation::WaitConditionHandle Waiter: Type: AWS::CloudFormation::WaitConditionHandle - StackModifyCrossAccountUserIfEnabledWaitCondition: + StackModifyIfEnabledWaitCondition: Type: AWS::CloudFormation::WaitCondition Properties: Handle: !If @@ -129,11 +130,11 @@ Resources: - !Ref Waiter Timeout: '1' Count: 0 - CloudGuardLambdaStackCreationRole: + CloudGuardOrchestratorRole: Type: AWS::IAM::Role - DependsOn: StackModifyCrossAccountUserIfEnabledWaitCondition + DependsOn: StackModifyIfEnabledWaitCondition Properties: - RoleName: !Sub CloudGuard-Lambda-CloudFormation-role${UniqueSuffix} + RoleName: !Sub CloudGuard-Onboarding-Orchestrator-role${UniqueSuffix} AssumeRolePolicyDocument: Version: 2012-10-17 Statement: @@ -144,27 +145,69 @@ Resources: Action: - sts:AssumeRole Policies: - - PolicyName: !Sub CloudGuard-Lambda-CloudFormation-policy${UniqueSuffix} + - PolicyName: !Sub CloudGuard-Onboarding-Orchestrator-policy${UniqueSuffix} PolicyDocument: Version: 2012-10-17 Statement: - - Sid: CloudGuardLambdaCloudFormation + - Sid: CloudGuardOnboardingOrchestratorCloudformation Action: - - '*' + - cloudformation:CreateStack + - cloudformation:DescribeStacks + - cloudformation:DeleteStack + - cloudformation:CreateChangeSet + - cloudformation:ExecuteChangeSet + - cloudformation:DeleteChangeSet + - cloudformation:DescribeChangeSet + Effect: Allow + Resource: + - !Sub >- + arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/CloudGuard-Onboarding* + - Sid: CloudGuardOnboardingOrchestratorCloudformationList + Action: + - cloudformation:ListStacks + Effect: Allow + Resource: !Sub >- + arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/*/* + - Sid: CloudGuardOnboardingOrchestratorIamListAccount + Action: + - iam:ListAccountAliases Effect: Allow Resource: '*' - - PolicyName: !Sub CloudGuard-Lambda-GetCloudGuardApiKeys-policy${UniqueSuffix} - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow + - Sid: CloudGuardOnboardingOrchestratorIam Action: - - secretsmanager:* + - iam:GetUser + - iam:CreateUser + - iam:DeleteUser + - iam:PutUserPolicy + - iam:DetachUserPolicy + - iam:AttachUserPolicy + - iam:DeleteUserPolicy + - iam:getUserPolicy + - iam:CreateAccessKey + - iam:DeleteAccessKey + - iam:ListAccessKeys + Effect: Allow + Resource: + - !Sub >- + arn:${AWS::Partition}:iam::${AWS::AccountId}:user/CloudGuard-Connect-RO-user${UniqueSuffix} + - !Sub >- + arn:${AWS::Partition}:iam::${AWS::AccountId}:user/CloudGuard-Connect-RW-user${UniqueSuffix} + - Sid: CloudGuardOnboardingOrchestratorSecretsmanagerList + Action: + - secretsmanager:ListSecrets + Effect: Allow + Resource: '*' + - Sid: CloudGuardOnboardingOrchestratorSecretsmanager + Action: + - secretsmanager:GetSecretValue + - secretsmanager:CreateSecret + - secretsmanager:DeleteSecret + Effect: Allow Resource: - !Sub >- - arn:${AWS::Partition}:secretsmanager:*:*:secret:CloudGuardCrossAccountUserCredentials-* + arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:CloudGuardCrossAccountUserCredentials-* - !Sub >- - arn:${AWS::Partition}:secretsmanager:*:*:secret:CloudGuardStackModifyCrossAccountUserCredentials-* + arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:CloudGuardStackModifyCrossAccountUserCredentials-* ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole CloudGuardOnboardingOrchestrator: @@ -172,7 +215,7 @@ Resources: Properties: FunctionName: !Sub CloudGuardOnboardingOrchestrator${UniqueSuffix} Runtime: dotnetcore3.1 - Role: !GetAtt CloudGuardLambdaStackCreationRole.Arn + Role: !GetAtt CloudGuardOrchestratorRole.Arn Handler: >- Dome9.CloudGuardOnboarding.Orchestrator::Dome9.CloudGuardOnboarding.Orchestrator.Function::FunctionHandler Timeout: 900 diff --git a/cft/replacements/metadata.yml b/cft/replacements/metadata.yml new file mode 100644 index 0000000..9996650 --- /dev/null +++ b/cft/replacements/metadata.yml @@ -0,0 +1,2 @@ +Metadata: + Version: 2.6.0 \ No newline at end of file diff --git a/cft/replacements/orchestartor_role.yml b/cft/replacements/orchestartor_role.yml new file mode 100644 index 0000000..1959f2e --- /dev/null +++ b/cft/replacements/orchestartor_role.yml @@ -0,0 +1,45 @@ +CloudGuardOrchestratorRole: + Type: AWS::IAM::Role + DependsOn: StackModifyIfEnabledWaitCondition + Properties: + RoleName: !Sub 'CloudGuard-Onboarding-Orchestrator-role${UniqueSuffix}' + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - 'sts:AssumeRole' + Policies: + - PolicyName: !Sub 'CloudGuard-Onboarding-Orchestrator-policy${UniqueSuffix}' + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: CloudGuardOnboardingOrchestratorCloudformation + Action: + - 'cloudformation:CreateStack' + - 'cloudformation:DescribeStacks' + - 'cloudformation:DeleteStack' + - 'cloudformation:CreateChangeSet' + - 'cloudformation:ExecuteChangeSet' + - 'cloudformation:DeleteChangeSet' + - 'cloudformation:DescribeChangeSet' + Effect: Allow + Resource: + - !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/CloudGuard-Onboarding*' + - Sid: CloudGuardOnboardingOrchestratorCloudformationList + Action: + - 'cloudformation:ListStacks' + Effect: Allow + Resource: !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/*/*' + - Sid: CloudGuardOnboardingOrchestratorIamListAccount + Action: + - 'iam:ListAccountAliases' + Effect: Allow + Resource: '*' + - REPLACEMENT_ORCHESTRATOR_ROLE_POLICY_STATEMENTS + + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole \ No newline at end of file diff --git a/cft/replacements/orchestrator.yml b/cft/replacements/orchestrator.yml index 9af712f..bbf86a5 100644 --- a/cft/replacements/orchestrator.yml +++ b/cft/replacements/orchestrator.yml @@ -3,7 +3,7 @@ CloudGuardOnboardingOrchestrator: Properties: FunctionName: !Sub 'CloudGuardOnboardingOrchestrator${UniqueSuffix}' Runtime: dotnetcore3.1 - Role: !GetAtt CloudGuardLambdaStackCreationRole.Arn + Role: !GetAtt CloudGuardOrchestratorRole.Arn Handler: Dome9.CloudGuardOnboarding.Orchestrator::Dome9.CloudGuardOnboarding.Orchestrator.Function::FunctionHandler Timeout: 900 Code: diff --git a/cft/replacements/role_based_orchestrator_role_policy_statements.yml b/cft/replacements/role_based_orchestrator_role_policy_statements.yml new file mode 100644 index 0000000..7d51941 --- /dev/null +++ b/cft/replacements/role_based_orchestrator_role_policy_statements.yml @@ -0,0 +1,107 @@ +- Sid: CloudGuardOnboardingOrchestratorIam + Action: + - 'iam:GetRole' + - 'iam:CreateRole' + - 'iam:DeleteRole' + - 'iam:PutRolePolicy' + - 'iam:DetachRolePolicy' + - 'iam:AttachRolePolicy' + - 'iam:DeleteRolePolicy' + - 'iam:getRolePolicy' + - 'iam:UpdateRole' + - 'iam:TagRole' + - 'iam:UntagRole' + - 'iam:DeleteRolePolicy' + - 'iam:PassRole' + Effect: Allow + Resource: + - !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Connect-RO-role${UniqueSuffix}' + - !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Connect-RW-role${UniqueSuffix}' + - !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuardFSPLogsSenderRole' + - !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuardServerlessCrossAccountRole' + - !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuardServerlessCodeAnalysisLambdaExecutionRole' + - !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuardServerlessFSPInjectorLambdaExecutionRole' +- Sid: CloudGuardOnboardingOrchestratorIntelligenceCloudtrail + Action: + - 'cloudtrail:DescribeTrails' + Effect: Allow + Resource: '*' +- Sid: CloudGuardOnboardingOrchestratorIntelligenceS3 + Action: + - 's3:GetBucketLocation' + - 's3:GetBucketNotification' + - 's3:PutBucketNotification' + Effect: Allow + Resource: '*' +- Sid: CloudGuardOnboardingOrchestratorServelessLambda + Action: + - 'lambda:GetFunction' + - 'lambda:GetFunctionConfiguration' + - 'lambda:TagResource' + - 'lambda:UntagResource' + - 'lambda:CreateFunction' + - 'lambda:DeleteFunction' + - 'lambda:UpdateFunctionCode' + - 'lambda:UpdateFunctionConfiguration' + - 'lambda:GetFunctionConfiguration' + Effect: Allow + Resource: + - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardNode14CodeAnalysis' + - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardJavaCodeAnalysis' + - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardPy3CodeAnalysis' + - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardCsCodeAnalysis' + - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CloudGuardFSPInjector' +- Sid: CloudGuardOnboardingOrchestratorServelessLambdaTp + Action: + - lambda:GetLayerVersion + Effect: Allow + Resource: + - !Sub 'arn:aws:lambda:${AWS::Region}:553035198032:layer:nodejs12:21' + - !Sub 'arn:aws:lambda:${AWS::Region}:985618988812:layer:aws-lambda-layer-csharp:*' + - !Sub 'arn:aws:lambda:${AWS::Region}:985618988812:layer:aws-lambda-layer-java:*' +- Sid: CloudGuardOnboardingOrchestratorServelessLogs + Action: + - logs:DescribeLogGroups + - logs:CreateLogGroup + - logs:DeleteLogGroup + - logs:CreateLogStream + - logs:PutRetentionPolicy + Effect: Allow + Resource: + - !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardNode14CodeAnalysis:log-stream:*' + - !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardJavaCodeAnalysis:log-stream:*' + - !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardPy3CodeAnalysis:log-stream:*' + - !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardCsCodeAnalysis:log-stream:*' + - !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardFSPInjector:log-stream:*' +- Sid: CloudGuardOnboardingOrchestratorLogsDescribe + Action: + - logs:DescribeLogGroups + Effect: Allow + Resource: !Sub 'arn:aws:logs:*:${AWS::AccountId}:log-group:*:' +- Sid: CloudGuardOnboardingOrchestratorServelessProtegoS3 + Action: + - s3:GetObject + Effect: Allow + Resource: + - !Sub 'arn:aws:s3:::${ServerlessStage}-protego/code_analysis_functions/*' +- Sid: CloudGuardOnboardingOrchestratorServelessS3 + Action: + - s3:GetBucketPolicy + - s3:CreateBucket + - s3:PutObject + - s3:PutBucketPolicy + - s3:DeleteObject + - s3:DeleteBucketPolicy + - s3:DeleteBucket + - s3:PutEncryptionConfiguration + - s3:PutBucketPublicAccessBlock + Effect: Allow + Resource: + - !Sub 'arn:aws:s3:::protego-fsp-${AWS::AccountId}' + - !Sub 'arn:aws:s3:::protego-fsp-${AWS::AccountId}/*' +- Sid: CloudGuardOnboardingOrchestratorServelessSns + Action: + - sns:Publish + Effect: Allow + Resource: + - !Sub 'arn:aws:sns:${AWS::Region}:${CloudGuardAwsAccountNumber}:${ServerlessStage}-${AWS::AccountId}-notifications' diff --git a/cft/replacements/stack_modify_policy_statements.yml b/cft/replacements/stack_modify_policy_statements.yml index e9ac6e3..999358c 100644 --- a/cft/replacements/stack_modify_policy_statements.yml +++ b/cft/replacements/stack_modify_policy_statements.yml @@ -20,7 +20,7 @@ - iam:DetachRolePolicy - iam:DeleteRolePolicy - iam:PutRolePolicy - Resource: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Lambda-CloudFormation-role${UniqueSuffix}' + Resource: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/CloudGuard-Onboarding-Orchestrator-role${UniqueSuffix}' - Sid: LambdaRemovePermission Effect: Allow Action: lambda:RemovePermission diff --git a/cft/replacements/user_based_orchestrator_role_policy_statements.yml b/cft/replacements/user_based_orchestrator_role_policy_statements.yml new file mode 100644 index 0000000..3ee0413 --- /dev/null +++ b/cft/replacements/user_based_orchestrator_role_policy_statements.yml @@ -0,0 +1,31 @@ +- Sid: CloudGuardOnboardingOrchestratorIam + Action: + - 'iam:GetUser' + - 'iam:CreateUser' + - 'iam:DeleteUser' + - 'iam:PutUserPolicy' + - 'iam:DetachUserPolicy' + - 'iam:AttachUserPolicy' + - 'iam:DeleteUserPolicy' + - 'iam:getUserPolicy' + - 'iam:CreateAccessKey' + - 'iam:DeleteAccessKey' + - 'iam:ListAccessKeys' + Effect: Allow + Resource: + - !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:user/CloudGuard-Connect-RO-user${UniqueSuffix}' + - !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:user/CloudGuard-Connect-RW-user${UniqueSuffix}' +- Sid: CloudGuardOnboardingOrchestratorSecretsmanagerList + Action: + - 'secretsmanager:ListSecrets' + Effect: Allow + Resource: '*' +- Sid: CloudGuardOnboardingOrchestratorSecretsmanager + Action: + - 'secretsmanager:GetSecretValue' + - 'secretsmanager:CreateSecret' + - 'secretsmanager:DeleteSecret' + Effect: Allow + Resource: + - !Sub 'arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:CloudGuardCrossAccountUserCredentials-*' + - !Sub 'arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:CloudGuardStackModifyCrossAccountUserCredentials-*' \ No newline at end of file diff --git a/cft/role_based/onboarding.yml b/cft/role_based/onboarding.yml index f84dc3e..14e6161 100644 --- a/cft/role_based/onboarding.yml +++ b/cft/role_based/onboarding.yml @@ -1,7 +1,6 @@ AWSTemplateFormatVersion: '2010-09-09' Description: 'Check Point CloudGuard Dome9 unified onboarding' -Metadata: - Version: 2.0.0 +REPLACEMENT_METADATA: Parameters: REPLACEMENT_PARAMETERS: @@ -11,6 +10,9 @@ Parameters: CloudGuardAwsAccountNumber: Description: The CloudGuard AWS account number Type: String + ServerlessStage: + Description: The Serverless stage name + Type: String Conditions: RemoteStackModifyEnabled: !Equals @@ -58,40 +60,14 @@ Resources: Waiter: Type: "AWS::CloudFormation::WaitConditionHandle" - StackModifyRoleIfEnabledWaitCondition: + StackModifyIfEnabledWaitCondition: Type: "AWS::CloudFormation::WaitCondition" Properties: Handle: !If [RemoteStackModifyEnabled, !Ref StackModifyRoleWaiter, !Ref Waiter] Timeout: '1' Count: 0 - - CloudGuardLambdaStackCreationRole: - Type: AWS::IAM::Role - DependsOn: StackModifyRoleIfEnabledWaitCondition - Properties: - RoleName: !Sub 'CloudGuard-Lambda-CloudFormation-role${UniqueSuffix}' - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Principal: - Service: - - lambda.amazonaws.com - Action: - - 'sts:AssumeRole' - Policies: - - PolicyName: !Sub 'CloudGuard-Lambda-CloudFormation-policy${UniqueSuffix}' - PolicyDocument: - Version: 2012-10-17 - Statement: - - Sid: CloudGuardLambdaCloudFormation - Action: - - '*' - Effect: Allow - Resource: '*' - ManagedPolicyArns: - - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole + REPLACEMENT_ORCHESTRATOR_ROLE: REPLACEMENT_ORCHESTRATOR: diff --git a/cft/role_based/serverless_cft.yml b/cft/role_based/serverless_cft.yml new file mode 100644 index 0000000..ec2e50e --- /dev/null +++ b/cft/role_based/serverless_cft.yml @@ -0,0 +1,491 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: 'Create a cross account role that authorizes access for Cloudguard BE.' +REPLACEMENT_METADATA: + +Parameters: + CloudGuardAwsAccountId: + Description: CloudGuard instance AWS AccountId that is requiring external trust + Type: String + ServerlessStage: + Description: The Serverless stage name + Type: String + TimeStamp: + Description: The current TimeStamp running TimeStamp + Type: String + ServerlessRegion: + Description: The Serverless region + Type: String + +Conditions: + IsProtegoRegionCondition: + Fn::Equals: + - !Sub "${AWS::Region}" + - !Ref ServerlessRegion + +Resources: + CrossAccountRole: + Type: AWS::IAM::Role + Properties: + RoleName: 'CloudGuardServerlessCrossAccountRole' + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + # https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html + AWS: + - !Ref CloudGuardAwsAccountId + Action: sts:AssumeRole + Condition: + StringEquals: + sts:ExternalId: + Fn::Base64: !Sub ${AWS::AccountId} + ManagedPolicyArns: + - arn:aws:iam::aws:policy/ReadOnlyAccess + + Policies: + - PolicyName: CrossAccountCustomerRO + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - lambda:InvokeFunction + - lambda:GetFunction + - lambda:GetLayerVersion + - lambda:UpdateFunctionConfiguration + - lambda:TagResource + - lambda:ListTags + - lambda:UntagResource + + Resource: + - !GetAtt ProtegoNode14CodeAnalysisFunction.Arn + - !GetAtt ProtegoJavaCodeAnalysisFunction.Arn + - !GetAtt ProtegoPython3CodeAnalysisFunction.Arn + - !GetAtt ProtegoCSharpCodeAnalysisFunction.Arn + - !GetAtt ProtegoFSPInjectorFunction.Arn + + - Effect: Allow + Action: + - lambda:UpdateFunctionCode + - lambda:UpdateFunctionConfiguration + Resource: + - !Join [ ":", [ !GetAtt ProtegoNode14CodeAnalysisFunction.Arn,"*"]] + - !Join [ ":", [ !GetAtt ProtegoJavaCodeAnalysisFunction.Arn ,"*"]] + - !Join [ ":", [ !GetAtt ProtegoPython3CodeAnalysisFunction.Arn,"*"]] + - !Join [ ":", [ !GetAtt ProtegoCSharpCodeAnalysisFunction.Arn,"*"]] + - !Join [ ":", [ !GetAtt ProtegoFSPInjectorFunction.Arn,"*"]] + - !Sub 'arn:aws:lambda:*:${AWS::AccountId}:function:CloudGuardFSPLogsSender*' + - !Sub 'arn:aws:lambda:*:${AWS::AccountId}:function:ProtegoFSPLogsSender*' + + ## + # Protego is installing on your account a Code - Analysis Lambda for each runtime language + # Java, Python, NodeJs and C# + # each of this Lambda require also a LogGroup + # + ProtegoPython3CodeAnalysisLogGroup: + Type: "AWS::Logs::LogGroup" + Properties: + LogGroupName: '/aws/lambda/CloudGuardPy3CodeAnalysis' + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + + ProtegoJavaCodeAnalysisLogGroup: + Type: "AWS::Logs::LogGroup" + Properties: + LogGroupName: '/aws/lambda/CloudGuardJavaCodeAnalysis' + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + + ProtegoNode14CodeAnalysisLogGroup: + Type: "AWS::Logs::LogGroup" + Properties: + LogGroupName: '/aws/lambda/CloudGuardNode14CodeAnalysis' + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + + ProtegoCSharpCodeAnalysisLogGroup: + Type: "AWS::Logs::LogGroup" + Properties: + LogGroupName: '/aws/lambda/CloudGuardCsCodeAnalysis' + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + + ProtegoFSPInjectorLogGroup: + Type: "AWS::Logs::LogGroup" + Properties: + LogGroupName: '/aws/lambda/CloudGuardFSPInjector' + RetentionInDays: 30 + DependsOn: + - PreDeployPhoneHomeCustomResource + + ## + # The Execution Role for these Code Analysis Lambdas + # + CodeAnalysisLambdaExecutionRole: + Type: 'AWS::IAM::Role' + Properties: + RoleName: 'CloudGuardServerlessCodeAnalysisLambdaExecutionRole' + Path: / + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - 'sts:AssumeRole' + Policies: + - PolicyName: CodeAnalysisLambdaExecutionPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + + - Effect: Allow + Action: + - 'logs:CreateLogStream' + - 'logs:PutLogEvents' + Resource: + - !GetAtt ProtegoPython3CodeAnalysisLogGroup.Arn + - !GetAtt ProtegoJavaCodeAnalysisLogGroup.Arn + - !GetAtt ProtegoNode14CodeAnalysisLogGroup.Arn + - !GetAtt ProtegoCSharpCodeAnalysisLogGroup.Arn + - Effect: Allow + Action: + - 'lambda:GetFunction' + - 'lambda:ListLayers' + - 'lambda:GetLayerVersion' + - 'lambda:ListLayerVersions' + Resource: '*' + + ## + # The Execution Role for these FSP Injector Lambda + # + FSPInjectorLambdaExecutionRole: + Type: 'AWS::IAM::Role' + Properties: + RoleName: 'CloudGuardServerlessFSPInjectorLambdaExecutionRole' + Path: / + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - 'sts:AssumeRole' + Policies: + - PolicyName: FSPInjectorLambdaExecutionPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + + - Effect: Allow + Action: + - 'logs:CreateLogStream' + - 'logs:PutLogEvents' + Resource: + - !GetAtt ProtegoFSPInjectorLogGroup.Arn + - Effect: Allow + Action: + - 'lambda:GetFunction' + - 'lambda:GetFunctionConfiguration' + - 'lambda:ListLayers' + - 'lambda:GetLayerVersion' + - 'lambda:ListLayerVersions' + - 'lambda:UpdateFunctionConfiguration' + - 'lambda:UpdateFunctionCode' + Resource: '*' + + ProtegoPython3CodeAnalysisFunction: + Type: 'AWS::Lambda::Function' + Properties: + Handler: function_code_analysis_python.lambda_handler + FunctionName: 'CloudGuardPy3CodeAnalysis' + Role: !GetAtt CodeAnalysisLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: !Sub code_analysis_functions/${ServerlessStage}_function_code_analysis_python3.zip + MemorySize: 3008 + Description: 'Statically analyze Python code' + Runtime: python3.8 + Timeout: 860 + Tags: [{"Key": "Owner", "Value": "Cloudguard Serverless Security"}] + DependsOn: + - CodeAnalysisLambdaExecutionRole + + ProtegoJavaCodeAnalysisFunction: + Type: 'AWS::Lambda::Function' + Properties: + Handler: io.protego.lambda.Handler + FunctionName: 'CloudGuardJavaCodeAnalysis' + Role: !GetAtt CodeAnalysisLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: code_analysis_functions/function_api_usage_java-1.0.jar + MemorySize: 3008 + Description: 'Statically analyze Java code' + Runtime: java11 + Timeout: 860 + Tags: [{"Key": "Owner", "Value": "Cloudguard Serverless Security"}] + DependsOn: + - CodeAnalysisLambdaExecutionRole + + ProtegoNode14CodeAnalysisFunction: + Type: 'AWS::Lambda::Function' + Properties: + Handler: index.handler + FunctionName: 'CloudGuardNode14CodeAnalysis' + Role: !GetAtt CodeAnalysisLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: !Sub code_analysis_functions/${ServerlessStage}_function_code_analysis_node.zip + MemorySize: 4096 + Description: 'Statically analyze NodeJs code' + Runtime: nodejs14.x + Timeout: 860 + Tags: [{"Key": "Owner", "Value": "Cloudguard Serverless Security"}] + Layers: + - !Sub 'arn:aws:lambda:${AWS::Region}:985618988812:layer:aws-lambda-layer-java:1' + DependsOn: + - CodeAnalysisLambdaExecutionRole + + ProtegoCSharpCodeAnalysisFunction: + Type: 'AWS::Lambda::Function' + Properties: + Handler: function_api_usage_c_sharp::function_api_usage_c_sharp.Handler::HandleRequest + FunctionName: 'CloudGuardCsCodeAnalysis' + Role: !GetAtt CodeAnalysisLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: code_analysis_functions/function_api_usage_c_sharp.zip + MemorySize: 1024 + Description: 'Statically analyze C# code' + Runtime: dotnetcore3.1 + Timeout: 860 + Tags: [{"Key": "Owner", "Value": "Cloudguard Serverless Security"}] + DependsOn: + - CodeAnalysisLambdaExecutionRole + + ProtegoFSPInjectorFunction: + Type: 'AWS::Lambda::Function' + Properties: + Handler: cloudguard.fspinjector.Handler::handleRequest + FunctionName: 'CloudGuardFSPInjector' + Role: !GetAtt FSPInjectorLambdaExecutionRole.Arn + Code: + S3Bucket: !Sub ${ServerlessStage}-protego + S3Key: !Sub code_analysis_functions/${ServerlessStage}_fsp_injector_min_template_v9.zip + MemorySize: 3008 + Description: 'FSP injector, add FSP runtime protection to functions' + Runtime: java11 + Layers: + - !Sub 'arn:aws:lambda:${AWS::Region}:553035198032:layer:nodejs12:21' + - !Sub 'arn:aws:lambda:${AWS::Region}:985618988812:layer:aws-lambda-layer-csharp:1' + Timeout: 860 + Tags: [{"Key": "Owner", "Value": "Cloudguard Serverless Security"}] + DependsOn: + - FSPInjectorLambdaExecutionRole + + ## + # @@@ Feature: PROTEGO FSP @@@ + # + ProtegoAgentBucket: + Type: 'AWS::S3::Bucket' + Condition: IsProtegoRegionCondition + Properties: + BucketName: !Sub 'protego-fsp-${AWS::AccountId}' + BucketEncryption: + ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: AES256 + PublicAccessBlockConfiguration: + BlockPublicAcls: true + BlockPublicPolicy: true + RestrictPublicBuckets: true + IgnorePublicAcls: true + DependsOn: + - PreDeployPhoneHomeCustomResource + + + + + ProtegoAgentBucketPolicy: + Type: AWS::S3::BucketPolicy + Properties: + Bucket: !Ref ProtegoAgentBucket + PolicyDocument: + Statement: + - Sid: ProtegoOnlySecureTransport + Effect: Deny + Principal: "*" + Action: "*" + Resource: !Sub 'arn:aws:s3:::${ProtegoAgentBucket}/*' + Condition: + Bool: + aws:SecureTransport: "false" + - Sid: ProtegoPermissions + Effect: Allow + Principal: "*" + Action: + - "s3:ListBucket" + - "s3:GetObject" + Resource: + - !Sub 'arn:aws:s3:::${ProtegoAgentBucket}' + - !Sub 'arn:aws:s3:::${ProtegoAgentBucket}/*' + Condition: + StringEquals: + aws:PrincipalAccount: !Ref AWS::AccountId + + ProtegoAgentPolicy: + Type: AWS::IAM::Policy + Properties: + PolicyName: 'CloudguardFSPPolicy' + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - s3:GetBucketPolicy + - s3:ListBucket + # this permissions are here only to support older accounts. will not be used for new accounts + - s3:PutBucketPolicy + - s3:DeleteBucketPolicy + Resource: !Sub 'arn:aws:s3:::${ProtegoAgentBucket}' + + - Effect: Allow + Action: + - s3:DeleteObject + - s3:GetObject + - s3:PutObject + Resource: !Sub 'arn:aws:s3:::${ProtegoAgentBucket}/*' + - Effect: Allow + Action: + - logs:PutSubscriptionFilter + - logs:DeleteSubscriptionFilter + - logs:DescribeSubscriptionFilters + - logs:DescribeLogGroups + Resource: !Sub 'arn:aws:logs:*:${AWS::AccountId}:log-group:*:' + Roles: + - !Ref CrossAccountRole + + ProtegoFSPLogsPolicy: + Type: AWS::IAM::Policy + Properties: + PolicyName: 'CloudguardFSPLogsPolicy' + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - lambda:CreateFunction + - lambda:DeleteFunction + - lambda:AddPermission + Resource: + - !Sub 'arn:aws:lambda:*:${AWS::AccountId}:function:CloudGuardFSPLogsSender*' + - !Sub 'arn:aws:lambda:*:${AWS::AccountId}:function:ProtegoFSPLogsSender*' + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:PutRetentionPolicy + - logs:DeleteLogGroup + Resource: + - !Sub 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardFSPLogsSender*:*' + - !Sub 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/ProtegoFSPLogsSender*:*' + - Effect: Allow + Action: + - iam:PassRole + Resource: !GetAtt ProtegoFSPLogsSenderRole.Arn + Roles: + - !Ref CrossAccountRole + + ProtegoFSPLogsSenderRole: + Type: 'AWS::IAM::Role' + Properties: + RoleName: 'CloudGuardFSPLogsSenderRole' + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - 'sts:AssumeRole' + Policies: + - PolicyName: 'ProtegoFSPLogsSenderPolicy' + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - 'logs:CreateLogStream' + - 'logs:PutLogEvents' + Resource: + - !Sub 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/CloudGuardFSPLogsSender*:*' + - !Sub 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/ProtegoFSPLogsSender*:*' + - Effect: "Allow" + Action: + - sqs:GetQueueUrl + - sqs:SendMessage + Resource: !Sub 'arn:aws:sqs:${AWS::Region}:${CloudGuardAwsAccountId}:${ServerlessStage}_customer_fsp_logs_queue*' + DependsOn: + - PreDeployPhoneHomeCustomResource + + PreDeployPhoneHomeCustomResource: + Type: Custom::PhoneHomeCustomResource + Condition: IsProtegoRegionCondition + Version: '1.0' + Properties: + ServiceToken: !Sub "arn:aws:sns:${AWS::Region}:${CloudGuardAwsAccountId}:${ServerlessStage}-${AWS::AccountId}-notifications" + AccountID: !Ref AWS::AccountId + TimeStamp: !Ref TimeStamp + CFTemplateVersion: 23 + + PhoneHomeCustomResourceNew: + Type: Custom::PhoneHomeCustomResource + Version: '1.0' + DependsOn: + - CrossAccountRole + - ProtegoAgentPolicy + - ProtegoFSPLogsPolicy + - ProtegoFSPLogsSenderRole + - ProtegoAgentBucketPolicy + + Properties: + ServiceToken: !Sub "arn:aws:sns:${AWS::Region}:${CloudGuardAwsAccountId}:${ServerlessStage}-${AWS::AccountId}-notifications" + RoleArn: !GetAtt CrossAccountRole.Arn + AccountID: !Ref AWS::AccountId + TimeStamp: !Ref TimeStamp + CFTemplateVersion: 23 + ProtegoFSPLambdaRoleARN: !GetAtt ProtegoFSPLogsSenderRole.Arn + + Features: + ProtegoBase: true + ProtegoFSP: true + ProtegoFSPInjector: true + + Python3CodeAnalysisFunc: !GetAtt ProtegoPython3CodeAnalysisFunction.Arn + JavaCodeAnalysisFunc: !GetAtt ProtegoJavaCodeAnalysisFunction.Arn + NodeCodeAnalysisFunc: !GetAtt ProtegoNode14CodeAnalysisFunction.Arn + CSharpCodeAnalysisFunc: !GetAtt ProtegoCSharpCodeAnalysisFunction.Arn + FSPInjectorFunc: !GetAtt ProtegoFSPInjectorFunction.Arn +Outputs: + RoleARN: + Description: The ARN of the role that can be assumed by the other account. + Value: !GetAtt CrossAccountRole.Arn + ProtegoFSPLambdaRoleARN: + Description: The ARN of the role that can be used by protego fsp logs sender lambda in customer account. + Value: !GetAtt ProtegoFSPLogsSenderRole.Arn + FSPInjectorLambdaRoleARN: + Description: The ARN of the role that is used by fsp injector lambda in customer account. + Value: !GetAtt FSPInjectorLambdaExecutionRole.Arn + CodeAnalysisLambdaRoleARN: + Description: The ARN of the role that is used by all code analysis lambdas in customer account. + Value: !GetAtt CodeAnalysisLambdaExecutionRole.Arn \ No newline at end of file diff --git a/cft/user_based/onboarding.yml b/cft/user_based/onboarding.yml index a299d2e..e459678 100644 --- a/cft/user_based/onboarding.yml +++ b/cft/user_based/onboarding.yml @@ -1,7 +1,6 @@ AWSTemplateFormatVersion: '2010-09-09' Description: 'Check Point CloudGuard Dome9 unified onboarding' -Metadata: - Version: 2.0.0 +REPLACEMENT_METADATA: Parameters: REPLACEMENT_PARAMETERS: @@ -63,53 +62,14 @@ Resources: Waiter: Type: "AWS::CloudFormation::WaitConditionHandle" - StackModifyCrossAccountUserIfEnabledWaitCondition: + StackModifyIfEnabledWaitCondition: Type: "AWS::CloudFormation::WaitCondition" Properties: Handle: !If [RemoteStackModifyEnabled, !Ref StackModifyCrossAccountUserWaiter, !Ref Waiter] Timeout: '1' Count: 0 - CloudGuardLambdaStackCreationRole: - Type: AWS::IAM::Role - DependsOn: StackModifyCrossAccountUserIfEnabledWaitCondition - Properties: - RoleName: !Sub 'CloudGuard-Lambda-CloudFormation-role${UniqueSuffix}' - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Principal: - Service: - - lambda.amazonaws.com - Action: - - 'sts:AssumeRole' - - Policies: - - - PolicyName: !Sub 'CloudGuard-Lambda-CloudFormation-policy${UniqueSuffix}' - PolicyDocument: - Version: 2012-10-17 - Statement: - - Sid: CloudGuardLambdaCloudFormation - Action: - - '*' - Effect: Allow - Resource: '*' - - - PolicyName: !Sub 'CloudGuard-Lambda-GetCloudGuardApiKeys-policy${UniqueSuffix}' - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - 'secretsmanager:*' - Resource: - - !Sub arn:${AWS::Partition}:secretsmanager:*:*:secret:CloudGuardCrossAccountUserCredentials-* - - !Sub arn:${AWS::Partition}:secretsmanager:*:*:secret:CloudGuardStackModifyCrossAccountUserCredentials-* - - ManagedPolicyArns: - - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole + REPLACEMENT_ORCHESTRATOR_ROLE: REPLACEMENT_ORCHESTRATOR: