Views:
You can update a Google Cloud project from TrendAI Cloud One File Storage Security (C1FSS) to TrendAI Vision One™ File Security Storage (V1FSS) using the TrendAI Vision One console and the Google Cloud console. This topic covers the preparation, settings, and behavior changes that apply to both update paths.
Note
Note
Three parts of this update have no console page on either side. Cloud Storage notification configurations are not shown anywhere in the Google Cloud console, the V1FSS deployment package must be applied with Terraform from a shell, and the promote and quarantine destinations are set in that package's main.tf file rather than in either console. Expect to work in Cloud Shell alongside both consoles.

Choose an update path

Two update paths are available. Both do the same work; they differ only in the order of two actions: turning on V1FSS scanning, and removing the C1FSS bucket notification.

Update paths

Path
Order
Result
Zero downtime
Turn on V1FSS first, remove C1FSS after
An overlap where both products scan every new object
Brief downtime
Remove C1FSS first, turn on V1FSS after
A gap where neither product scans
  • Zero downtime: Choose this path if scanning must not be interrupted. Be aware that during the interval before C1FSS scanning stops, every new object is scanned by both C1FSS and V1FSS. If the promote-or-quarantine plugin is in use and you carry its settings over to V1FSS, both products also move the same objects, which can cause race conditions. These lead to inconsistent object metadata, an inconsistent file state (one product moves an object while the other is still reading it), or duplicate processing (both products attempt the same move, and whichever one wins deletes the source while the other logs a failure).
  • Brief downtime: Choose this path if you can tolerate a short interruption of scanning. Scanning pauses only between removing the C1FSS bucket notification and turning on scanning in the TrendAI Vision One console, which is typically a few minutes. This path has the least chance of problems during the update, and is the better choice if you use the promote-or-quarantine plugin.

Before you begin

