Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
4 changes: 3 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"version": "0.2",
"allowCompoundWords": true,
"ignorePaths": [],
"ignorePaths": [
"yarn.lock"
],
"ignoreRegExpList": [
":.*:",
"arn:.*"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const { nodeExternalsPlugin } = require('esbuild-node-externals')
const rimraf = require('rimraf')
const fs = require('fs')
const path = require('path')
const archiver = require('archiver')

const OUT_DIR = 'dist'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
artifact.zip
54 changes: 54 additions & 0 deletions scan-triggers/gcp-nodejs-bucket-full-and-scheduled-scan/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Cloud One File Storage Security Scan Trigger - GCP Full Scan and Scheduled Scan

This plugin is design to perform full scan and schedule scan on GCP cloud storage.

## Prerequest

1. Install File storage security in you GCP environment
1. [Terraform](https://developer.hashicorp.com/terraform/install) (Not needed for cloud shell.)

## Installation

### Using GCP Cloud Shell

[![Open in Cloud Shell](https://gstatic.com/cloudssh/images/open-btn.svg)](https://shell.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Ftrendmicro%2Fcloudone-filestorage-plugins&cloudshell_workspace=scan-triggers%2Fgcp-nodejs-bucket-full-and-scheduled-scan&cloudshell_tutorial=docs%2Ftutorial.md)

### Local machine

1. Initialize terraform

```bash
terraform init
```

1. Deploy the function and fill the variables following the CLI. (Or using the `main.auto.tfvars` file)

```sh
terraform apply
```

Instead of filling in the variables individually, you can create and use a `main.auto.tfvars` file. Enter the variables in to the `main.auto.tfvars.example` file, and then save the file as `main.auto.tfvars`. Once you have created and saved the file, you can reuse the file rather than fill in the variables every time.

1. Remember to save the `terraform.tfstate` file.

### Variables

- **deployment_name**: Name of the deployment. This is used to generate unique suffix for resources created by the plugin.
- **project_id**: GCP project ID which the plugin will be deployed.
- **region**: GCP region to deploy the plugin.
- **scanner_pubsub_topic_project**: GCP project ID which the scanner Pub/Sub topic is deployed. This value can be found in the FSS scanner deploy output **scannerProjectID**.
- **scanner_pubsub_topic**: Scanner Pub/Sub topic name. This value can be found in the FSS scanner deployment output **scannerTopic**.
- **scan_result_topic**: Scan result Pub/Sub topic name. This value can be found in the FSS storage deployment output **scanResultTopic**.
- **scanning_bucket_name**: GCS bucket to perform schedule scan on.
- **schedular_settings**: Settings for the cloud scheduler trigger for workflow. Default to run on every monday at 12:00 AM UTC.
- **trend_micro_fss_bucket_listener_role_id**: Reused custom role used by the bucketListener function to create presigned URL. This value can be found in IAM console page with title `trend-micro-fss-bucket-listener-role`.

## Test plugin

1. Find the deployed workflow. Workflow name can be found in the terraform output **workflow_name**.

1. Execute workflow using the following argument.

```json
{ "bucketName": "<SCANNING_BUCKET_NAME>" }
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Cloud One File Storage Security Full scan and schedule scan plugin for GCP

## Overview

<walkthrough-tutorial-duration duration="10"></walkthrough-tutorial-duration>

This tutorial will guide you to deploy a promote and quarantine function.

## Project Setup

Copy the execute the script below to select the project where the storage stack is deployed.

<walkthrough-project-setup></walkthrough-project-setup>

```sh
gcloud config set project <walkthrough-project-id/>
```

## Deploy full scan and schedule scan plugin

1. Initialize terraform.

```sh
terraform init
```

1. Deploy the function and fill the variables following the CLI. (Or using the `main.auto.tfvars` file)

```sh
terraform apply
```

Instead of filling in the variables individually, you can create and use a `main.auto.tfvars` file. Enter the variables in to the `main.auto.tfvars.example` file, and then save the file as `main.auto.tfvars`. Once you have created and saved the file, you can reuse the file rather than fill in the variables every time.

1. Remember to save the `terraform.tfstate` file.

### Variables

- **deployment_name**: Name of the deployment. This is used to generate unique suffix for resources created by the plugin.
- **project_id**: GCP project ID which the plugin will be deployed.
- **region**: GCP region to deploy the plugin.
- **scanner_pubsub_topic_project**: GCP project ID which the scanner Pub/Sub topic is deployed. This value can be found in the FSS scanner deploy output **scannerProjectID**.
- **scanner_pubsub_topic**: Scanner Pub/Sub topic name. This value can be found in the FSS scanner deployment output **scannerTopic**.
- **scan_result_topic**: Scan result Pub/Sub topic name. This value can be found in the FSS storage deployment output **scanResultTopic**.
- **scanning_bucket_name**: GCS bucket to perform schedule scan on.
- **schedular_settings**: Settings for the cloud scheduler trigger for workflow. Default to run on every monday at 12:00 AM UTC.
- **trend_micro_fss_bucket_listener_role_id**: Reused custom role used by the bucketListener function to create presigned URL. This value can be found in IAM console page with title `trend-micro-fss-bucket-listener-role`.

## Test plugin

1. Find the deployed workflow. Workflow name can be found in the terraform output **workflow_name**.

1. Execute workflow using the following argument.

```json
{ "bucketName": "<SCANNING_BUCKET_NAME>" }
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
deployment_name = "<DEPLOYMENT_NAME>"
project_id = "<GCP_PROJECT_ID>"
region = "<GCP_REGION>"

scanner_pubsub_topic_project = "<SCANNER_PUBSUB_TOPIC_GCP_PROJECT_ID>"
scanner_pubsub_topic = "<SCANNER_PUBSUB_TOPIC>"
scan_result_topic = "<SCAN_RESULT_TOPIC>"

scanning_bucket_name = "<SCANNING_BUCKET_NAME>"

schedular_settings = {
cron = "0 0 * * 1"
timezone = "Etc/UTC"
}

trend_micro_fss_bucket_listener_role_id = "<BUCKET_LISTENER_ROLE_ID>"
111 changes: 111 additions & 0 deletions scan-triggers/gcp-nodejs-bucket-full-and-scheduled-scan/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
locals {
services = [
"artifactregistry.googleapis.com",
"cloudbuild.googleapis.com",
"cloudscheduler.googleapis.com",
"cloudtasks.googleapis.com",
"iam.googleapis.com",
"iamcredentials.googleapis.com",
"run.googleapis.com",
"storage.googleapis.com",
"workflows.googleapis.com",
]
}

resource "google_project_service" "enable_apis" {
for_each = toset(local.services)
service = each.value
disable_on_destroy = false
}

resource "random_id" "deploy_suffix" {
keepers = {
# Generate a new suffix each time we switch to a new deployment
deployment_name = "${var.deployment_name}"
}

byte_length = 3
}

resource "google_project_iam_custom_role" "workflow_custom_role" {
role_id = "tmfssfsplwf${lower(random_id.deploy_suffix.hex)}"
title = "TM C1FSS fullscan and schedule scan workflow custom role"
permissions = [
"iam.serviceAccounts.actAs"
]
project = var.project_id
}

module "function_sa" {
source = "./modules/iam"
id = "tmfss-st-sa${lower(random_id.deploy_suffix.hex)}"
name = "tmfss-st-sa"
roles = {
readObejctRole = {
name = "roles/storage.objectViewer"
project = var.project_id
}
messagePublishRole = {
name = "roles/pubsub.publisher"
project = var.scanner_pubsub_topic_project
}
signObjectRole = {
name = var.trend_micro_fss_bucket_listener_role_id
project = var.project_id
}
}
description = "Service account for C1FSS fullscan and schedule scan plugin cloud function"
}

module "workflow_sa" {
source = "./modules/iam"
id = "tmfss-wf-sa-${lower(random_id.deploy_suffix.hex)}"
name = "tmfss-wf-sa"
roles = {
listObjectsRole = {
name = "roles/storage.objectViewer"
project = var.project_id
}
functionTriggerRole = {
name = "roles/run.invoker"
project = var.project_id
}
workflowTriggerRole = {
name = "roles/workflows.invoker"
project = var.project_id
}
cloudTaskCreateRole = {
name = "roles/cloudtasks.enqueuer"
project = var.project_id
}
customRole = {
name = google_project_iam_custom_role.workflow_custom_role.name
project = var.project_id
}
}
description = "Service account for C1FSS fullscan and schedule scan plugin workflow"
depends_on = [module.function_sa]
}

module "function" {
source = "./modules/cloudfunctions"
service_account_email = module.function_sa.service_account_email
deployment_name = var.deployment_name
project_id = var.project_id
region = var.region
scan_result_topic = var.scan_result_topic
scanner_pubsub_topic_project = var.scanner_pubsub_topic_project
scanner_pubsub_topic = var.scanner_pubsub_topic
suffix = lower(random_id.deploy_suffix.hex)
}

module "workflow" {
source = "./modules/workflow"
project_id = var.project_id
region = var.region
service_account = module.workflow_sa.service_account_email
schedular_settings = var.schedular_settings
scanning_bucket_name = var.scanning_bucket_name
scan_trigger_function_url = module.function.cloudfunction_url
suffix = lower(random_id.deploy_suffix.hex)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
locals {
source_files = [
"${path.root}/src/index.js",
"${path.root}/package.json",
"${path.root}/yarn.lock"
]
project = var.project_id
}

resource "google_storage_bucket" "function_artifact_bucket" {
name = "tmfss-fullscan-artifact"
location = var.region
uniform_bucket_level_access = true
}

data "archive_file" "function_artifact" {
type = "zip"
output_path = "${path.root}/artifact.zip"
source {
content = file(local.source_files[0])
filename = "src/${basename(local.source_files[0])}"
}

source {
content = file(local.source_files[1])
filename = basename(local.source_files[1])
}

source {
content = file(local.source_files[2])
filename = basename(local.source_files[2])
}
}

resource "google_storage_bucket" "bucket" {
name = "${local.project}-gcf-source-${var.suffix}" # Every bucket name must be globally unique
location = var.region
uniform_bucket_level_access = true
}

resource "google_storage_bucket_object" "object" {
name = "artifact.zip"
bucket = google_storage_bucket.bucket.name
source = data.archive_file.function_artifact.output_path
}

resource "google_cloudfunctions2_function" "function" {
name = "tmfss-fs-pl-st-${var.suffix}"
location = var.region
description = "TM C1 FSS Fullscan and schedule scan scan trigger function"

build_config {
runtime = "nodejs20"
entry_point = "handler"
source {
storage_source {
bucket = google_storage_bucket.bucket.name
object = google_storage_bucket_object.object.name
}
}
}

service_config {
service_account_email = var.service_account_email
environment_variables = {
"SCANNER_PUBSUB_TOPIC" : var.scanner_pubsub_topic
"SCANNER_PROJECT_ID" : var.scanner_pubsub_topic_project
"SCAN_RESULT_TOPIC" : var.scan_result_topic
"DEPLOYMENT_NAME" : var.deployment_name
"REPORT_OBJECT_KEY" : var.report_object_key
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "cloudfunction_name" {
value = google_cloudfunctions2_function.function.name
}

output "cloudfunction_id" {
value = google_cloudfunctions2_function.function.id
}

output "cloudfunction_url" {
value = google_cloudfunctions2_function.function.url
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
variable "project_id" {
type = string
description = "ID of the GCP project which the plugin will be deployed."
sensitive = true
}

variable "region" {
type = string
description = "GCP region to deploy the plugin."
}

variable "service_account_email" {
type = string
description = "Email of the service account which cloud function will used."
}

variable "scanner_pubsub_topic" {
type = string
description = "Pub/Sub topic to trigger scanner."
}

variable "scanner_pubsub_topic_project" {
type = string
description = "Scanner Pub/Sub topic gcp project."
}

variable "scan_result_topic" {
type = string
description = "Scan result Pub/Sub topic."
}

variable "deployment_name" {
type = string
description = "The name of the deployment. This is used to generate unique suffix for some resource."
}

variable "report_object_key" {
type = bool
default = false
description = "If true, the report object key will be used instead of sha256."
}

variable "suffix" {
type = string
description = "Suffix to be appended to the resources."
}
Loading