This document explains how to ingest File Scanning Framework logs to Google Security Operations using Google Cloud Storage V2.
File Scanning Framework (FSF) is an open-source, modular recursive file scanning solution developed by Emerson Electric Co. FSF uses a client-server architecture to analyze files and generate detailed JSON scan results including file metadata, YARA signature matches, extracted sub-objects, and module-specific metadata.
Before you begin
Make sure that you have the following prerequisites:
A Google SecOps instance
A GCP project with Cloud Storage API enabled
Permissions to create and manage GCS buckets
Permissions to manage IAM policies on GCS buckets
A deployed FSF server instance with write access to log directory
Ingestion labels: The label to be applied to the events from this feed.
Click Next.
Review your new feed configuration in the Finalize screen, and then click Submit.
Grant IAM permissions to the Google SecOps service account
The Google SecOps service account needs Storage Object Viewer role on your GCS bucket.
Go to Cloud Storage > Buckets.
Click the bucket name (fsf-logs-secops).
Go to the Permissions tab.
Click Grant access.
Provide the following configuration details:
Add principals: Paste the Google SecOps service account email.
Assign roles: Select Storage Object Viewer.
Click Save.
Verify ingestion
Wait 10-15 minutes for the initial ingestion to complete.
In Google SecOps, go to SIEM Settings > Feeds.
Locate the feed (FSF File Scanning Logs).
Verify the Status shows as Active.
Click the feed name to view ingestion metrics.
Verify that Events ingested count is increasing.
Go to Search in Google SecOps.
Run a search query to verify FSF logs are being ingested:
metadata.log_type = "FILE_SCANNING_FRAMEWORK"
Verify that FSF scan results appear in the search results.
Troubleshooting
No logs appearing in GCS
Verify FSF is writing logs to /var/log/fsf/:
ls-lh/var/log/fsf/
tail-f/var/log/fsf/*.log
Check Fluentd logs for errors:
sudotail-f/var/log/td-agent/td-agent.log
Verify the GCP service account key is valid and has correct permissions.
Check that the bucket name in the Fluentd configuration matches the actual bucket name.
Fluentd permission errors
Verify the service account (fsf-fluentd-shipper) has Storage Object Admin role on the bucket.
Check that the key path in the Fluentd configuration is correct.
Verify the key file has correct ownership and permissions:
ls-l/etc/td-agent/gcp-key.json
Google SecOps not ingesting logs
Verify the Google SecOps service account has Storage Object Viewer role on the bucket.
Check that the bucket URI in the feed configuration is correct and includes the trailing slash.
Verify files exist in the GCS bucket at the specified prefix path.
Check the feed status in SIEM Settings > Feeds for error messages.
FSF logs not in expected format
Verify FSF is configured to write JSON output (default behavior).
Check that the Fluentd section is configured with @type json.
Inspect a log file manually to verify it contains valid JSON:
head-n1/var/log/fsf/*.log|jq.
UDM mapping table
Log field
UDM mapping
Logic
CompressType_label, compressed_parents
about.labels
Merged from CompressType_label (key "Compress Type", value from Object.EXTRACT_ZIP.Object_0.Compress Type if message contains "Compress Type") and compressed_parents (key "Compressed Parent Files", concatenated from Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.additional_info.compressed_parents)
Value from Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.MD5 if EXTRACT_EMBEDDED present, else Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.MD5 if EXTRACT_ZIP present, else Object.EXTRACT_SWF.META_BASIC_INFO.MD5 if EXTRACT_SWF present, else Object.EXTRACT_GZIP.META_BASIC_INFO.MD5 if EXTRACT_GZIP present, else Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.MD5
Value from Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA1 if EXTRACT_EMBEDDED present, else Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA1 if EXTRACT_ZIP present, else Object.EXTRACT_SWF.META_BASIC_INFO.SHA1 if EXTRACT_SWF present, else Object.EXTRACT_GZIP.META_BASIC_INFO.SHA1 if EXTRACT_GZIP present, else Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA1
Value from Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA256 if EXTRACT_EMBEDDED present, else Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA256 if EXTRACT_ZIP present, else Object.EXTRACT_SWF.META_BASIC_INFO.SHA256 if EXTRACT_SWF present, else Object.EXTRACT_GZIP.META_BASIC_INFO.SHA256 if EXTRACT_GZIP present, else Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA256
Value from Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.Size if EXTRACT_EMBEDDED present, else Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.Size if EXTRACT_ZIP present, else Object.EXTRACT_SWF.META_BASIC_INFO.Size if EXTRACT_SWF present, else Object.EXTRACT_GZIP.META_BASIC_INFO.Size if EXTRACT_GZIP present, else Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.Size; stripped of trailing " .*" and converted to uinteger
Set to Object.META_EMERSON_INFO.result_summary if present, else Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.verbose_msg
Filename
target.file.full_path
Value copied directly
Object.META_BASIC_INFO.MD5
target.file.md5
Value copied directly
Summary.Yara
target.file.mime_type
Extracted from first index of Summary.Yara, uppercased and "FT_" removed if Yara present, else set to "ZIP" if EXTRACT_ZIP present, "SWF" if EXTRACT_SWF present, "GZIP" if EXTRACT_GZIP present, "CAB" if EXTRACT_CAB present
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2026-10-05 UTC."],[],[]]