Work through all six checks below before you change anything. They apply to both update paths.
  1. Confirm that V1FSS can replace your C1FSS layout.
    Two C1FSS layouts have no V1FSS equivalent. Check both before you plan anything else.

    Supported C1FSS layouts

    C1FSS layout
    Update supported?
    All-in-One (scanner stack and storage stack together)
    Yes
    Scanner stack only, or storage stack only, in the same project
    Yes
    Several storage stacks in one project
    Yes. They collapse into one V1FSS stack.
    Cross-project, with buckets in one project and the scanner in another
    No
    Multi-region or dual-region buckets
    No. V1FSS for GCP protects single-region buckets only.
    Important
    Important
    A cross-project layout changes your whole plan. Every V1FSS resource is scoped to a single project, and a bucket can only be served by a scanner in its own project. If C1FSS runs hub-and-spoke, you need one V1FSS deployment for each project that holds buckets, and the hub scanner project goes away. Check the Cloud One console to confirm whether your current setup is cross-project, and if it is, plan the per-project split before you change anything.
  2. Check whether you use the promote-or-quarantine plugin.
    C1FSS can move clean or malicious objects to other buckets, but only through a separate plugin deployed once per scanning bucket. V1FSS has this capability built in, but the settings do not carry across automatically, and one default differs in a way that changes where your files land. The plugin is also not part of any C1FSS stack, so nothing else in this update finds or removes it.
    Run the following in Cloud Shell.
    gcloud functions list --filter="name~promote-and-quarantine" --format="value(name,region)"
    If the command returns anything, read Update promote and quarantine settings before you start, and record the plugin settings now. You need them before you install V1FSS, not after.
  3. Record what C1FSS protects, and how. Do this first, before you make any changes.
    The C1FSS Bucket Listener is a Cloud Functions (1st gen) function with a google.storage.object.finalize trigger. Cloud Functions creates a notification configuration on your bucket to deliver those events, and that notification configuration is what you remove at cutover. Record its details now: they are your baseline for confirming that C1FSS has stopped scanning, and for confirming that it comes back correctly if you roll back. Some of this information becomes unreadable once the C1FSS stacks are gone.
    1. In the Cloud One console, go to File Storage SecurityStacks and note each stack's name, type (scanner, storage, or All-in-One), and region.
    2. In Cloud Shell, run the following to find the bucket that each Bucket Listener protects, along with everything else you need for cutover.
      OUTFILE="c1fss-inventory-$(date +%Y%m%d).csv"
      echo "function,region,bucket,c1_notification_id,c1_notification_topic,object_finalize_count" > "$OUTFILE"
      
      gcloud functions list --filter="name~bucket-listener" --format=json </dev/null \
      | jq -r '.[] | (.name | split("/")) | "\(.[5]),\(.[3])"' \
      | while IFS=, read -r fn region; do
          bucket=$(gcloud functions describe "$fn" --region="$region" \
            --format="value(eventTrigger.resource)" </dev/null | sed 's#.*/buckets/##')
      
          if [ -z "$bucket" ]; then
            echo "$fn,$region,,MISSING,MISSING,0" >> "$OUTFILE"
            continue
          fi
      
          notifs=$(gcloud storage buckets notifications list "gs://$bucket" --format=json </dev/null 2>/dev/null)
          id=$(echo "$notifs" | jq -r '[.[]."Notification Configuration" | select(.topic | test("cloud-functions-"))][0].id // "MISSING"')
          topic=$(echo "$notifs" | jq -r '[.[]."Notification Configuration" | select(.topic | test("cloud-functions-"))][0].topic // "MISSING"')
          count=$(echo "$notifs" | jq '[.[]."Notification Configuration" | select(.event_types == null or any(.event_types[]; . == "OBJECT_FINALIZE"))] | length')
          echo "$fn,$region,$bucket,$id,$topic,$count" >> "$OUTFILE"
        done
      
      column -s, -t "$OUTFILE"
      echo "Saved to: $(pwd)/$OUTFILE"
    3. Download the CSV file from Cloud Shell and save it somewhere accessible, alongside the Cloud One stack names and regions from the first step. A text file or a ticket comment is enough.
    Between the CSV file and the stack list you have everything the update needs: which function protects which bucket, the region to select when you generate the deployment package, the C1FSS notification id and topic to delete at cutover and confirm on rollback, the function name to redeploy for rollback and delete at teardown, and the OBJECT_FINALIZE count that is your baseline for the sixth check below.
    Note
    Note
    If a bucket has no notification configuration pointing at a Cloud Functions topic, C1FSS is not scanning it. Leave that bucket out of the update.
  4. Identify which C1FSS generation you have.
    C1FSS shipped two GCP deployment mechanisms, and teardown differs between them. Run the following in Cloud Shell.
    gcloud deployment-manager deployments list

    C1FSS deployment generations

    Result
    Generation
    Teardown command
    Deployments named <prefix>-scanner or <prefix>-storage
    Deployment Manager
    gcloud deployment-manager deployments delete
    No deployments listed
    Terraform
    terraform destroy, run in the directory you were told to keep
  5. Confirm that you have the required permissions and tools.
    • Permissions on the Google Cloud project: For the full list, see Google Cloud required permissions.
    • Terraform in Cloud Shell: Cloud Shell provides gcloud, gsutil, and jq, but it no longer preinstalls Terraform. Install Terraform yourself, because deploy.sh does not run without it.
    Note
    Note
    Step 1 of either update path runs ./deploy.sh precheck. That command is a Terraform plan, which shows you what would be created. It is not a permissions check, so confirm your permissions separately.
  6. Check the notification slots on each bucket. This check applies to GCP only.
    A bucket can hold at most 10 notification configurations for a single event type. C1FSS uses one, and V1FSS needs one more. If a bucket already has 9 or more OBJECT_FINALIZE configurations, turning it on in V1FSS fails silently: TrendAI Vision One logs the failure internally and continues, and the bucket stays unprotected with no error in the console.
    for b in <bucket-1> <bucket-2>; do
      n=$(gcloud storage buckets notifications list "gs://$b" 2>/dev/null | grep -c 'OBJECT_FINALIZE' || true)
      echo "$b: $n OBJECT_FINALIZE notification(s)"
    done
    Any bucket at 9 or above needs a slot freed before you turn it on.

Update promote and quarantine settings

Skip this section if gcloud functions list --filter="name~promote-and-quarantine" returns nothing. Without the plugin, C1FSS only wrote object metadata, and V1FSS does the same.
In C1FSS, promote and quarantine were a separate plugin deployed once per scanning bucket, with its own Terraform state. In V1FSS they are built into the post-scan action service and configured on the module "file-storage-security" block in the deployment package's main.tf file. V1FSS ships with the destinations empty, which tags objects in place, so you set them in the package before you install.
Record the plugin settings first
Every plugin instance names its resources with a shared 10-character suffix, which is visible in the function name. Run the following in Cloud Shell to list each instance and its region.
gcloud functions list --filter="name~promote-and-quarantine" --format=json </dev/null \
| jq -r '.[] | (.name | split("/")) | "\(.[5])\t\(.[3])"' | column -t
The plugin's whole configuration is four environment variables. In the Google Cloud console, go to Cloud Functionsthe plugin functionVariables, or run the following.
gcloud functions describe <plugin-function-name> --format="value(environmentVariables)"

