Automated malware scanning for Google Cloud Storage using Trend Micro Vision One File Security.
┌─────────────────────────────────────────────────────────────────────────────┐
│ GCP Architecture │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ GCS Bucket │────▶│ Eventarc │────▶│ Scanner Function│ │
│ │ (upload) │ │ Trigger │ │ (Python 3.12) │ │
│ └─────────────┘ └──────────────┘ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ Secret │────▶│ Vision One │────▶│ Pub/Sub Topic │ │
│ │ Manager │ │ File Security│ │ (scan results) │ │
│ └─────────────┘ └──────────────┘ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ Quarantine │◀────│ Tag Function │◀────│ Pub/Sub │ │
│ │ Bucket │ │ (metadata) │ │ Subscription │ │
│ └─────────────┘ └──────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
- Automatic Scanning - Files scanned immediately on upload
- Multi-Bucket Support - Monitor multiple GCS buckets
- Object Metadata Tagging - Scan results stored as object metadata
- Quarantine - Automatically isolate malicious files
- Monitoring - Cloud Monitoring alerts for malware detection
- Serverless - Cloud Functions Gen 2 (scales to zero)
- GCP Project with billing enabled
- gcloud CLI installed and authenticated
- Terraform >= 0.15
- Vision One API Key (get one here)
gcloud auth application-default login
gcloud config set project YOUR_PROJECT_IDcd terraform
cp terraform.tfvars.example terraform.tfvarsEdit terraform.tfvars:
project_id = "your-project-id"
v1fs_apikey = "your-vision-one-api-key"
gcs_bucket_names = ["bucket-1", "bucket-2"]
region = "us-central1"terraform init
terraform plan
terraform apply# Upload a test file
echo "test" > /tmp/test.txt
gcloud storage cp /tmp/test.txt gs://your-bucket/
# Check scan result (wait ~30 seconds)
gcloud storage objects describe gs://your-bucket/test.txt --format="yaml(metadata)"| Variable | Description |
|---|---|
project_id |
GCP project ID |
v1fs_apikey |
Vision One API key |
gcs_bucket_names |
List of buckets to monitor |
| Variable | Default | Description |
|---|---|---|
region |
us-central1 |
GCP region (must match bucket region) |
v1fs_region |
us-east-1 |
Vision One region |
prefix |
v1fs |
Resource name prefix |
enable_tag |
true |
Enable metadata tagging |
quarantine_bucket |
"" |
Bucket for malicious files |
delete_malicious |
false |
Delete malicious files after quarantine |
sdk_tags |
["env:prod"] |
Tags for Vision One console |
| Region | Location |
|---|---|
us-east-1 |
United States |
eu-central-1 |
Europe (Germany) |
ap-northeast-1 |
Asia Pacific (Japan) |
ap-southeast-1 |
Asia Pacific (Singapore) |
ap-southeast-2 |
Asia Pacific (Australia) |
ap-south-1 |
Asia Pacific (India) |
Scanned objects receive the following metadata:
| Key | Description | Example |
|---|---|---|
fss-scanned |
Scan completed | true |
fss-scan-result |
Scan verdict | clean, malicious, unknown |
fss-scan-detail-code |
Result code | 0=clean, 1=malicious |
fss-scan-date |
Scan timestamp | 2026/02/04 12:34:56 |
fss-scan-detail-message |
Additional details | Malware names if detected |
fss-quarantined |
File was quarantined | true (if applicable) |
When quarantine_bucket is configured:
- Malicious files are copied to:
gs://{quarantine_bucket}/{timestamp}/{source_bucket}/{object_path} - Quarantine metadata includes original location and malware details
- If
delete_malicious = true, the original file is deleted
quarantine_bucket = "my-quarantine-bucket"
delete_malicious = trueThe deployment includes Cloud Monitoring resources:
- Malware Detection Alert - Notifies when malware is found
- Scanner Error Alert - Notifies on function failures
- Scan Results Metric - Tracks clean/malicious/error counts
- Edit
monitoring.tf - Uncomment the
google_monitoring_notification_channelresource - Set your email address
- Run
terraform apply
# Scanner function logs
gcloud functions logs read --gen2 \
--region=us-central1 \
--filter="resource.labels.function_name~v1fs-scanner"
# Tag function logs
gcloud functions logs read --gen2 \
--region=us-central1 \
--filter="resource.labels.function_name~v1fs-tag"To add more buckets to monitor:
-
Edit
terraform.tfvars:gcs_bucket_names = ["bucket-1", "bucket-2", "new-bucket-3"]
-
Apply changes:
terraform apply
Terraform automatically creates new Eventarc triggers and IAM bindings.
| Resource | Pricing |
|---|---|
| Cloud Functions | Pay per invocation |
| Eventarc | Free tier available |
| Pub/Sub | Pay per message |
| Secret Manager | Pay per secret version |
| Vision One | Contact Trend Micro |
-
Verify bucket is in the same region as functions:
gcloud storage buckets describe gs://your-bucket --format="value(location)" -
Check Eventarc trigger exists:
gcloud eventarc triggers list --location=us-central1
-
Verify service account has bucket access:
gcloud storage buckets get-iam-policy gs://your-bucket
-
Check function service account:
gcloud functions describe v1fs-scanner-XXXXX --gen2 --region=us-central1 \ --format="value(serviceConfig.serviceAccountEmail)"
-
Verify secret exists:
gcloud secrets list --filter="name~v1fs-apikey" -
Check secret value (be careful with output):
gcloud secrets versions access latest --secret=v1fs-apikey-XXXXX
terraform destroy