Plugin settings to record

Setting
What it means
PROMOTE_STORAGE_BUCKET
Destination for clean objects. An empty value means promote was turned off.
PROMOTE_MODE
move, which deletes the source object, or copy, which leaves it
QUARANTINE_STORAGE_BUCKET
Destination for malicious objects. An empty value means quarantine was turned off.
QUARANTINE_MODE
move or copy
There is no failure or isolation destination. The plugin only ever acted on clean and malicious results. Also note which bucket each instance acts on: it is the scanning bucket of the C1FSS storage stack the plugin was deployed alongside, which you can match by the scan-result Pub/Sub topic the plugin is triggered from.
Set the values in main.tf
Open main.tf in the unzipped package. Cloud Shell includes an editor, which you open with cloudshell edit main.tf. Find the module "file-storage-security" block and set the following three values.
  1. Where objects go. Each destination is a JSON string, resolved in the order custom, then regional, then global.
    # If every protected bucket used the same destination:
    clean_bucket      = jsonencode({ global = "my-clean-bucket" })
    quarantine_bucket = jsonencode({ global = "my-quarantine-bucket" })
    
    # If destinations differed per source bucket:
    quarantine_bucket = jsonencode({
      custom = {
        "source-bucket-1" = { destBucket = "quarantine-bucket-1", destRegion = "us-east1" }
        "source-bucket-2" = { destBucket = "quarantine-bucket-2", destRegion = "us-west1" }
      }
    })
    
    # Or per region, keyed by region name, with an optional global fallback:
    quarantine_bucket = jsonencode({ "us-east1" = "quarantine-use1", global = "quarantine-fallback" })
    Leave a variable as jsonencode({}) if that action was turned off. Those objects are tagged in place, exactly as before.
    Important
    Important
    Use global only if every bucket you are protecting had a plugin for that action. A global value applies to all of them, including buckets that never had a plugin, and those buckets were only tagged under C1FSS. If you give them a destination, V1FSS starts moving their objects. If only some buckets had a plugin, use the custom form, which affects only the source buckets you list.
  2. Where objects land inside the destination. You must change this value.
    use_source_bucket_as_folder = false
    The package ships with true, which is the correct default for a new deployment but not for an update.

    Destination paths

    Configuration
    Path your objects land at
    C1FSS plugin
    <destination>/<object>
    V1FSS with false
    <destination>/<object>, the same as C1FSS
    V1FSS with true
    <destination>/<source-bucket>/<object>, which is different
    If anything reads your quarantined or promoted objects by path, true breaks it at cutover. Note the trade-off that the setting exists for: with false, two source buckets that hold an object of the same name overwrite each other in the destination. C1FSS behaved the same way, so false matches your current behavior. If that was only safe because each plugin instance had its own destination bucket, keep that arrangement with the custom form rather than collapsing to one global destination.
  3. Leave the failure destination empty, to match C1FSS.
    failure_bucket = jsonencode({})
    The C1FSS plugin had no failure destination, so objects whose scan failed stayed where they were. V1FSS can move them somewhere instead, which is a new capability but not your current behavior.
For more information about destination buckets in V1FSS, see Customized destination buckets in GCP.
Two behaviors that cannot be carried over
  • Copy mode. If PROMOTE_MODE or QUARANTINE_MODE was copy, the plugin left the original object in place. V1FSS always moves the object: it copies the object to the destination and then deletes the original. Make sure nothing depends on the original staying in the source bucket.
  • Destinations in another project. V1FSS grants its post-scan action service account roles/storage.objectAdmin on each destination bucket as part of the Terraform apply, so the identity you run deploy.sh with needs permission to set IAM on that bucket. If a destination is in another project and you cannot grant that permission, the apply fails on the binding. Move the bucket into this project, or ask the other project's administrator to grant the …-action-tag service account access after you deploy.
Important
Important
The plugin replaces an object's metadata in full, not only the fss- keys, immediately before it copies the object to the destination. For objects the plugin acts on, both the V1FSS keys and any custom metadata of your own are absent from the destination copy. This is existing C1FSS behavior and the update does not change it.

What changes after the update

V1FSS is not an exact feature-for-feature match for C1FSS. Review the following before you delete anything.
What is different
  • Bucket selection is a console setting, not a deployment parameter. C1FSS fixed the scanning bucket when you deployed the stack, one stack per bucket. V1FSS deploys once for each project, and you turn buckets on and off in the TrendAI Vision One console.
  • Only one V1FSS stack is supported for each project. V1FSS records its deployment metadata in a secret with a fixed name, so a second stack in the same project fails to apply. Several C1FSS storage stacks collapse into one V1FSS stack, which is usually what you want, but it is not optional.
  • V1FSS grants itself project-wide access to Cloud Storage. Instead of per-bucket IAM bindings, it creates two project-level custom roles that cover every bucket in the project. There is no option to scope access to individual buckets. If the per-bucket model in C1FSS was a control you relied on, review this before you update.
  • V1FSS uses Cloud Run v2 instead of Cloud Functions (1st gen), so it does not depend on the Cloud Build, Cloud Functions, or Deployment Manager APIs.
  • Promote and quarantine always move objects, never copy them, and they are configured once in the deployment package rather than once for each bucket in a separate plugin.
  • The scan-result Pub/Sub topic changed, along with the shape of its messages. If you had your own subscriber on the C1FSS …-scan-result-topic topic, subscribe it to the V1FSS topic and update your parser.
  • Scan history stays in Cloud One. TrendAI Vision One starts fresh at cutover. Export anything you need to keep before your Cloud One tenant is removed.
What does not carry over
  • A cross-project scanner: A V1FSS deployment is confined to one project. A hub-and-spoke C1FSS layout becomes one V1FSS deployment for each project that holds buckets.
  • Object prefix filtering (objectFilterPrefix): The V1FSS Terraform supports it, but the path that a TrendAI Vision One managed deployment uses cannot set it. If C1FSS scanned only a prefix of a bucket, V1FSS scans the whole bucket. Check your object volumes first, because for a prefix that covered a small part of a large bucket, this is a significant change in how much is scanned.
  • Per-bucket IAM scoping (disableScanningBucketIAMBinding): No equivalent in V1FSS.
  • Reporting object keys to the backend (reportObjectKey): No equivalent in V1FSS. Object keys are always hashed in telemetry.
  • Multi-region and dual-region buckets: Not protected by either product's V1FSS path. They always report as not deployed.
What you gain, and might want to set up afterward
  • Detections in TrendAI Vision One XDR and Workbench visibility, alongside the rest of your security data.
  • Object moving without a separate plugin, built into V1FSS and configured once instead of once for each bucket, with no extra service account or custom roles of its own to manage.
  • A destination for failed scans (failure_bucket). The C1FSS plugin left those objects in place.
  • Better failure handling, with three dead-letter queues and exponential backoff instead of one queue, and daily automatic credential rotation.
  • A configurable metadata format: separated keys, which is the default and matches C1FSS, a single merged key, or no metadata at all.

Common questions

Which update path should I use?
Use zero downtime if you cannot pause scanning. Use brief downtime if you can, and especially if you use the promote-or-quarantine plugin and are carrying its settings over. The plugin is the one case where the overlap causes real problems rather than just duplicate work.
How long is the brief downtime?
Only the gap between removing the C1FSS bucket notification and turning on scanning in the TrendAI Vision One console. Both are single actions, so it is typically a few minutes. The duration depends on you, not on any deployment step.
In the zero-downtime path, why not remove the C1FSS bucket notification before validating?
Validating during the overlap makes results hard to attribute, so you validate on a bucket that C1FSS never protected instead. There is no overlap on that bucket, so nothing holds the overlap window open, and every result is attributable to V1FSS. Removing the C1FSS notification first would not shorten the update, because V1FSS is already turned on in both orders. It would only move the risk earlier: if V1FSS turned out to be misconfigured, you would find out with your real buckets already unprotected. You still get end-to-end confirmation on a bucket that C1FSS protected, at the check point at the end of step 3, after the C1FSS notification is gone but before its other resources are deleted. At that point attribution is unambiguous and rollback is still available.
Which buckets does C1FSS actually protect?
The Cloud One console's File Storage SecurityStacks page names the scanning bucket behind each storage stack. Confirm it against the bucket itself with gcloud storage buckets notifications list gs://<bucket>. If there is no notification configuration pointing at a Cloud Functions topic, C1FSS is not scanning that bucket.
Why are my objects being scanned twice?
In the zero-downtime path, both products are turned on during the overlap. That is how the path avoids downtime, and it stops when you remove the C1FSS bucket notification.
My fss- object metadata keeps changing, or keys keep disappearing.
This is expected during the overlap. C1FSS replaces the whole fss- metadata set on each scan, which removes the extra keys that V1FSS writes, while V1FSS merges its keys instead. It stops as soon as C1FSS is torn down. Do not make anything depend on fss- metadata until then.
I turned on a bucket, the console accepted it, but nothing is being scanned.
Check the notification count with gcloud storage buckets notifications list gs://<bucket>. Cloud Storage caps notifications at 10 for each event type, and when that cap is reached, TrendAI Vision One logs the failure internally and continues, so the bucket stays unprotected with no visible error. Free a slot and turn the bucket on again. See Before you begin.
My buckets do not appear on the Inventory page.
TrendAI Vision One discovers buckets by probing your project when your deployment registers, and then on a roughly hourly schedule. Wait and refresh.
A bucket shows as not deployed and will not turn on.
That bucket's region has no registered V1FSS scanner. Either the region is not supported, you did not select it when you generated the deployment package, or the probe has not caught up. You also see this for a multi-region or dual-region bucket, which cannot be protected at all.
The deploy.sh script fails immediately, saying that Terraform is not a real binary.
Cloud Shell no longer preinstalls Terraform. Install it and run the command again. See Before you begin.
The deploy.sh install command failed. Can I run it again?
Yes. The script is Terraform behind a Cloud Storage backend in your own project, so running it again continues from the recorded state rather than starting over. Fix whatever it reported and run the same command again. Do not delete the state bucket between attempts, and check deploy_gcp.log for what happened.
The Terraform apply failed on a disabled API.
The deploy.sh script enables only some of the APIs that V1FSS needs. The one that is missing is most often run.googleapis.com or cloudscheduler.googleapis.com. Enable the full list and run ./deploy.sh install again.
The Terraform apply failed, saying that the secret exists.
There is already a V1FSS stack in this project, and only one is supported. Either use the existing stack, or remove it with ./deploy.sh uninstall from its package directory before you deploy again.
The Terraform destroy command refuses to delete the C1FSS custom roles.
This is expected, because the roles are marked prevent_destroy in the C1FSS gcp-configuration module. Delete the roles directly from IAM & AdminRoles in the Google Cloud console, or with gcloud iam roles delete, and leave gcp-configuration alone.
How do I remove the V1FSS deployment?
Run bash ./deploy.sh uninstall from the package directory. Be careful if this project has other TrendAI Vision One features connected, because the command destroys the whole Cloud Account Management Terraform state, which means every feature that package deployed, not only File Security Storage. To remove only File Security Storage, clear it in the TrendAI Vision One console, download the regenerated package, and run ./deploy.sh install again. The uninstall command also leaves the TrendAI Vision One cloud account record in place unless you add --delete_cloud_account.
Teardown left buckets, roles, or APIs behind. Is that a problem?
The trend_micro_fss_* custom roles and the appspot service account binding are stale grants to a Cloud One service account, so remove them. Artifact, pattern-update, and gcf-sources-* buckets are harmless, and you can delete them if you prefer not to keep them. Enabled APIs are harmless. A leftover qua-pro-plugin-sa-… service account is not harmless, because it can delete objects in your buckets.
I already installed V1FSS, and now I want to set the promote and quarantine destinations.
Edit main.tf in the package directory and run bash ./deploy.sh install again. This is an update, not a new deployment. If you no longer have the package, download it again from the TrendAI Vision One console. The regenerated package ships with the destinations empty, so apply your edits again before you install.
Objects are moving, but landing at a different path than they did under C1FSS.
This is the use_source_bucket_as_folder setting. The package ships with true, which prefixes the destination path with the source bucket name, and the C1FSS plugin did not. Set it to false and run ./deploy.sh install again. See Update promote and quarantine settings.
Can I do this without Cloud Shell?
Yes, from any machine that has gcloud, jq, and Terraform installed, that is authenticated with gcloud auth login, and that is pointed at the correct project. Cloud Shell is recommended only because it already has most of these, with ambient credentials.
Can I update several projects at once?
Each project is an independent update, with its own deployment package, its own registration, and its own buckets. The package also includes org_deploy.sh, which runs deploy.sh against every project in an organization or folder. That is useful for a large number of projects, but it does not change the per-project process described here.