# Introduction

Cloud Storage Security offers two solutions: Antivirus for Amazon S3 and Data Classification for Amazon S3.

{% hint style="info" %}
In this documentation the following shorthand will be used in some cases to avoid repetition:\
**AV:** Antivirus for Amazon S3\
**DC:** Data Classification for Amazon S3
{% endhint %}

## Antivirus for Amazon S3

{% embed url="<https://www.youtube.com/watch?v=xS3AsVJx-zI>" %}

Antivirus for Amazon S3 allows users to detect Amazon S3 files that are infected with malware and viruses. When infected files are uploaded to Amazon S3, Cloud Storage Security detects the malicious files and guards against the spread of malware.

Computer malware is rampant and an everyday fact of doing business. Historically malware has been delivered through email, web, or even file sharing through shared network drives. The threat has evolved to include a new attack vector - uploading infected files to Amazon S3. From there, other users that access the infected files can end up spreading the malware.

Users and applications have come to rely on public cloud to provide storage of critical business files. More malware is finding its way to cloud storage as a result. Cloud Storage Security provides anti-malware protection for cloud storage to prevent users from inadvertently exposing themselves to malware by checking existing and new files for malware infections. Anti-malware software inspects a file and checks the content to detect malicious code or data. Once detected, Cloud Storage Security will remediate the object by either deleting, quarantining, or repairing the file.

## Data Classification for Amazon S3

Cloud storage has become the center pin of every cloud workflow. Once available, data finds its way in. With as scalable and easy to use as cloud storage is, it is getting harder and harder to keep track and maintain awareness of what you have in the cloud. Our Data Classification solution will allow you to automatically discover, identify and classify sensitive and regulated data based on custom and predefined rules.

Cloud Storage Security is an automated security solution that efficiently discovers and scans files in Amazon S3 buckets for malware, threats and sensitive data. It integrates natively, scales automatically, and does not interfere with DevOp workflows. It is managed from a single console to optimize IT administration and security operations resources.

## How to Use this Help Documentation

The Help Docs are broken into six main sections: `Getting Started`, `How it Works`, `Console Overview`, `FAQ`, `What's New`, and `Troubleshooting`.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td><strong>Getting Started</strong></td><td>Get you up and running in minutes.</td><td><a href="/pages/BVVtU6GjVPv2szpOVEUL">/pages/BVVtU6GjVPv2szpOVEUL</a></td></tr><tr><td></td><td><strong>Console Overview</strong></td><td>All aspects of the Console for AV and DC.</td><td><a href="/pages/0xnJTDHP7kaPoPkeYhLk">/pages/0xnJTDHP7kaPoPkeYhLk</a></td></tr><tr><td></td><td><strong>How it Works</strong></td><td>Product functionality, architecture, config options, sizing considerations and more.</td><td><a href="/pages/VBMUfaZVikh41eafn1MW">/pages/VBMUfaZVikh41eafn1MW</a></td></tr><tr><td></td><td><strong>Frequently Asked Questions</strong></td><td>All the small or simple questions we find coming up a lot.</td><td><a href="/pages/iJOmrppBWWTY8vgDU3x6">/pages/iJOmrppBWWTY8vgDU3x6</a></td></tr><tr><td></td><td><strong>What's New</strong></td><td>New functionality released in the product.</td><td><a href="/pages/GzQYwevRKnXGfgVz5bqw">/pages/GzQYwevRKnXGfgVz5bqw</a></td></tr><tr><td></td><td><strong>Troubleshooting</strong></td><td>Common issues and solutions.</td><td><a href="/pages/2711FtqBQxCsDhKlPP3e">/pages/2711FtqBQxCsDhKlPP3e</a></td></tr></tbody></table>

## Remember to Search

The documentation navigation is fairly straight forward and easy to find what you need. Additionally we provide the ability to `Search`. The upper right corner on all of the documentation pages has a search field. Every aspect of the documentation is indexed and searchable (case-insensitive). Search enables you to find topics that you may not be able to specifically recall or find through the table of contents.

For example, to find a topic related to protecting buckets in other regions, simply search on `region` to discover all pages and content related to "region". Below shows the results of searching on "region":

<figure><img src="/files/bFrs7xpXONzZGhdhtbVg" alt=""><figcaption><p>Search for region information</p></figcaption></figure>


# Getting Started

Deploy our solution to your environment in three easy steps.

**Antivirus for Amazon S3** and **Data Classification for Amazon S3** are available via the [AWS Marketplace](https://aws.amazon.com/marketplace/seller-profile?id=6ca3cdf7-b551-4872-b1cf-2f818b397df3\&ref=dtl_B08SPXP292). To install the software and get it running, you will have to complete three tasks.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Task 1 - Subscribe</strong></td><td></td><td>Subscribe to either or both of the Cloud Storage Security solutions in the AWS Marketplace. This will start the process and allow you to pay for the service through your AWS bill.</td><td><a href="/pages/8DA6VzmAP2RnLrtxun8m">/pages/8DA6VzmAP2RnLrtxun8m</a></td></tr><tr><td><strong>Task 2 - Deploy</strong></td><td></td><td>After you are subscribed, the software is deployed as an Amazon Elastic Container Service (ECS) container and set of resources. The software is installed using a CloudFormation Template. You will be asked a series of questions to determine how to install the software.</td><td><a href="/pages/GNfSfRxplGNDS7754NHk">/pages/GNfSfRxplGNDS7754NHk</a></td></tr><tr><td><strong>Task 3 - Configure</strong></td><td></td><td>Once the software is running, you will connect to the Cloud Storage Security Console and start your Amazon S3 protection.</td><td><a href="/pages/p4bnxi2CYF9V7rT7BEpp">/pages/p4bnxi2CYF9V7rT7BEpp</a></td></tr></tbody></table>

## After you've deployed

Once you have completed these tasks, Antivirus for Amazon S3 or Data Classification for Amazon S3 (or both) will be monitoring your Amazon S3 Buckets for malware and/or sensitive data. You will be able to monitor and reconfigure the solutions from the provided Console.

{% hint style="info" %}
Both solutions can be deployed independently from one another or they can share the same web interface. There is a Free Trial included with each that can also be used independently.
{% endhint %}


# How to Subscribe

Antivirus for Amazon S3 and Data Classification for Amazon S3 are available via AWS Marketplace.

In order to use Cloud Storage Security's Antivirus for Amazon S3 or Data Classification for Amazon S3 solutions, you must be subscribed to one of the AWS Marketplace listings for each of the tools you want to use in the account that you want to deploy the Management Console in.

Subscribing is a simple click-through process within your AWS account through AWS Marketplace. If both products are subscribed to, they can be run separately or as a unified solution.

## Antivirus for Amazon S3

In this section, you will see three different listing options on AWS Marketplace for Antivirus for Amazon S3 (**AV**): `Pay-As-You-Go (PAYG)`, `Bring Your Own License (BYOL) / GovCloud`, and `AWS Transfer Family`.

{% hint style="info" %}
If you are looking to start a free trial to test our solution use PAYG. If you have questions please [contact us](/contact-us).
{% endhint %}

Select the listing you plan to use below to learn more about the subscription process.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Pay-As-You-Go (PAYG)</strong></td><td>This listing deploys Antivirus for Amazon S3 with a PAYG model. This means you will only be charged for each GB of data that you scan.</td><td><strong>Most customers will use this listing.</strong></td><td><a href="/pages/8WVX3KsQx6kXHEbXKAdD#antivirus-for-amazon-s3">/pages/8WVX3KsQx6kXHEbXKAdD#antivirus-for-amazon-s3</a></td></tr><tr><td><strong>Bring Your Own License (BYOL) / GovCloud</strong></td><td>For customers who require a custom license or need to deploy in GovCloud.</td><td></td><td><a href="/pages/ZZVI3J404ZN9O9BbIifR">/pages/ZZVI3J404ZN9O9BbIifR</a></td></tr><tr><td><strong>Transfer Family Integration</strong></td><td>For customers who need to deploy our Integrated AWS Partner Solution for AWS Transfer Family.</td><td></td><td><a href="/pages/jA3e2rcK1Ah3Ob5mMlWN">/pages/jA3e2rcK1Ah3Ob5mMlWN</a></td></tr></tbody></table>

## Data Classification for Amazon S3

Within the `Pay-As-You-Go (PAYG)` article you will also find detail on our available listing option on AWS Marketplace for Data Classification for Amazon S3 (**DC**). Select the PAYG page below and navigate to the DC listing link within the article to learn more about the subscription process.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Pay-As-You-Go (PAYG)</strong></td><td>This listing deploys Data Classification for Amazon S3 with a PAYG model. This means you will only be charged for each GB of data that you classify.</td><td><strong>Most customers will use this listing</strong></td><td><a href="/pages/8WVX3KsQx6kXHEbXKAdD#data-classification-for-amazon-s3">/pages/8WVX3KsQx6kXHEbXKAdD#data-classification-for-amazon-s3</a></td></tr></tbody></table>


# Pay-As-You-Go (PAYG)

This is the most common subscription option for Antivirus for Amazon S3 and Data Classification for Amazon S3 when deploying for a free trial or production deployment.

## What is the PAYG subscription?

In order to deploy and use our Antivirus for Amazon S3 or Data Classification for Amazon S3 solutions, you must be subscribed to the AWS Marketplace listings for each of the tools you want to use in the account that you want to deploy the Management Console in.

Our PAYG subscription allows you to transact directly through AWS Marketplace when using our Antivirus for Amazon S3 and Data Classification for Amazon S3 solutions. Each tool has its own AWS Marketplace PAYG listing:

* [Antivirus for Amazon S3](https://aws.amazon.com/marketplace/pp/B089QBV2GC/?ref=_ptnr_help_doc_)
* [Data Classification for Amazon S3](https://aws.amazon.com/marketplace/pp/prodview-vre2bxzpiytb2)

{% hint style="info" %}
If you only want to deploy one of the tools then subscribe to the listing for that specific tool. If you want to deploy both AV and DC then subscribe to both PAYG listings.

**Please note**, each listing has different subscription terms and you will be charged separately for the AV and DC subscriptions.

**Billing cycles** are every 30 days. This means that if your payment took place on the 1st of the month, the next one will be either the 31st or the 1st of the next month, depending on each month.
{% endhint %}

## Step 1 - Find the PAYG listing on AWS Marketplace

Go to the Cloud Storage Security listing on AWS Marketplace for the specific tool you want to subscribe to and deploy.

Alternatively, you can search on AWS Marketplace for `"Cloud Storage Security"`.

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

<figure><img src="/files/Z47H1oI1NX6lmNLdCObD" alt=""><figcaption><p>AV AWS Marketplace Listing Header</p></figcaption></figure>
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}

<figure><img src="/files/qaT6mUqPzikoEb5Jgk4T" alt=""><figcaption><p>DC AWS Marketplace Listing Header</p></figcaption></figure>
{% endtab %}
{% endtabs %}

## Step 2 - Subscribe to the product listing

Click on the `Continue to Subscribe` button within the AWS Marketplace listing to begin the subscription process.

You will be asked to accept the terms. Please review our EULA before accepting the terms.

The `Effective Date` and `Expiration Date` will change to `Pending` for a few seconds. Once they are approved, click the `Continue to Configuration` button. You are now officially subscribed to the product.

## Step 3 - Configure and Launch Antivirus for Amazon S3

For the next screen, leave the `Fullfilment Option` and `Software Version` to the default options and click the `Continue to Launch` button.

{% hint style="info" %}
To deploy with Terraform instead of CloudFormation, find the registry module [here](https://registry.terraform.io/modules/cloudstoragesec/cloud-storage-security/aws/latest).
{% endhint %}

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

<figure><img src="/files/hWxxpo37NwnSNUfCrqVu" alt=""><figcaption><p>Click Continue to Launch</p></figcaption></figure>
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}

<figure><img src="/files/sQKHaYpBewLXL5Zy0iD0" alt=""><figcaption><p>Click Continue to Launch</p></figcaption></figure>
{% endtab %}
{% endtabs %}

Once configuration is complete you can launch the software. Scroll down to `Container Images`. Within `Deployment Templates`, click the `Click to Launch Antivirus for Amazon S3 Deployment` link.

This will open the AWS Console CloudFormation service in a different tab with the CloudFormation Stack used to deploy the solution ready for you to configure. Leave the AWS Marketplace tab open just in case you need to restart the Stack again.

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

<figure><img src="/files/5YGvxUQTr9hFIOlU3343" alt=""><figcaption><p>Launch the CloudFormation Template</p></figcaption></figure>
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}

<figure><img src="/files/OqRTnnlOv399Qurm1w4R" alt=""><figcaption><p>Launch the CloudFormation Template</p></figcaption></figure>
{% endtab %}
{% endtabs %}

Next go to the [How to Deploy](/getting-started/how-to-deploy) section to learn more about the deployment process and how to configure the CloudFormation Stack to deploy our solution in your AWS environment.


# Bring Your Own License/GovCloud (BYOL)

Customers who require a custom license or need to deploy in GovCloud can use our BYOL to subscribe and deploy our Antivirus for Amazon S3 solution.

## What is the BYOL subscription and why would I use it instead of the PAYG subscription?

Our PAYG subscription allows you to transact entirely through AWS Marketplace metering and billing. We have some customers who either do not want to transact through AWS Marketplace and want to purchase a license from us directly OR they need to deploy in GovCloud, which does not currently support AWS Marketplace metering for Fargate containers.

This is why we offer our BYOL AWS Marketplace listing as an alternative, so you can eliminate use of AWS Marketplace metering and transactions entirely. Because AWS Marketplace metering is not used, this means you will have to purchase a separate license for your deployment directly from Cloud Storage Security. Please contact us at <sales@cloudstoragesec.com> to procure a license.

{% hint style="danger" %}
**If you are deploying GovCloud please take note** - Amazon Cognito is only supported in GovCloud US West, so the console must be deployed in this region. Scanning can be done in West or East, but the console deployment must be done in US West.
{% endhint %}

## Step 1 - Find the BYOL/GovCloud listing on AWS Marketplace

For use on GovCloud, leverage the [`BYOL and GovCloud` Listing](http://aws.amazon.com/marketplace/pp/B08SPXP292) on AWS Marketplace.

<figure><img src="/files/r59vI056CoIbrC5jEpHS" alt=""><figcaption><p>AV AWS Marketplace Listing Header</p></figcaption></figure>

Alternatively, you can search on AWS Marketplace for `"Cloud Storage Security"`.

## Step 2 - Subscribe to Antivirus for Amazon S3

Click on the `Continue to Subscribe` button within the AWS Marketplace listing to begin the subscription process.

You will be asked to accept the terms. Please review our EULA before accepting the terms.

The `Effective Date` and `Expiration Date` will change to `Pending` for a few seconds. Once they are approved, click the `Continue to Configuration` button. You are now officially subscribed to the product.

## Step 3 - Configure and Launch Antivirus for S3

For the next screen, you can leave the `Delivery Method` and `Software Version` to the default options and click the `Continue to Launch` button.

<figure><img src="/files/jrTb5vUdPEc3SMiGViH7" alt=""><figcaption><p>Click Continue to Launch</p></figcaption></figure>

Once configuration is complete you can launch the software. Scroll down to `Container Images`. Within `Deployment Templates`, click the `Commercial Deployment` or `GovCloud Deployment` link to launch.

{% hint style="info" %}
Please note, we support the BYOL listing for both AWS Commercial Cloud and GovCloud. The CloudFormation Templates are different for each. **Please ensure that you are selecting the correct CloudFormation Template for your AWS environment.**
{% endhint %}

This will open the AWS Console CloudFormation service in a different tab with the CloudFormation Stack used to deploy the solution ready for you to configure. Leave the AWS Marketplace tab open just in case you need to restart the Stack again.

<figure><img src="/files/OiilgP9gMx41ZeIROcb8" alt=""><figcaption><p>Launch the CloudFormation Template</p></figcaption></figure>

Next go to the [How to Deploy](/getting-started/how-to-deploy) section to learn more about the deployment process and how to configure the CloudFormation Stack to deploy our solution in your AWS environment.

{% hint style="info" %}
**Reminder**

Because AWS Marketplace metering is not used, this means you will have to purchase a separate license for your BYOL deployment directly from Cloud Storage Security. Please contact us at <sales@cloudstoragesec.com> to procure a license.
{% endhint %}


# AWS Transfer Family

Ensure the data that is moved into Amazon S3 via AWS Transfer Family is free of ransomware, viruses, trojans and other payloads by scanning it inline with Antivirus for Amazon S3

Learn more about our Transfer Family integration [here](/how-it-works/integrations/aws-transfer-family).

## Steps to Deploy

### Step 1 - Locate the Transfer Family-specific offering

To deploy the solution, first you need to find it on the AWS Marketplace. Locate the direct listing [here](https://aws.amazon.com/marketplace/pp/prodview-s56hvqbcyj5qe?ref_=aws-mp-console-subscription-detail) on AWS Marketplace.

Alternatively, you can search on AWS Marketplace for `"Cloud Storage Security"`.

<figure><img src="/files/6QRYiESGEQDdZ3r2uuXV" alt=""><figcaption><p>AV for Managed File Transfers Marketplace Listing Header</p></figcaption></figure>

### Step 2 - Subscribe to the listing

Click on the `Continue to Subscribe` button within the AWS Marketplace listing to begin the subscription process.

You will be asked to accept the terms. Please review our EULA before accepting the terms.

### Step 3 - Launch the software

After you subscribe you will need to launch the pre-populated CloudFormation template.

<figure><img src="/files/oNjJP7l90woLp1ilYWic" alt="" width="563"><figcaption><p>Click Continue to Launch</p></figcaption></figure>

Next, go to the [AWS Transfer Family](/getting-started/how-to-deploy/aws-transfer-family) page under the [How to Deploy](/getting-started/how-to-deploy) section to learn more about the deployment process and how to configure the CloudFormation Stack to deploy our solution in your AWS environment.


# How to Deploy

Once you've subscribed to the Antivirus and/or Data Classification for Amazon S3 listing(s), the next step is to start your deployment.

## Ensure you are subscribed

Ensure you have properly subscribed to Antivirus and/or Data Classification for Amazon S3 before you attempt to deploy the CloudFormation template. If you are not properly subscribed, the deployment will fail to start. Antivirus and/or Data Classification for Amazon S3 won't run because it will fail the AWS Marketplace entitlement check.

If you'd like to run the software outside the context of the AWS Marketplace, please [Contact Us](/contact-us) to discuss the possibility of a private license.

## Resources created during deployment

Deploying **Antivirus for Amazon S3** and/or **Data Classification for Amazon S3** is accomplished by using a CloudFormation Template that will install the necessary infrastructure components as well as the required roles and permissions. This section will help you fill out and run the CloudFormation Template.

During deployment the CloudFormation Template will create the following resources:

| Resource                                        | Description                                                                                                                                                                                    |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ECS Fargate Cluster with 1 Service and Task     | This is used to run the Antivirus for Amazon S3 Management Console                                                                                                                             |
| DynamoDB; AppConfig                             | This is used to save data for the software                                                                                                                                                     |
| IAM Roles and Policies                          | These are used to run the software                                                                                                                                                             |
| Cognito UserPool                                | Used for user management                                                                                                                                                                       |
| SNS Topic and CloudWatch Log Groups --> Streams | These are used for logging and notification purposes                                                                                                                                           |
| Load Balancer (**Optional**)                    | Leverage to use your own domain or to abstract the Management Consoles public access a step further. Check out the [Deployment Details](/how-it-works/deployment-details) for more information |

Once running, the Management Console will create the following resources:

* Services and Tasks (Scanning Agents) in the region cluster where you deployed your Management Console. This is used to run the scanning agents that process the objects.
* 1 ECS Cluster + Services and Tasks in each additional region you scan buckets in. This is used to run the scanning agents in additional regions.
* SNS Topic, SQS Queue, S3 Bucket events, CloudWatch Log Groups --> Streams. These are used to keep track of the object work.

## Consider the region you are deploying in

Launching the deployment template from the Marketplace Listing will default you to the `us-east-1` region. If you'd like to deploy in a different region, please ensure to change regions before proceeding.

<details>

<summary>Supported regions for Console deployment</summary>

* us-east-1 (N. Virginia)
* us-east-2 (Ohio)
* us-west-1 (California)
* us-west-2 (Oregon)
* ap-south-1 (Mumbai)
* ap-northeast-2 (Seoul)
* ap-southeast-1 (Singapore)
* ap-southeast-2 (Sydney)
* ap-northeast-1 (Tokyo)
* ca-central-1 (Canada)
* eu-central-1 (Frankfurt)
* eu-west-1 (Ireland)
* eu-west-2 (London)
* eu-west-3 (Paris)
* eu-north-1 (Stockholm)
* me-south-1 (Bahrain)
* sa-east-1 (Sao Paulo)
* GovCloud (West) AWS regions

**Missing regions in this list are due to Amazon Cognito not being supported in those regions.**

</details>

{% hint style="info" %}
The scanning agent will run in any region that supports Amazon ECS Fargate.
{% endhint %}

Once you have taken the above factors into consideration you are ready to move onto the [Steps to Deploy](/getting-started/how-to-deploy/steps-to-deploy) our solution.


# Steps to Deploy

Deployment of our solution happens using a CloudFormation Template.

{% hint style="info" %}
If you're planning to deploy both AV and DC at the same, then subscribe to both products and deploy AV first. When you enter the AV management console you can navigate to Configuration -> License Management, where you will see an option to activate DC.
{% endhint %}

{% hint style="info" %}
If you are using Terraform, you can find the Steps to deploy [here](https://registry.terraform.io/modules/cloudstoragesec/cloud-storage-security/aws/latest#usage-example).
{% endhint %}

## Consider your deployment options

Which parameters you configure in the CloudFormation Template depends on what your requirements for your deployment are. Options include:

* The `Standard Deployment` which requires filling out only 5 fields in the CloudFormation Template
* A completely `Private Deployment` where all of our components run in private VPCs and private Subnets with no public IPs assigned at all
* An in-between option where you have public access (public Load Balancer) while still running all solution components in a private VPC and Subnets

You can mix and match as well as incorporate VPC Endpoints to keep as much traffic as possible going over the AWS backbone.

For an in-depth overview of deployment options and details [**click here**](/how-it-works/deployment-details).

## Standard Deployment

The `Standard Deployment` is the simplest deployment. After providing only 5 inputs to the CloudFormation Template you will have a deployed and running solution in \~5 minutes. This deployment expects the Console and the Agent(s) to be placed in VPCs and Subnets that have an Internet Gateway (IGW) allowing for outbound traffic.

This a typical setup for VPCs and Subnets.The outbound routing allows ECS to pull down images from ECR, allows the Console and Agent(s) to communicate with required AWS Services and provides access to the management UI. Although public IPs are assigned, control is still done through Security Groups and access can be limited through IP ranges.

With this deployment, we register your application subdomain with a Route53 Hosted Zone we host and manage in one of the Cloud Storage Security AWS accounts. This allows you to have consistent access to your application. If you'd prefer to manage the domain and SSL certificate required for a persistent URL yourself, you can leverage the Application Load Balancer options discussed below and on the [Advanced Deployment Considerations](/getting-started/how-to-deploy/advanced-deployment-considerations) page.

### Step 1 - Quick Create Stack and Specify the Parameters

You must provide values for the following fields in the CloudFormation template:

1. Virtual Private Cloud (VPC) ID
2. Subnet A ID
3. Subnet B ID
4. Console Security Group CIDR Block
5. Email

You can leave all the default settings in the rest of the fields.

<figure><img src="/files/bmISoSh4sqcX33UsRWuB" alt=""><figcaption><p>Set your network configuration</p></figcaption></figure>

<figure><img src="/files/q2YDp9MkA5oPlCNV2D5F" alt=""><figcaption><p>Set an initial email address</p></figcaption></figure>

#### Virtual Private Cloud (VPC) ID

You must select a `VPC` from the drop down list for the Management Console to run in.

#### Subnet A ID

You must select a `Subnet A ID` from the drop down list contained in the selected VPC. Since we are doing a Standard Deployment, the subnet you select should be public, meaning it should have an IGW attached to it that allows outbound traffic.

#### Subnet B ID

You must select a **different** `Subnet B ID` from the drop down list contained in the selected VPC.

{% hint style="info" %}
The subnets you choose for `A` and `B` must either be able to offer a public IP or be on a network you can access. Without that, the console will run, but not be reachable. This could simply be a public subnet reachable through an Internet Gateway.

Alternatively, it could be a private subnet that is an extension of your corporate network you access either from your corporate network or through a VPN connection. Or these subnets may be private subnets fronted by a public Load Balancer. Learn more about this option in the [Advanced Deployment Considerations](/getting-started/how-to-deploy/advanced-deployment-considerations).

\
If you want to deploy privately continue reading further below.
{% endhint %}

**Please note**, If you select the same subnets for A and B, stack creation will fail. If you happen to pick the same value for each field, you will get a message as follows, please correct this before moving on.

<figure><img src="/files/RjdBB5bbOwqvwjJu2Pr0" alt=""><figcaption></figcaption></figure>

Ensure both subnets you select belong to the VPC you have selected. You must select subnets in different Availability Zones.

#### Console Security Group CIDR Block

We will create a Security Group (SG) for the Management Console that we deploy. This SG will have rules that contain IP ranges which can access the Console. You must select a `Console Security Group CIDR Block`. Specify your network access or set to "0.0.0.0/0" to access the Management Console from anywhere.

If you need to add multiple IP ranges you can set your first one through the CloudFormation Template and once the solution is deployed you can go to the SG to add additional rules.

{% hint style="info" %}
0.0.0.0/0 is wide open to the world. The application is still protected by SSL, a username and a password, but you may still choose to control this access. This could be your corporate network range or the /32 IP address your specific system is currently assigned. Google "what's my ip" and the first thing returned is what your current IP address is.\
\&#xNAN;***Note:*** *If your IP address changes, you may have to manually change the AWS Security Group value to represent the new IP*
{% endhint %}

#### Email

You must set a valid Email address which we will use to send the initial account username and password that you will use to access your Management Console.

{% hint style="danger" %}
If you do not properly set the above 5 parameters, the stack creation will fail and/or you will be unable to access your deployment. If you run into any trouble whatsoever, please [Contact Us](/contact-us) and also make sure to review the [Troubleshooting](/trouble-shooting) section of our help docs.
{% endhint %}

### Step 2 - Review Stack and Acknowledge

<figure><img src="/files/qSanCwSmOFlOfUsUp83V" alt=""><figcaption><p>Acknowledge before creating the stack</p></figcaption></figure>

Ensure you have set all of the parameters in your CFT correctly. Check `I acknowledge that AWS CloudFormation might create IAM resources with custom names.` under `Capabilities`. Click `Create Stack` at the bottom of the screen.

### Step 3 - Track the events and troubleshoot if needed

The stack you just created will have a status of `CREATE_IN_PROGRESS` as it runs. Wait for this to change to `CREATE_COMPLETE` and monitor the events it generates.

<figure><img src="/files/rleRTtfwhrSvjq6FKEwD" alt=""><figcaption></figcaption></figure>

When finished the status for the stack will show `CREATE_COMPLETE`:

<figure><img src="/files/x5hDwjeOv2UA9zMofRZ8" alt=""><figcaption></figcaption></figure>

If the stack creation fails, click here to open the [Troubleshooting](/trouble-shooting) section.

### Step 4 - Console Access

<figure><img src="/files/MaTAPlIPbmEVdZAci2LV" alt=""><figcaption></figcaption></figure>

Once the stack creation completes, click the `Output` tab. The top row in the table will have the URL for your Management Console. It will be in the format of `https://<accountID-appID>.cloudstoragesecapp.com`.

You will also receive an email to the address you entered while configuring your CloudFormation Template details. This email will include the URL to your console + a username and password which you will use to login to your account.

{% hint style="info" %}
It may take a few minutes for DNS to propagate the URL of your management console. If you are unable to load the URL provided in the email/CloudFormation Outputs then wait a few minutes. If it continues to be an issue, check the [console access troubleshooting](/trouble-shooting/i-cannot-access-the-management-console) to see if it is another issue or [Contact Us](/contact-us).
{% endhint %}

{% hint style="info" %}
If you chose to use a load balancer, the first field will be called `LBWebAddress` instead of `ConsoleWebAddress`
{% endhint %}

<figure><img src="/files/BX0j6uudXOgM3gmoWboZ" alt=""><figcaption></figcaption></figure>

## Private Deployment

In order to deploy privately you'll have to set the 5 parameters discussed above in the Standard Deployment section. However, this time you'll need to choose two private subnets (again in separate availability zones).

`Private Deployments` are defined by locking down the solution components (Console and Agents) such that they do not have public IPs (meaning leveraging private subnets that are behind a NAT Gateway). You can still provide public access if desired while locking everything else down. Whether it is best practices, compliance or internal rules you can deploy and leverage the solution as needed.

If you reviewed the [Deployment Details](/how-it-works/deployment-details) page you'll see the deployment options leveraging Application Load Balancers. These can be `internet-facing` or `internal` and can even be leveraged with the `Standard Deployment`. You do not have to leverage an ALB in a private deployment, but there are a number of reasons you might want to.

First off, AWS Fargate tasks do not get assigned persistent IP addresses. As a result, the IP address can change underneath you requiring you to look it up. You may also decide you'd like to manage or apply your own domain and SSL certificate for accessing the application. A load balancer allows you to accomplish all of these things: a persistent access point, apply your own domain and leverage your own certificates.

### Accessing a private deployment

If you only choose to use private subnets and do not use a Load Balancer in front of your Management Console, you will need to use the private IP that is generated by the ECS task that is stood up to host the console.

<figure><img src="/files/ygbr3Tg6Rhi3yUASPfOX" alt=""><figcaption></figcaption></figure>

If you would like to have a persistent URL to access your privately deployed management console then you will need to stand up a load balancer in front of it. You can read more on this topic on the [Deployment Details](/how-it-works/deployment-details) and [Advanced Deployment Considerations](/getting-started/how-to-deploy/advanced-deployment-considerations) page.

## Advanced Deployment Considerations

The 5 fields discussed above are the minimum fields that have to be set to get the product successfully deployed. For many deployments, the default settings will work well. With that said, the other options in the CloudFormation Template could be beneficial for you to configure and therefore could warrant your attention.

To view details for configuring additional settings within your CloudFormation Template you can review our [Advanced Deployment Considerations](#advanced-deployment-considerations) section. Feel free to **SKIP** this section if you just want to start with the defaults. However, please consider **two exceptions**:

1. By default, the stack will deploy without the use of a Load Balancer. There are times when this will not work for your use case. Two such scenarios are: you want to use your own DNS and SSL certificate or you want to deploy in a private subnet behind a NAT. These are both great reasons to leverage a load balancer.

   If you would like to include a load balancer at the time of deployment you can do so in your CloudFormation Template. You can also add a load balancer to an existing deployment without one. And you can remove the load balancer after the fact as well. Simply run a Stack Update and add or remove the load balancer. This must be done manually through the CloudFormation Console.
2. Resources can only be renamed to match your particular naming scheme at the time of deployment. Changing these values later will result in errors. The default values are fine to leave but if you feel the need to rename values such as your quarantine bucket you should do so now before you've deployed.

You can learn more about both of the above considerations by reviewing our [Advanced Deployment Considerations](#advanced-deployment-considerations) section.

## After you have finished deploying

You have completed creating the stack for Antivirus and/or Data Classification for Amazon S3. Next, go to the [How to Configure](/getting-started/initial-config) section to start setting up the anti-malware detection.


# Advanced Deployment Considerations

The CloudFormation template can optionally be customized beyond the default settings.

The 5 fields discussed in [Steps to Deploy](/getting-started/how-to-deploy/steps-to-deploy) are the minimum fields that have to be set to get the product successfully deployed. For many deployments, the default settings will work well. With that said, the other options in the CloudFormation Template could be beneficial for you to configure and therefore could warrant your attention.

To view details for configuring additional settings within your CloudFormation Template you can review the sections below on this page. Feel free to **SKIP** this article if you just want to start with the defaults. However, please consider **two exceptions**:

1. By default, the stack will deploy without the use of a Load Balancer. There are times when this will not work for your use case. Two such scenarios are: you want to use your own DNS and SSL certificate or you want to deploy in a private subnet behind a NAT. These are both great reasons to leverage a load balancer.

   If you would like to include a load balancer at the time of deployment you can do so in your CloudFormation Template. You can also add a load balancer to an existing deployment without one. And you can remove the load balancer after the fact as well. Simply run a Stack Update and add or remove the load balancer. This must be done manually through the CloudFormation Console. Specific steps to setting up a load balancer in your CloudFormation Template can be viewed below.
2. Resources can only be renamed to match your particular naming scheme at the time of deployment. Changing these values later will result in errors. The default values are fine to leave but if you feel the need to rename values such as your quarantine bucket you should do so now before you've deployed.

## Console and Agent Sizing - vCPU and Memory

The default values provided for both the Console and the Agents will meet the needs of the vast majority of customers. If any changes are made initially, you could up the Console settings if you plan to do large sets of Scheduled Scanning or regular assessment reports. You could also adjust the Agents down to 1vCPU and 3GB Memory for similar performance and about half the cost. All of the [performance testing](/how-it-works/sizing) we have done has been with 2/4, but we saw very little impact on CPU overhead and memory that reducing both of those should work. Additional testing will come with different configurations in the near future.

If you do decide to make changes for either task, you must specify the proper vCPU:Memory ratio. The memory must be in the range of 2x to 8x of the vCPU.

> vCPU = .5, then 1gb <= memValue <= 4gb
>
> vCPU = 1, then 3gb <= memValue <= 8gb
>
> vCPU = 2, then 4gb <= memValue <= 16gb
>
> vCPU = 3, then 6gb <= memValue <= 24gb
>
> vCPU = 4, then 8gb <= memValue <= 32gb

{% hint style="info" %}
The new minimum memory requirement for agents is 3gb. We no longer offer a 2gb memory choice as we saw unstable scanning results with this value.

***

Agent vCPU and Memory recommendations have changed. We recommend to run the scanning agents with 1 vCPU and 3gb Memory. The defaults have been 2 vCPU and 4gb Memory, but we are finding there is no advantage to those settings at the moment. Switching to 1 and 3 is a worthwhile cost savings while having no impact on performance. In the [Performance Throughput Table](/how-it-works/sizing#throughput-table) the ClamAV numbers were produced with 2vCPU and 4gb Mem, but the Sophos numbers were run with 1vCPU and 3gb Mem. In subsequent testing, we saw no noticeable reduction in performance with ClamAV as well.
{% endhint %}

{% hint style="danger" %}
If the memory specified for the Console and Agent are not within the proper range, you will see the following:
{% endhint %}

<figure><img src="/files/QSWqNAOZ8Ap83JtclDc9" alt=""><figcaption></figcaption></figure>

These values can be changed after the fact. Go to the [Console Settings](/console-overview/configuration/console-settings#console-task-settings) page to modify the console specs. Go to the [Agent Settings](/console-overview/configuration/agent-settings) page to modify the agent specs.

## Access to KMS Encryption Keys

<figure><img src="/files/AXQESwZmL7ziFYKPDdSU" alt=""><figcaption></figcaption></figure>

The default value is `Yes` and this is our preference to simplify scanning for you. In order to scan objects in buckets with a KMS Key assigned, the Scanning Agent Role requires access to the key. This setting gives the scanner role access to all KMS keys, but with only the scope to use with Amazon S3. This is good for when new buckets come online and use new keys for the encryption or you change the keys on existing buckets. The scanning agent will automatically be ready to go without a hitch.

Alternatively, you can select `No` and then manually, individually assign keys to the scanner role. Check this [trouble shooting writeup](/trouble-shooting/objects-show-unscannable-with-access-denied) for more information. This value can be changed post-deployment as well by following the trouble shooting link.

## Auto Assign Public IPs - Console and Scanning Agents

<figure><img src="/files/l7cFmocF081EYxMMhnRc" alt=""><figcaption></figcaption></figure>

The default value is `Enabled` and this will assign public IPs to the Console and Scanning Agent tasks. For the scenarios where you will not be leveraging the public IP or do not want the IP assigned at all, you can switch these values (one or both) to `Disabled` and we will not assign a public IP.

## Agent Auto-Scaling Configuration

<figure><img src="/files/uQCq6CsqSr8V6it17K72" alt=""><figcaption></figcaption></figure>

The default selections will set you up to have an scanning agent running 24x7x365. Depending on your workflow and your time-to-verdict requirements, you may not need a scanning agent running all the time. Changing the `Only Run Scanning Agents When Files are in Queue` option to **Yes** will set the scanning agents to shut down completely when there is no work to be done. We call this feature [Smart Scan](/console-overview/configuration/agent-settings#smart-scan) This is great for cost efficiencies, but does slow down how quickly a file is scanned as it takes 60-90 seconds to spin a scanning agent up. Decide what your requirements are and then fill this section out.

When you switch `Only Run ...` to **Yes**, you must change the `Minimum Number of Agents Per Region` to **0**. `Maximum Number of Running Agents Per Region` can be set to any value. It can be left high or reduced down to some smaller number so you know exactly how many agents will spin up at any given time.

`Number of Messages in Queue to Trigger Scaling` is used to determine when the first or next scanning agent will spin up. If you are in Smart Scan mode then it will determine when the first agent spins up. Most leverage Smart Scan with a value of **1**, but some like to let the work build up a bit before they spin a scanning agent up. Choose a number that makes sense for your organization.

Alternatively, you can create [Scheduled Scans](/console-overview/scheduled-scans) that allow you to only spin up scanning agents on a schedule basis to scan your objects (all or new).

**Note:** *all of these settings can be changed after the fact from our* [*Management Console Agent Settings*](/console-overview/configuration/agent-settings) *page*

## Optional Load Balancer Configuration

<figure><img src="/files/KNGtPynITEHkjQbKlJiz" alt=""><figcaption></figcaption></figure>

By default, the stack will deploy without the use of a Load Balancer. Instead if you deploy using public subnets, we register your console IP with a subdomain tied to the `cloudstoragesecapp.com` domain in a Route53 hosted zone inside one of our Cloud Storage Security AWS accounts. If you deploy using private subnets, you will need to use the private IP that is generated by the ECS task that is stood up to host the console [as mentioned here](/getting-started/how-to-deploy/steps-to-deploy#accessing-a-private-deployment).

There are times when this will not work for your use case. Two such scenarios are:

1. You want to use your own DNS and SSL cert
2. You want to deploy using private subnets behind a NAT but you also want a persistent URL that you can use to access the management console, instead of the private IP address of the console service task which will change anytime the console service reboots.

These are both great reasons to leverage a load balancer.

### **Required Fields**

There are 5 fields you must provide values for in your CFT in order to stand up a load balancer:

#### Use a Load Balancer

* `Use a Load Balancer for the Console` - change this to **Yes**

You'll need to specify that you want to use a load balancer. If this option is set to `No` the load balancer will not be deployed.

#### SSL Certificate

* `SSL Certificate ARN` - specify the **ARN** to a certificate accessible in-region

While load balancers in AWS may not require SSL certificates in order to be stood up, because we are security-centric we require an SSL certificate as part of the LB setup process. Usually, we recommend using a wildcard SSL certificate since most of our customers access their console through a subdomain. This SSL certificate needs to either be requested through AWS Certificate Manager (ACM) **OR** created elsewhere with any third-party you may use for your certificate authority and then imported into ACM.

If you are unfamiliar with ACM or importing certificates into ACM, [this section](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate.html) of the AWS ACM User Guide discusses importing certificates.

If you are exporting the certificate from a third-party it may not be in the PEM format AWS requires for importing certificates. If that's the case, AWS offers a blog article that discusses converting the certificate file to the PEM format using OpenSSL. You can read that article [here](https://aws.amazon.com/blogs/security/how-to-import-pfx-formatted-certificates-into-aws-certificate-manager-using-openssl/). While this article discusses converting from PFX to PEM format, other common formats for SSL certificates do exist and you'll be able to find resources online for converting the format using OpenSSL.

Once you have an SSL certificate that you can use in ACM you will need to take the ARN value of the certificate and paste it into the `SSL Certificate ARN` field of your CFT.

#### Load Balancer Scheme

* Should the load balancer be `internet-facing` or `internal`?

If you are using public subnets for your Load Balancer then it would make sense to set this to internet-facing. If you are using private subnets then you should set this to internal.

#### Subnet A ID and Subnet B ID

* `Load Balancer Subnet A ID` - specify the **Subnet ID** found in the AWS console
* `Load Balancer Subnet B ID` - specify a different **Subnet ID** found in the AWS console

Similar to your Management Console, you'll need to select two public or private subnets for your Load Balancer. You can choose the same subnets that you used for your Management Console if you want to reuse them.

{% hint style="warning" %}
Load Balancer subnets and the Console subnets **must** be in the same Availability Zones (*this is an AWS requirement*). For example, the Console gets put in private-subnet1 in AZ-a and private-subnet2 in AZ-b, then the load balancer should be placed in public-subnet1 in AZ-a and public-subnet2 in AZ-b. If the subnets do not match availability zones the load balancer will not be able to communicate with the console
{% endhint %}

### Submit the CFT and optionally Configure a Custom URL

Once the above fields have been configured you are ready to submit the CFT and let it run. After the load balancer has been stood up there will be a load balancer URL that is generated.

If you use the Load Balancer URL you may receive a browser warning that the SSL certificate is not valid, since the certificate is associated with a different domain/subdomain. It is perfectly fine to continue using just the Load Balancer URL, however if you'd like to use a custom URL you can configure a CNAME record, either in Route53 or wherever you manage your DNS records, that points a custom URL to the Load Balancer URL.

If you use Route53 you can setup the custom URL as part of the optional fields mentioned below.

### **Optional Fields**

The remaining fields are optional. If you happen to be using Route53 for your domain, then you can leverage these fields to setup the DNS value (*although this can be done after deployment sa well*). If you are managing DNS in some other way, you can skip these fields and setup DNS how you normally would to point at the Load Balancer URL.

* `Register a subdomain on Route53` - change this to **Yes**
* `Hosted Zone Name` - specify the **base domain value**
* `Subdomain` - specify the **unique meaningful name** to access the Antivirus for Amazon S3 application
* `Info Opt-Out` - do not send any DNS info and version information to us
* `Container Security Group ID` - You may specify your own security groups for us to utilize. We will add the necessary ingress routes to them. This is generally only necessary if you have an internal policy that requires all resources to be tagged at creation time

## Optional Local Image Repository

<figure><img src="/files/K4cHe7R9WhmX45Y46ekr" alt=""><figcaption></figcaption></figure>

If you have a requirement to host the repo for the container images, you can specify an `account number` in this field to instruct the Console and Scanning Agents where to look to retrieve their images. Simply create the repos in your own account, name them as required (cloudstoragesecurity/console and cloudstoragesecurity/agent), download the images from our repos and place them into your own repo. When the console or scanning agents boot up they will look to your local repo for updates.

### How to Setup Local ECR Mirroring For CSS Console & Agent Repositories

1. Go to CodeBuild
2. Go to "Build projects"
3. Click "Create build project"
4. Provide name, such as "ReplicateCloudStorageSecEcr"
5. Choose "No source" for Source provider
6. Select Managed image - Ubuntu - Standard - aws/codebuild/standard:5.0 - Always use latest
7. Check box for "Enable this flag if you want to build Docker images..."
8. Either create a new service role or point at an existing one you have (that you can modify to add additional permissions to)
9. Expand Additional configuration.
10. Add environment variables:
11. Name: AWS\_DEFAULT\_REGION Value: the region name you are placing this project and the ECR repos in (for example, us-east-1, but your specific region)
12. Name: AWS\_ACCOUNT\_ID Value: the account ID you are placing this project and the ECR repos in
13. You can leave everything else in the additional config as default settings, or customize as desired (vpcs/subnets/etc)
14. Buildspec - switch to editor, and paste in the provided code
15. Logs - customize as desired
16. Click "Create build project"
17. In the new build project, go to "Build triggers" and if desired, add a trigger for the project to run at the desired interval (recommended to run daily)
18. In IAM, go to the role that was created or the existing role you pointed to, and add a new inline policy matching the one provided. Keep in mind that you have to fill the \<region>,\<your\_account\_id>, \<your\_codebuild\_project\_name> and pieces.

#### Buildspec

```
version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to CloudStorageSec Amazon ECR repos...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin 564477214187.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/console
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin 564477214187.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/agent
      - echo Logging in to local Amazon ECR repos...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/console
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/agent
  build:
    commands:
      - echo Build started on `date`
      - echo Getting latest tags...
      - LATEST_CSS_CONSOLE_TAG=$(aws ecr list-images --registry-id 564477214187 --repository-name cloudstoragesecurity/console --region $AWS_DEFAULT_REGION | jq -r '.imageIds | sort_by(.imageTag) | reverse | .[] | select(.imageTag != null) | .imageTag ' | head -n 1)
      - LATEST_CSS_AGENT_TAG=$(aws ecr list-images --registry-id 564477214187 --repository-name cloudstoragesecurity/agent --region $AWS_DEFAULT_REGION | jq -r '.imageIds | sort_by(.imageTag) | reverse | .[] | select(.imageTag != null) | .imageTag ' | head -n 1)
      - LATEST_CUSTOM_CONSOLE_TAG=$(aws ecr list-images --registry-id $AWS_ACCOUNT_ID --repository-name cloudstoragesecurity/console --region $AWS_DEFAULT_REGION | jq -r '.imageIds | sort_by(.imageTag) | reverse | .[] | select(.imageTag != null) | .imageTag ' | head -n 1)
      - LATEST_CUSTOM_AGENT_TAG=$(aws ecr list-images --registry-id $AWS_ACCOUNT_ID --repository-name cloudstoragesecurity/agent --region $AWS_DEFAULT_REGION | jq -r '.imageIds | sort_by(.imageTag) | reverse | .[] | select(.imageTag != null) | .imageTag ' | head -n 1)
      - |-
          if [ -z $LATEST_CUSTOM_CONSOLE_TAG ] || [ "$LATEST_CSS_CONSOLE_TAG" != "$LATEST_CUSTOM_CONSOLE_TAG" ]; then
            echo "Newer Console image available. Copying image..."
            docker pull 564477214187.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/console:$LATEST_CSS_CONSOLE_TAG
            docker tag 564477214187.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/console:$LATEST_CSS_CONSOLE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/console:$LATEST_CSS_CONSOLE_TAG
            docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/console:$LATEST_CSS_CONSOLE_TAG
            echo "Console $LATEST_CSS_CONSOLE_TAG Copied"
          else
            echo "Console image is up to date."
          fi
      - |-
          if [ -z $LATEST_CUSTOM_AGENT_TAG ] || [ "$LATEST_CSS_AGENT_TAG" != "$LATEST_CUSTOM_AGENT_TAG" ]; then
            echo "Newer Agent image available. Copying image..."
            docker pull 564477214187.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/agent:$LATEST_CSS_AGENT_TAG
            docker tag 564477214187.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/agent:$LATEST_CSS_AGENT_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/agent:$LATEST_CSS_AGENT_TAG
            docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/cloudstoragesecurity/agent:$LATEST_CSS_AGENT_TAG
            echo "Agent $LATEST_CSS_AGENT_TAG Copied"
          else
            echo "Agent image is up to date."
          fi
  post_build:
    commands:
      - echo Build completed on `date`
```

{% hint style="warning" %}
You are now responsible for ensuring your local repos get updated. Our solution will now only look to your repo for updates.
{% endhint %}

#### IAM INLINE POLICY

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:logs:<region>:<account-id>:log-group:/aws/codebuild/ReplicateCloudStorageSecEcr",
                "arn:aws:logs:<region>:<account-id>:log-group:/aws/codebuild/ReplicateCloudStorageSecEcr:*"
            ],
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::codepipeline-<region>-*"
            ],
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "codebuild:CreateReportGroup",
                "codebuild:CreateReport",
                "codebuild:UpdateReport",
                "codebuild:BatchPutTestCases",
                "codebuild:BatchPutCodeCoverages"
            ],
            "Resource": [
                "arn:aws:codebuild:<region>:<account-id>:report-group/ReplicateCloudStorageSecEcr-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ecr:BatchGetImage",
                "ecr:GetDownloadUrlForLayer",
                "ecr:ListImages"
            ],
            "Resource": [
                "arn:aws:ecr:<region>:564477214187:repository/cloudstoragesecurity/agent",
                "arn:aws:ecr:<region>:564477214187:repository/cloudstoragesecurity/console"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:CompleteLayerUpload",
                "ecr:InitiateLayerUpload",
                "ecr:ListImages",
                "ecr:PutImage",
                "ecr:UploadLayerPart"
            ],
            "Resource": [
                "arn:aws:ecr:<region>:<account-id>:repository/cloudstoragesecurity/agent",
                "arn:aws:ecr:<region>:<account-id>:repository/cloudstoragesecurity/console"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

## Optional AWS Resource Renaming

{% hint style="danger" %}
Do not change after the initial deployment. If you feel you need to rename any resources after deployment, please [Contact Us](/contact-us). There are ways to rename most services, but you need to be aware of the impacts.
{% endhint %}

<figure><img src="/files/iq67yr0EBMjHglycXlbX" alt=""><figcaption></figcaption></figure>

By default, we uniquely name each resource we deploy with `CloudStorageSec-`. We often include the resource type (i.e. Queue) and append the unique application ID. When customers have a formal naming standard they would like to see our resource naming follow suite. Leveraging the fields in this section will allow you to rename all resources. Be aware, you should do this at the time of deployment. It can be done after, but it has to be done with care.

{% hint style="info" %}
We are calling these "prefix naming" because we must still append the unique `appID` to each resource.
{% endhint %}

## Optional Security Group ID

<figure><img src="/files/95i8ZFenw5yrOEJK0ApL" alt=""><figcaption></figcaption></figure>

You may specify your own security groups for us to utilize. We will add the necessary ingress routes to them. This is generally only necessary if you have an internal policy that requires all resources to be tagged at creation time.

We do tag all resources, but CloudFormation will perform that tagging action in a separate step for Security Groups, so there is a short period of time during which they are untagged.


# AWS Transfer Family

Ensure the data that is moved into Amazon S3 via AWS Transfer Family is free of ransomware, viruses, trojans and other payloads by scanning it inline with Antivirus for Amazon S3

## Deployment Options

Deploy AWS Transfer Family and antivirus scanning at the same time in 5-15 minutes via an AWS CloudFormation Template. If you are new to Transfer Family, everything you need to be up and running will be deployed for you. If you are already using Transfer Family, it is easy to select the S3 buckets linked with your Server to deploy antivirus scanning.

{% hint style="info" %}
If you are currently subscribed to the Antivirus for Amazon S3 product and have a Transfer Family Server deployed, all you need to do is [protect the S3 bucket](https://help.cloudstoragesec.com/console-overview/protected-buckets) linked to your Transfer Family Server to ensure its contents are clean.
{% endhint %}

### Step 1 - Create Stack and Specify the Parameters

First, ensure that you are deploying the software in the desired region.

Next, we need to review and configure the CloudFormation template:

<figure><img src="/files/Qo1ckNAEkyneaM99jIxN" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/bzLzdqOSUFBWu9PFrKfS" alt=""><figcaption></figcaption></figure>

1. Set your Stack name
2. Set your Admin User Name
   * This will be the initial user created for the console management website, with admin-level permissions. If modifying the default value, ensure the name entered is three characters or greater.
3. Admin User Email Address
   * Login credentials for the Console management account will be sent to this address.
4. Virtual Private Cloud (VPC) ID
   * The public-facing console will be deployed within this VPC.
5. Two Subnets
   * Choose two subnets that the console can be placed within, and ensure they both allow for outbound internet traffic.
   * The subnets you choose for A and B must either be able to offer a public IP or be on a network you can access. Without that, the console will run, but not be reachable. This could simply be a public subnet reachable through an Internet Gateway. Or it could be a private subnet that is an extension of your corporate network you access either from your corporate network or through a VPN connection. Or these subnets maybe private subnets fronted by a public Load Balancer. Learn more about this option in the [Advanced Deployment Considerations](https://help.cloudstoragesec.com/getting-started/how-to-deploy/advanced-deployment-considerations).
6. Console Security Group CIDR Block
   * Enter an IP address range that can access the console.
   * Specify your network access or set to "0.0.0.0/0" to access the console from anywhere.
   * 0.0.0.0/0 is wide open to the world. The application is still protected by SSL, a username and a password, but you may still choose to control this access. This could be your corporate network range or the /32 IP address your specific system is currently assigned. Google "what's my ip" and the first thing returned is what your current IP address is. Note: If your IP address changes, you may have to manually change the AWS Security Group value to represent the new IP
7. Agent Scanning Engine
   * Choose the engine that should be used to scan files.
   * Please refer to our [Marketplace listing](https://aws.amazon.com/marketplace/pp/prodview-q7oc4shdnpc4w?__hstc=80615752.c71ffa01d1c528c694f9175d7594c9f7.1689623283745.1689705638784.1689987286735.3&__hssc=80615752.1.1689987286735&__hsfp=4022829000\&hsCtaTracking=322b61f7-7ca4-4b9e-8324-0d6bb79af66c%7C43f96aaf-3308-43f1-8c49-8f730e4fba85#pdp-pricing) for pricing differences between the different engines.
8. Multi-Engine Scanning Mode
   * Choose how many engines you want to use to scan your files:
     * Disabled will use a single engine.
     * All will scan every file with both engines.
     * LargeFiles will scan files larger than 2GB using the Sophos engine.
9. Agent Disk Size
   * Choose a larger disk size (up to 200 GB) to enable scanning larger files.
   * Note that this only applies when using the Sophos scanning engine.
10. Enable Large File Scanning
    * If "Yes" is selected, an EC2 instance will be launched if a file is found to be too large to be scanned by the normal agent.
11. Extra Large File Disk Size
    * Choose a larger disk size (between 20 - 16,300 GB) to enable scanning larger files, up to 5 GB fewer than the total disk size.
    * Note that this only applies when using the Sophos scanning engine with EC2 large file scanning enabled.
12. Buckets to Protect
    * Enter any pre-existing buckets that you would like to have event-based protection enabled on when the console is launched.
    * Bucket names must be separated by commas (e.g. bucket1,bucket2,bucket3)
    * Note that this only works for buckets in the same region as this deployment.
13. Existing Transfer Family Server
    * If you do not have an existing Transfer Family Server, or would like a new one created, set this option to ‘No’, and a Transfer Family Server will automatically be deployed for you.
14. Quick Start Disable Auto-Protect
    * When set to 'No', the bucket which is created to store files uploaded to the Transfer Server is automatically protected by the console.
    * Note that this only applies when you have chosen ‘No’ for the Existing Transfer Family Server setting

### Step 2 - Review Stack and Acknowledge

1. Review all settings for accuracy
2. Check the following items at bottom of the CloudFormation template:
   * `I acknowledge that AWS CloudFormation might create IAM resources with custom names.`
   * `I acknowledge that AWS CloudFormation might require the following capability: CAPABILITY_AUTO_EXPAND`
3. Click `Create Stack` at the bottom of the screen.

<figure><img src="/files/vMxLTISP1m4nsfmqLhjr" alt=""><figcaption></figcaption></figure>

### Step 3 - Console Access

Once the stack creation completes, click the Output tab. The top row in the table will have the URL for your Management Console. It will be in the format of `https://<accountID-appID>.cloudstoragesecapp.com`.

You will also receive an email to the address you entered in the Admin User Email field while configuring your CloudFormation Template.

It may take a few minutes for DNS to propagate the URL of your management console. If you are unable to load the URL provided in the email/CloudFormation Outputs then wait a few minutes. If it continues to be an issue, check the console access troubleshooting to see if it is another issue or Contact Us.

{% hint style="info" %}
If you chose to use a load balancer, the first field will be called `LBWebAddress` instead of `ConsoleWebAddress`.
{% endhint %}

### Step 4 - Ensure Connectivity to the Transfer Family Server (Optional)

If you did not have a Transfer Family Server created as part of your deployment you can skip this step.

Before you can connect to the Transfer Family Server, you must first login to the console. Follow these steps if you skipped Step 4.

1. Login to the email address previously added to the Admin User Email field within the CloudFormation Template during deployment.
2. Locate the Antivirus for Amazon S3 - Console Account Information email.
3. Open the console link and login using the provided temporary credentials.
4. Upon login you will be prompted to update your password.

{% hint style="info" %}
The username and password entered to connect to the console is the same username and password that will be used to connect to the Transfer Family Server.
{% endhint %}

5. Login to the AWS Transfer Family console and review the pre-configured settings of the Server created on your behalf.
   * You can obtain the Transfer Family Server Id by reviewing the Outputs from the CloudFormation Template.
6. We recommend that you connect to your server and upload a test file.
   * Please note that:
     1. The server's protocol will be SFTP (SSH File Transfer Protocol) - file transfer over Secure Shell.
     2. The server will have a public endpoint.
     3. A Lambda function is created during the deployment and will validate authentication for secure file transfers.
     4. Files will be uploaded to S3 directly and will trigger an event-based scan by Antivirus for Managed File Transfers.

### Configure the Antivirus for Amazon S3 Console

You have completed creating the stack for Antivirus for Amazon S3 and Transfer Family.

Next, go to the [How to Configure](/getting-started/initial-config) section to start setting up the anti-malware detection.


# How to Configure

Once you've deployed Amazon S3 and/or Data Classification for Amazon S3 you can start to configure your settings through the management console.

As we saw in the previous steps, we have made some configuration decisions already such as networking and container and queue sizing. The remaining configuration revolves around enabling scanning on your preferred buckets. We've made this simple for you. Now that we have subscribed to and deployed, let's jump into the Console to start scanning your buckets.

{% hint style="info" %}
It may take a few minutes for DNS to propagate the URL of your management console. If you are unable to load the URL provided in the email/CloudFormation Outputs then wait a few minutes. If it continues to be an issue, check the [console access troubleshooting](/trouble-shooting/i-cannot-access-the-management-console) to see if it is another issue or [Contact Us](/contact-us).

The email with the login credentials arrives in your inbox even before the CloudFormation deployment completes. Please wait until you see the stack creation process complete to access the console.
{% endhint %}

## Step 1 - Launch and sign into the Management Console

Open your browser of choice (Chrome, Firefox, Edge, Safari, etc.) and navigate to the `access URL` you retrieved in the [Steps to Deploy section](/getting-started/how-to-deploy/steps-to-deploy). You will be taken to the Console Login page as seen below.

<figure><img src="/files/xTxdkCPgJv1YHwVCPFtx" alt=""><figcaption><p>Management Console Sign In</p></figcaption></figure>

During deployment, you were sent an email with information on how to sign in to the console. This email contains the current `access URL` as well. You can simply click that to launch the console.

<figure><img src="/files/sP4z4ArDnnRbZUx6gT0e" alt=""><figcaption><p>Invite Email</p></figcaption></figure>

Each additional user created through the console will also receive a similar email.

### Sign into the Management Console

As seen above, an email is sent to you to provide your `User Name` and `Temporary Password`. Place the username and temporary password into the appropriate fields and click `Log in`.

The first thing you must do is replace the temporary password by creating a new password for your user.

<figure><img src="/files/lNVLe0QcEa9pc48FWoed" alt=""><figcaption><p>Change Password</p></figcaption></figure>

Clicking `Change Password` will save your new password and pass you through to the console dashboard.

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

<figure><img src="/files/Gi8p0gYW9w9qeRM854ih" alt=""><figcaption><p>Antivirus for Amazon S3 Console Dashboard</p></figcaption></figure>
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}

<figure><img src="/files/xXXg5jnacVbr2TeGtiYy" alt=""><figcaption><p>Data Classification for Amazon S3 Console Dashboard</p></figcaption></figure>
{% endtab %}
{% endtabs %}

We'll get into [greater details](/console-overview/console-overview) about what you see here, but for now just know this is the overall status view into your environment.

{% hint style="info" %}
You can leverage SSO with our solution. Check out the [SSO FAQ](/faq/architecture-related#can-i-leverage-single-sign-on-sso-with-your-product) which discusses it.

You must have at least one internal user setup and usable to enable the SSO users (one time) within the console.
{% endhint %}

### Step 2 - Enable Scanning and/or Classification <a href="#step-2-enable-bucket-scanning" id="step-2-enable-bucket-scanning"></a>

Once you've signed in for the first time after deploying either of our products you'll notice the top information banner indicating the following:

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

<figure><img src="/files/WOtz7oZ18RJD06n47AtT" alt=""><figcaption></figcaption></figure>

The information banner has 5 steps to get you started. All 5 steps have links to useful spots in the documentation to quickly get you started. The second will also direct you to the `Bucket Protection` page under Configuration where you will be able to enable your first bucket for scanning. Click the `Switch to the Protected Buckets page` link to enable your first Amazon S3 Bucket.

You could also have selected `Bucket Protection` from the left navigation.

<figure><img src="/files/fpPqTgMN9eCRfTs50F8L" alt=""><figcaption></figcaption></figure>

Displayed to you are all of the buckets within your AWS account. It is quite easy to enable scanning for a bucket, simply select one or multiple checkboxes (or leverage `Select Visible` to select all currently shown) for the buckets you wish to protect and select `Turn On Selected` from the `Actions` drop-down button at the top of the bucket list. To get started pick a bucket in the same region as your console and turn it on. This will enabled the bucket for new object, event-based scanning.

Info

There are 3 types of protection we will be getting into more detail as we go. But, those 3 types are: event-based (this is real-time protection), schedule-based (protection on a schedule) and on-demand protection. As stated above, you enabled the event-based real-time protection with what you just did above.

You will also be prompted to scan the existing objects in the bucket(s). You have the choice to skip this by clicking the `Don't Scan` button or follow the instructions to select some or all of the buckets you had turned on to scan the existing objects as well.

<figure><img src="/files/SsJ1EdHj9D3wnk3wDpJ1" alt=""><figcaption></figcaption></figure>

**That's it!**\
Once you are to this point, you should see a green shield (![green shield](https://help.cloudstoragesec.com/img/green-shield.png)) in the row for any bucket you "turned on" above.

[More details](/console-overview/protection/aws/protected-buckets#scan-existing-objects) about scanning existing objects will be covered.

{% hint style="info" %}
Clicking `Don't Scan` will not turn off event based scanning for those buckets you turned on. It will only skip the scanning of existing objects.

Enabling a bucket(s) will automatically deploy the Agent Scanner in the region the bucket is located. If you selected buckets from multiple regions, you will get an Agent Scanner in each.

Notice the `Account` identifier shows as `Primary`. This represents the default account you deployed the solution in. If you [link accounts](/console-overview/access-management/linked-accounts) for cross-account scanning, you will see a different identifier for those buckets that come from other accounts.
{% endhint %}

{% hint style="warning" %}
You may see rows with a yellow, red or purple background color (you should not see purple on your initial installation) to them. Yellow and red colors (as seen above) indicate there could be a conflict with activating event-based scanning for those particular buckets and you **may** have to take additional steps to enable scanning.

For information on how to resolve conflicted buckets, please read the [Trouble Shooting](/trouble-shooting/conflicted-buckets) section.

"Conflicted" buckets have no barrier for scan existing object scans. Since `scan existing` crawls the objects (read more [here](/how-it-works/object-scanning#retro-scanning)) and is not triggered by events, there are absolutely no conflicts. Scan existing away!
{% endhint %}

## Which Resources do I Protect? <a href="#which-buckets-do-i-enable" id="which-buckets-do-i-enable"></a>

Protect them all! As simple as that sounds, you can decide which resources you do and don't want to protect. All resources with any public aspects to them should be scanned. Any resources you share with others (public or not) should generally be scanned as you want to ensure what is shared is clean. No matter whether you choose to enable all or a subset it is easy and you can feel comfortable your files will be clean. Resources that may be written by trusted programs like CloudTrail may not need to be scanned, but can be if regulations require you to.

## Enabling Buckets in Other Regions <a href="#enabling-buckets-in-other-regions" id="enabling-buckets-in-other-regions"></a>

This solution is designed to scan all of your buckets, whether in one or multiple regions. If you select buckets in regions other than the console **for the first time**, you will be prompted to select a VPC and Subnet(s) for that region. Because we'll be deploying the Agent Scanner container to that region you must identify the networking for it to run on.

Selecting a bucket in a different region prompts you as follows:

<figure><img src="/files/uPL7x2NSZQSrqHsZjWR5" alt=""><figcaption></figcaption></figure>

Select the VPC and Subnet(s). You will be presented with VPC and Subnet selections for each new region you are enabling buckets in. Click `Save and Close`.
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}

<figure><img src="/files/qBTbPvUZKsBuJtxyyeJe" alt=""><figcaption></figcaption></figure>

The information banner has 5 steps to get you started. All 5 steps have links to useful spots in the documentation to quickly get you started. The second will also direct you to the `Schedules` where you will be able to create and execute your first schedule for classification scanning.

You could also have selected `Schedules` from the left navigation.

<figure><img src="/files/548KHVFWcNECRlK4NESJ" alt=""><figcaption><p>Schedules Page</p></figcaption></figure>

Initially displayed to you is the blank Schedules page as none are created by default. It is quite easy to create a schedule, simply click the `Create Schedule` button and follow the wizard. Creating a schedule includes three tasks: select which buckets to scan, the rules to check against and the timing to run. For this first schedule, pick buckets within the same region of the deployment.

## Creating a Classification Schedule

### Step 1: Select Buckets

![Create Schedule step 1](/files/SqywRakx2eVD17GZTqac)

### Step 2: Select Rules

<figure><img src="/files/qlRccE1YPyyzBoArGP0f" alt=""><figcaption></figcaption></figure>

### Step 3: Select Run Time

<figure><img src="/files/IlGvEqO2YXdOxTtI50wg" alt=""><figcaption></figcaption></figure>

### Step 4: Activate Schedule

To complete the process you must activate the schedule:

<figure><img src="/files/3lUXbtwj32yuEhkztOJB" alt=""><figcaption></figcaption></figure>

You can choose to execute the first pass of the schedule now if desired.

<figure><img src="/files/snE6ZfeHTkvv1IuUPnyU" alt=""><figcaption></figcaption></figure>

We'll get into more details regarding creating and managing schedules on the [Scheduled Scans page](/console-overview/scheduled-scans)

**That's it!**

## Which Resources should I Classify? <a href="#which-buckets-should-i-scan" id="which-buckets-should-i-scan"></a>

Claissfy them all for sensitive data! As simple as that sounds, you can decide which resources you do and don't want to classify. You may already know which resources are leveraged in your workflows that could ingest sensitive data. You may be unaware of how and where that data has moved as individuals are processing it. All buckets with any public aspects to them should be scanned to ensure you are not leaking sensitive data. Any buckets you share with others (public or not) should generally be scanned as you want to ensure what is shared is clean and safe to share. No matter whether you choose to enable all or a subset it is easy and you can feel comfortable your files will be identified. Buckets that may be written by trusted programs like CloudTrail may not need to be scanned, but can be if regulations require you to.

## Classifying Resources in Other Regions <a href="#scanning-buckets-in-other-regions" id="scanning-buckets-in-other-regions"></a>

This solution is designed to scan all of your buckets, whether in one or multiple regions. If you select buckets in regions other than the console **for the first time**, you will be prompted to select a VPC and Subnet(s) for that region. Because we'll be deploying the Classification Scanner container close to the data in that region you must identify the networking for it to run on.

Selecting a bucket in a different region prompts you as follows:

![Select VPC and Subnets](/files/65M316luvOyHSv1mUZmo)

Select the VPC and Subnet(s). You will be presented with VPC and Subnet selections for each new region you are enabling buckets in. Click `Save and Close`.
{% endtab %}
{% endtabs %}

{% hint style="danger" %}
The VPC and Subnets you choose must have an outbound path to reach Amazon ECR. If not, the agents will [never boot properly](/trouble-shooting/my-scanning-agents-keep-starting-up-and-immediately-shutting-down). As discussed in the troubleshooting topic, you can do with outbound access to the internet or through VPC Endpoints that give you access to ECR and API.

We now show `Public` / `Private` next to each VPC to indicate whether or not the VPC is tied to an Internet Gateway and therefor likely to have an outbound path. We also show `Public` / `Restricted` next to each Subnet to indicate whether each Subnet appears to have outbound routing.

Some regions only support Fargate in some of the Availability Zones. Regions ap-south-1 and ca-central-1 have limited AZs. If you get a message saying the container task cannot start up due to capacity or a Fargate instance isn't available, that could indicate you have found another AZ not supported. Switch which AZ the Fargate Service is pointing at and you should be fixed.

You can get more information at this [AWS Fargate](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html) page. \* You'll notice ap-south-1 is called out, but ca-central-1 is not although we found the same issue in both regions.
{% endhint %}

## Enable API Scanning for Antivirus for Amazon S3 (optional)

API-based scanning is an alternative option where you can leverage an API to perform file scanning. It is not directly S3-integrated as **Step 2** provides, but API scanning is very useful in many workflows where you want the file scanned before it is written to is destination.

Read more about [API Based Scanning](/how-it-works/object-scanning#api-driven-scanning).


# Console Overview

In the How to Configure section, we covered our first bucket activation to enable scanning and our first data classification schedule. Now let's take a closer look at the rest of the console.

The following sections will walk you through each area of the console and what you can expect from it. The goal, in general, has been to make the scanning, classifying, and protection of your objects simple and straight forward. The console is simple to get around with left side and top navigation. The left side will take you between the main Dashboard view, Bucket Protection and/or Schedules page, the Configuration options and the User Management area. While the top allows for in-place upgrades, your account management options, and Group switching.

<figure><img src="/files/SiI0uu11YwiyV5q6eiKC" alt=""><figcaption><p>Console dashboard page</p></figcaption></figure>


# Dashboard

The Dashboard view is the window into your scanning and/or classifying status.

## Dashboard Overview

If you are using Antivirus for Amazon S3 it is made up of six main parts:

* Top Row Informational widgets
* Threat Map
* Total GBs Scanned chart
* Total Objects Scanned chart
* Total Problem File Objects chart
* Bucket Protection Status chart

If you are using Data Classification for Amazon S3 it is made up of six main parts:

* Top Row Informational widgets
* Threat Map
* Total GBs Classified chart
* Total Objects Classified chart
* Total Objects with Findings chart
* Bucket Protection Status chart

If you are using both tools within the same Management Console then you will see the above data separated for AV and DC within your dashboard.

Right after completing the initial configuration and enabling one bucket within the same region as the console, your Dashboard view could look as follows:

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

<figure><img src="/files/MxML2fsrg6z8oLylZn5K" alt=""><figcaption><p>Screenshot of the Home page when just the AV feature is enabled</p></figcaption></figure>
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}

<figure><img src="/files/AFylXrm3xyxLQIMqH8Mt" alt=""><figcaption><p>Screenshot of the Home page when just the DC feature is enabled</p></figcaption></figure>
{% endtab %}

{% tab title="Both tools in use at once" %}

<figure><img src="/files/JMiwAF8Qa0CWm5HXO5Oj" alt=""><figcaption><p>Screenshot of the Home page when both DC and AV features are enabled</p></figcaption></figure>
{% endtab %}
{% endtabs %}

### Top Row Widgets

The top row of widgets gives you a quick view to specific details around your environment. Whereas the charts below it give you more real-time data, the top row gives you the aggregate totals for the time slices for `Total Data Scanned` and `Total Objects Scanned` along with the total number of accounts protected within this deployment and total number of problem files found in the last 24 hours. Each informational is clickable. The `Total Data Scanned` and `Total Objects Scanned` will pop open the totals for each time slice. What is shown on the main page for those two are lifetime totals. The `Total Active Accounts` will redirect you to the [Linked Accounts](/console-overview/access-management/linked-accounts) page. The `Total Active Accounts` tells you all the linked accounts you have setup and whether they are actively being protected. The `Problem Files (24hr)` will redirect you to the [Problem Files](/console-overview/see-whats-infected/problem-files) page. The `Problem Files (24hr)` shows you the infected, error and unscannable file counts.

To see what it looks like, click between the tabs just below:

{% tabs %}
{% tab title="After initial configuration" %}

<figure><img src="/files/sV3XvuxFRJAi1tebAotC" alt=""><figcaption><p>Top row of widgets with no data</p></figcaption></figure>
{% endtab %}

{% tab title="With some data" %}

<figure><img src="/files/8rUHHVuwIOYUl3fTb0xX" alt=""><figcaption></figcaption></figure>

Top row of widgets with data
{% endtab %}
{% endtabs %}

### Threat Map

The Threat Map provides a centralized view of all regions, highlighting detected malware and the total S3 storage usage.

{% tabs %}
{% tab title="Threats by Region Map" %}

<figure><img src="/files/CED3Pb45nVOvusn4xUGS" alt=""><figcaption><p>Widget showing threats by region map</p></figcaption></figure>
{% endtab %}

{% tab title="S3 Storage by Region Map" %}

<figure><img src="/files/0wyxoKyhZl71BLT5phsS" alt=""><figcaption><p>Widget showing storage by region map</p></figcaption></figure>
{% endtab %}
{% endtabs %}

### **Threats by Region**

The *Threats by Region* map provides an overview of all regions containing buckets (AWS) or blob containers (Azure). It also indicates whether malware, suspicious files, or sensitive data have been detected, with the latter available only when Data Classification is enabled.

<figure><img src="/files/CED3Pb45nVOvusn4xUGS" alt=""><figcaption><p>Widget showing threats by region map</p></figcaption></figure>

![](/files/I3M0oLvYoNsr2i1eXnCz) A green region indicates no malware or sensitive data was found.

![](/files/wjr9FCwIhqYWmZvfrhS6) A yellow region indicates that suspicious files were found (with AV) or that sensitive data was detected (with DC).

![](/files/I16Kh9Nr0cnpJfFNR29s) A red region indicates malware was detected.

Clicking on one of the dots (green, yellow, or red in the legend) filters the view to show only regions where malware was found or not found:

<figure><img src="/files/7tdsRYynFjrdAb7OxK8M" alt=""><figcaption><p>Filters with green, yellow, and red relating to the above descriptions</p></figcaption></figure>

You can also switch with the toggle at the left side, to only see the regions from Azure or AWS

<div align="center"><figure><img src="/files/oLpHlUrNkjbH9fLizCTe" alt=""><figcaption><p>Toggle for the threats by region map to select cloud provider</p></figcaption></figure></div>

### Regional Information

By default, the right section of the threat map displays *Regional Information*. Here, you can view which containers contain malware and the total number of affected objects. The arrow icon ![](/files/5OmL8TXWwRv2M25a6sOJ) allows you to navigate to the **Problem File** page for more detailed malware information.

Similarly, if sensitive information is detected, the map displays the total number of affected buckets and objects. You can click the arrow icon to access these details on the **Findings** page.

<figure><img src="/files/vtyoWR25aRixODZTkphR" alt=""><figcaption><p>Widget in the threat map showing found malware and sensitive data.</p></figcaption></figure>

Hovering over a region on the map highlights specific information for that region.

<figure><img src="/files/g40Hmab84aW50nhO1v72" alt=""><figcaption><p>Widget in the threat map highlighting a region when hovered</p></figcaption></figure>

Clicking the refresh button ![](/files/BRIWaG6RN5rBoVgBLcSI) restores the default information for all regions.

### S3 Storage by Region

The **S3 Storage by Region map** displays the total amount of data and storage (in GB) across all your buckets. The size of the circles on the map indicates the relative amount of data stored in each region, helping you easily identify regions with higher or lower storage usage.

<figure><img src="/files/1q6nQUeQofdKkRHswNen" alt=""><figcaption><p>Widget showing storage by region map</p></figcaption></figure>

### **Regional information**

This section provides an overview of your **total storage usage**, including the combined number of GB, buckets, and objects across all your S3 storage.

<figure><img src="/files/FYEH3fSmgB4qsaZo7dwF" alt=""><figcaption></figcaption></figure>

When you hover over a specific region on the map, the details for that region—including the amount of data, number of buckets, and number of objects—are highlighted.

<figure><img src="/files/YQUOln1eO15QZp3C1nsc" alt=""><figcaption></figcaption></figure>

Clicking the refresh button ![](/files/BRIWaG6RN5rBoVgBLcSI) restores the default information for all regions.

### Configuration Dashboard Panel

Click the gear icon ![](/files/dKf5RC70IRn7sXBMzN2K) above the **Regional Information** section to open the **Configuration Dashboard Panel**. In this panel, you can customize the map view by selecting filters to display regions based on:

* The number of buckets
* The amount of data
* The number of objects

The size of the circles on the map will adjust dynamically based on the selected filter, visually emphasizing regions with higher values for your chosen metric.

<figure><img src="/files/RQJORP4edmLnvMeezn41" alt=""><figcaption><p>options for dashboard panel: filter by Total Size, Total Buckets, or Total Objects</p></figcaption></figure>

### Overview / Detailed Chart Information

The charts can give you high-level information or slightly more detailed information. This toggle is what determines what the charts will show. For example, in the `Total GBs Scanned` the Overview option will simply show a total number of GBs that have been scanned in the time slice selected. While the Detailed option will reflect the breakdown of the 3 scan types (event, retro and API).\
![Overview Detailed toggle](/files/kNzlVhiCZSZkJGV2u8T0)

### Time Window

You centrally control the time window the charts should reflect. The default is a 24 hour view when landing on the page. You can drop that to one hour or extend it out to cover a greater period of time. `Custom` allows you to specify a particular window of time that may not conform to the default selections.<br>

<div align="left"><figure><img src="/files/HqBKrV8vWmUE3oHgZO5Z" alt=""><figcaption><p>Filter allowing for time windows of 1 hour, 24 hours, 30 days, 90 days, or a Custom amount</p></figcaption></figure></div>

### Total GBs Scanned Chart

This chart represents the number of gigabytes scanned across all enabled buckets and regions (and [linked accounts](/console-overview/access-management/linked-accounts)). You can track the number of gigabytes in 6 time slices: 1 hour, 24 hour, 7 day, 30 day, 90 day and custom range from the central time window picker.

To see what it looks like, click between the tabs just below:

{% tabs %}
{% tab title="After initial configuration:" %}

<div align="left"><figure><img src="/files/tM2YwyHP8By68T0toKAL" alt=""><figcaption><p>Total GBs scanned chart with no data</p></figcaption></figure></div>
{% endtab %}

{% tab title="With some data:" %}

<div align="left"><figure><img src="/files/qQQvLiS5CV5iOibXSsIN" alt=""><figcaption><p>Total GBs scanned chart with some data</p></figcaption></figure></div>
{% endtab %}

{% tab title="Detailed Data View:" %}

<figure><img src="/files/0aqDaMNp2GcmbvFCbbdE" alt=""><figcaption></figcaption></figure>

Total GBs scanned chart with detailed data
{% endtab %}
{% endtabs %}

### Total Objects Scanned Chart

The number of objects or files scanned across all enabled buckets and regions (and [linked accounts](/console-overview/access-management/linked-accounts)). You can track the number of objects / files in 6 time slices: 1 hour, 24 hour, 7 day, 30 day, 90 day and custom range from the central time window picker.

To see what it looks like, click between the tabs just below:

{% tabs %}
{% tab title="After initial configuration:" %}

<div align="left"><figure><img src="/files/IbGBHMC5PK6JB2ePawGy" alt=""><figcaption><p>Total objects scanned chart with no data</p></figcaption></figure></div>
{% endtab %}

{% tab title="With some data:" %}

<div align="left"><figure><img src="/files/0UuPe2EqJaXmvK7I8bqR" alt=""><figcaption><p>Total objects scanned chart with some data</p></figcaption></figure></div>
{% endtab %}

{% tab title="Detailed Data View:" %}

<div align="left"><figure><img src="/files/b7fP4aKveZr9m05RwlhG" alt=""><figcaption><p>Total objects scanned chart with detailed data</p></figcaption></figure></div>
{% endtab %}
{% endtabs %}

### Total Number of Problem File Objects

The number of objects or files found to be infected, unscannable (exceeding file size limit or password protected) or in an errored state across all enabled buckets and regions (and [linked accounts](/console-overview/access-management/linked-accounts)). You can track the number of infected / exceeded file size / error files in 6 time slices: 1 hour, 24 hour, 7 day, 30 day, 90 day and custom range from the central time window picker.

{% hint style="info" %}

#### Note

**`Exceeded File Size`** files are currently only those over 2gb in size.

Password protected files and encrypted files are logged as unscannable.

If you work with a lot of these types of files please [Contact Us](/contact-us) and we'll work with you to get this sorted out.
{% endhint %}

To see what it looks like, click between the tabs just below:

{% tabs %}
{% tab title="After initial configuration:" %}

<div align="left"><figure><img src="/files/SWCIxdIDUtn2PA0qpMVc" alt=""><figcaption><p>Total problem files chart with no data</p></figcaption></figure></div>
{% endtab %}

{% tab title="With some data:" %}

<div align="left"><figure><img src="/files/Z3DJrV0e3GiKtfFylCI9" alt=""><figcaption><p>Total problem files chart with some data</p></figcaption></figure></div>
{% endtab %}

{% tab title="Detailed Data View:" %}

<div align="left"><figure><img src="/files/wAGH9y47rZccTDEziD7P" alt=""><figcaption><p>Total problem files chart with detailed data</p></figcaption></figure></div>
{% endtab %}
{% endtabs %}

### Bucket Protection Status

A by-region view of all of the buckets in your account and their current enabled status. If they are enabled for scanning by the console you are connected to, they will show in green. If they are enabled for scanning by another Cloud Storage Security Console, the will show in purple. If they are not enabled for scanning by any console, they will show in red.

To see what it looks like, click between the tabs just below:

{% tabs %}
{% tab title="After initial configuration:" %}

<div align="left"><figure><img src="/files/MnZ1k2NVzNPkPEdHBZNa" alt=""><figcaption><p>Bucket protection status with one Console</p></figcaption></figure></div>
{% endtab %}

{% tab title="With another Cloud Storage Security console also scanning:" %}

<div align="left"><figure><img src="/files/70OPVU0SkOjPFTfajdJy" alt=""><figcaption><p>Bucket protection status with multiple Consoles</p></figcaption></figure></div>
{% endtab %}
{% endtabs %}

## Populated Dashboard Example

Once you've been running the product for a while, your dashboard may look as follows:

<figure><img src="/files/0PC5D41nzBfItbvwJKx5" alt=""><figcaption><p>Landing page populated with data</p></figcaption></figure>


# Malware Scanning

There is very little to configure to get the product up and scanning your data. The only activity you truly have to do post deployment is enable protection for the storage volume of your choice.

Under the Malware Scanning section you will find the ability to manage protection for each of the below storage types we protect.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Buckets</strong></td><td>Protect your S3 buckets through event-based and retro-based scanning.</td><td></td><td><a href="/pages/Zu2gT9kQJK4CxaD20I5S">/pages/Zu2gT9kQJK4CxaD20I5S</a></td></tr><tr><td><strong>EBS Volumes</strong></td><td>Protect your EBS Volumes through scheduled scanning.</td><td></td><td><a href="/pages/7MCMj4AFNchzaOZTUHPj">/pages/7MCMj4AFNchzaOZTUHPj</a></td></tr><tr><td><strong>EFS Volumes</strong></td><td>Protect your EFS Volumes through scheduled scanning.</td><td></td><td><a href="/pages/tz7d2mtKfxOf5tm1KznZ">/pages/tz7d2mtKfxOf5tm1KznZ</a></td></tr><tr><td><strong>FSx Volumes</strong></td><td>Protect your FSx Volumes through scheduled scanning.</td><td></td><td><a href="/pages/ZJrWmPZLhsfM7XP1iJo0">/pages/ZJrWmPZLhsfM7XP1iJo0</a></td></tr><tr><td><strong>Azure Blobs</strong></td><td>Along with AWS storage volumes you can connect and scan Azure Blobs.</td><td></td><td><a href="/pages/ML08SRlqe6gUjnDDjLZD">/pages/ML08SRlqe6gUjnDDjLZD</a></td></tr></tbody></table>


# AWS

Configure scanning for AWS storage containers here.


# Buckets

## Bucket Protection Table

The Bucket Protection table is a complete list of the current status of all buckets across all regions within the AWS account the console is running in as well as active linked accounts.

We've seen configuration for this page covered in the [Initial Configuration](/getting-started/initial-config#step-2-enable-bucket-scanning) section, but we'll get into more details here

<div data-full-width="false"><figure><img src="/files/hUb90EKdKIqlE7I2qDn8" alt=""><figcaption></figcaption></figure></div>

{% hint style="info" %}
Notice the `Account` identifier shows as `Primary`. This represents the default account you deployed the solution in. If you [link accounts](/console-overview/access-management/linked-accounts) for cross-account scanning, you will see a different identifier (the nickname you gave it) for those buckets that come from other accounts.

The bucket list is refreshed every 30 minutes in the background, but if you have recently created new buckets or deleted existing, you can force a refresh with the `Actions --> Refresh Buckets` menu item at the top of the buckets list.

You may have noticed the **Object Count** and **Total Size (GB)** values for each bucket. These are not real-time reliable numbers. This data is pulled from CloudWatch Metrics for S3 Buckets. Amazon only updates these metrics once per day at the end of each day. So the numbers you are seeing are always a day old, but can give you a good feel.
{% endhint %}

### Bucket Attributes

We check certain attributes related to buckets to give you information pertinent to setting up protection. As a result, you may notice icons next to the bucket names. The two main aspects we check now are public status and the encryption status. We want you to be informed on which buckets are public and how they are public. We also want to stop you from scanning whole buckets of encrypted objects when we don't have permissions to the key to decrypt those objects. Giving the AgentRole [permissions to the key](/trouble-shooting/objects-show-unscannable-with-access-denied) will solve this issue.

* ![possibly public lock](/files/hsSPNPgw2GhgnxLI768G) when bucket is capable of being `public`, but not actually `public`.
  * Some of the `Block Public Access` checks are turned off, but there isn't an ACL or a Bucket Policy set to make the bucket public.
* ![truly public lock](/files/L1XWK8tgubqUVHgRnGUD) when bucket is truly `public` via ACL or Bucket Policy.
  * Some of the `Block Public Access` checks are turned off and there is an ACL or a Bucket Policy set to make the bucket public.
  * The tooltip will give you details on the ACL settings.
* ![kms encryption no permissions](/files/lKzuQSapwvjFUxglH0S9) when KMS encryption enabled on the bucket and the AgentRole **does not** have permission to the key.
  * Follow the [trouble shooting](/trouble-shooting/objects-show-unscannable-with-access-denied) for how to enable the AgentRole with the key.

{% hint style="info" %}
You will not be able to turn on protection for a bucket or perform a `Scan Existing` if the AgentRole does not have permission to the key
{% endhint %}

* ![kms encryption with permissions](/files/CDg91tV2lMtecoBYyI6z) when KMS encryption enabled on the bucket and the AgentRole **does** have permissions to the key.

## Scan new objects uploaded to a bucket

You can enable buckets one at a time by selecting one checkbox or you can multi-select checkboxes or you can "select all" with the `Select Visible` button at the top of the page to create any kind of bucket set for enabling protection. For any buckets in new regions where you aren't currently scanning, you will be asked to configure the VPC and Subnet(s) as we saw in the [Initial Configuration](/getting-started/initial-config#enabling-buckets-in-other-regions). And if you select multiple new regions during the same action, you will be prompted to configure each one. Look to the steps below where two buckets are selected from two different regions (`eu-central-1` and `eu-north-1`) not currently enabled.

<figure><img src="/files/Yd3AfehBoCAoXZXCe2F0" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
`Select Visible` means all rows available from the filtered search. If no search criteria has been entered, then all buckets in your list will be selected. If you have filtered the list down with a search, then only those search results will be selected.

This is a great way to find the set of buckets you want to take a batch action against and trigger the action.

You can chain sets together by filtering to select a few buckets, filter with different criteria and select a few buckets. Both selected sets will remain selected. This allows you to take the same action against different filtered sets.
{% endhint %}

Selecting `Turn On Selected` from the `Actions` drop down button yields the following popup where you must configure a VPC and Subnet(s) for any regions that are not already setup.

<div data-full-width="true"><figure><img src="/files/3npEgO7r7ALqRuTYzS3U" alt=""><figcaption></figcaption></figure></div>

{% hint style="warning" %}
The VPC and Subnets you choose must have an outbound path to reach Amazon ECR. If not, the agents will [never boot properly](/trouble-shooting/my-scanning-agents-keep-starting-up-and-immediately-shutting-down). As discussed in the troubleshooting topic, you can do with outbound access to the internet or through VPC Endpoints that give you access to ECR and API.

We now show `Public` / `Private` next to each VPC to indicate whether or not the VPC is tied to an Internet Gateway and therefor likely to have an outbound path. We also show `Public` / `Restricted` next to each Subnet to indicate whether each Subnet appears to have outbound routing.
{% endhint %}

### **Automating Bucket Protection**

In addition to selecting buckets in a one or many fashion as described above, you can automate the protection of buckets by leveraging `tag triggered protection`. By specifying [a particular tag on the bucket](/console-overview/configuration/console-settings#automatic-bucket-protection) we will automatically turn event-based protection on for that bucket(s).

We do this in the every 30 minute refresh cycle where we refresh the bucket catalog for bucket characteristics, new or removed buckets and now for the protection of those buckets.

For more information check out the [Console Settings page](/console-overview/configuration/console-settings#automatic-bucket-protection) to define the tag we look for.

## Scan Pre-existing Objects

Any time you enable a bucket for scanning, you will be asked if you would like to scan all the existing objects in that bucket as well. You can also trigger a `scan existing objects` any time from the `Actions` drop down button at the top of the bucket list as well. In the scenario above, you turned on two buckets and were first prompted to select network settings. Once that is complete you will be presented the `Scan Existing Objects` popup. If you'd prefer not to scan existing objects at this time you can simply click `Don't Scan` and this popup will be closed. If you do prefer to scan your existing objects as well, you select some or all of the buckets you had enabled for event-based scanning and then click the `Scan Selected` button. You must select the disclaimer checkbox as well before the button will be enabled.

<figure><img src="/files/6HJ6jx3JvPSUhXLB3ocF" alt=""><figcaption></figcaption></figure>

Buckets being turned on for event-based scanning is **not** a pre-requisite for scanning existing objects. Whether the bucket is turned on or off and whether it has a conflict or not, a `scan existing` can be triggered on it. More than one `scan existing` can be triggered on a bucket if so desired (picture two or more distinct, non-contiguous date ranges needed). Triggering a `scan existing` for a bucket or buckets is simple on this page. Select one or many buckets using the `Select All` button or the checkboxes and then select `Scan Existing Objects` from the `Actions` button. This will pull up the same popup as seen above.

<figure><img src="/files/54M7KVzDfDvnqpszo6r6" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/kwzfB6KExf9d3UQXEhee" alt=""><figcaption></figcaption></figure>

For a time window, the default is beginning of time through current time. The intends to scan all objects within the bucket. The date picker allows you to select from one of the present values as well as create a completely custom range. `Custom Range` allows you to select down to specific hours and minutes of the day if needed.

<figure><img src="/files/DzA8Gv4wREMji358GOsm" alt=""><figcaption></figcaption></figure>

You can add specific prefixes to crawl, limiting the scan to only those paths inside the S3 bucket. When you run the 'Scan Pre-Existing Objects' option for the bucket, you can also choose 'Only Scan Objects that Have Not Already Been Scanned' to avoid rescanning files that were already processed:

<figure><img src="/files/fN7pv1FQW6iVqTnwiIrG" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
The instructions for this popup are collapsed by default. Expand for detailed steps.

A Fargate `run task` (temporary tasks) is spun up for each bucket to crawl the objects and place matching files into a temporary SQS Queue. Each run task will shut down as crawling is completed. A new set of `run tasks` will be spun up to to process the queue entries. We will automatically attempt to spin up the number of `run tasks` required to process the queue in \~1 hour.

On-demand and Scheduled scan-existing scans are considered Jobs and can be tracked on the [Monitoring → Jobs](/console-overview/monitoring/jobs) page.
{% endhint %}

To learn more retro scanning of your existing objects. More details can be found [here](/how-it-works/object-scanning#retro-scanning).

### Scheduled Scanning

In addition to the on-demand scanning that [Scan Existing](#scan-existing-objects) offers, you can create schedules to scan your buckets as well. You simply need to select the buckets you would like to scan and then define the scan frequency as desired.

Select the buckets and then from the action menu click on `Create Schedule`

<figure><img src="/files/cglTJd70PSLOjaQct5se" alt=""><figcaption></figcaption></figure>

The `Create Schedule` modal will pop up to allow you to review selected buckets and define the scan frequency (daily, weekly, monthly, yearly).

<figure><img src="/files/TERhTiGiQsalhVyyHTui" alt=""><figcaption></figcaption></figure>

For more information, review the [Scheduled Scans](/console-overview/scheduled-scans) documentation page.

{% hint style="warning" %}
Creating a schedule from this page, does NOT actually activate the schedule. You must go to the [Scheduled Scans](/console-overview/scheduled-scans#activating-and-deactivating) page and then activate the schedule. Only at that time will the schedule execute and protect your buckets as defined.
{% endhint %}

## Protection Statuses

"Protection" can mean multiple things. In regards to **Antivirus for Amazon S3** it means: real-time scanning (event-based), schedule scanning (pre-defined schedule based) and on-demand (pick a bucket(s) and scan immediately whenever you want).

The Shield Color Legend shown on this page will reflect how a bucket is being protected with event-based scanning as seen below.

<figure><img src="/files/oqOGxKD3f8KzZksIULKt" alt=""><figcaption></figcaption></figure>

### Event-based Protection

<figure><img src="/files/gMXVMsSazdJxzjlrWmmW" alt=""><figcaption></figcaption></figure>

A green shield means a bucket is protected and a red shield indicates a bucket is not protected.

### Schedules Status

The schedule icons shown below will reflect whether a bucket is associated with a schedule and whether that schedule is active or not.

* Protected by Active Schedule - ![Green clock](/files/lJ1kLIbSVuFqOkrKTQer)
* Part of an **Inactive** Schedule - ![Red clock](/files/vUhRatVagKA1mxxren87)
* Not a Part of any Schedule - ![Red clock](/files/uuBiYZaSpsuUm0sJNOkD)

### Conflicted Buckets

{% hint style="warning" %}
As of v7.00.000 we automatically use EventBridge to resolve any bucket conflicts.

If you are running an older version (any version prior to v7.00.000) of our product please check out the [Trouble Shooting - Address Conflicts](/trouble-shooting/conflicted-buckets) section for detailed steps on how to resolve these conflicts.
{% endhint %}

<figure><img src="/files/HHmFvH0FgOtYDM9deCyg" alt=""><figcaption></figcaption></figure>

On top of these main statuses, you may have buckets that are in some form of conflict for scanning. As of v7.00.00 we automatically resolve any conflicted buckets using EventBridge.

If a bucket is conflicted it will have a shield with a slash through it. If a bucket is protected by event bridge it will have a green shield with a star inside of it.

<figure><img src="/files/9Rakdm53ryYMHVOPzbwN" alt=""><figcaption></figcaption></figure>

You can protect a conflicted bucket by clicking on the shield associated with the bucket. You will receive a prompt notifying you that we can protect this bucket with EventBridge and additional charges from EventBridge will be incurred. If you select `Turn On` your bucket will have event-based scanning enabled (using EventBridge).

\
You can also enable EventBridge globally for all buckets on the [Scan Settings](/console-overview/configuration/scan-settings) so you can use it by default anytime you protect a bucket.

<figure><img src="/files/ixr4hPfJncjf2nDria3J" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If `Protect with Event Bridge` is enabled globally from [Scan Settings](/console-overview/configuration/scan-settings) then we will protect all selected buckets with Event Bridge without acknowledgment.

\
If `Protect with Event Bridge` is not enabled we will protect buckets using the "best choice". If the bucket can be protected with the S3 Event Notification we will do so, but if conflicted we will fail over to Event Bridge.
{% endhint %}

Along with these main conflicts, you can see a purple colored shield associated with a bucket if there is another Antivirus for Amazon S3 console running and protecting that bucket.

If you'd like to protect it with a different console you'll first need to disable protection on that bucket inside the console that is already protecting it.

<figure><img src="/files/vdSqeF8jeN3ju4UB8tGG" alt=""><figcaption></figcaption></figure>

## Search

Every field in the table can be searched upon utilizing the `Search` field at the top of the page. Want to see only the buckets in 'east' search for that. Want all of the buckets that have a particular piece of text in their name, just type in that piece of text. You can search for multiple things as well separated by a space. Want to see all the buckets in `us-east-1` for the `Production` account just add both of those in with a space between them.

### Special Search Terms

There are some special terms that you can search on:

1. Public
2. Encrypt
3. Conflict
4. Protected

Protection Status can be searched by `Protected.`\
\&#xNAN;*You may find bucket names that one `protected` within the name which could throw the results slightly unprotected. In this case, use column sort on Protection Status.*

Bucket Conflicts can be searched for by using the word `conflict` in the search field. This will return all the highlighted rows that reflect a potential event conflict.

Searching on `public` will identify all buckets that have some public aspects to them as seen in the [Bucket Attributes](#bucket-attributes) above.

Searching on `encrypt` will return all buckets that have a KMS key associated with them and identify whether the AgentRole has access to the key as seen in the [Bucket Attributes](#bucket-attributes) above.

### Additional Search Capabilities

We also provide the ability to search leveraging regex within the search field. This gives you great flexibility to really narrow down exactly what you are looking for. Whereas a general partial word specified in the Search field may pull back more rows than you'd like, the regex option will allow you to better pattern match.

But, if you want a specific set of buckets that starts with "has" folders that end with "it", we could specify `Regex(has.*it)` to get the two buckets that contain "has" and end with "it":

<figure><img src="/files/oLDIXtuXwU87VtpH3x2a" alt=""><figcaption></figcaption></figure>

### Aggregate search terms

Another useful capability is that you can aggregate multiple individual searches to build a larger selected list. We can create a potentially complex regex or we can do multiple simple searches for our selections. Extending the example above, albeit a simple one, might look as follows.

Search for and select the buckets you want. In this example, we are searching for buckets named `classification`.

<figure><img src="/files/oigV3LfsfY0B1rCNswq7" alt=""><figcaption></figcaption></figure>

Notice the bottom summary line: <mark style="background-color:blue;">`Showing 7 of 896 buckets - 1 Selected`</mark>

Clear `classification` from the search and enter `eu` in place of it and select the bucket(s) you want.

<figure><img src="/files/gO5CZGfWYlxt6bC63GdK" alt=""><figcaption></figcaption></figure>

Now notice the bottom summary line: <mark style="background-color:blue;">`Showing 51 of 896 buckets - 3 Selected (1 not currently visible)`</mark>

Your first search selection is still maintained as well as any subsequent search selections made. So you can build up your selected list very simply this way. This can be used for one off retro scanning ([Scan Existing](#scan-existing-objects)) as well as the basis for creating [schedule based scans](/console-overview/scheduled-scans).

### Search Examples

{% tabs %}
{% tab title="Search Account and Region" %}

<figure><img src="/files/KB6sg7fMLbLZtBYblTSh" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Search Public Status" %}

<figure><img src="/files/oqCGhxy7DXMXz02Q9xHB" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Search Conflicts" %}

<figure><img src="/files/vXyc0WZZfdSAGgASmhKZ" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Search with Regex" %}

<figure><img src="/files/RhLeUr5aPPBxhBC9wIR7" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

### Filtering

\
Next to the **Select Visible** button, there is a **Show** button that lets you search and filter buckets based on the following options:

* **Show all buckets**
* **Show unprotected buckets** (Red Shield)
* **Show protected buckets** (Green Shield)
* **Show buckets protected by another console** (Purple Shield)
* **Show buckets protected by schedules** (Watch icon)

<figure><img src="/files/Wf7p4Ff87JiXgHz0NwLB" alt=""><figcaption></figcaption></figure>


# Amazon EBS Volumes

{% embed url="<https://www.youtube.com/watch?v=xX6psnJHyzI>" %}

## Architecture

<figure><img src="/files/1Y1Cqux9oP1dImKlrHVa" alt=""><figcaption></figcaption></figure>

1. The Console Service creates an EC2 instance in the EBS Volume region as a Scanning Agent
2. The Agent creates an EBS Snapshot
3. The EBS Snapshot is scanned by the Scanning Agent
4. Results are sent to CloudWatch
5. Job status and other scan details are sent to DyanamoDB
6. The Console service ingests details from CloudWatch and DyanamoDB, and when the scan is done, scanning architecture and the EBS Snapshot are torn down

## Console EBS Protection Page

The EBS Protection page will show you any EBS volumes that are associated with the account that you have deployed our solution in, as well as volumes from any accounts linked to your console. Here you'll be able to create Antivirus scanning and Data Classification schedules for EBS Volumes.

<figure><img src="/files/Ao0y2vPxMk09s6at9gVo" alt=""><figcaption></figcaption></figure>

## Setting up your VPC and Subnets for the regions you are protecting EBS volumes in

If you do not have a VPC and subnets staged in the region your EBS Volumes exist in, you will be asked to set a VPC and subnets when activating the schedule. You can learn more about staging regions in the [Event Agent Settings](/console-overview/configuration/agent-settings#staged-regions) page.

<figure><img src="/files/rfJMd2DhYuaDeY12macp" alt=""><figcaption><p>VPC and Subnets</p></figcaption></figure>

## Creating an EBS volume scan or classification schedule

You can create a schedule within the [Schedules page](https://help.cloudstoragesec.com/console-overview/scheduled-scans), or you can create a schedule for EBS volumes directly from the EBS Volumes page.

1. Select the EBS volume(s) you want to protect through a schedule
2. Click actions and select either `Create AV Schedule` or `Create DC Schedule`
3. You can select any additional EBS volumes and add EFS volumes or S3 buckets to the schedule through the schedule popup
4. Once you have all of the resources you want to add to a schedule selected, click on the `Create Schedule` tab
5. Name your schedule, add the scan period and make any additional changes you need
6. Click `Save` once you're done

<figure><img src="/files/51lLIX3LvXVmoLsGLisX" alt=""><figcaption><p>Create your Schedule</p></figcaption></figure>

After your schedule is created you'll want to go to the Schedules page and activate the schedule.

<figure><img src="/files/WOvQUl8MCjntT5bOjmfa" alt=""><figcaption><p>Activate your Schedule</p></figcaption></figure>

Now your schedule will run per the scan period that you originally configured. If you need to add or remove volumes, or make any other configuration changes you can always edit the schedule on the `Schedules` page.

## Volume Schedule Statuses

The schedule icons shown below will reflect whether a bucket is associated with a schedule and whether that schedule is active or not.

* Protected by Active Schedule - ![Green clock](/files/lJ1kLIbSVuFqOkrKTQer)
* Part of an **Inactive** Schedule - ![Red clock](/files/vUhRatVagKA1mxxren87)
* Not a Part of any Schedule - ![Red clock](/files/uuBiYZaSpsuUm0sJNOkD)

## On-demand antivirus scanning and data classification

<figure><img src="/files/4GROdjRILLHMEBl8xAbr" alt=""><figcaption><p>EBS On-demand Scanning</p></figcaption></figure>

In addition to scheduled scans, you can select and perform on-demand AV and DC scanning for EBS volumes.


# Amazon EFS Volumes

{% embed url="<https://www.youtube.com/watch?v=nZqL2PaEV7A>" %}

## Architecture

<figure><img src="/files/nX61tTVx5U0Gi833LAfd" alt=""><figcaption></figcaption></figure>

1. The Console initiates an EFS scan job, whether triggered by an on-demand scan or a set schedule
2. The scanning agent initiates a crawl job to identify files in the target EFS volume
3. Crawl job places objects to be scanned in an SQS Queue
4. The scanning agent initiates a scan job, reading files from the Queue and scanning them for viruses
5. Results are sent to CloudWatch
6. Job status and other scan details are sent to DynamoDB
7. The Console service ingests details from CloudWatch and DynamoDB, and when the scan is done, scanning architecture is torn down

## Console EFS Protection Page

The EFS Protection page will show you any EFS volumes that are associated with the account that you have deployed our solution in, as well as volumes from any accounts linked to your console. Here you'll be able to create Antivirus scanning and Data classification schedules for EFS Volumes.

{% hint style="info" %}
Currently you can only scan EFS volumes in the account that you deployed our solution in. If you have EFS volumes in other accounts you'll need to deploy a separate deployment in those accounts to scan those volumes.

You can choose to show or hide the EFS volumes from your linked accounts by clicking the 'Show/Hide Linked Accounts' button at the top of the page.
{% endhint %}

<figure><img src="/files/DfnLYUH6wnW6Yfg018em" alt=""><figcaption><p>EFS Protection</p></figcaption></figure>

## Creating an EFS volume scan or classification schedule

You can create a schedule within the [Schedules page](https://help.cloudstoragesec.com/console-overview/scheduled-scans), or you can create a schedule for EFS volumes directly from the EFS Volumes page.

1. Select the EFS volumes you want to protect through a schedule
2. Click actions and select either `Create AV Schedule` or `Create DC Schedule`
3. You can select any additional EFS volumes and add EBS volumes or S3 buckets to the schedule through the schedule popup
4. Once you have all of the resources you want to add to a schedule selected, click on the `Create Schedule` tab
5. Name your schedule, add the scan period and make any additional changes you need
6. Click `Save` once you're done

<figure><img src="/files/UZHwmUURyNNzHZ7PS4oR" alt=""><figcaption><p>Create an EFS Schedule</p></figcaption></figure>

After your schedule is created you'll want to go to the Schedules page and activate the schedule.

<figure><img src="/files/okD96MMDQssCt3Egfrtj" alt=""><figcaption><p>Activate your EFS Schedule</p></figcaption></figure>

When activating the schedule you will be asked to select the VPC and Subnets where the EFS Volume being scanned resides. This step is critical, as we must place an agent within the same VPC as the Volume to run a scan of the Volume. If the selected VPC for the agent differs from the EFS Volume VPC, the two VPCs must be peered for our scan to execute.

Also note that the chosen VPC and Subnets must allow outbound internet traffic, and mount targets for the EFS Volume(s) must exist in the selected subnets' availability zones.

Now your schedule will run per the scan period that you originally configured. If you need to add or remove volumes, or make any other configuration changes you can always edit the schedule on the `Schedules` page.

## Volume Schedule Statuses

The schedule icons shown below will reflect whether a bucket is associated with a schedule and whether that schedule is active or not.

* Protected by Active Schedule - ![Green clock](/files/lJ1kLIbSVuFqOkrKTQer)
* Part of an **Inactive** Schedule - ![Red clock](/files/vUhRatVagKA1mxxren87)
* Not a Part of any Schedule - ![Red clock](/files/uuBiYZaSpsuUm0sJNOkD)


# Amazon FSx Volumes

The FSx Protection page will show you any FSx volumes that are associated with the account that you have deployed our solution in, as well as volumes from any accounts linked to your console. Here you'll be able to create Antivirus scanning and Data classification schedules for FSx Volumes.

{% hint style="info" %}
Currently we support the NetApp ONTAP, Lustre, and OpenZFS file systems, however we will add support for additional file systems in future releases. If you need a specific file system supported please [Contact Us](/contact-us).

At the moment, you can only scan FSx volumes in the account that you deployed our solution in. If you have FSx volumes in other accounts you'll need to deploy a separate deployment in those accounts to scan those volumes.
{% endhint %}

<figure><img src="/files/hQGGLrMWqEQpYCznaU7X" alt=""><figcaption><p>FSx Protection</p></figcaption></figure>

## Creating an FSx volume scan or classification schedule

You can create a schedule within the [Schedules page](https://help.cloudstoragesec.com/console-overview/scheduled-scans), or you can create a schedule for FSx volumes directly from the FSx Volumes page.

1. Select the FSx volumes you want to protect through a schedule
2. Click actions and select either `Create AV Schedule` or `Create DC Schedule`
3. You can select any additional FSx volumes and add EFS and EBS volumes or S3 buckets to the schedule through the schedule popup
4. Once you have all of the resources you want to add to a schedule selected, click on the `Create Schedule` tab
5. Name your schedule, add the scan period and make any additional changes you need
6. Click `Save` once you're done

<figure><img src="/files/2TmfVcocoNq09u3zpfPB" alt=""><figcaption><p>Create an FSx Schedule</p></figcaption></figure>

After your schedule is created you'll want to go to the Schedules page and activate the schedule.

<figure><img src="/files/5Gu5v3X0aIkktZqpZ7bg" alt=""><figcaption><p>Activate your FSx Schedule</p></figcaption></figure>

Now your schedule will run per the scan period that you originally configured. If you need to add or remove volumes, or make any other configuration changes you can always edit the schedule on the `Schedules` page.

## Networking Considerations

We will add a security group (SG) to the ENI connected to the FSx subnets. There is a hard limit of 5 SGs per ENI, so there is a possibility that you may have the number of attached SGs maxed out before adding us to the mix. Please review and combine SGs, if possible.

<figure><img src="/files/UPNgSXIePMJDmJk0amv4" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
With Job Networking, it is essentially giving us permission to run our processes through those chosen subnets/AZs. But once permission is granted, they can't (yet) be modified through the console. They currently need to be updated in DynamoDB. We will be adding a central job networking page where you can modify these settings at-will. If you need assistance with this [Contact Us](/contact-us).
{% endhint %}

## Volume Schedule Statuses

The schedule icons shown below will reflect whether a bucket is associated with a schedule and whether that schedule is active or not.

* Protected by Active Schedule - ![Green clock](/files/lJ1kLIbSVuFqOkrKTQer)
* Part of an **Inactive** Schedule - ![Red clock](/files/vUhRatVagKA1mxxren87)
* Not a Part of any Schedule - ![Red clock](/files/uuBiYZaSpsuUm0sJNOkD)


# Azure

Configure scanning for Azure storage containers here.


# Blob Containers

Similar to scanning AWS storage volumes you can also scan Azure Blobs.

{% hint style="info" %}
Before you can start protecting your data in Azure Blobs you'll need to [link in your Azure account(s)](/console-overview/access-management/linked-accounts/linking-an-azure-account).
{% endhint %}

## How It Works

When linking an account in the CSS console, we deploy resources in the new CSS Resource Group created in Azure. Those resources will have access to the Blob Containers that reside within the linked Azure Account.

Once the Azure Account is linked, Azure Blob Containers will be made available to be scan through the CSS Console in the Protection > Azure Blob Containers page. You can select blob containers to scan or run scans on a schedule basis.

We offer two types of scanning for Azure: Event-Based Scanning and Retro Scanning.

{% tabs %}
{% tab title="Event-Based Scanning" %}

<figure><img src="/files/Wm7cWLcpymGnywHZC4Nt" alt=""><figcaption></figcaption></figure>

1. Users upload data to storage containers.
2. The storage account's system topic has an Event Grid Subscription tied to it that points to Azure Queue Storage as its event handler.
3. The Azure Queue Storage receives information about the object via the Event Grid Subscription.
4. The Container Application pulls information from the queue and scans the object that the notification refers to.
5. Results are tagged onto the object.
6. Results and metering are sent back to the CSS Console.
   {% endtab %}

{% tab title="Retro Scanning" %}

<figure><img src="/files/PU4NmsUwsa9wVEdT6qO5" alt=""><figcaption></figcaption></figure>

1. Users upload data to storage containers.
2. The Container Application runs a Crawl Job that evaluates the items to be scanned.
3. The Crawl Job places objects in Azure Queue Storage.
4. The Container Application pulls information from the queue and runs a Scan Job to scan the objects in the Queue.
5. Results and metering are sent back to the CSS Console.
   {% endtab %}
   {% endtabs %}

## Protecting Blob Containers

<figure><img src="/files/2rJUlMXI7kSIFUgcdBUe" alt=""><figcaption></figcaption></figure>

"Protection" can mean multiple things: real-time scanning (event-based), schedule scanning (pre-defined schedule based) and on-demand (pick one or more blobs and scan immediately whenever you want).

### Shield Status

The shield color shown on this page will reflect how a blob is being protected with event-based scanning. A red shield means a blob is not protected and a green shield means a blob is protected.

### Schedule Status

The schedule icons shown below will reflect whether a blob is associated with a schedule and whether that schedule is active or not.

* Protected by Active Schedule - ![Green clock](/files/lJ1kLIbSVuFqOkrKTQer)
* Part of an **Inactive** Schedule - ![Red clock](/files/vUhRatVagKA1mxxren87)
* Not a Part of any Schedule - ![Red clock](/files/uuBiYZaSpsuUm0sJNOkD)

## Enable event-based protection on a blob

Similar to protecting Amazon S3 buckets, you can click the red shield associated with each Blob to enable event-based protection on a blob and scan any new files being uploaded to the Blob automatically.

You can also select multiple blobs at the same time, go to the Actions menu, and select Turn On Event AV to enable event-based protection on multiple buckets at the same time.

## Retro-based scanning on a blob

### On-demand Scanning

You can scan pre-existing files in a blob at anytime by selecting which blob you'd like to scan and then selecting Scan Existing - AV in the Actions menu.

<figure><img src="/files/T0M4iDORQU6dtEW56qWP" alt=""><figcaption></figcaption></figure>

### Scheduled Scanning

You can add blobs to a schedule by selecting the blobs you want to scan on a scheduled basis and selecting Create AV Schedule in the Actions menu.

<figure><img src="/files/PrVUUvXp3cEY0MdcvG4V" alt=""><figcaption></figcaption></figure>

### Azure On-demand and Scheduled Scan Job Status

If you go to Monitoring > Jobs you'll be able to see the status of on-demand and scheduled retro scans for Azure blobs.

<figure><img src="/files/jTUK9Nsmf5AMBysfjrln" alt=""><figcaption></figcaption></figure>


# GCP

Configure scanning for GCP storage containers here.


# GCP Buckets

Similar to scanning AWS storage volumes you can also scan GCP Buckets.

{% hint style="info" %}
Before you can start protecting your data in GCP Buckets you'll need to [link in your GCP account(s)](/console-overview/access-management/linked-accounts/linking-a-gcp-account).
{% endhint %}

## How It Works <a href="#schedule-status" id="schedule-status"></a>

When linking an account in the CSS console, we deploy resources in a new CSS Project created in GCP through our Terraform module. Those resources will have access to the customer project(s) denoted in the deployments parameters (projects\_to\_protect).

Once the projects are linked, GCP buckets will be made available to be scan through the CSS Console in the Protection > GCP Buckets page. You can select buckets to scan or run scans on a schedule basis.

We offer two types of scanning for GCP: Event-Based Scanning and Retro scanning.

{% tabs %}
{% tab title="Event-Based Scanning" %}

<figure><img src="/files/3c9b3qlxMotOyffPOd4P" alt=""><figcaption></figcaption></figure>

1. Users or apps place files into Google Cloud Storage.
2. The Pub/Sub service has a Topic set up to notify whenever new objects are created in designated Buckets.
3. The Cloud Run Job's subscription to the Topic activates whenever a new file is created.
4. The Cloud Run Job accesses the designated Bucket and loads that new object in memory to scan.
5. Files in the protected Bucket are tagged with their scan result.
6. (Optional) The Cloud Run Job will move infected files to a Quarantine Cloud Storage that resides in CSS' Project.
7. Results are returned to the Console service for processing.
   {% endtab %}

{% tab title="Retro Scanning" %}

<figure><img src="/files/AimFvpWmOc9zIRqJZYiM" alt=""><figcaption></figcaption></figure>

1. Users or apps place files into Google Cloud Storage.
2. The Console Service initiates a scan request to the Cloud Run service that resides in CSS' Project that is provisioned via Terraform.
3. The Cloud Run Job accesses the customer's Cloud Storage and loads a list of its objects in memory, procedurally scanning each item.
4. (Optional) The Cloud Run Job will move infected files to a Quarantine Cloud Storage that resides in CSS' Project.
5. Results are returned to the Console service for processing.
   {% endtab %}
   {% endtabs %}

## Protecting Buckets <a href="#schedule-status" id="schedule-status"></a>

<figure><img src="/files/zl4wkAVEYQ2olPttpck4" alt=""><figcaption></figcaption></figure>

"Protection" can mean multiple things: real-time scanning (event-based), schedule scanning (pre-defined schedule based) and on-demand (pick one or more buckets and scan immediately whenever you want).

## Shield Status <a href="#shield-status" id="shield-status"></a>

The shield color shown on this page will reflect how a bucket is being protected with event-based scanning. A red shield means a bucket is not protected and a green shield means a bucket is protected.

## Schedule Status <a href="#schedule-status" id="schedule-status"></a>

The schedule icons shown below will reflect whether an object is associated with a schedule and whether that schedule is active or not.

* Protected by Active Schedule - ![Green clock](https://help.cloudstoragesec.com/~gitbook/image?url=https%3A%2F%2F905555942-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FlGcQw8I2CHyi1loKBlfi%252Fuploads%252FcWjXBZghM895Qpeu9Zr7%252Fgreen-clock.png%3Falt%3Dmedia\&width=300\&dpr=4\&quality=100\&sign=3b3c0c07\&sv=2)
* Part of an **Inactive** Schedule - ![Red clock](https://help.cloudstoragesec.com/~gitbook/image?url=https%3A%2F%2F905555942-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FlGcQw8I2CHyi1loKBlfi%252Fuploads%252FD1I4zDFdWHhwv79Ma0Zi%252Fyellow-clock.png%3Falt%3Dmedia\&width=300\&dpr=4\&quality=100\&sign=f385a9b2\&sv=2)
* Not a Part of any Schedule - ![Red clock](https://help.cloudstoragesec.com/~gitbook/image?url=https%3A%2F%2F905555942-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FlGcQw8I2CHyi1loKBlfi%252Fuploads%252FLAvOVzethjMYhwSe7V27%252Fred-clock.png%3Falt%3Dmedia\&width=300\&dpr=4\&quality=100\&sign=ecd8378e\&sv=2)

## Enable event-based protection on a Bucket <a href="#enable-event-based-protection-on-a-blob" id="enable-event-based-protection-on-a-blob"></a>

Similar to protecting Amazon S3 buckets, you can click the red shield associated with each Bucket to enable event-based protection on a bucket and scan any new files being uploaded to the Bucket automatically.

You can also select multiple buckets at the same time, go to the Actions menu, and select Turn On Event AV to enable event-based protection on multiple buckets at the same time.

## Retro-based scanning on a bucket

### On-demand Scanning <a href="#on-demand-scanning" id="on-demand-scanning"></a>

You can scan pre-existing files in a bucket at anytime by selecting which bucket you'd like to scan and then selecting Scan Existing - AV in the Actions menu.

* Navigate to Protection > GCP > Buckets page
* Select the check mark next to the bucket name of your volume
* Click Actions > Scan Existing - AV
* Select your date range, prefixes (optional) and whether you'd like to scan files that have been already scanned.
* Acknowledge that scanning files will result in a charge and scan selected.

<figure><img src="/files/i22VO3mQBvw0sveOmha5" alt=""><figcaption></figcaption></figure>

### Scheduled Scanning <a href="#scheduled-scanning" id="scheduled-scanning"></a>

You can add buckets to a schedule by selecting the buckets you want to scan on a scheduled basis and selecting Create AV Schedule in the Actions menu.

* Navigate to Protection > GCP > Buckets page
* Select the check mark next to the bucket name of your volume
* Click Actions > Create AV Schedule
* Select the Schedule tab and enter in your schedule name, scan period, schedule description (optional), files to scan, and prefixes to crawl (optional).
* Acknowledge that scanning files will result in a charge and save the schedule.

<figure><img src="/files/ULURz7wE86DeSIzFc2CJ" alt=""><figcaption><p>Create AV Schedule</p></figcaption></figure>

* Click on Schedules, find the schedule you created. Click the button with 3 dots on it and click Activate.

<figure><img src="/files/muVL8MFEtxTARw0rB843" alt=""><figcaption></figcaption></figure>

### GCP On-demand and Scheduled Scan Job Status <a href="#azure-on-demand-and-scheduled-scan-job-status" id="azure-on-demand-and-scheduled-scan-job-status"></a>

If you go to Monitoring > Jobs you'll be able to see the status of on-demand and scheduled retro scans for GCP Buckets.

<figure><img src="/files/T4IcmG9EQUPkfQCGN6TL" alt=""><figcaption></figcaption></figure>


# See What's Infected

The See What's Infected page provides malware information at a glance. Findings at a glance, Malware History, and a more granular Results page live here.


# Findings

The Findings page is where you will find details about any findings surfaced during antivirus scanning and data classification.

## Overview

{% hint style="info" %}
Depending on which product(s) you are using this page may have a different name in the navigation.

* AV: Problem Files
* DC: Classification Results
* AV and DC: Findings`Infected`, `Unscannable` and `Error` files are deemed collectively as `Problem Files`. They represent files that are infected with malware (Infected), password protected / KMS encrypted / file size limit exceeded (Unscannable) and where the cross account role is broken or the file no longer exists (Error). This page will present the list of problem files found by Antivirus for Amazon S3 whether from new objects coming in or through the evaluation of your existing objects. The list of problem files is a running tally of all issues you've discovered. You may take actions on the files directly in the bucket and and through the page. Whether the file has been cleaned and moved or deleted, the data will tell you whether the file still exists and needs to be dealt with or if it no longer exists. Actions that you can take on the files include restoring back to original bucket (in case of false positive) as well as taking further investigative actions by initiating a `Static` or `Dynamic` Analysis which can detonate the file in a sandbox to see what the file actually does.
  {% endhint %}

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}
The files are broken down by bucket and account so you know where the file entered and into which account.

<figure><img src="/files/L89BVl9q5OgDLcEiUJsn" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}
`Matching`, `Unclassifiable` and `Error` files are deemed collectively as `Problem Files`. They represent files that have classified data (Matching), password protected / KMS encrypted / file size limit exceeded (Unclassifiable) and where the cross account role is broken or the file no longer exists (Error). This page will present the list of problem files found by Classification for Amazon S3 whether from new objects coming in or through the evaluation of your existing objects. The list of problem files is a running tally of all issues you've discovered. You may take actions on the files directly in the bucket and and through the page. Whether the file has been cleaned and moved or deleted, the data will tell you whether the file still exists and needs to be dealt with or if it no longer exists.

The files are broken down by bucket and account so you know where the file entered and into which account.

![Problem Files page](/files/z1IukA4ZuoIEeafWFfu0)
{% endtab %}
{% endtabs %}

## Getting the Results Set

You will not see any results when you land on this page. You must first apply filters to get to your working data set. You can then search amongst the results. There are five pieces of data you will provide for the filter:

1. One or multiple accounts.
2. The types of problem files.
3. The date range.
4. The analysis run type.
5. The results per page to display.

![Problem Files Filters](/files/xvN5XEscYPdbJzuR4UGQ)

### Accounts

<figure><img src="/files/4cpKPyX92aJs3wiyBsZk" alt=""><figcaption><p>Accounts</p></figcaption></figure>

\
The `Accounts (count in past 24h)` is a multi-select picker where you can choose one or more accounts to review. If you have many accounts, you can search by typing into the field to limit the account list further. You are presented the account nickname, the account number and the number of problem files found in the last 24 hours.

### Problem File Types

<div align="center"><figure><img src="/files/69269rKw0mGiUjp7kEAA" alt=""><figcaption><p>Problem File Types</p></figcaption></figure></div>

The `Problem File Types` is a multi-select picker where you can choose one or more of the problem types to review. There are five choices of problem file types (four if you're using only AV or only DC):

1. Infected
2. Suspicious
3. Error
4. Unscannable (if using AV)
5. Unclassifiable (if using DC)

By default, all problem types are chosen, but you can limit this by clearing the undesirable types out.

### Suspicous Findings

This is a Sophos-only finding that means the engine didn't find anything infected within the file but has found the file to have suspicious characteristics that do not fit the file type. One example of a Suspicious finding is the CXMail finding.

The Sophos scanning engine has a CXMail identity that is specific to files sent over email channels. This finding while useful, does not fully apply to cloud storage mediums. Because of this, we re-categorize all findings under the CXMail identity to be found as suspicious. If you come across a CXMail finding we recommend you run a static or dynamic analysis to see if the file is legitimately malicious.

### Date Range

<div align="left"><figure><img src="/files/oVuFKLSM6jaMDUxjaTtU" alt=""><figcaption><p>Date Range</p></figcaption></figure></div>

The `Date Range` is a date/time calendar with presets where you can select the specific time range to evaluate. By default, the time selected is the last 24 hours (It actually counts from 00:00 of the previous day to 23:59 of the present one).

With all three fields populated, the `Apply Filters` button will be enabled. Click the button to retrieve the filtered results.

{% hint style="warning" %}
So as not to "spam" you on the Problem Files page or in the [scan results notifications](/console-overview/configuration/proactive-notifications#proactive-notifications), we are throttling the number of entries we write to both for two particular scenarios: 1) the bucket is encrypted (and we do not have permissions to the key), therefore every object would fail to scan and 2) access to a linked account has been broken so we cannot grab the objects and therefore every object would fail to scan.

In both scenarios, you could end up with thousands (or much more) of `unscannable` and/or `unclassifiable` messages depending on the object counts for the given bucket(s) or account(s). We will write one message per hour for each unscannable and/or unclassifiable scenario (per bucket and per account).
{% endhint %}

### Page Size & Pagination

The `Page Size` dropdown allows you to choose how many results, per page, are displayed in the report table. You can select 10, 100, 1,000, or 5,000 results per page. If your dataset has more results that can display on a single page, you can use the pagination controls to navigate back and forth between the pages of results.

<figure><img src="/files/Jp17L9ispPB6mDqJcKCP" alt="" width="112"><figcaption></figcaption></figure>

Click the page number to jump to that specific page, use the `<` and `>` controls to jump one page forward or back, and use `<<` or `>>` to jump back to the first page or to the last available page.

<figure><img src="/files/hmSwt4sMQL3y2nu5WEVq" alt="" width="375"><figcaption></figcaption></figure>

## Allowing Suspect Files - False Positives / Acceptable Risks

It is inevitable that false positives will occur or known and previously identified as risky files will be acceptable to use within your environment. If you are leveraging the default quarantining behavior of the solution you will then need a mechanism to bring the file back to the original production bucket for continued use. You need to restore the file without it immediately being picked up again so it can be used going forward.

<figure><img src="/files/7o9gB6qWd7cXqVXAzs2p" alt=""><figcaption><p>Allowing Infected Files</p></figcaption></figure>

You have two restore options:

1. Once
2. Permanently

`Once` will move the object from the quarantine bucket back to the original bucket and path. The scanning agents will skip this file one time, but if it is processed again (i.e. [Scheduled Scan](/console-overview/scheduled-scans), [On-Demand Scan](/console-overview/protection/aws/protected-buckets#scan-existing-objects), or upload) it will be caught again. This can be useful if you want to make sure you are checking the file again in case you didn't just accept it, but also fixed it.

`Permanently` will allow the file for continued use for the problems/infections found indefinitely. If you believe an item to be a false positive and will permanently be in place in the given file then permanent is the right choice. Even if you upload a new version of the object, that particular issue will still be allowed. If new issues are found (different infection) then it will still be processed as an infected file according to your settings.

In either case, the `scan-result` tag placed on the object will changed from `Infected` to `InfectedAllowed`.

{% hint style="warning" %}
If you have any policies or rules in place for object handling that key off of a `scan-result=clean`, you will want to augment to include `scan-result=InfectedAllowed` as well.
{% endhint %}

## Static and Dynamic Analysis

<figure><img src="/files/ijW9uBXEEsVcAd94FWOh" alt=""><figcaption><p>Examples of Static and Dynamic Analysis</p></figcaption></figure>

Additional analysis of problem files may be required when it isn't obvious if the file is truly a problem or not. We offer two additional methods (in addition to the in-tenant scanning engine that identified the problem file initially): `Static Analysis` and `Dynamic Analysis`. **Please note that this feature is only available in PayGo licensing mode and NOT BYOL.**

We're leveraging the [SophosLabs Intelix Platform](https://www.sophos.com/en-us/medialibrary/pdfs/factsheets/sophoslabs-intelix-ds.pdf) to perform this analysis. On any file shown in the Problem Files table click the Action button and select the analysis you'd like to run. Browse the report there below the file line item or download it for later. You will always be able to come back and view this report as we have saved them for you.

![Problem Files SophosLabs Intelix](/files/cuh5oGhxv4H3IrqDCCKs)

### Static Analysis

Harness the power of multiple machine learning models, global reputation, deep file scanning, and more without needing to execute the file in real time.

These static analyzers generate rich reports, including industry-wide detection coverage, and ensure speedy analysis to determine a verdict or identify files that need further analysis via dynamic file analysis.

Click the Actions button (![Problem Files Actions button](/files/NXQ8bZirOt4kAbyERF1e)) and select `Run Static Analysis`

<figure><img src="/files/5DWIqdcEczuSPBaZ2IyV" alt=""><figcaption><p>Run Static Analysis</p></figcaption></figure>

You will be prompted to acknowledge that you will be sending the specified file outside of your AWS Account to the Cloud Storage Security OEM slice of the SophosLabs Cloud Sandbox.

<figure><img src="/files/1KoA7AVfIbr0fzX9bbCF" alt=""><figcaption><p>Static Analysis Dialog</p></figcaption></figure>

The file will be sent to the sandbox for static analysis. A report will be generated and displayed within the line item. This can be downloaded and/or reviewed later at any time.

<figure><img src="/files/5kqWEUvvGaoq8nGUZCRs" alt=""><figcaption><p>Static Analysis Report</p></figcaption></figure>

As part of the static analysis you will also receive a VirusTotal report.<br>

<figure><img src="/files/vkQLiqu3G8GY4kWDMlLP" alt=""><figcaption><p>VirusTotal Report</p></figcaption></figure>

### Dynamic Analysis

Detonate malware in real-time in a sandbox utilizing the latest analysis techniques for unmatched visibility into malicious files among the unknown. Every activity and behavior is recorded to reveal the true nature and capabilities of a potential threat.

Advanced anti-evasion technologies thwart malware that attempts to detect if it’s in a sandbox or running in a virtual machine, leaving malware with no place to hide.

Click the Actions button (![Problem Files Actions button](/files/NXQ8bZirOt4kAbyERF1e)) and select `Run Dynamic Analysis`

<figure><img src="/files/T8FA92MchSMZEzoffM3d" alt=""><figcaption><p>Run Dynamic Analysis</p></figcaption></figure>

You will be prompted to acknowledge that you will be sending the specified file outside of your AWS Account to the Cloud Storage Security OEM slice of the SophosLabs Cloud Sandbox. The file will be sent to the sandbox to be `detonated` for dynamic analysis. A report will be generated and displayed within the line item. This can be downloaded and/or reviewed later at any time.

<figure><img src="/files/x0Dvqql8V5gjcWc8KlNc" alt=""><figcaption><p>Dynamic Analysis Report</p></figcaption></figure>

You can see a detailed `Activity Tree` of what took place when the file was detonated.

<figure><img src="/files/NQ6eGF69wMtwUJiWt0FT" alt=""><figcaption><p>Activity Tree</p></figcaption></figure>

At any time after the fact, for both the Static and Dynamic Analysis, you can come back to this page to review the reports.

<figure><img src="/files/LUo8PQ3QMsqOVFsAZOo4" alt=""><figcaption><p>Show previously run Analysis</p></figcaption></figure>

## Searching the Data

The main data fields are presented within the table:

1. Object name
2. Uploaded to bucket
3. Account
4. Result
5. Scan on date
6. Quarantine bucket
7. File exists check.

`File Exists` indicates whether that file is still available. The `Search` field above the filtered results is a global search across the entire table. Start by typing in the value for any of the fields and it will start filtering the table down to the matching values. You can also space separate search criteria to search by multiple values.

For example, you want to search by a particular originating bucket and the infected status. Your search bar might look like `partial-bucket-name infected`. That will search by both the bucket name as well as the status of infected. It is very simple to drill down to what you are looking for.

### Searching Tips

{% hint style="info" %}
You may see a short delay after typing in your search value since we won't actually trigger the search until typing has stopped for 1 second.
{% endhint %}

* **Match words out of order:**\
  For example if you search for Virus Found it would match a row containing the words Virus and Found, regardless of the order or position that they appear in the table.
* **Partial word matching:**\
  As filtering provides immediate feedback, parts of words can be matched in the result set. For example Vir will match Virus.
* **Multiple searches:**\
  The table provides functionality to enter multiple words separated by a space and the search will return all rows containing at least one of those words.
* **Preserved text:**\
  This table adds the ability to search for an exact phrase by enclosing the search text in double quotes. For example "Virus Found" will match only text which contains the phrase Virus Found. It will not match Virus is in Found.

### Export Data

The Problem Files report gives you two options for exporting the data into a CSV format:

**Export Filter to CSV**

This option allows you to export all results that match the current filter configuration. You do not need to apply your filters before exporting. With this option, all data that matches the filters will be exported into the CSV file.

**Export Table to CSV**

This option will export the data that is currently displayed within the results table. This option allows you to export a subset of results to CSV, and is impacted by both the table page selection and any filtering executed by search.

If you want to export all results from your filter configuration, it is best to use the **Export Filter to CSV** option.

## Rescanning problem files

You can rescan any problem files that are found to be infected, unscannable, suspicious, or have an error. If you are scanning a file with a single scanning engine, it is a good practice to change the scanning engine or enable multi-engine scanning to see if a different scanning engine will treat the file any differently.

All you need to do is select the files that you want to rescan, click `Selected Actions`, and then click `Rescan`. This action will force our scanner to attempt to scan the file again. If the file is found to be clean it will be tagged as such. Otherwise it will again be tagged with a different finding.

<figure><img src="/files/ZjzXmAOw3qTzzUokoJJc" alt=""><figcaption><p>Rescanning problem files</p></figcaption></figure>

{% hint style="info" %}
If a file is found to be unscannable or produces an error upon being scanned, we will not charge you for the data that scan used. Once you rescan, if the file is scanned successfully and is found to be clean, infected, or suspicious the scan will count towards your scanning data.
{% endhint %}


# Malware History

For users that want to get a visual understanding of how malware has been found over time, you can use the Malware History report to track historic malware findings.

<figure><img src="/files/4QBigULCoKQmqFZzPFrG" alt=""><figcaption><p>Malware History Dashboard</p></figcaption></figure>

You can expand a specific identity and view more information around how often it was found. At this time, this report pulls data from the last 30 days of enabling it and will show information from that point onwards.

<figure><img src="/files/Pv2sMG2lEos4DQv3J3fM" alt=""><figcaption><p>Times a malware was found in history</p></figcaption></figure>

We also leverage [Amazon Bedrock](/how-it-works/integrations/amazon-bedrock) to interpret the malware finding to provide a human-readable summary and description of the malware found. As a result, Amazon Bedrock must be enabled for this feature.

<figure><img src="/files/4KyWbkzbezd89nRep7gE" alt=""><figcaption><p>Amazon BedRock analysis of a Malware found</p></figcaption></figure>


# Results

The Problem Files Chart on the Dashboard is great for an active, high level view into the activity within your environment. But, sometimes you want and need to see more specific metrics.

{% hint style="info" %}
**Note**

In the Console, this page changes name depending on whether you have AV, Classification, or both enabled. The name will be 'AV Results', 'Classification Results', and 'Results' respectively.
{% endhint %}

## Overview

The `Scan Results` page is a simple view by day, week, month or custom time range for all scan results across the deployment. Charts at the top of this page will match to the time window selected and will give you graphical view into the total scan results. The table below will give you granular views for each day, week or month. There are three tabs across the top of the table giving you a total `Summary` or a breakdown by `Account` and even a breakdown by `Bucket`.

{% tabs %}
{% tab title="Scan Results" %}
![Scan Results](/files/u9Bdinzs81PpeqRP1z7S)
{% endtab %}

{% tab title="Classification Results" %}
![Scan Results](/files/Au8pMEGvDlT7TY3aDGTM)

## Table Data

<div align="center"><figure><img src="/files/8wOBmffdfxmOakCa6JvW" alt=""><figcaption><p>Summary</p></figcaption></figure></div>

The table data shown below the charts are the details for each slice of the time window. If the `Daily` time window is selected then we show the last 30 days worth of data. If `Weekly` is selected then we show the last 17 weeks of data. With `Monthly` selected we show the last 13 months of data.

This page and table is meant to be a very simple report on the classifying taking place in your environment.

### Summary Tab

On this tab you will see an overall view for the deployment. This is the total number of objects classified across all accounts within the deployment.

{% hint style="success" %}
You'll also notice that most numbers within the `Summary` tab are clickable. These links take you into the [Problem Files page](/console-overview/see-whats-infected/problem-files) with the results filtered down to that time slice and result (non-matching, matching, error or unclassifiable). This allows you to directly drill down into the details for the day or the problem file type making it easier to dig deeper.

* Clicking the `Date` will take you to all the files found on that date
* Clicking one of the numbers for `Error` or `Unclassifiable` you will be redirected to the Problem Files page filtered down to those type of problems
  {% endhint %}

### Account Breakdown Tab

On this tab you will see an activity breakdown by the accounts you have linked within your deployment. So you will see the scan numbers for each and every account.

{% hint style="info" %}
If you are looking for amounts of data scanned and not total file counts, then check out the [Usage Report](broken://pages/UATaH6zaN7tgDUUp4KIo).
{% endhint %}

### Bucket Breakdown Tab

On this tab you will see activity for each bucket that had activity in the given time window. This is very useful to get a feel for where the activity is coming from and to ensure you are protecting where you are expecting.
{% endtab %}
{% endtabs %}

## Table Data

{% tabs %}
{% tab title="Scan Results" %}
The table data shown below the charts are the details for each slice of the time window. If the `Daily` time window is selected then we show the last 30 days worth of data. If `Weekly` is selected then we show the last 17 weeks of data. With `Monthly` selected we show the last 13 months of data.

This page and table is meant to be a very simple report on the scanning taking place in your environment.

<div align="center"><figure><img src="/files/ch9iXJgBQt7dEDxvzQBK" alt=""><figcaption><p>Summary</p></figcaption></figure></div>

## Summary Tab

On this tab you will see an overall scan view for the deployment. This is the total number of scans across all accounts within the deployment. At times you may see zeros for the current day row. This is a result of when we gather the data (midnight). So zeros are shown until the nightly run. You can get an immediate current count for the day by clicking the `Update All Scan Results` green button.

{% hint style="success" %}
You'll also notice that most numbers within the `Summary` tab are clickable. These links take you into the [Problem Files page](/console-overview/see-whats-infected/problem-files) with the results filtered down to that time slice and scan result (infected, error or unscannable). This allows you to directly drill down into the details for the day or the problem file type making it easier to dig deeper.

* Clicking the `Date` will take you to all the files found on that date
* Clicking one of the numbers for `Infected`, `Error` or `Unscannable` you will be redirected to the Problem Files page filtered down to those type of problems
  {% endhint %}

## Account Breakdown Tab

On this tab you will see an activity breakdown by the accounts you have linked within your deployment. So you will see the scan numbers for each and every account.

{% hint style="info" %}
If you are looking for amounts of data scanned and not total file counts, then check out the [Usage Report](/console-overview/monitoring/usage-rollup).
{% endhint %}

![Scan Results Table Data Account](/files/vDUTqWd8ax5WTclpuflL)

## Bucket Breakdown Tab

On this tab you will see activity for each bucket that had activity in the given time window. This is very useful to get a feel for where the activity is coming from and to ensure you are protecting where you are expecting.

![Scan Results Table Data Bucket](/files/g2D7SSTYYdsXuXXdaX5d)
{% endtab %}

{% tab title="Classification Results" %}
The table data shown below the charts are the details for each slice of the time window. If the `Daily` time window is selected then we show the last 30 days worth of data. If `Weekly` is selected then we show the last 17 weeks of data. With `Monthly` selected we show the last 13 months of data.

This page and table is meant to be a very simple report on the classifying taking place in your environment.

<div align="center"><figure><img src="/files/8wOBmffdfxmOakCa6JvW" alt=""><figcaption><p>Summary</p></figcaption></figure></div>

## Summary Tab

On this tab you will see an overall view for the deployment. This is the total number of objects classified across all accounts within the deployment.

{% hint style="success" %}
You'll also notice that most numbers within the `Summary` tab are clickable. These links take you into the [Problem Files page](/console-overview/see-whats-infected/problem-files) with the results filtered down to that time slice and result (non-matching, matching, error or unclassifiable). This allows you to directly drill down into the details for the day or the problem file type making it easier to dig deeper.

* Clicking the `Date` will take you to all the files found on that date
* Clicking one of the numbers for `Error` or `Unclassifiable` you will be redirected to the Problem Files page filtered down to those type of problems
  {% endhint %}

## Account Breakdown Tab

On this tab you will see an activity breakdown by the accounts you have linked within your deployment. So you will see the scan numbers for each and every account.

{% hint style="info" %}
If you are looking for amounts of data scanned and not total file counts, then check out the [Usage Report](broken://pages/UATaH6zaN7tgDUUp4KIo).
{% endhint %}

## Bucket Breakdown Tab

On this tab you will see activity for each bucket that had activity in the given time window. This is very useful to get a feel for where the activity is coming from and to ensure you are protecting where you are expecting.
{% endtab %}
{% endtabs %}

## Export Data

{% tabs %}
{% tab title="Scan Results" %}
You can export the data you see based on the time slice you are in by clicking the `Export to CSV` button. You'll have the choice to download all three of the tab's data or for an individual tab. Sample outputs can be seen below.

<div align="center"><figure><img src="/files/DxQKP1FTjXLMF21OAcQ8" alt=""><figcaption><p>Export to CSV</p></figcaption></figure></div>

## Summary Report Exported:

<div align="center"><img src="/files/3c347pMkbec09hRH47lR" alt="Scan Results Exported CSV Day"></div>

## Account Report Exported:

<div align="center"><img src="/files/gFSvd8aT4A59bqzAzzWu" alt="Scan Results Exported CSV Day"></div>

## Bucket Report Exported:

![Scan Results Exported CSV Day](/files/EZDRm2Q6fOoUjnrpk2Qc)
{% endtab %}

{% tab title="Classification Results" %}
You can export the data you see based on the time slice you are in by clicking the `Export to CSV` button. You'll have the choice to download all three of the tab's data or for an individual tab.

<div align="center"><figure><img src="/files/d7ktNujJ6RjCCSLgLKwz" alt=""><figcaption><p>Export to CSV</p></figcaption></figure></div>
{% endtab %}
{% endtabs %}


# Schedules

Scheduled Scanning allow you to process new or existing files based on a schedule, and include a Classify Now option for immediate classification.

## Overview

Instead of processing new files as they come in, your workflow may allow them to be scanned once per day (or at some other preferred time interval). For compliance reasons you may be required to scan all of your files on a quarterly basis and Scheduled Scanning will allow you to do that. Whether it is compliance or infrastructure efficiencies and cost optimizations, scheduled scanning provides you the flexibility to determine how you scan your data.

![Schedules Page](/files/KEoi1nycAOgAryLkbFf1)

## Creating a Schedule

Creating a schedule is a simple process. It is made up of two steps: picking the resources you want included and defining the scan frequency.

1. Click the `Create Schedule` button.
2. Select the resources to include in this schedule.
3. Define the Scan Frequency by filling in the details.
4. Click the `Save` button.

<figure><img src="/files/PlhwRMiAUygxpd8q4GFB" alt=""><figcaption><p>Creating an AV Schedule</p></figcaption></figure>

The process for creating a classification schedule is similar. If you are Classifying files, you'll aslo need to define Matching Rules. This is the heart of Classification, defining patterns you are searching for. You can choose all patterns that the system has with Select Visible, or for a certain region with Regions, or you can select specific matching patterns individually with check boxes.

<figure><img src="/files/WMiz2WaoMKVFAU8bUfQN" alt=""><figcaption><p>Create a Classification Schedule</p></figcaption></figure>

{% hint style="warning" %}
A schedule is not activated when you save it (as you can see in the pic above). You have to take the second step from the row actions menu to activate the schedule. You may be prompted to take additional steps for region setup. If you are protecting resources with a schedule in a region that has never been configured before, you will need to provide [networking setup information](/console-overview/protection/aws/protected-buckets#enable-buckets-for-scanning) as part of the schedule activation.
{% endhint %}

| Fields                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Schedule Name          | Name to identify this particular schedule (must be unique)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Scan Period            | Choose what the scan frequency should be from: **Hourly, Daily, Weekly, Monthly, Yearly**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Schedule Description   | Provide a useful description of what this schedule is doing (optional)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Files to Scan/Classify | <p>This allows you to specify whether this schedule should scan all objects within the resources or only the new objects since the last scheduled scan. When first creating or re-activating a schedule, the <code>last scanned value</code> is set to current UTC time.<br><br>Possible Values:<br></p><ul><li><strong>All Files</strong> - will scan all objects in the resource(s) every time the schedule is kicked off</li><li><strong>New Files Since Schedule Creation</strong> - Going forward from creation and then from the last schedule execution, this schedule will scan only new objects found in the resource(s)</li><li><strong>Scan/Classify All Files on First or Next Run</strong> - this is an add-on to the <strong>New Files</strong> option. This allows you to baseline the resource(s) by scanning all objects within the resource(s) the very first time the schedule is created. <strong>Note:</strong> <em>you can click this again at any time the schedule is active and the very next execution of the schedule will scan all objects again.</em></li></ul>                                                                                  |
| Times to Scan          | <p>Each scan period will allow you to specify options for when to scan within that period.<br><br>Possible Values:<br></p><ul><li><strong>Hourly</strong> - You can select <code>Every Hour</code> or <code>Every Half Hour</code><br><em>Note: If the resources included in this schedule are quite large (>\~8 million objects) you may not get find all the new objects in the half hour option</em></li><li><strong>Daily</strong> - You can select every hour of the day or some subset of the day (at noon and midnight for example)<br><em>Note: all times are UTC</em></li><li><strong>Weekly</strong> - You can select all days of the week or any subset. For example, every Friday night the schedule would run. Or every Monday, Wednesday and Friday.</li><li><strong>Monthly</strong> - You can select any one day of the month. For the last day of the month, select the <code>Last Day of Month</code> option</li><li><strong>Yearly</strong> - You can select all months of the year or any subset. For example, if you wanted to perform quarterly scans you could select <code>Last Day of Month</code> for March, June, September and December</li></ul> |

## Managing Schedules

Once the schedule is created you will need to manage it. There are 5 main things you can perform on your schedules:

1. Activate
2. Deactivate
3. Modify
4. Delete
5. Scan/Classify now

### Activating and Deactivating

As noted above, schedules are not created in an `active` state. You must activate the schedule using the action menu to the far right side of the schedule row. Simply click the button and select `Activate` as seen below.

<figure><img src="/files/cCmlxCau8uBOt5HXRdxn" alt=""><figcaption><p>Activate a Schedule</p></figcaption></figure>

To deactivate the schedule you click the action menu and select `Deactivate`. The deactivate menu option will only appear when the current state of the schedule is `active`.

<figure><img src="/files/eYVF8E3D6I5CabFiiSZz" alt=""><figcaption><p>Deactivate a Schedule</p></figcaption></figure>

{% hint style="info" %}
Once a schedule is activated, it will execute at the Next Scheduled Scan time. While a schedule is inactive, it won't scan at all. If you reactivate a schedule that has previously run, its last scan time will be set to current UTC time and move forward as if it were a new schedule. The schedule will not go back to the previously active time.

If a schedule is missed because the console is offline (upgrades, reboots, etc), the schedule will make up for the lost time and scan since the set last scanned time.

You must deactivate a schedule before you can delete it.
{% endhint %}

### Editing

You may need to modify an existing schedule in some way: add or take away resources, modify the scan period, etc. Editing can be triggered by clicking the `Edit` button from the action menu.

<figure><img src="/files/YY71bCNM8BR9rt2TGqST" alt=""><figcaption><p>Make whatever changes are needed and click the <code>Save</code> button.</p></figcaption></figure>

### Deleting

Whether you want to get rid of test schedules or a schedule that is no longer needed, you can easily delete a schedule from the action menu.

{% hint style="info" %}
The schedule must be inactive before it can be deleted. The delete menu option will not appear until the schedule is in an `inactive` state.
{% endhint %}

<figure><img src="/files/05zLWPLowBA0xdAmcf37" alt=""><figcaption><p>Delete a Schedule</p></figcaption></figure>

### Scan Now and Classify Now

If you need to run a schedule immediately or on-demand you can do so with the `Scan Now` option for AV and `Classify Now` option for DC in the action menu. If your schedule is an `All Files` schedule then for the selected resources all objects will be scanned. If the schedule is a `New Files` schedule then new objects from the last scan date will be scanned.

<figure><img src="/files/lVKOUYKLNb4hy9bxDTxU" alt=""><figcaption><p>Scan Now and Classify Now</p></figcaption></figure>

### Searching

The provided search field will search anything in the Schedule Name, Schedule Description and Scan Frequency columns. On top of that, you can also search by volume names and any schedules that match the full or partial volume name will be displayed.

<figure><img src="/files/82Xud0HlwKK81UBdpKgD" alt=""><figcaption><p>Searching Schedules</p></figcaption></figure>


# Monitoring

Under the Malware Scanning section you will find the ability to view different aspects of the CSS application: Viewing error logs, storage container statuses, scanning agents by region, and more.


# Error Logs

This page gathers all Error Logs to aid with troubleshooting.

Historically, error logs were only accessible through CloudWatch. For customers who prefer to use the CSS Console as a starting point, we provide this page to pull errors that are both logged into CloudWatch and otherwise. You can set a filter to search by a custom date range and search by keywords for the returned results.

<figure><img src="/files/Mpc5Xgi0EPYfwt9pfcOH" alt=""><figcaption></figcaption></figure>

This page should be used as a starting point to search for errors. Logs gathered from CloudWatch provide a 'Link' field when expanded where you can use to jump right to the problematic log in CloudWatch for further investigation.

<figure><img src="/files/DaPldw10UfzwJlyaOFNn" alt=""><figcaption></figcaption></figure>


# Bucket Settings

The Bucket Settings page offers a configuration overview for all of the buckets you have access to, including all of the buckets in the deployment account and any linked accounts.

## Overview

There are two main sections to this page:

1. The summary section
2. The detailed filterable chart.

The Summary section gives you counts for each of the tracked settings (more settings will be added as we go along). So if one in particular is of interest you can get a quick understanding if you have any buckets matching that.

The detailed filterable table is a list of the entire bucket catalog with a red / yellow / green association with the different bucket characteristics. This is somewhat arbitrary based on the value you place with each characteristic.

![Bucket Settings Overview](/files/qk7UamcqNZ8bAkJGzYmK)

### Bucket Summary

<figure><img src="/files/oUA4C3pTclNlEOhyPqq7" alt=""><figcaption><p>Bucket Summary</p></figcaption></figure>

This is a simple count of buckets matching for each bucket characteristic.

### Detailed Filterable Table

The table data is a list of the entire bucket catalog with a red / yellow / green association with the different bucket characteristics. This is somewhat arbitrary based on the value you place with each characteristic. Please [Contact Us](/contact-us) if you have opinions on what red / yellow / green means to you so we can get a consensus and make adjustments.

The table data is filterable in two ways: by AccountID and Region and then also at the table column heading. The data is filtered with `and` logic so as you apply more filters the data set gets smaller.

#### Filtering by AccountID and / or Region

<figure><img src="/files/9PcTmRLbYOdmwrZmt04X" alt=""><figcaption></figcaption></figure>

If you'd like to filter the list down to a particular account or accounts and / or a particular set of regions, you can do so with these inputs. Simply click into the field and you will be presented with a list of accounts or regions. You can search for and select one or as many as you like. By selecting values here you are pre-filtering the table before ever applying table filters.

<div align="center"><figure><img src="/files/sCnpIzsabCozagQ37Dob" alt=""><figcaption><p>Region Filter Example - 2 Regions Selected</p></figcaption></figure></div>

#### Filtering with Table Columns

<div align="center"><figure><img src="/files/lYq4DOxb59gksL75Hhtn" alt=""><figcaption></figcaption></figure></div>

Each column has this icon (![Bucket Filter icon](/files/4dimptHXJk3OngWeV8Qx)) in it.

This triggers the filter for this particular column. Each column will show all of the possible values in it that you can select and filter by. The values are also searchable. This is mostly applicable to the Bucket Name column as the other columns are binary. Once you've selected filter click Apply. The filter icon will change colors to represent you have selected that particular filter. It is very subtle because it is such a small icon, but if you are ever wondering why you may not be seeing your entire bucket list, look to see if you have column filters applied.

Here is an example of the first two columns where the `Public Access Blocked` filter has been applied:

<div align="center"><figure><img src="/files/tREb4LcfESsNLTmk4t7n" alt=""><figcaption></figcaption></figure></div>

You can clear a filter simply by clicking back in to the filter itself and clicking the `Clear` button.


# Deployment

The Deployment Overview page was created to give you a better understanding of the current infrastructure you've deployed.

## Overview

The Deployment Overview also portrays a general protection status for the account(s) you are monitoring with the solution. At a quick glance you can see which regions have some level of protection (event scanning, scheduled scanning or an API endpoint) configured and which do not. You can also easily determine which regions you have Amazon S3 buckets in and how many are being protected.

The Deployment Overview page has a second function to it which is the ability to clean up (uninstall) parts or the entirety of the solution.

![Deployment Overview collapsed](/files/yzl5f1IPGULqJuGLHf4e)

## Infrastructure Overview

In the collapsed card view, as seen in the picture below, you can quickly see there are 16 regions with buckets (16 region cards appear) in the account(s) this deployment is monitoring. I can also see that 7 of the regions have current protection setup (bucket icon is not red) and 8 of the regions have or have had some level of protection enabled (8 of the 16 cards are white) indicated by the fact the Event Agent is present. We can also determine that 9 of the regions are not currently being protected (indicated by red bucket icons) and 8 of the regions have never had any level of protection configured (indicated by red cards). The red bucket icons and red cards and the fraction of buckets could be indicators for where more protection should be considered.

![Deployment Overview callouts](/files/l2LEBuHxHPB9vAbM0GbY)

This can also be see in the expanded card view:

![Deployment Overview expanded](/files/xCxvfjJZ8gLOgV9En7xQ)

The expanded card view gives you additional details about the deployment such as: whether or not agents are currently running and the count, the aggregate runtime hours for the agents (current month) and whether or not [Smart Scan](/console-overview/configuration/agent-settings#smart-scan) is enabled for that region. You will also get a count of buckets protected either by real-time protection or through a schedule.

You can expand / collapse all cards with the buttons above the cards (![expand buttons](/files/iHN5BcZbWSg21jhH8Rjq)) or individually by clicking anywhere on the particular card header.

## Solution Cleanup / Uninstall

There are a number of infrastructure items initially created during the CloudFormation or Terraform deployment. There are additional items that are created post deployment by during console operations. This can make it challenging to clean up the solution. We wanted to make it simple for you to clean up a portion or completely uninstall when needed. There are a number of scenarios where this may make sense and we'll leave it to you to determine what that is for your situation, but here are a few:

1. You decide you no longer want to protect buckets in a particular region so you want to scrub that region of infrastructure.
2. You did a POC install and want to remove it now that you will be doing a fresh Prod install.
3. The case where you tried the product and do not want to proceed with it (our least favorite).

### Types of cleanup available:

#### **Delete Event Agent** (if present)

Deletes all infrastructure related to the Event Agent (Fargate service, SNS topic, SQS queue, bucket events).

<div align="center"><figure><img src="/files/RjexMfHb3jFRZUaS23dl" alt=""><figcaption><p>Delete Event Agent</p></figcaption></figure></div>

#### **Delete API Agent** (if present)

Deletes all infrastructure related to the API Agent (Fargate service and Load Balancer).

<div align="center"><figure><img src="/files/sSLC4l9nQXjq18Nilugq" alt=""><figcaption><p>Delete API Agent</p></figcaption></figure></div>

#### **Delete Retro Agent** (if present)

Deletes all infrastructure related to the Retro Agent (Fargate service, SNS topic, SQS queue).

<div align="center"><figure><img src="/files/uX9RLSr0XUn21UZrVB65" alt=""><figcaption><p>Delete Retro Agent</p></figcaption></figure></div>

{% hint style="info" %}
In the v5.03.000 release the Scheduled Scan and On-Demand Scan functionality was re-architected to no longer use the Retro Service. The upgrade process when going to v5.03.000 or later will automatically remove this service from all regions it had been installed.
{% endhint %}

#### **Deactivate Region** (if present)

Performs the delete functionality for the Event, API and Retro agents.

<div align="center"><figure><img src="/files/u58fzJ1a887CSCwHG5p0" alt=""><figcaption><p>Deactivate Region</p></figcaption></figure></div>

#### **Delete Application**

{% hint style="danger" %}
This cleanup type deletes all infrastructure created by the Console across all regions.
{% endhint %}

{% hint style="warning" %}

* Security Groups will be left behind and must be manually removed.
* **Make sure to unprotect all buckets first to get rid of all S3 Event Notifications Subscription in each of them**
  {% endhint %}

{% hint style="info" %}
You will have the option to keep or delete the quarantine buckets that were created to house infected files.
{% endhint %}

You can only trigger the Delete Application function through the action menu for the region your console is deployed in. Unless you chose otherwise during deployment, the default region set in the deployment template is `us-east-1`.

<div align="center"><figure><img src="/files/XYeWVM2B6yylliEu24eI" alt=""><figcaption><p>Delete Application</p></figcaption></figure></div>

Upon completion, you will be provided with a link provided to complete the uninstall by deleting the CloudFormation Stack used during the initial deployment.

If you used Terraform, you will just be asked to tear down the stack with your Infrastructure As Code. In that case, initiate a Terraform Destroy.

{% hint style="info" %}
Occasionally, Terraform may struggle to delete an SSM Document created by our application. Use the following AWS CLI Command to delete this resource, and then run Terraform Destroy again. Substitute the value for your unique Application ID, which found in the Terraform error message.<br>

```
aws ssm delete-document --name CloudStorageSecConfig-Schema-{your_application_id} --force
```

{% endhint %}

If you originally deployed using our PAYG listing, are deleting the entire application, and no longer wish to use our solution you **must** unsubscribe in AWS Marketplace after deleting the application. If you do not unsubscribe you will continue to be charged our base subscription.


# Jobs

On-demand and scheduled scans/classifications are considered jobs within the system. As a result, they can be monitored and managed independently from one another.

This page can be leveraged for seeing what activity you have in the system, monitoring individual jobs, cancelling active jobs, and reviewing the history of activity.

{% hint style="info" %}
On-demand and Scheduled scans/classifications are the first two job types to show up, but others will follow shortly to help keep better track of the system and perform tasks that make sense to wrap up this way (report gathering, health checks, etc).
{% endhint %}

![Jobs Overview](/files/u3F2n8ZlWpN3vwzK2ctC)

## Job Filters

You can filter the jobs view by accounts, a date range and job status. By default all accounts you have access to will be shown and selected. Make changes to the filters as desired and click `Apply Filter` to modify what is shown below.

![job filters](/files/Sw5xuvhC3l1BwnQG4l7o)

Once you have the results filtered, you can search amongst the results with the `Search` bar. The Search bar is a free form text search that will search across all the columns in the results table.

<figure><img src="/files/56sB3TD1wMOnXBdQquwG" alt=""><figcaption></figcaption></figure>

## Job IDs

Each job is assigned a unique ID, which is displayed as the first column in the Jobs table.

This Id is also written to the Agent.ScanResults/Console.Jobs CloudWatch logs specific to that job execution. This allows you to easily search your logs to monitor activity or troubleshoot errors.

## Job Insights

For each job that you start you can now see additional details by clicking into a job and sorting through each category:

* By Account: shows the AWS accounts that you have linked in that were associated with the job
* By Container: shows the containers that were associated with the job (S3 bucket, EBS volume, etc.)
* By Result: gives you an overview of all the results associated with the scanning done by the job
* Logs: provides an overview of any logs generated by the job including the messages of the logs and which log groups you can find the details in if you are using CloudWatch.

<figure><img src="/files/xU4FLKsLod3dDLCSeeW6" alt=""><figcaption></figcaption></figure>


# Notifications

The Notifications page allows you to search through different system events that we log. This can be useful for users who want to dive deeper into our console logs without CloudWatch.

## Filter Notifications <a href="#overview" id="overview"></a>

**Accounts**

You can filter notifications by different accounts you have linked. Select one account at a time for more granular searches or select multiple at once for a wider search.

<figure><img src="/files/R9wy3nbFVzIQqioudqul" alt=""><figcaption></figcaption></figure>

**Notification Types**

You can filter by type of notification. Here are the current types of notifications we offer logging on:

* BucketAutoProtectionFailed
* BucketProtection
* BucketsDeleted
* BucketsDiscovered
* BucketsPublicAccess
* ClassificationResult
* EbsVolumesDiscovered
* EfsVpcPeeringFailed
* FsxVolumesDiscovered
* Job
* LowPrepaidData
* ProactiveMonitorResult
* ScanResult
* SecurityFinding
* StorageAssessment
* TrialExpiring
* UpdatesAvailable

**Date Range**

Users can slice by date ranges as well to filter by the most relevant logs.

<figure><img src="/files/9PvmkA8XbOIi8eeHGBWS" alt=""><figcaption></figcaption></figure>

## **Results**

We will produce a list of notifications that match your filters.

<figure><img src="/files/Rr5BKmc9ehy0IXtGD5Uj" alt=""><figcaption></figcaption></figure>


# Storage Assessment

The Storage Assessment page gives you detailed information about your Amazon S3 storage state.

## Overview

Details that are useful for understanding your Amazon S3 environment and to give you an overall feel of your data include:

* Relevant charts showing an S3 Overview
* File Information
* Bucket Information
* Trends

You can filter the information shown by bucket, region, account, and/or date. You can also see the date of the last scan under the Storage Assessment Data section. Finally, under the Filters you can see the time frame you are viewing data for.

<figure><img src="/files/WnyWgVlYcBUHE8dfJYOO" alt=""><figcaption><p>Storage Assessment</p></figcaption></figure>

## **Top Row Informationals**

The top row of widgets gives you a quick view to specific details around your S3 environment. The top row gives you the aggregate totals of the latest snapshot for Total Data in your S3 environment, Total Objects in your S3 environment, Buckets and Regions enabled with Storage Assessment, Total Objects Scanned with our application, and Total Objects Encrypted in your S3 environment.

<figure><img src="/files/v77wJIUeJnrT3Bd6QMuC" alt=""><figcaption><p>Storage Assessment Snapshot</p></figcaption></figure>

## Assessment Visuals

Any chart labeled Top X will show 10 if there are more than 10 total buckets in your S3 account. Additionally, the first 2 panel charts will only show you information about the latest snapshot. For example, if you have a 30 day time frame selected it will only display information about the latest day (yesterday) as that contains the most up to date information.

### **S3 Overview**

This panel contains 4 charts about your S3 environment. Going clockwise from the top left: Total Object Count and Size chart of your current S3 environment, Top 10 Largest Buckets in GB's, Percent Scanned of 10 Largest Buckets, and Percent Encrypted of 10 Largest Buckets.

<figure><img src="/files/w4rI4WrrCmcc5fIbl9nl" alt=""><figcaption><p>S3 Overview</p></figcaption></figure>

### File Information

The panel contains 3 charts about files in your S3 environment. Going clockwise from the top left: Top 10 File Types by size, Top 10 File Types by count, and File Ages of all files in your S3 environment.

<figure><img src="/files/CagKlkD5nUuX8gFrl4ZV" alt=""><figcaption><p>File Information</p></figcaption></figure>

### **Bucket Information**[**¶**](https://help.cloudstoragesec.com/console-overview/storage-assessment/#bucket-information)

This panel contains 4 charts about Buckets in your S3 environment. Going clockwise from the top left: Public and Private Bucket Count by Region Encrypted and Unencrypted Bucket Count by Region, Percentage of a regions scanned object, and Percentage of a regions encrypted objects. The top 2 charts information we get from our Bucket information collection and the bottom 2 charts information we get from Storage Assessment data. If you do not have Percent Scanned enabled that graph will display 0's for all regions.

<figure><img src="/files/RWZJzZYex3k9jbVGQ6dX" alt=""><figcaption><p>Bucket Information</p></figcaption></figure>

### Trends

The trends tab contains 3 graphs that will only be visible if your time frame is larger than 1 day. They will display trends for whatever time frame is selected. First Graph is Bucket Object count by day, then Bucket Size by day, then Percent Scanned of each bucket by day.

<figure><img src="/files/DgEAx9hCpMYVlVesgVe0" alt=""><figcaption><p>Trends</p></figcaption></figure>

## Keywords <a href="#keywords" id="keywords"></a>

### **Storage Assessment**

An assessment of aggregated stats by our application using a manual bucket crawl initially and then AWS’s Inventory configuration report for the remaining time.

### **Manual Crawl**

Our application manually crawls your buckets and gathers information about the files sizes, last modified date, encryption status, and file type.

### **Inventory Configuration**

A snap shot report generated once a day by AWS that contains information about your bucket contents. It contains file name, size, last modified date, encryption status, storage class, intelligent tiering access tier, and the name the bucket it resides in. Inventory configuration can have 2 status: Enabled and Disabled. Enabled means that a report is generated and delivered every night. Disabled means that Inventory Configuration settings are primed on the bucket but no report is generated and delivered. Our application configures the Inventory Config to deliver the reports to a directory in your quarantine bucket in the same buckets region.

### **Percent Scanned**

This refers to the percent of objects scanned in your bucket. It takes the key name from the Inventory Config and checks the file for tags in S3 that match our applications tags. We then take the count of objects with matching tags and find the percentage against your buckets total object count.

{% hint style="info" %}
Since the Inventory Config’s report is generated separately from when we aggregate it there could be a discrepancy if files are deleted during that time frame that are in the report.
{% endhint %}

### **Percent Encrypted**

We can get the file encryption status information from the Inventory Config’s report so we do not have to make an additional S3 call but we aggregate it the same way above.

## Requirements for Storage Assessment

For Storage Assessment to be active it must be:

1. Enabled on the Console Settings page (under Configuration).
2. At the Storage Assessment Settings modal's Enable Bucket Assessments tab each bucket that you want to include in the report must be enabled.
3. If you want to have an Objects Scanned count and percentage, then you must enable Percent Scanned Settings at the Storage Assessment Settings modal.\
   More details can be found in the Process section of this help page.

## **Enabling or Disabling**

There is one new parameter in the CloudFormation Template used for deployment: `Enable Storage Assessment`.

If that parameter is enabled the app will do a manual crawl on all of your buckets and put an enabled inventory config on all of your buckets. If that parameter is disabled it will not do a manual crawl and will put an inventory config on all buckets in a disabled state.

To enable Storage Assessment if you have disabled it in the CloudFormation Template you will have to go to the Console Settings page, enable the Storage Assessment toggle, and then go to the Storage Assessment page to enable the buckets you would like to be aggregated. If you install the app with Storage Assessment disabled a manual crawl will not happen, it will wait until the first Inventory Config report is generated and delivered.

### **Console Settings Page**

To enable/disable Storage Assessment throughout the application toggle this setting on/off on the Console Settings Page. If you are enabling it you will then have to follow the link and enable the buckets you’d like aggregated.

{% hint style="info" %}
Enabling Storage Assessment on the Console Settings page will not enable any bucket’s Inventory Config, it just allows the application to continue the Storage Assessment process.
{% endhint %}

### **If you're upgrading your deployment**

Upon upgrade, Storage Assessment is enabled by default. This means it will first do a manual crawl on all of your buckets then put an enabled Inventory Config on your buckets.

## Assessment Settings

The settings modal in the top right of the page is where you can enable/disable buckets and configure your Percent Scanned settings.

**Enable Bucket Assignments** is the first tab and it will display a table with buckets. Checked buckets are enabled (can also tell the buckets status by the Enabled column). To enable buckets check the box to the left of the bucket name and just click save. To disable buckets simply uncheck a checked box and click save. You can enable/disable multiple buckets at a time. time frame will be set accordingly.

{% hint style="info" %}
On the Bucket Protection page Event Driven Scanning is off for all buckets at deployment (because its relatively expensive), and on this page Bucket Assessments are enabled for all buckets at deployment (because it's relatively cheap), but you may want to put these settings in sync with each other.
{% endhint %}

<figure><img src="/files/9Bww7QJrzSlZ7PHDhekg" alt=""><figcaption><p>Enable Bucket Assessments</p></figcaption></figure>

**Percent Scanned Settings** is the second tab and this configuration contains

1. An Enabled/Disabled toggle
2. A time frame selection
3. A Run Tonight option

To configure the last two you need to enable Percent Scanned in the toggle.

Time Frame is the amount of time between scans and if change will set the next date as X days from the current day. If Run Tonight is selected it will set the next Percent Scanned date as tonight and the time frame will be set accordingly.

<figure><img src="/files/YcL9EdoDlZeh1cCnUtVR" alt=""><figcaption><p>Percent Scanned Settings</p></figcaption></figure>

## Additional Costs

This feature is automatically turned on when you upgrade to the latest release through the standard console upgrade process. You can disable this feature at upgrade by manually updating the stack and turning the drop down selection to `False`.

This feature will start by crawling all of your data to give you an initial overview to all of the files you have stored in Amazon S3. After that initial crawl, Storage Assessment will leverage [S3 Inventory](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-inventory.html) to continue to assess the data. **Both the crawl and S3 Inventory have minimal charges associated with them (but they could add up over a month if you do this daily).**

`Percent Scanned` requires the checking of S3 Tags to determine if the scan-result tags exist on the objects. `GetObjectTagging` calls will be made against every inventoried S3 bucket. Please take into account the following pricing considerations for Storage Assessment:

* The initial crawl will invoke LIST calls to gather all of the objects associated with your S3 buckets. AWS charges $0.005 per thousand list calls and you receive 1000 objects per list call. This means crawling 1 million objects costs $0.005.
* Storage Assessment generates nightly (in the future this will be configurable) S3 inventory reports. AWS charges $0.0025 per million objects listed for an S3 inventory report.
* If you want to calculate the number/percent of objects scanned this functionality performs GET calls for each object. GET calls cost $0.40 per million objects. The frequency of this calculation is configurable within the Storage Assessment settings.


# Usage

The Dashboard is great for a high level view into the activity within your environment. But, sometimes you want to see the specific numbers broken down by Group and / or Account.

## Usage Rollup Overview

The `Usage` page is a rollup view of each/all Groups and each/all Accounts by time slice (month to date, previous month, 3/6/12 months). Charts at the top of this page will show you a rolling 12 month view the total GBs scanned based on which Group you have selected. The panels below the charts will give you greater detail into the overall GBs scanned broken down by `scan type` (Event, Retro or API) for each and every group. If you do not use groups at all, then you will see all of your accounts listed both in the charts as well as the panels.

![Usage Rollup](/files/tLj4DKppNVzrCdn1KTlW)

## Charts

The charts give you a quick, high level view into the usage. When you land on the page the `Primary` group will be selected and show you the first-level set of groups below.

### Total GB Scanned By Group

The counts you see in this chart will be an aggregate set of usage for all branches below each individual first-level group. If any accounts directly exist in the top-level group selected they will be shown as individual entities as well. The filter below the chart will impact this chart as well as the panels below. When you land on the page you will see all groups / accounts below the absolute top of the tree you have access to. You can then select individually the first-level of groups below.<br>

<figure><img src="/files/YRbKRKkROLp2uULmysul" alt=""><figcaption><p>Total GB Scanned By Group</p></figcaption></figure>

### Total GB Scanned By Account

This chart shows you a breakdown for all the accounts in the entire tree for the top-level selected. This could turn out to be a lot of accounts so filter down as needed either at the [Group-level](/console-overview/access-management/group-mgmt#filter-console-view-by-group) for the entire console session or at the filter-level within the page. The legend reflects the Account Nickname and Number for each account.<br>

<figure><img src="/files/2nZlV0pT7RnOioOq0SGO" alt=""><figcaption><p>Total GB Scanned By Account</p></figcaption></figure>

## Group Panels

The `Group Panels` will give you the details for each and every group you have access to. If you are at the top level, `Primary`, you will see every group below. If you do not see Primary, then you are assigned only to a sub-group(s) and will have access to those alone.

In the case of the picture below, you can see this user has full Primary access and there are three first-level groups:

1. Development
2. Production
3. Testing

The page loads with all group panels collapsed, but with a summary for the selected time frame. All first-level groups will show at the top of the list and then the sub-groups will follow for each top-level group.

{% hint style="info" %}
New groups added after the first load of this page could show up at the bottom until the console is rebooted.
{% endhint %}

![Group Panels](/files/lEErhRGoJTu0g9FqCE9Z)

Each individual group panel will show a complete rollup of the child groups and accounts directly assigned to this group.

### Primary Panel - full view of child groups and directly assigned accounts

<figure><img src="/files/hvuzE33gmZdrwLvSUO1i" alt=""><figcaption><p>Primary Panel</p></figcaption></figure>

### Child Group Panel

<figure><img src="/files/usuJFtlI7mwim6CwHDm3" alt=""><figcaption><p>Child Group Panel</p></figcaption></figure>

## Export Data

You can export the data described above into a CSV format by clicking the `Export to CSV` button. A sample output can be seen below:

<figure><img src="/files/ige9t8JI4wAPFFHYPGcY" alt=""><figcaption><p>CSV Export</p></figcaption></figure>


# Configuration

The Configuration section provides application configuration settings like Console and Agent settings, integrations, license management, and more.


# Scan Settings

There are four configuration adjustments you can make to the Scanning/Classification Agents

1. Tag Name changes
2. Infected File handling (for AV) and Matching File handling (for DC)
3. Scan Engine choice
4. Decisions around which objects to scan (Scan list / Skip list).

These `Scan Behavior Settings` modifications will apply to all agents currently running and new ones that spin up going forward no matter the region. Changes made here will not require a reboot for any agent, but could take 30 seconds to take affect. Such as, custom naming the tags we apply to each object as well as providing scan list and skip list functionality for the buckets.

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

<figure><img src="/files/5FXeEfAGOYUVnjXSdQjY" alt=""><figcaption><p>Scan Settings</p></figcaption></figure>
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}

<figure><img src="/files/3j25uGhzS6ErkhziMPox" alt=""><figcaption><p>Scan Settings</p></figcaption></figure>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
These are global changes and therefore it is not currently possible to create different behavior by region or group
{% endhint %}

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

## Object Tag Keys

Every file the S3 scanner touches has an AWS Tag applied to it. You can change the default key names if required or desired, but not the values.

<figure><img src="/files/jOl2zoJfgHKIpQVzjQ8g" alt=""><figcaption><p>Object Tagging</p></figcaption></figure>

<table><thead><tr><th width="150">Key</th><th>Description</th></tr></thead><tbody><tr><td>scan-result</td><td><p>Identifies whether a file is found to be clean or having issues. Possible values: <code>Clean</code>, <code>Infected</code>, <code>Unscannable</code>, <code>Error</code>, <code>InfectedAllowed</code>, <code>UnscannableAllowed</code>, <code>ErrorAllowed</code>, <code>Pending</code>, <code>Suspicious</code></p><ul><li><code>Clean</code> = no issues found with file</li><li><code>Infected</code> = malware found</li><li><code>InfectedAllowed</code> = represents a file categorized as "Infected" you have marked as safe; could be a "false positive"</li><li><code>Unscannable</code> = object is password protected or greater than maximum size allowed (2GB for ClamAV, 5TB for Sophos and CSS Premium)</li><li><code>UnscannableAllowed</code> = represents a file categorized as "Unscannable" you have marked as safe</li><li><code>Error</code> = access to object issues: KMS permissions, cross account permissions, bucket policy blocking, other</li><li><code>ErrorAllowed</code> = Represents a file categorized as "Error" you has marked as safe</li><li><code>Pending</code> = A temporary tag representing a file that hasn't completed scanning yet. Is replaced by the actual finding when the scan is complete. Seen with Extra Large File Scans and Async API calls</li><li><code>Suspicious</code> = this is a Sophos-only finding that means the engine didn't find anything infected within the file but has found the file to have suspicious characteristics that do not fit the file type</li></ul></td></tr><tr><td>date-scanned</td><td>The date and time the object was scanned</td></tr><tr><td>message</td><td>A description of what has been identified in the file. Only populated for <code>Error</code> or <code>Unscannable</code> results.hint</td></tr><tr><td>virus-name</td><td>Name of virus identified</td></tr><tr><td>uploaded-by</td><td>AWS user identifier</td></tr></tbody></table>

{% hint style="info" %}
AWS allows an object to have only 10 tags applied to it. At most we will add 5 tags (for infected files) and only 2 tags for clean files. If you have a number of tags on your object already, we will trim the number of tags we add to ensure none of the existing tags are dropped. If only 1 tag is available for example, we will write only the `scan-result` tag onto the object.
{% endhint %}

## Action for Infected Files

There are 3 main actions you can take with an infected file: move (default), delete and keep.

> `Move` directs the scanner to take the file and place it (copy then delete) in a quarantine bucket. The console creates a quarantine bucket in each region you enable buckets for scanning. The bucket will be named uniquely with the ApplicationID tacked onto it along with the region it was created in. This is the default behavior.\
> Whenever a file scan results Infected, this will create a path inside the quarantine bucket with the buckets name where the infected file was resting. This allows to track which bucket is getting malware uploaded.

> `Delete` directs the scanner to remove the file entirely.

> `Keep` directs the scanner to leave the file in the bucket it found it. The scanner will still tag the object appropriately.

{% hint style="info" %}

#### Restore Quarantined Files

Using the default `Move` action places files identified as *infected* into a quarantine bucket. You may need to restore the file from quarantine bucket back into the originating bucket. You can do this on a one-time basis or permanently. Check out the [Allow Suspect Files](/console-overview/see-whats-infected/problem-files#allowing-suspect-files-false-positives-acceptable-risks) documentation for more information.
{% endhint %}

{% hint style="info" %}

#### Anecdotally

Most customers continue with the default value of `Move`, but we have seen a number go with `Keep`. They keep the objects in place and leverage a bucket policy to make access to them available only when they are tagged with scan-result=clean.
{% endhint %}

### Sample Bucket Policy to do this

```json
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "BlockAccessExceptClean",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::<staging bucket or any bucket>/*",
                "Condition": {
                    "StringNotEquals": {
                        "aws:PrincipalArn": [
                            "arn:aws:iam::<account-number>:role/CloudStorageSecConsoleRole-<applicationID>",
                            "arn:aws:iam::<account-number>:role/CloudStorageSecAgentRole-<applicationID>",
                            "<account-number>"
                        ],
                        "s3:ExistingObjectTag/scan-result": [
                            "Clean",
                            "Unscannable",
                            "InfectedAllowed"
                        ]
                    }
                }
            }
        ]
    }
```

{% hint style="info" %}
We have a number of customers also using a "2 Bucket System" for more of a "physical separation" of the object storage. They utilize a staging/dirty bucket for all files to first be placed in. This is where all the scanning takes place. Once a file is found to be `clean` it is copied/moved to the production/usable bucket(s). At that point then downstream users and applications will be aware of the files and able to use them. This system uses a combination of our standard event-based scanning (on the staging bucket) and a lambda triggered by our [real-time notifications](/console-overview/configuration/proactive-notifications#proactive-notifications). For more information on how to set this up, check out the [2 Bucket System write-up here](/faq/architecture-related#can-i-setup-a-staging-bucket-for-all-of-my-files-to-first-land-in-and-then-move-them-to-a-production).
{% endhint %}

## Quarantine Buckets

![Quarantine Buckets](/files/tIH0OiF5jX5Fm2QM4sVM)

If you leverage the `Move` action above, then the quarantine bucket and its settings come into play. By default, we place a quarantine bucket in each account (installed and linked accounts) that has buckets being protected by event-based scanning or on-demand/scheduled scanning. Because we don't want to pull files across accounts to store we have this as the default behavior. The quarantine buckets are also created per region so we aren't pulling across regions to store. So theoretically, you could have 20+ buckets added to your S3 if you are protecting data in that many regions.

We have had a number of customers determine they do not want to quarantine in the linked accounts. They would prefer to have all infected files quarantined to their centralized security account (the account the Antivirus for Amazon S3 solution is installed). There is an option here in the settings to `Move to Main Account`. Simply tick the toggle and we'll change how the application quarantines files. We will start storing all `infected` files into a centralized quarantine bucket.

A Lifecycle Policy is added to the quarantine bucket. The default policy indicates to keep files indefinitely, but you can change that so quarantined files will be deleted after a certain number of days. Pick a value that will give you time to work through whatever workflows you have in place to examine quarantined files.

## Scanning Engine

<div align="left"><img src="/files/3NQOhA1rnmMy87anHXjV" alt="Scan Engine"></div>

Antivirus for Amazon S3 has been designed to work with multiple AV engines easily. Currently, there are three engines available: [Sophos, CSS Premium, and ClamAV](/how-it-works/architecture-review#scan-engines). You can choose any engine and even easily switch it after the fact, but there are some distinctions that could weigh the decision in one favor or the other.

* Choice comes down to cost vs large files with a bit of brand-name mixed in as well.
* In large environments, the additional scan costs of the Sophos engine could be somewhat accounted for by the performance gains and the need to run less infrastructure.
* CSS Premium is our latest scanning engine, which can be used as either a primary or secondary engine to enhance scan efficacy
* Look to the table below for the key differentiators.

| Engine      | Maximum File Size | Performance |
| ----------- | ----------------- | ----------- |
| Sophos      | Up to 5 TB        | Better      |
| CSS Premium | Up to 5 TB        | Better      |
| ClamAV      | Up to 2 GB        | Good        |

### Multi-engine Scanning

<div align="center"><figure><img src="/files/ksf0h1OCOrgJYSl0iohZ" alt="" width="335"><figcaption><p>Scan All Files with enabled engines</p></figcaption></figure></div>

Multi-engine scanning provides two options to use multiple engines for scanning. The two choices for how to use multi-engine scanning are: `All Files` and `By File Size`.

* `All Files` indicates every file that is event-based scanned or on-demand/schedule scanned will be processed by the enabled engines.
* `By File Size` means smaller files (<2GB) are scanned by ClamAV, while larger files (>2GB) are scanned by Sophos or CSS Premium. This approach lets you reduce scan costs by leveraging ClamAV for smaller files while ensuring larger files are still scanned with Sophos or CSS Premium.

<figure><img src="/files/sOyyF5K8AixFJ6JkN900" alt=""><figcaption></figcaption></figure>

| Multi-Engine Selection | Files (<2GB)      | Larger Files (>2GB)   |
| ---------------------- | ----------------- | --------------------- |
| All Files              | All three engines | Sophos or CSS Premium |
| By File Size           | ClamAV            | Sophos or CSS Premium |

### Bucket Protection Method

<figure><img src="/files/V2D19Ec7bpC0rP7Nxzge" alt=""><figcaption></figcaption></figure>

As of v7.00.000 we automatically use EventBridge to resolve any bucket conflicts.

If `Protect with Event Bridge` is enabled globally then we will protect all selected buckets with Event Bridge without acknowledgment.

\
If `Protect with Event Bridge` is not enabled we will protect buckets using the "best choice". If the bucket can be protected with the S3 Event Notification we will do so, but if conflicted we will fail over to Event Bridge.

You can learn more about how EventBridge works with protected buckets [here](/console-overview/protection/aws/protected-buckets#conflicted-buckets).

### Private Mirror - Local Signature Updates

<figure><img src="/files/zFkvzdusdA1OoW3OZs9O" alt=""><figcaption></figcaption></figure>

In certain situations, you may prefer your scanning agents to retrieve signature updates locally rather than accessing the public internet. Some customers have requirements where applications that touch sensitive data cannot connect outside their account. Using local updates allows you to control and potentially eliminate outbound access for VPCs hosting the scanning agents.

This option lets you specify an Amazon S3 bucket in your account where scanning agents will look for signature updates. You can populate this bucket as needed (a sample Sophos Lambda is provided below). Each time a scanning agent boots, it retrieves the latest definitions. Running agents will check for new signature definitions as follows:

* **ClamAV:** every 1 hour
* **Sophos:** every 15 minutes
* **CSS Premium:** every 15 minutes

**Default Behavior Without Local Updates**

If you do not use local updates:

* **ClamAV:** agents download updates directly from the internet. All agents require outbound internet access to retrieve updates.
* **Sophos and CSS Premium:** updates are maintained in an S3 bucket hosted by Cloud Storage Security. Agents retrieve updates directly from this bucket.

**Using Local Updates**

For all three engines, you can configure agents to retrieve updates from your local S3 bucket.

* **Sophos:** A sample Lambda is provided to copy updates from our S3 bucket to your local bucket.
* **ClamAV:** You are responsible for setting up a Lambda to pull updates from the internet to your local bucket.
* **CSS Premium:** You are responsible for setting up a Lambda to copy updates from our S3 bucket to your local bucket.

{% hint style="info" %}

#### Note

If you can't wait 1 hour (or the 15 minutes) after a new signature update comes out, simply reboot all your agents and they will pick the new updates up immediately.

This is for signature updates only. Engine updates are done as part of our build process and will be rolled out with the next release.

If you choose to use Private Mirror with multi-engine scanning, you will need to set up Private Mirror for the update sets of all engines. You should use the same bucket for all three engines.
{% endhint %}

## Sophos Lambda Sample

We provide a lambda function for Sophos. Sophos requires authentication to download their updates, so we are hosting them in a bucket where your account will be added to the permissions list. This is done automatically by switching on `Local Updates`.

{% hint style="info" %}
Because the updates are taking place inside of AWS already you may not consider it a need for local updates unlike how we download ClamAV updates directly from the internet. But, if you still want updates coming from your own bucket, then read on.
{% endhint %}

Sophos updates are already done from a bucket. A bucket we have granted your application account access to and the agents simply pull the updates from that bucket we host. For local updates for the Sophos engine all you really need to do is copy the update files from our bucket to yours. We have provided some sample code you can turn into a lambda to pull the updates over.

{% hint style="info" %}
We recommend that you choose your CSS\_SOPHOS\_BUCKET based on the region where your Console is deployed in. Refer to the list below to determine which bucket name you should point your lambda and permissions to. In the examples below, replace all references to 'css-sophos-updates' with the appropriate bucket.
{% endhint %}

```
{RegionEndpoint.USEast1, "css-sophos-updates"},
{RegionEndpoint.USEast2, "css-sophos-updates-ohio"},
{RegionEndpoint.USWest1, "css-sophos-updates-california"},
{RegionEndpoint.USWest2, "css-sophos-updates-oregon"},
{RegionEndpoint.CACentral1, "css-sophos-updates-canada"},
{RegionEndpoint.CAWest1, "css-sophos-updates-calgary"},
{RegionEndpoint.EUCentral1, "css-sophos-updates-frankfurt"},
{RegionEndpoint.EUCentral2, "css-sophos-updates-zurich"},
{RegionEndpoint.EUNorth1, "css-sophos-updates-stockholm"},
{RegionEndpoint.EUSouth1, "css-sophos-updates-milan"},
{RegionEndpoint.EUSouth2, "css-sophos-updates-spain"},
{RegionEndpoint.EUWest1, "css-sophos-updates-ireland"},
{RegionEndpoint.EUWest2, "css-sophos-updates-london"},
{RegionEndpoint.EUWest3, "css-sophos-updates-paris"},
{RegionEndpoint.APEast1, "css-sophos-updates-hong-kong"},
{RegionEndpoint.APNortheast1, "css-sophos-updates-tokyo"},
{RegionEndpoint.APNortheast2, "css-sophos-updates-seoul"},
{RegionEndpoint.APNortheast3, "css-sophos-updates-osaka"},
{RegionEndpoint.APSouth1, "css-sophos-updates-mumbai"},
{RegionEndpoint.APSoutheast1, "css-sophos-updates-singapore"},
{RegionEndpoint.APSoutheast2, "css-sophos-updates-sydney"},
{RegionEndpoint.APSoutheast3, "css-sophos-updates-jakarta"},
{RegionEndpoint.APSoutheast4, "css-sophos-updates-melbourne"},
{RegionEndpoint.AFSouth1, "css-sophos-updates-cape-town"},
{RegionEndpoint.MECentral1, "css-sophos-updates-uae"},
{RegionEndpoint.MESouth1, "css-sophos-updates-bahrain"},
{RegionEndpoint.SAEast1, "css-sophos-updates-sao-paulo"},
{RegionEndpoint.USGovCloudWest1, "css-sophos-updates-us-gov-west-1"},
{RegionEndpoint.USGovCloudEast1, "css-sophos-updates-us-gov-east-1"}
```

#### Lambda Code

```python
import boto3
import botocore
from datetime import datetime, timezone

CSS_SOPHOS_BUCKET = 'css-sophos-updates'
VDL_FILE_NAME = 'vdl.zip'
IDE_FILE_NAME = 'ide.zip'
DESTINATION_SOPHOS_BUCKET = '<enter-your-bucket-name-here>'
LAST_UPDATED_FILE_NAME = 'def_files_last_updated.txt'


def lambda_handler(event, context):
    s3 = boto3.client('s3')
    vdlLastModified = datetime(2006, 3, 14)
    ideLastModified = datetime(2006, 3, 14)

    try:
        lastUpdatedObj = s3.get_object(
            Bucket=DESTINATION_SOPHOS_BUCKET,
            Key=LAST_UPDATED_FILE_NAME
        )
        lastUpdated = lastUpdatedObj['Body'].read().decode('utf-8').split('|')
        vdlLastModified = datetime.strptime(lastUpdated[0], '%Y-%m-%dT%H:%M:%S%z')
        ideLastModified = datetime.strptime(lastUpdated[1], '%Y-%m-%dT%H:%M:%S%z')
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] not in ['404', 'NoSuchKey']:
            raise

    filesWereUpdated = False

    try:
        s3.copy_object(
            Bucket=DESTINATION_SOPHOS_BUCKET,
            Key=VDL_FILE_NAME,
            CopySource={'Bucket': CSS_SOPHOS_BUCKET, 'Key': VDL_FILE_NAME},
            CopySourceIfModifiedSince=vdlLastModified,
            ACL='bucket-owner-full-control'
        )
        vdlLastModified = datetime.now(timezone.utc)
        filesWereUpdated = True
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] != 'PreconditionFailed':
            raise

    try:
        s3.copy_object(
            Bucket=DESTINATION_SOPHOS_BUCKET,
            Key=IDE_FILE_NAME,
            CopySource={'Bucket': CSS_SOPHOS_BUCKET, 'Key': IDE_FILE_NAME},
            CopySourceIfModifiedSince=ideLastModified,
            ACL='bucket-owner-full-control'
        )
        ideLastModified = datetime.now(timezone.utc)
        filesWereUpdated = True
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] != 'PreconditionFailed':
            raise

    if filesWereUpdated:
        obj = boto3.resource('s3').Object(
            DESTINATION_SOPHOS_BUCKET,
            LAST_UPDATED_FILE_NAME
        )
        obj.put(
            Body=f'{vdlLastModified.strftime("%Y-%m-%dT%H:%M:%SZ")}|'
                 f'{ideLastModified.strftime("%Y-%m-%dT%H:%M:%SZ")}'
        )

    return {
        'statusCode': 200,
        'body': (
            'Sophos VDL and/or IDE file(s) were updated.'
            if filesWereUpdated
            else 'Sophos VDL and IDE files are already up to date.'
        )
    }
```

#### Permissions to add to Lambda

<pre class="language-json"><code class="lang-json">{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "GetSophosFilesFromCSS",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectTagging"
            ],
            "Resource": [
                "arn:aws:s3:::css-sophos-updates/*",
                "arn:aws:s3:::css-sophos-updates"
            ]
        },
        {
            "Sid": "PlaceSophosFilesInMirrorBucket",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:PutObjectTagging",
                "s3:PutObjectAcl",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::&#x3C;enter-your-bucket-name-here>/*",
                "arn:aws:s3:::&#x3C;enter-your-bucket-name-here>"
            ]
        }
<strong>    ]
</strong>}
</code></pre>

#### Steps to Set Up the Lambda Function

**1. Create the Lambda Function**

* Choose **Author from scratch**.
* Set the runtime to **Python 3.13**.
* Leave the architecture as default (**x86\_64**).
* For permissions, either create a new role with basic Lambda permissions or use an existing role with the policy provided in the documentation.
* Adjust any additional configuration if needed, then create the function.

<figure><img src="/files/TlwHFhhbwRrUXNb5FGPG" alt=""><figcaption></figcaption></figure>

**2. Deploy the Lambda Code**

* Copy the sample Lambda code from the documentation.
* Replace the bucket name with the S3 bucket you want the agents to monitor for virus definition updates.
* Deploy the code.

<figure><img src="/files/y6LC66R54lG78E8VOVi2" alt=""><figcaption></figcaption></figure>

**3. Update the IAM Role**

* Go to **Configuration → Permissions** and click on the role.
* Copy the policy provided in the documentation and create an inline policy in JSON format.
* Add your bucket name for the Private Mirror in the policy, then save it.

<figure><img src="/files/eee9MBdbg0RHO89ZcyhK" alt=""><figcaption></figcaption></figure>

**4. Adjust Lambda Timeout**

* In **Configuration → General configuration**, change the default timeout from **3 seconds** to **9 seconds** (typical runtime is 8–9 seconds).

<figure><img src="/files/UC5fwRzSCMOAWVmF3K2s" alt=""><figcaption></figcaption></figure>

**5. Test and Enable Private Mirror**

* Click **Test** to ensure the function retrieves the virus definition files to your bucket.
* In the AV Console, go to **Scan Settings** and enable the Private Mirror configuration. Use the same bucket specified in the Lambda code and policy, and select the **Sophos Engine**.

<figure><img src="/files/L0PqC4FjpIfUZxmA2uIm" alt=""><figcaption></figcaption></figure>

6. **Create a trigger cadence for the Lambda Function**

*Decide the regular interval in which to trigger the Lambda to search from updates from our S3 bucket. Look* [*here*](/) *for an example to add a trigger to the Lambda function. We recommend triggering the Lambda every 15 minutes to keep on top of new antivurs updates.*

After configuring this trigger, your private mirror setup is complete!

### Extra Large File Scanning

![Extra Large File](/files/HmGQLqN1QdsVyL1ChnTU)

Most of our customers are scanning files under the Fargate disk cap of 200GB. But, there are those in many industries (life sciences, media, etc.) that do have files that are larger than 200GB and some much more so. Antivirus for Amazon S3 supports up to the Amazon S3 file size maximum (5TB) for file scanning.

This is done by bypassing the internal disk limitations of Fargate leveraging an EC2 instance(s) for such files. The "extra large file scanning" doesn't have to be leveraged for only really big files, but can be used to scan any size file over the disk size you have assigned to the standard scanning agents we provide. For example, let's say you occasionally need to process 50GB files, but it isn't worth it to you to keep a larger disk attached to every scanning agent running. So you keep the default disk size of 20GB, and have the `Extra Large File Scanning` toggle switch on. Any file 15GB and smaller will be processed by the scanning agent, but any file greater than 15GB in size will be scanned by the extra large file scanning process. This can ensure that no file is ever skipped due to size, but if large files are rare in your system you don't have to sit on the expense of a larger default disk.

Extra large file scanning can be triggered by [event based scanning](/how-it-works/object-scanning#event-driven-scanning), [retro scanning](/how-it-works/object-scanning#retro-scanning) and even [API based scanning](/how-it-works/object-scanning#api-driven-scanning)(scan existing API only). When any of these scanning agents picks up a file that is too large to scan (too large based on the disk size assigned under the [Agent Settings](/console-overview/configuration/agent-settings#agent-task-settings) or [API Agent Settings](/console-overview/configuration/api-agent-settings#service-settings)) and the `Extra Large File Scanning` toggle is on, a `Job` is defined to be kicked off. The job will be picked up within 10 minutes and kicked off. A temporary EC2 instance will be spun up with an EBS volume of the size defined in the `Disk Size` field. The EC2 will pick up the file and scan it. Because it is a "job", it is monitored under the [Jobs page](/console-overview/monitoring/jobs). On the Jobs page you can monitor the job going through "Not Started" while waiting for the EC2 to start up, "Scanning", and "Completed". Each "large file" is treated as its own job. If you have 50 large files come in then 50 jobs will be kicked off for the duration it takes to scan each individual file.

You must either select the Sophos or CSS Premium engine or have multi-engine scanning model enabled with `By File Size` selected if you intend to use ClamAV and need extra large files scanned.

Sample scenarios and scanning outcomes: (Note: subtract 5GB for overhead from disk sizes for agents and Extra Large File Scan size)

<table><thead><tr><th width="305">Scenario</th><th>Scanning Outcome</th></tr></thead><tbody><tr><td>File is smaller than defined scanning agent disk size</td><td>Scanning agent picks file up to scan<br><br>Scan Result is whatever the outcome of file is</td></tr><tr><td>File is larger than defined scanning agent disk size<br><code>Extra Large File Scanning</code> is <em><strong>off</strong></em></td><td>Scanning agent rejects file and does not even attempt to scan it<br><br>Scan Result is set to <code>Unscannable</code></td></tr><tr><td>File is larger than defined scanning agent disk size<br><code>Extra Large File Scanning</code> is <em><strong>on</strong></em></td><td>Scanning agent creates an Extra Large File Scan Job and moves on to the next file<br>Large File Job shows up on the Jobs page and is kicked off within 10 minutes of creation<br><br>Scan Result is set to whatever the outcome of the file is</td></tr><tr><td>File is larger than Extra Large File Scanning disk size<br><code>Extra Large File Scanning</code> is <em><strong>on</strong></em></td><td>Scan Result is set to <code>Unscannable</code></td></tr></tbody></table>

## Scan and Skip Lists

Buckets themselves are inherently skipped by the fact they are turned off to start. When you enable a bucket for scanning, you are explicitly marking it to be scanned. When you do this and nothing else, then all objects in the given bucket will be scanned no matter the path inside the bucket. This portion is all handled from the [Bucket Protection](/console-overview/protection/aws/protected-buckets) page.

The `Scan List` and `Skip List` located here inside the `Agent Configuration` page allows you to take this concept a step further by allowing you to apply it to paths (folders) within the buckets. Scan listing and skip listing are opposites of one another. Scan listing a `path` is explicitly marking that specific path(s) within that bucket to be scanned. All other paths within the bucket will be ignored. You can list as many paths within the bucket as you'd like. For example, you have 5 different paths within the bucket and you want to scan only 3 of them. Simply add the 3 you want scanned to the Scan List. There is no need to add the other 2 paths to the Skip List as they will automatically be skipped. Skip listing a `path` will stop that defined path(s) from being scanned, but leave all others to be scanned. Depending on how many you want to include versus exclude you can choose which list to leverage. From the previous example, you could have just Skip listed the 2 paths you didn't want to scan which leaves the other 3 to be scanned. With numbers that split you could go either way, but if you have a much larger number of paths, one may become more self-evident.

{% hint style="info" %}

#### Special Scan / Skip List Capabilities

The `root` of the bucket is also a "path" that we define in the settings as an empty path. So, if you'd like to scan or skip list the root along with your paths you can do so.

**You can use a wild card (`*`) in the path**. This is useful in a repeated sub-path structure where you need to skip a certain folder amongst all those top level folders.

For example, you have a path structure that is Year/Month/scanMe and Year/Month/skipMe where the month reflects each month of the year creating 12 unique paths. Underneath that Month folder you have folders you want scanned or skipped. You can create a path one time to setup scanning in every Month folder like this: Year/\*/scanMe. That path will scan the `scanMe` folder under every month in the bucket without you having to add 12 entries.

This could also be leveraged not just in the path, but down to the object name as well. If you only wanted to scan a certain file type in a given bucket/folder you could put a path with `*.jpg`.

#### :pencil2: Note

*As you can see, but wasn't spelled out, the `*` does not mean everything at the level it is placed and below. If you wanted everything underneath Year you could place a path /Year/ and that would do absolutely everything below Year. The wildcard represents the level itself where it is placed only.*

Similar to wild cards an often used with wild cards, **you can specify a global entry or your Scan and Skip Lists**. If you have a repeated path structure across all your buckets where being able to define a scan / skip entry that would apply to all, you can select the `_GLOBAL_` option in place of a bucket to then define across all buckets.

<img src="/files/1eTNDA2FISC0UK6Xq7Z6" alt="" data-size="original">
{% endhint %}

Let's take a look at an example. The following is an S3 bucket with 4 paths (folders) in it. With the default settings, meaning no `paths` defined, the root and all 4 folders will be scanned.

<figure><img src="/files/Z1qc5LVdlYl0mV3dghfK" alt=""><figcaption></figcaption></figure>

First thing you need to do is enter the `<bucket name>` in the Scan List or Skip List field and click `Add Scan list`.

<div align="left"><figure><img src="/files/YigFvucCa8VCPN9BHvp5" alt=""><figcaption></figcaption></figure></div>

You'll get:

<div align="left"><figure><img src="/files/GW8bO3BNrKy5TDLruriJ" alt=""><figcaption></figcaption></figure></div>

Next, you'll add the `path` you want to scan and click the `Add Entry` button. \*This can be the full multi-depth path.

<div align="left"><figure><img src="/files/ZGbuXeJtTuAQYxUS3Dlb" alt=""><figcaption></figcaption></figure></div>

That's it. You've now identified that the only thing you will scan in the `css-protect-01` bucket will be the `scan-me` folder and nothing else. The steps above can be used for skip listing as well. Look below at the examples.

{% tabs %}
{% tab title="Default Setting - scan all" %}

<div align="left"><figure><img src="/files/d46pBG00XyBPJHdENc1Z" alt=""><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Scan list - scan-me folder" %}

<div align="left"><figure><img src="/files/ZGbuXeJtTuAQYxUS3Dlb" alt=""><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Skip list - root and donot-scan-me" %}

<div align="left"><figure><img src="/files/S2EQxQLOyBMPhmtPYpMI" alt=""><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Full Rules" %}

<div align="left"><figure><img src="/files/PSBu8jOjPlBU06rJpKjK" alt=""><figcaption></figcaption></figure></div>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
You probably wouldn't have a scan list and a skip list entry for the same bucket as we see in this example, but it is possible and I'm sure a scenario could be found to support it.
{% endhint %}

## AV Two-Bucket System Configuration

With the Two-Bucket System you can move objects from a source bucket or region to a different bucket and/or prefix after it has been successfully scanned and tagged as Clean.

All other scan result types (Infected, Error, Unscannable), remain in the protected source bucket.

<figure><img src="/files/uhMdV6xzAt2ziSL1YTfL" alt=""><figcaption></figcaption></figure>

When using this method you no longer need to add Lambda Functions to move your files, [as outlined here](https://help.cloudstoragesec.com/faq/architecture-related#can-i-setup-a-staging-bucket-for-all-of-my-files-to-first-land-in-and-then-move-them-to-a-production). With the AV Two-Bucket System Configuration the agent task itself will promote the clean files as part of the scanning process.

{% hint style="info" %}
This feature will not protect the bucket(s) configured within the setting. You will still need to ensure the bucket(s) are protect within the Bucket Protection page.
{% endhint %}

There are two options for configuring the Two-Bucket System:

1. By Region\
   When using this setting, any protected bucket within the choosen region will have its clean files delivered to the destination bucket.
   1. Choose a region from the Add Region selection
   2. Choose a target destination bucket
   3. Optionally, choose a desired prefix to place objects in.
2. By Bucket
   1. Choose a bucket from the Add Bucket selection
   2. Choose a target destination bucket
   3. Optionally, choose a desired prefix to place objects in.

{% hint style="info" %}
If you have very long object paths, specifying a prefix for either By Region or By Bucket could cause you to exceed the max key length and impact file delivery.
{% endhint %}

Delete any region or bucket by clicking the delete icon next to its source.

Be sure to click the save button to apply your changes.

### Two-Bucket System Configuration in Different Accounts <a href="#docs-internal-guid-9c64e60d-7fff-dcee-bb66-1479763edbf9" id="docs-internal-guid-9c64e60d-7fff-dcee-bb66-1479763edbf9"></a>

**Source bucket in the primary account and destination bucket in a linked account**

To set up a two-bucket system with a source bucket in the primary account and a destination bucket in another linked account, you need to add permissions to the destination bucket in the linked account. These permissions are necessary for the agent to send objects to that bucket.

**Steps to Configure the Two-Bucket System**

1. Add the source bucket and the destination bucket in the AV Console.
2. Log in to the account where the destination bucket is located.
3. Navigate to Amazon S3, then Buckets.
4. Select the destination bucket in your linked account.

<figure><img src="/files/PpMce6QxGfQ5QRz09wwk" alt=""><figcaption></figcaption></figure>

5. Click on Permissions.
6. Scroll down to the Bucket Policy section and select Edit.

<figure><img src="/files/myO1Y59uQwyFbjj98BcO" alt=""><figcaption></figcaption></figure>

7. Add the following JSON policy to the destination bucket

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "<arn:aws:iam::awsaccountnumber:role/CloudStorageSecAgentRole-appID>"
            },
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:PutObjectTagging"
            ],
            "Resource": [
                "arn:aws:s3:::<destination-bucket>/*",
                "arn:aws:s3:::<destination-bucket>"
            ]
        }
    ]
}
```

8\. Replace the placeholders in the policy:

* **awsaccountnumber** with the AWS account number of the primary account.
* **appID** with the application ID of your console.
* **destination-bucket** with the name of the destination bucket.

This policy allows the agent to put the clean objects in the linked account's bucket.

#### Source bucket in the linked account and destination in the primary account: <a href="#docs-internal-guid-ca8a4ad5-7fff-6737-3fa1-0bbcf8c4b733" id="docs-internal-guid-ca8a4ad5-7fff-6737-3fa1-0bbcf8c4b733"></a>

To set up a two-bucket system with a source bucket in a linked account and a destination bucket in the primary account, you need to add permissions to both buckets. These permissions allow the agent to transfer objects between the source and destination buckets.<br>

Setting up the policy for the source bucket in the linked account:

1. Log in to the linked account where the source bucket is located.
2. Navigate to Amazon S3, then Buckets.
3. Select the source bucket in the linked account.
4. Click on Permissions.
5. Scroll down to the Bucket Policy section and select Edit.
6. Add the following JSON policy to the source bucket

```json5
{
	"Version": "2012-10-17",
	"Statement": [
    	{
        	"Effect": "Allow",
        	"Principal": {
            	"AWS": "arn:aws:iam::<awsaccountnumber>:role/CloudStorageSecAgentRole-<appID>"
        	},
        	"Action": [
            	"s3:DeleteObjectTagging",
                "s3:GetObject",
                "s3:GetObjectTagging",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
        	"Resource": [
            	"arn:aws:s3:::<source-bucket>/*",
            	"arn:aws:s3:::<source-bucket>"
        	]
    	}
	]
}
```

Replace the placeholders in the policy:

* \<awsaccountnumber> with the AWS account number of the primary account.
* \<appID> with the application ID of your console.
* \<source-bucket> with the name of the source bucket.

This policy allows the source bucket to place objects in the destination bucket within the primary account.

Setting up the policy in the destination bucket in the primary account:

1. Log in to the linked account and go to CloudFormation.
2. Select the CloudStorageSecurity Linked Account stack.
3. Click on Resources and select the hyperlink for the Remote Access Role.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXciOLnqt_X_XGPBSIOASgkn9GZQD9hsYxb6O_RFZCK3mz_5xg_NfC69DdN-WPGV0IEc-5egsJ5B6ligKepXlqAQBrZm-EjU-9ZljHRkQimCRl5MYKT06preU5UAkuIYpvskaogak9jINuf4QXq-EEDxA1Ir?key=ghRcsCoPVZjpFyJk-CAkSQ" alt=""><figcaption></figcaption></figure>

4. Copy the ARN for the CloudStorageSecRemoteRole.
5. Log in to the primary account.
6. Navigate to Amazon S3, then Buckets.
7. Select the destination bucket in the primary account.
8. Click on Permissions.
9. Scroll down to the Bucket Policy section and select Edit.
10. Add the following JSON policy to the destination bucket:

```json
{
	"Version": "2012-10-17",
	"Statement": [
    	{
        	"Effect": "Allow",
        	"Principal": {
            	"AWS": "arn:aws:iam::<awsaccountnumber>:role/CloudStorageSecRemoteRole-<appID>"
        	},
        	"Action": [
            	"s3:PutObject",
            	"s3:ListBucket",
            	"s3:PutObjectTagging"
        	],
        	"Resource": [
            	"arn:aws:s3:::<destination-bucket>/*",
            	"arn:aws:s3:::<destination-bucket>"
        	]
    	}
	]
}

```

11. Replace the placeholders in the policy:
12. \<arn:aws:iam::\<awsaccountnumber>:role/CloudStorageSecAgentRole-\<appID> with the ARN you copied from the CloudStorageSecRemoteRole in the linked account.
13. \<destination-bucket> with the name of the destination bucket.

This policy allows the remote role to place objects into the destination bucket.<br>
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}

## Object Classification Tag Keys

Every file the s3 scanner touches has an AWS Tag applied to it. You can change the default key names if required or desired, but not the values.

<figure><img src="/files/5twRyA5V1PrCGwijwszO" alt=""><figcaption><p>Object Tagging</p></figcaption></figure>

| Key                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| classification-result  | <p>Identifies whether a file is found to be nonmatching or having issues. Possible values: <code>NonMatching</code>, <code>Matching</code>, <code>Unclassifiable</code>, <code>Error</code></p><ul><li><code>NonMatching</code> = no issues found with file</li><li><code>Matching</code> = classified data found;</li><li><code>Unclassifiable</code> = object is password protected or non-text</li><li><code>Error</code> = access to object issues: KMS permissions, cross account permissions, bucket policy blocking, other</li></ul> |
| date-classified        | The date and time the object was scanned                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Error Message          | A description of what has been identified in the file. Only populated for `Error` or `Unclassifiable` results.                                                                                                                                                                                                                                                                                                                                                                                                                              |
| classification-matches | What classification rule(s) matched                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

{% hint style="info" %}
AWS allows an object to have only 10 tags applied to it. At most we will add 4 tags (for matching files) and only 2 tags for non-matching files. If you have a number of tags on your object already, we will trim the number of tags we add to ensure none of the existing tags are dropped. If only 1 tag is available for example, we will write only the `classification-result` tag onto the object.
{% endhint %}

## Scan and Skip Lists

Buckets themselves are inherently skipped by the fact they are turned off to start. When you enable a bucket for scanning, you are explicitly marking it to be scanned. When you do this and nothing else, then all objects in the given bucket will be scanned no matter the path inside the bucket. This portion is all handled from the [Bucket Protection](/console-overview/protection/aws/protected-buckets) page.

The `Classify List` and `Classify Skip List` located here inside the `Agent Configuration` page allows you to take this concept a step further by allowing you to apply it to paths (folders) within the buckets. Scan listing and skip listing are opposites of one another. Scan listing a `path` is explicitly marking that specific path(s) within that bucket to be scanned. All other paths within the bucket will be ignored. You can list as many paths within the bucket as you'd like. For example, you have 5 different paths within the bucket and you want to scan only 3 of them. Simply add the 3 you want scanned to the Scan List. There is no need to add the other 2 paths to the Skip List as they will automatically be skipped. Skip listing a `path` will stop that defined path(s) from being scanned, but leave all others to be scanned. Depending on how many you want to include versus exclude you can choose which list to leverage. From the previous example, you could have just Skip listed the 2 paths you didn't want to scan which leaves the other 3 to be scanned. With numbers that split you could go either way, but if you have a much larger number of paths, one may become more self-evident.

{% hint style="info" %}
**Special Scan / Skip List Capabilities**

The `root` of the bucket is also a "path" that we define in the settings as an empty path. So, if you'd like to scan or skip list the root along with your paths you can do so.

**You can use a wild card (`*`) in the path**. This is useful in a repeated sub-path structure where you need to skip a certain folder amongst all those top level folders.

For example, you have a path structure that is Year/Month/scanMe and Year/Month/skipMe where the month reflects each month of the year creating 12 unique paths. Underneath that Month folder you have folders you want scanned or skipped. You can create a path one time to setup scanning in every Month folder like this: Year/\*/scanMe. That path will scan the `scanMe` folder under every month in the bucket without you having to add 12 entries.

This could also be leveraged not just in the path, but down to the object name as well. If you only wanted to scan a certain file type in a given bucket/folder you could put a path with `*.jpg`

#### Note

<mark style="background-color:blue;">`As you can see, but wasn't spelled out, the * does not mean everything at the level it is placed and below. If you wanted everything underneath Year you could place a path /Year/ and that would do absolutely everything below Year. The wildcard represents the level itself where it is placed only.`</mark>

Similar to wild cards an often used with wild cards, **you can specify a global entry or your Scan and Skip Lists**. If you have a repeated path structure across all your buckets where being able to define a scan / skip entry that would apply to all, you can select the `_GLOBAL_` option in place of a bucket to then define across all buckets.

<img src="/files/L6rsxPnPe9kTDfZwVUhr" alt="" data-size="original">
{% endhint %}

Let's take a look at an example. The following is an S3 bucket with 4 paths (folders) in it. With the default settings, meaning no `paths` defined, the root and all 4 folders will be scanned.

<div align="left"><figure><img src="/files/Z1qc5LVdlYl0mV3dghfK" alt=""><figcaption></figcaption></figure></div>

First thing you need to do is enter the `<bucket name>` in the Scan List or Skip List field and click `Add Scan list`.

<div align="left"><figure><img src="/files/YigFvucCa8VCPN9BHvp5" alt=""><figcaption></figcaption></figure></div>

You'll get:

<div align="left"><figure><img src="/files/GW8bO3BNrKy5TDLruriJ" alt=""><figcaption></figcaption></figure></div>

Next, you'll add the `path` you want to scan and click the `Add Entry` button. \*This can be the full multi-depth path.

<div align="left"><figure><img src="/files/ZGbuXeJtTuAQYxUS3Dlb" alt=""><figcaption></figcaption></figure></div>

That's it. You've now identified that the only thing you will scan in the `css-protect-01` bucket will be the `scan-me` folder and nothing else. The steps above can be used for skip listing as well. Look below at the examples.

{% tabs %}
{% tab title="Default Setting - scan all" %}

<div align="left"><figure><img src="/files/d46pBG00XyBPJHdENc1Z" alt=""><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Scan list - scan-me folder" %}

<div align="left"><figure><img src="/files/ZGbuXeJtTuAQYxUS3Dlb" alt=""><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Skip list - root and donot-scan-me" %}

<div align="left"><figure><img src="/files/S2EQxQLOyBMPhmtPYpMI" alt=""><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Full Rules" %}

<div align="left"><figure><img src="/files/PSBu8jOjPlBU06rJpKjK" alt=""><figcaption></figcaption></figure></div>
{% endtab %}
{% endtabs %}

{% hint style="info" %}

#### Note

You probably wouldn't have a scan list and a skip list entry for the same bucket as we see in this example, but it is possible and I'm sure a scenario could be found to support it.
{% endhint %}
{% endtab %}
{% endtabs %}


# Automatic Scanning Configuration

Automate storage container protection and scanning.

For customers who want to implement universal storage container protection, we offer the ability to apply both event-based and scheduled scanning for S3 Buckets, Azure Blob Containers, and GCP Buckets. When these features are activated, we also perform a daily discovery of new storage resources and add them to our existing schedule or event-based scanning if they match a rule that's been activated.

Note that for Azure and GCP, you'll have to link these cloud accounts into CSS first. Refer to our [Azure Linked Accounts](https://help.cloudstoragesec.com/console-overview/access-management/linked-accounts/linking-an-azure-account) and [GCP Linked Accounts](https://help.cloudstoragesec.com/console-overview/access-management/linked-accounts/linking-a-gcp-account) documentation for more details.

<figure><img src="/files/M6HYWh0TOgl6wAAuZ7dQ" alt=""><figcaption></figcaption></figure>

## Global Settings

Under the Global Settings page, we offer the Protect All and Enable Smart Scanning options.

<figure><img src="/files/UHGu3K6pyhJuPFdsuJRd" alt=""><figcaption></figcaption></figure>

### **Protect All**

The Protect All option enables the following:

* Real-Time Protection for AWS, Azure, and GCP
* Monthly Schedule Protection for AWS, Azure, and GCP

When you turn the slider on, you can notice that all the other sliders except Enable Smart Scanning turn on. This is a visual representation of what it does.

If this feature is enabled, we'll do the following:

* Create a Scheduled Scan for all Amazon S3, Azure Blob, and GCP Buckets that triggers on the first of every month.
* Begin monitoring all Amazon S3, Azure Blob, and GCP Buckets for new files. We'll scan files as they enter those containers.

### Enable Smart Scanning

For customers who want to minimize infrastructure costs at the tradeoff of a slightly longer scan time, we offer Smart Scanning. While Event-Based scanning typically has agents standing by to immediately scan files that enter storage containers, Smart Scan turns off Event Agents when they are not actively scanning to minimize your compute costs.

Once new files are detected, they will enter a queue and our Agents will spin up to scan the files in the queue. Note that it can take up to 10 minutes from a new file introduction to the creation of a fully functional agent.

You can modify the threshold to which agents will begin spinning up. While the default is 1 file for the agent to begin creation, this feature obeys the Configuration > Event Settings page. The application will refer to the Scaling Threshold set for each region, or the default value if there isn't a custom configuration.

Read more about Smart Scanning here: [Smart Scan](https://help.cloudstoragesec.com/console-overview/configuration/agent-settings#smart-scan)

## AWS S3 Buckets Protection

<figure><img src="/files/VK2wpJkFkpBuGvaZ6JS4" alt=""><figcaption></figcaption></figure>

We offer more granular controls for each cloud provider that we offer scanning for. The settings here are relatively straightforward:

### S3 Bucket Real-Time Protection

We enable Real-Time protection for all Amazon S3 Buckets, which means that once protection is running, any new files that are dropped in to any of these buckets will be scanned. The application runs a job once a day to poll for new buckets and adds them to protection if they are found.

### S3 Bucket Monthly Schedule Protection

We create a Schedule that targets all Amazon S3 Buckets. This schedule fires off on the first day of every month. The application runs a job once a day to poll for new buckets and adds them to the schedule if they are found.

### S3 Bucket Exclusion Lists

If you want to add exceptions to the buckets we protect or schedule scans for, this can be configured in the S3 Bucket Exclusion List and the S3 Region Exclusion List. Simply click the dropdown, find the relevant entry, and click 'Add Exclusion list'.

The S3 Bucket Exclusion List adds buckets that will be skipped, while the S3 Region Exclusion list adds entire regions that will be skipped. These rules apply for both Real-Time Protection and Monthly Schedule Protection.

In the example below, I've added 'jl-frombucket' to my Exclusion list and it will not be protected when Real-Time or Monthly Schedule Protection is turned on.

<figure><img src="/files/KgcnSAp9t1D18U5ea8uD" alt=""><figcaption></figcaption></figure>

## Azure Blob Protection

<figure><img src="/files/EO1gbrko4au9LWsoZUwW" alt=""><figcaption></figcaption></figure>

Similar to Amazon S3, we offer individual configuration settings for Azure Blob Containers.

### Blob Container Real-Time Protection

We enable Real-Time protection for all Azure Blob Containers, which means that once protection is running, any new files that are dropped in to any of these buckets will be scanned. The application runs a job once a day to poll for new buckets and adds them to protection if they are found.

### Blob Container Monthly Schedule Protection

We create a Schedule that targets all Azure Blob Containers. This schedule fires off on the first day of every month. The application runs a job once a day to poll for new buckets and adds them to the schedule if they are found.

If you want to add exceptions to the buckets we protect or schedule scans for, this can be configured in the S3 Bucket Exclusion List and the S3 Region Exclusion List. Simply click the dropdown, find the relevant entry, and click 'Add Exclusion list'.

### Blob Container Exclusion Lists

The Blob Container Exclusion List adds buckets that will be skipped, while the Azure Region Exclusion list adds entire regions that will be skipped. These rules apply for both Real-Time Protection and Monthly Schedule Protection. Simply click the dropdown, find the relevant entry, and click 'Add Exclusion list'.

## GCP Buckets Protection

<figure><img src="/files/udzQ9UvEBO9QOwOVquql" alt=""><figcaption></figcaption></figure>

The same concepts for AWS and Azure apply to GCP.

### GCP Bucket Real-Time Protection

We enable Real-Time protection for all GCP Buckets, which means that once protection is running, any new files that are dropped in to any of these buckets will be scanned. The application runs a job once a day to poll for new buckets and adds them to protection if they are found.

### GCP Bucket Monthly Schedule Protection

We create a Schedule that targets all GCP Buckets. This schedule fires off on the first day of every month. The application runs a job once a day to poll for new buckets and adds them to the schedule if they are found.

If you want to add exceptions to the buckets we protect or schedule scans for, this can be configured in the GCP Bucket Exclusion List and the GCP Region Exclusion List. Simply click the dropdown, find the relevant entry, and click 'Add Exclusion list'.

### GCP Bucket Exclusion Lists

The GCP Bucket Exclusion List adds buckets that will be skipped, while the GCP Region Exclusion list adds entire regions that will be skipped. These rules apply for both Real-Time Protection and Monthly Schedule Protection. Simply click the dropdown, find the relevant entry, and click 'Add Exclusion list'.

## Additional Notes

#### Agent Network Configuration

Agents that we spin up for you will obey the networking configuration set in Configuration > Event Agent Settings. Note that we scan files on a Per Region basis, which means we create agents in each region that you have storage containers protected. The Agent Settings page allows unique configuration per region, we will obey those rules on a per-region basis and follow the Default rules if there isn't an explicit configuration set there.

For more information, refer to our [Event Agent Settings](/) documentation.

#### Container Protection Behavior

When there are existing Event Agent configurations in place, Protect All and Real-Time Protection don't overwrite those configurations. For example, if a bucket were already protected prior to Real-Time Protection's activation, it would remain even after Real-Time Protection were deactivated.

`Protect 'bucket-1' ->Enable Protect All -> Disable Protect All ->'bucket-1' will remain protected`

For Schedules, we create an entirely different schedule, it will behave like any other schedule and won't interfere with existing schedules set in place.


# Classification Rule Sets

If you have Data Classification enabled you will see this Classification Rule Sets page under the Configuration section

Here you will see the rule sets available for Data Classification. The grey rule sets are default rule sets available out of the box. You cannot edit these default rule sets.

<figure><img src="/files/iIMEghwaZG6TEduqAIbn" alt=""><figcaption><p>Rule Sets Page</p></figcaption></figure>

The Rules Count column will show how many rules exist in each rule set. The Containers Count column shows how many buckets a particular rule set is enabled on whether it be for event-based or retro-based data classification.

## Creating a custom rule set

You can create your own custom rule set by clicking the `Create Rule Set` button. A custom rule set will allow you to mix and match rules from any default rule set available. This way you can build a rule set based on the specific frameworks and data you need to classify on.

Additionally, you can add your own [custom classification rules](/console-overview/configuration/classification-custom-rules) you've created as part of this custom rule set.

<figure><img src="/files/RrP1lRqVuTBJZ5sA04AW" alt=""><figcaption><p>Select your rules</p></figcaption></figure>

Once you have the rules selected for your custom rule set you can click the save button to create the rule set. After that all you need to do is enable event-based protection on a bucket or create a DC schedule.

### Rule Locales

You'll notice that some rules can be global since the type of information that is being classified isn't formatted in a specific way. Other rules can have localized options since the type of information you need to classify on can be different based on country.

<figure><img src="/files/EqRQ81UOzEAHTTivpBgv" alt="" width="266"><figcaption><p>Select either the entire rule or a specific country in the list</p></figcaption></figure>

#### Filtering Locales

You can filter the rule sets down to show only rules for specific countries. Select the country you want to filter by from the `Regions` dropdown.

<figure><img src="/files/VB47F9vYkgBbgLok818t" alt="" width="375"><figcaption><p>Search for a specific locale in the Regions dropdown</p></figcaption></figure>

## Default Rule Sets

Below is a list of the default rule sets we currently have available, the number of rules for each rule set, and descriptions of what you can expect for each rule set.

| Rule Set                            | Number of Rules | Description                                                                                                                                                                                                                      |
| ----------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Canadian Health Service             | 9               | Personal health card number information for British Columbia, Ontario, and Quebec.                                                                                                                                               |
| Document classification             | 33              | Confidential, sensitive, personal, etc. content markers                                                                                                                                                                          |
| Financial Data                      | 87              | Bank account details, credit card numbers, financial/personal identifiers, etc.                                                                                                                                                  |
| Health Care                         | 26              | Social Security Numbers, ailments, medical patient forms, etc.                                                                                                                                                                   |
| HIPAA                               | 15              | Social Security Numbers, ailments, medical patient forms, etc. Localized to USA formats and specific for HIPAA compliance                                                                                                        |
| Item identifiers                    | 13              | Vehicle license plates, Postal codes, Microsoft license keys, etc.                                                                                                                                                               |
| PCI DSS                             | 55              | Bank account details, credit card numbers, financial/personal identifiers, etc. Specific to PCI DSS compliance                                                                                                                   |
| Personally Identifiable Information | 319             | Bank account details, driver's license details, passport details, etc.                                                                                                                                                           |
| UK National Health Service          | 5               | National insurance numbers with qualifying term, National insurance numbers, NHS number personal identifier near date of birth, NHS number personal identifier, Community Health Index. Specific rule set for the United Kingdom |


# Classification Custom Rules

If you have Data Classification enabled you will see this Classification Custom Rules page under the Configuration section.

Effective data classification requires policies and rulesets that are written for particular types of information. Along with out of the box rules, you are able to create your own custom rules using Regular Expressions (RegEx). Once created you can add these rules to a custom rule set and use them to classify your text based objects.

<figure><img src="/files/FRlW7hbs4fIv8pmdZjH7" alt=""><figcaption></figcaption></figure>

## Creating a custom rule

After clicking the Create Rule button you can enter a name, description, and regular expression for your rule. Once you save the rule, you'll be able to use it as part of a custom classification rule set.

<figure><img src="/files/aOcdNhA2KjbyiLxjOdE0" alt=""><figcaption></figcaption></figure>

## Using Amazon Bedrock to create RegEx rules

Crafting RegEx policies is often challenging because the syntax can be complex and dense. Our integration with [Amazon Bedrock](/how-it-works/integrations/amazon-bedrock) simplifies this process by leveraging the power of artificial intelligence. All you need to do is enter a simple text prompt to identify patterns or text and the exact value you need for the rule will be created.

To get started, you’ll need to enable the Amazon Bedrock integration. Then you can navigate to Configuration in the navigation of your AV console and click on Classification Custom Rules. From there, click the “Create Rule” button. In the popup, enter a name and description, then click on “Create expression using Amazon Bedrock” to have the RegEx built for you.

For example, to create a RegEx rule that identifies certain credit card numbers, enter the Prompt “create a regular expression that discovers all American Express credit card numbers”. Then select Send Prompt to generate a RegEx rule that can be used. Each response is accompanied by an explanation of the RegEx. Click “save”.

<figure><img src="/files/kc2a26ZTadywCZM8qrOg" alt=""><figcaption></figcaption></figure>

If you’re a RegEx pro, custom classification rules can be created without the assistance of Bedrock—simply enter the regular expression, add a name plus description, and hit “save” to create the rule.


# Console Settings

The Console Settings page is used to make modifications to the console characteristics

This includes the CPU and Memory it is running with, the VPC and Subnets it is running within as well as the access URL you leverage to reach the console. Also included on this page is useful information about this particular deployment.

![Console Settings](/files/7n0wD9QVgQmQ5CTlSizZ)

## Console Information

<figure><img src="/files/NzRODExxftgfChenl9zJ" alt=""><figcaption></figcaption></figure>

It is often useful to know the details of how the particular console you are in came about. Which stack did this console get deployed from? Where is it running? What is the unique service name? etc. Whether this is for your own purposes to explore within your AWS account or whether it is to get support from Cloud Storage Security, these data points are helpful. The Console Information section does just that. It gives you your current Subdomain, the CloudFormation Stack Name used to deploy, the uniquely generated Service Name and the AWS Region the console is deployed in.

## AWS EventBridge Proactive Notifications

<figure><img src="/files/OPgdvuJGGP9QOO8i4Oe8" alt=""><figcaption><p>Setups Setup an EventBus to receive the Proactive Notifications setup</p></figcaption></figure>

This integration allows you to send notifications to EventBridge, usually used by customers that need to monitor results and stream the data somewhere else (e.g.: AWS Kinesis). Find setup instructions and examples [here](/console-overview/configuration/proactive-notifications#eventbridge-notifications).

## Automatic Bucket Protection

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

<figure><img src="/files/IHcMei4SJ7p2Em8GtsWF" alt=""><figcaption></figcaption></figure>

This field specifies the Tag Name to look for on a bucket to automatically turn on event-based protection for that bucket. The bucket catalog is refreshed every 30 minutes. During this refresh we will look for this tag and if present (currently values do no matter) we will protect the bucket. You can change this to any Tag Name you'd like.

{% hint style="info" %}
Bucket Protection will be turned on when this tag is found. If you have disabled bucket protection from the console on the Bucket Protection page, at the next 30 minute catalog refresh protection will be turned back on. If you do not want this bucket to be protected again, you will need to remove this tag.

This should be part of the consideration when determining to use existing tag names or creating a custom one.

We don't currently use the tag value in any real way, so the presence of the tag alone will trigger the protection.
{% endhint %}

{% hint style="warning" %}
When using `tag triggered protection` any bucket in any region with the defined tag will be protected. If you do not have the region(s) pre-configured with networking setup then protection cannot be enabled. You must pre-configure or `stage` the regions you will be protecting buckets in.

Use the [Event Agent Settings page](/console-overview/configuration/agent-settings) to stage any/all regions where automatic protection may take place.
{% endhint %}
{% endtab %}

{% tab title="Data Classification for Amazon S3" %}
{% hint style="info" %}
This field is not used for Classification at this time (only for our Antivirus for Amazon S3 product)
{% endhint %}
{% endtab %}
{% endtabs %}

## Subdomain Management

<figure><img src="/files/ZgzAB0Oj56xM8JmH941w" alt=""><figcaption></figcaption></figure>

In order to give you a secure and consistent experience with how you access the Console, Cloud Storage Security has implemented a subdomain registration process on your behalf. By default, we create a subdomain that is made up of your `AWS account ID - AppID`. With this we generate an access URL to the Management Console consisting of `<accountID-appID>.cloudstoragesecapp.com`. This is shown to you in the Stack Outputs after completing the CloudFormation Template stack create. You are welcome to continue with this URL for as long as you use the product. But, we have seen with some customers they would prefer something more meaningful and relevant to their organization.

This management page is to allow you to do just that. Pick a value that is useful and meaningful to you. Check the availability just in case it is being used. If your value is unique, the `Save` button will be enabled. Clicking `Save` will replace the value with your new value.

{% hint style="info" %}

#### Note

With any DNS changes, you may find that it takes a couple of minutes for the new URL to be recognized by the DNS servers you are pointing at.
{% endhint %}

## Console Security Group Inbound Access

<figure><img src="/files/cae3LchOstP32zqKoC65" alt=""><figcaption></figcaption></figure>

External inbound access to the Console is controlled through an AWS Security Group (identified by the name CloudStorageSecConsoleGroup-)d

## System Tags

<figure><img src="/files/Ox9gpIiTYmsHZoTk02sQ" alt=""><figcaption></figcaption></figure>

Tagging your resources within AWS is crucial for maintaining well-organized and manageable cloud infrastructure. By applying descriptive tags to your resources, you gain the ability to categorize, search, and filter based on specific criteria. The System Tags feature allows you to apply your own custom tags to the resources deployed by Cloud Storage Security within your AWS environment.

To use this feature, simply add the Tag Key(s) and Tag Value(s) that you would like added to your resources and click the Apply Tag Changes button. The console will initiate the update to apply the tags across your resources.

You can also delete your custom tags from this same menu by clicking the trash icon next to any added tag you would like removed. Be sure to click the Apply Tag Changes button to save and apply your changes.

{% hint style="info" %}
**Note**

It will take a few minutes for these changes to be applied within AWS. We recommend that you apply all of your tag updates at once, or wait 5-10 minutes between updates to ensure all tags are applied appropriately.
{% endhint %}

The tags that you enter must adhere to AWS tag naming limits and requirements:

* The tag key must be a minimum of 1 and a maximum of 128 characters.
* The tag value must be a minimum of 1 and a maximum of 256 characters.
* In general, the allowed characters are letters, numbers, spaces representable, and the following characters: \_ . : / = + - @.
* Tag Key cannot start with 'aws:'.

## Console Task Settings

<figure><img src="/files/cRFOIAeO1m1iWSTBjftR" alt=""><figcaption></figcaption></figure>

The `Task Settings` apply to the actual AWS Fargate Task (container) running the console. The default settings within the CloudFormation Template are to run the console with .5vCPU and 1GB of Memory. This is suitable in most cases and certainly when you get started. As your data sets grow and you do more with it as well and if you have large numbers of existing objects you plan to retro scan regularly, you may find that bumping these numbers will help your console run more smoothly. You selected a VPC and two subnets to run the console in during the CloudFormation deployment. There may be times you'd like to change these values after the fact and this section makes it very easy to do so.

This section is to allow you to easily modify the running values of the console.

{% hint style="info" %}

#### Note

The Memory must always be set to a value that is between 2x and 8x of the vCPU.

Examples

* vCPU = 0.5, then 1gb <= memValue <= 4gb
* vCPU = 1, then 2gb <= memValue <= 8gb
* vCPU = 2, then 4gb <= memValue <= 16gb
* vCPU = 4, then 8gb <= memValue <= 32gb
  {% endhint %}

You'll notice a `Public` or `Private` associated with each VPC. This is an indicator of whether or not the VPC is tied to an Internet Gateway. Thought process being that with an IG in place you will have the required outbound access. The console does not require a public IP address or to be accessible from the public in general, but it does require outbound internet access to get to AWS ECR to pull new Task images.

<div align="left"><img src="https://help.cloudstoragesec.com/img/console-task-settings-vpcs.png" alt="Console Task Settings - VPCs"></div>

You'll notice a `Public` or `Restricted` associated with each Subnet. This is an indicator of whether or not the Subnet is outbound routable to the internet. Minimally, the agent task must be able to reach the AWS ECR to pull new Task images and to be able to pull AV signature updates. Two validations are performed for this check. First, we check to see if the NACL associated with the Subnet(s) has outbound open for 0.0.0.0/0. Secondly, we check to see if there is a custom Route Table in place and verify it is routed to an internet gateway.

<div align="left"><img src="https://help.cloudstoragesec.com/img/console-task-settings-subnets.png" alt="Console Task Settings - VPCs"></div>

{% hint style="success" %}
Generally, the first indicator for a good configuration will be whether or not the VPC has an internet gateway or something that is taking its place. Secondly, check the subnets for their outbound access.
{% endhint %}

{% hint style="warning" %}
Changing these values will cause the console to reboot.

***

If the VPC or Subnets are not proper for the console, you could have [trouble reaching the console](/trouble-shooting/i-cannot-access-the-management-console).
{% endhint %}


# AWS Integrations

On the AWS Integrations page you can enable or disable use and access to any of the following AWS services we integrate with:

* [Amazon GuardDuty](/how-it-works/integrations/aws-guardduty)
* [AWS Security Hub](/how-it-works/integrations/aws-security-hub)
* [AWS CloudTrail Lake](/how-it-works/integrations/integrations)
* [Amazon Bedrock](/how-it-works/integrations/amazon-bedrock)

<figure><img src="/files/ZsORpYvhqHsOuYrgvilT" alt=""><figcaption></figcaption></figure>


# Job Networking

The Job Networking page allows you to manage the VPC and subnets that will be assigned to any scan jobs that are started.

<figure><img src="/files/QvchLGIZekuOhcFpKLQA" alt=""><figcaption><p>Job Networking</p></figcaption></figure>

If you already have a VPC and subnets set for your event-based scanning agents we will automatically use those settings for any scan jobs.


# API Agent Settings

The API scanning agent can be deployed to most regions at this time.

Unlike the Event Agent which is setup at the time protection is turned on for a bucket in a new region, the API agent is specifically setup in regions of your choice completely independently of whether you have S3 integrated protections ([event-based](/how-it-works/object-scanning#event-driven-scanning) and [retro-based scanning](/how-it-works/object-scanning#retro-scanning)) in place. As part of the deployment process, a Load Balancer is created as the entry point to the API Agent. After setup is complete, you will have an API Agent Service in your Fargate Cluster and a Load Balancer (either internet-facing or internal) as the persistent access mechanism. On top of this setup, you can configure aspects of the scanning agent and characteristics for how they scale. This includes the CPU, Memory and Disk Size (for the AWS Fargate tasks), the VPC and Subnet(s) as well as the scaling characteristics including Minimum # of Agents and Maximum # of Agents.

<figure><img src="/files/KLp7raRuK2rshecLIMYa" alt=""><figcaption><p>API Agent Settings</p></figcaption></figure>

With the API Agent you have choices as to whether you deploy in more than one region. With the Event Agent, we deployed infrastructure to each region with protected buckets to keep the scanning close to the data. With the API Agent effectively being an API endpoint, you could make one bit of infrastructure available to all of your applications if networking and latency allowed for it. Applications, whether on-prem, living in AWS or being run by third parties could leverage one endpoint. You have the choice to deploy to additional regions to get closer to your users as you see fit.

With all of the infrastructure we deploy, you can get more detailed deployment information on the [Deployment Overview page](/console-overview/monitoring/deployment-overview) where we represent all of the different Fargate infrastructure we have deployed.

{% hint style="info" %}
To learn more about triggering an API scan of a file, check out the [api-based scanning overview](/how-it-works/object-scanning#api-driven-scanning) page.
{% endhint %}

## Deployed Regions

\
If there are no currently deployed API agents, then you will only have an `Add New Region` button available to you. Otherwise, displayed to you are any regions where API agents have been deployed. To setup new regions click the `Add New Region` button. To edit an existing region's setup, click the specific region pill. Either will populate the bottom portion of the page with the fields that are required to stand up the service.

<figure><img src="/files/DEGamAjGbaWSFI4D2dVI" alt=""><figcaption><p>Pick A Region</p></figcaption></figure>

## Default DNS

\
This will not show on the page as you are setting up a new service region. Once the setup is complete and the load balancer has been created, this page will show the default DNS value. This is the value assigned to the load balancer, not necessarily the value you plan to use with your application teams. This URL is a fully valid and working address, so you can submit API scans to this. It is recommended that you create a CNAME record in your DNS that links a friendlier name to this LB url. This is to ensure validity of the SSL certificate being used. While it still works to simply use the LB url, you would need to disable SSL certificate verification in order to access it.

<figure><img src="/files/4eJd10KxouE4PzDFXNZz" alt=""><figcaption><p>Default DNS</p></figcaption></figure>

## Network Settings

The `Network Settings` section defines which network the API Agent will run in and the connectivity to it.

<figure><img src="/files/ZMk0Et8AEz0uVpKit1xs" alt=""><figcaption><p>Network Settings</p></figcaption></figure>

You start by specifying which `VPC and Subnets` you want the load balancer and Fargate service to run in. Whichever VPC and Subnets you pick ensure that they meet your access needs whether from the outside or inside of your network.

If you are using an API Load Balancer you can also define the Subnets of the API Load Balancer through these settings without having to make changes in the AWS console.

<details>

<summary>VPC and Subnet Access Importance</summary>

You'll notice a `Public` or `Private` associated with each VPC. This is an indicator of whether or not the VPC is tied to an Internet Gateway. Thought process being that with an IG in place you will have the required outbound access. The API Agent does not require a public IP address or to be accessible from the public in general, but it does require outbound internet access to get to AWS ECR to pull new Task images.

<img src="/files/402zodDKwvcoK3WQhkB0" alt="" data-size="original">

You'll notice a `Public` or `Restricted` associated with each Subnet. This is an indicator of whether or not the Subnet is outbound routable to the internet. Minimally, the agent task must be able to reach the AWS ECR to pull new Task images and to be able to pull AV signature updates. Two validations are performed for this check. First, we check to see if the NACL associated with the Subnet(s) has outbound open for 0.0.0.0/0. Secondly, we check to see if there is a custom Route Table in place and verify it is routed to an internet gateway.

![](/files/8E8sI4xhURTiSeHizuIq)

Changing these values will cause the agents to reboot.

</details>

You also define who can access the URL via the `Inbound Access CIDR`. This directly corresponds to an AWS Security Group for the load balancer. Lock this down to the network(s) allowed to access the URL.

The `Internet Facing Load Balancer` determines whether the load balancer is created with public IPs or not. If you plan to leverage this API endpoint from outside the network, then you'll want this box ticked. If you plan to use the endpoint from resources on the same network then you can uncheck it.

{% hint style="info" %}
If you decide after the fact you want a different value for `Internet Facing Load Balancer` you will have to tear the API Agent down and recreate it because there are no AWS APIs to change this value after the fact. You can tear down the API Agent from the [Deployment Overview page](/console-overview/monitoring/deployment-overview#solution-cleanup-uninstall).

The tear down can take upwards of 15 minutes for the load balancer to be removed. Once that has completed you can re-setup the region.
{% endhint %}

The `SSL Certificate ARN` is the SSL certificate to associate with the load balancer. You will typically create the certificate to match a friendly URL. If the certificate and API URL do not match, you will get certificate validation warnings and errors. You can code around those, but better to match them up. With the `SSL Certificate ARN` you have a choice to create your own or leverage ours like the Management Console. The default behavior of the Management Console is to give you persistent access through the `cloudstoragesecapp.com` domain. We also offer this option for the API Endpoint(s). This allows for a very fast and simple setup for the API Endpoint and doesn't require you to provide your own cert and friendly DNS entry. Your environment could look like the following: console = `customerA.cloudstoragesecapp.com` and your API endpoint = `customerA-api.cloudstoragesecapp.com`. And we'll do it all for you.

When first setting up the API Endpoint you'll have an option for `New Cert`.<br>

<figure><img src="/files/qkrGFCcEi6mp6DGUYDPe" alt=""><figcaption><p>SSL Certificate Required</p></figcaption></figure>

If you have your own certificate you'd like to use, then simply past the ARN value into this field and ignore the `New Cert` button. If you'd like us to register your API Endpoint with our DNS as described above, then click the `New Cert` button to reveal the following popup. Here you can specify the subdomain value you'd like to use for the friendly URL.\
\
Type in whatever value you'd like to use and check the availability. If it is free, then simply click `Create` button. We will create the entries in our DNS to make the friendly URL. You may see the following until the certificate and DNS settings are completely setup.<br>

<figure><img src="/files/d4Ii3G09VEA28uub1MRH" alt=""><figcaption><p>SSL Certificate ARN</p></figcaption></figure>

<figure><img src="/files/YtE3iUR5Eq5zl3PsAYkF" alt=""><figcaption><p>Create Certificate for API Load Balancer</p></figcaption></figure>

## Service Settings

![API Service Settings](/files/nx1nmTunF0PKqPwDqo7O)

| Field           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Min Agents      | The minimum number of scanning agents you'd like running by default or in the given region. This value **cannot** be `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Max Agents      | The maximum number of scanning agents you would like to possibly scale to. This number can be anything greater or equal to the minimum.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Scanning Engine | You can select between Sophos or ClamAV for your API agent scanning engine. ClamAV can scan files up to 2GB in size. If you need to scan a file larger than 2GB you will need to use Sophos.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| CPU             | The amount of vCPU you would like allocated to each agent. Each additional auto-scaled agent would also have this value.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Memory          | The amount of memory you would like allocated to each agent. Each additional auto-scaled agent would also have this value.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Disk Size (GB)  | <p>The amount of disk space assigned to each agent. Each additional auto-scaled agent would also have this value.<br><br>The default value and included in the AWS pricing is 20GB. If all files you will be scanning are under 15GB in size then keep the default. If there are regions or needs to scan files larger than 15GB in size, then increase this to a size large enough to handle your largest files. 200GB is the current maximum this number can be set to. As a result, the maximum size file that can be scanned through this scanning method is 195GB. If you require the scanning of anything larger than 195GB, please refer to <a href="/pages/EaG45wuCtv8Xui4BTTK5#extra-large-file-scanning">==Extra Large File Scanning==</a> option. You can scan TB(s) sized files.<br><br><strong>NOTE:</strong> There are increased pricing costs for any GB above the 20GB size. Currently, this price per GB per hour is $0.000111, but refer to the <a href="https://aws.amazon.com/fargate/pricing/">AWS Fargate Pricing</a> page to get the latest costs.</p> |

{% hint style="info" %}
The Memory must always be set to a value that is between 2x and 8x of the vCPU.
{% endhint %}

> ```
> vCPU = 1, then 3gb <= memValue <= 8gb  
> vCPU = 2, then 4gb <= memValue <= 16gb
> vCPU = 3, then 6gb <= memValue <= 24gb
> vCPU = 4, then 8gb <= memValue <= 32gb
> ```

{% hint style="danger" %}
Changing these values will cause the agents to reboot.

If the VPC or Subnets are not proper for the agents, you could have [trouble with the agents not booting up or entering a constant reboot cycle](https://help.cloudstoragesec.com/how-it-works/trouble-shooting/#fix-scanning-agents-in-reboot-loop).
{% endhint %}

Once you click `Setup <region-name>` the process of creating the load balancer and API Endpoint agents will commence. This can take a number of minutes to do. While this is happening you will see the following message. You will know it is complete when the yellow bar goes away.

<figure><img src="/files/9NTkZ352M0q83U6B1das" alt=""><figcaption><p>API Agent Settings</p></figcaption></figure>

## Scaling Considerations

Currently we have seen sufficient performance with scaling out instead of up such that the default values of 1vCPU and 3GB Memory should be all you need for most any workload. Scaling out is driven by two main factors: number of connections to the load balancer and the CPU utilization of the task. Either factor can trigger scaling based on an average over a full minute.

For connections, it is 1000 or greater connections lasting over 1 minute. If 10,000 connections come in all at once and haven't been processed within a minute, then tasks will be scaled out to match the number of connections remaining. If 10,000 were still remaining the scaling policy would start up 9 more tasks.

For CPU utilization, 75% or greater utilization lasting over a minute will trigger scaling. Scaling by CPU utilization behaves slightly differently than connections in that only 1 new instances will be spun up at a time. So if the utilization averages over 75% for a minute then a second instance will spin up. If the utilization of both instances averages over 75% again, then a third instance will spin up and so forth.

Contracting back down after the scaling event takes a bit longer since the load balancer wants to see the connections drained and the cpu utilization stabilized before dropping resources. So you may see tasks linger longer than you'd expect, but they will scale back down.

## Scanning Engine Consideration

When setting up your API agent you'll need to select which antivirus scanning engine the API agent will use to scan files. We support the following scanning engines for API driven scanning:

* Sophos
* ClamAV

You have the option to use a single scanning engine or you can enable multi-engine scanning to have your API agent use multiple scanning engines at the same time.

{% hint style="info" %}
If you toggle on `Use Default Scan Settings` we will use the scanning engine settings you've configured for Event-based and Retro-based scanning through the [Scan Settings](/console-overview/configuration/scan-settings) page. If it's toggled off the engine settings you configure for your API agent will be separate from your Event-based and Retro-based scan settings.
{% endhint %}

### Single Engine API Scanning

<figure><img src="/files/CfSAoFDNZuH4g0YoTTSF" alt="" width="375"><figcaption><p>Select a single engine you want to use for your API Agent</p></figcaption></figure>

### Multi-Engine API Scanning

<figure><img src="/files/pbX0S92ifBWoSzwshUtc" alt="" width="375"><figcaption><p>Select multiple engines to use for your API Agent</p></figcaption></figure>

## Classification Rule Sets

Similar to our data classification functionality for other storage volumes, you can also integrate data classification into your API scan. This way you'll be able to perform an antivirus scan and classify files for PII against the rulesets that you select here.

You can learn more about using the classification functions on the [API Driven Scanning](/how-it-works/object-scanning/api-driven-scanning) overview page.

<figure><img src="/files/YUXY0xdPjjpSAD1GZ9jj" alt=""><figcaption></figcaption></figure>


# Proactive Notifications

{% tabs %}
{% tab title="Antivirus for Amazon S3" %}

#### Proactive Notifications

![Proactive Notifications Dashboard](/files/MD2MXPDtEny8v0UZIGkp)

The Dashboard is a great resource to monitor your environment while you are using the console. For all the times you are not in front of the console, it is critically important you are made aware of any system notifications such as `problem file` scan results. Scan Results which could identify infected or unscannable files is the most critical, but other system messages may be important enough for you to follow as well. The other types of information we notify on is: public / private status of buckets, newly discovered buckets, protection turned on / off for buckets, availability of system updates, trial expiration and low prepaid data counts. With this in mind, a Notifications SNS Topic is provided where Antivirus for Amazon S3 publishes these useful messages. You can simply subscribe to the Topic with the protocol (HTTP, HTTPS, Email, Email-JSON, Amazon SQS, AWS Lambda, Platform Application Endpoint, SMS) of your choice.

All notification messages we generate will have a `Notification Type` attribute as well as possible secondary attributes. These attributes along with their values can be leveraged for filtering the messages down. Along with the notification type attribute, there are other message attributes such as `scanResult`, `bucket` and `account`. AWS SNS subscription filtering works in an ***and*** fashion with additional attributes. ***Or*** functionality is supported within attribute values, but as soon as you have more than one attribute those behave as ***and***. This is critical to be aware of as you may add combinations that will never occur and therefore never receive the messages you are expecting.

We have made our wizard so you cannot make these unusable combinations. The filtering that is allowed:

* **notificationType** - on its own this is the highest level (generic) filter
  * You can get all scan results but just setting this attribute to `scanResult`, but you may truly not want all scan results, just `infected`
  * Possible values - \[scanResult, largeFileScan, bucketsDiscovered, bucketProtection, bucketCrawling, bucketsPublicAccess, bucketAutoProtectionFailed, updatesAvailable, lowPrepaidData, trialExpiring]
* **scanResult** - allows you to filter by the result itself
  * You can filter by one or more values - \[Clean, Infected, Unscannable, Error, InfectedAllowed]
* **bucket** - filter by a particular bucket name
  * Useful if you want different subscriptions/notifications for different buckets to have different outcomes or go to different teams
* **account** - filter by account number
  * For multi-account environments this allows you to filter at the account level
  * Similar to bucket, you could have different processes or teams responsible at the account level and so need separate subscriptions to notify those particular teams

#### Message Types

All possible message information:

<table><thead><tr><th width="174">Key Name</th><th>Description</th></tr></thead><tbody><tr><td>notificationType</td><td><p>You can get all scan results but just setting this attribute to <code>scanResult</code>, but you may truly not want all scan results, just <code>Infected</code><br>Possible values:<br></p><ul><li>scanResult</li><li>largeFileScan</li><li>bucketsDiscovered</li><li>bucketProtection</li><li>bucketCrawling</li><li>bucketsPublicAccess</li><li>bucketAutoProtectionFailed</li><li>updatesAvailable</li><li>lowPrepaidData</li><li>trialExpiring</li></ul></td></tr><tr><td>scanResult</td><td><p>Secondary attribute to allow filtering by the scan result itself<br>Possible values:<br></p><ul><li>Infected</li><li>Error</li><li>Unscannable</li><li>Clean</li><li>InfectedAllowed</li></ul></td></tr><tr><td>bucket</td><td>Secondary attribute to provide filtering by bucket name. Useful if you want different subscriptions/notifications for different buckets to have different outcomes or go to different teams. You can provide more than 1 bucket name if desired in a comma separate list.<br><br>Possible values: <code>your_bucket_name(s)</code></td></tr><tr><td>accountID</td><td>For multi-account environments this allows you to filter at the account level. Similar to bucket, you could have different processes or teams responsible at the account level and so need separate subscriptions to notify those particular teams. Can be used with scanResult, bucketsDiscovered, bucketProtection, bucketCrawling, bucketPublicAccess</td></tr></tbody></table>

**Proper Combinations**

Proper combinations can be:

* **notificationType**,
* **notificationType**\['scanResult'] + **scanResult**\['Infected', 'Clean', 'Unscannable', 'Error', 'InfectedAllowed\`],
  * **notificationType** + **scanResult** + **bucket**\[' < bucket-name(s) >'],
  * **notificationType** + **scanResult** + **account**\['< account-number(s) >'],
* **notificationType**\['scanResult'] + **bucket**\['< bucket-name(s) >'],
* **notificationType**\[any but updatesAvailable|lowPrepaidData|trialExpiring] + **account**\['< account-number(s) >'],

{% hint style="info" %}

#### Example

You may want your Support/IR team to be informed of infected files only so you setup a subscription that filters down to `scanResult = Infected`and gets sent to their emails or distribution list.

While classsificaton results of `Error` and `Unscannable` may get filtered down and sent to your infrastructure team since both of those results typically relate to access issues (either KMS related, password protection, file extension reading software, etc).

You may want yet another subscription that either captures all scanResults messages or just the Clean ones so you capture your own audit log of those files. So the endpoint could be an email not responded to or an application that gathers all this data.
{% endhint %}

Here is a sample message so you can see the format that gets sent. More samples for the other notification types below.

```json
{
    "Type" : "Notification",
    "MessageId" : "45927ed5-6884-542e-96c6-27777317db99",
    "TopicArn" : "arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh",
    "Subject" : "AV-for-S3: Infected object found",
    "Message" : "{\"guid\":\"a59f0da2-0fdd-4667-b272-618d79cd520d\",\"dateScanned\":\"2021-08-26T22:44:34.5595461Z\",\"bucketName\":\"css-protect-versioning\",\"key\":\"infected_bill.pdf\",\"versionId\":\"ohjRhn8aiPIjVTU1T6xOKWoJBR8i0v0w\",\"result\":1,\"scanResults\":[{\"result\":\"Infected\",\"virusName\":[\"Win.Ransomware.WannaCry-6313787-0\"],\"message\":[],\"dateScanned\":\"2021-08-26T22:44:34.5595461Z\",\"engine\":\"ClamAV\",\"engineVersion\":\"0.103.3\",\"virusDbVersion\":\"26275\",\"scanType\":\"GoFwd\"},{\"result\":\"Infected\",\"virusName\":[\"Troj/PDFJs-AIA\"],\"message\":[\"infected_bill.pdf\"],\"dateScanned\":\"2021-08-26T22:44:33.3838187Z\",\"engine\":\"Sophos\",\"engineVersion\":\"3.82.1\",\"virusDbVersion\":\"5.86\",\"scanType\":\"GoFwd\"}],\"actionTaken\":\"Move\",\"virusUploadedBy\":\"AWS:AIDA2T7AZ3IMGHBWXMN4W\",\"fileExists\":true,\"movedTo\":\"cloudstoragesecquarantine-pxlhbmh-<account-number>-us-east-1\",\"region\":\"us-east-1\",\"accountId\":\"<account-number>\",\"allowOnceExemptionAdded\":false,\"permanentlyAllowed\":false}",
    "Timestamp" : "2021-08-26T22:44:35.049Z",
    "SignatureVersion" : "1",
    "Signature" : "or+H3m1RpSvHe3GlccGjnckSj13iz+mFYaEMjwKWuE3uFhytHUkc6cIxk4E3lI7GwtOmuxTCQgc9ms7c/yp+487Chh0IM3nLGCD7WWNaW3W/8BnpFg1wkWQoSAPIh4EuhYLEWMzqF1ldENp6SNGZpG60vYyS/vNx9GnA5nrRDwLfQ76HDlRq/PQpbnzBPleaW61TOsRRhKpVpNZ1dKTRECqCtP9Tgno12XURZ8Li4PQP/w3IJ6EPZOKrva7A2vaaOe4hRyx4lWSagHtigqZ9RMIsTBOFXrCwG3iXopUhnylDgtaeODyepXTUEMHzw931hRMmcjGT+h1epJ10mraA8Q==",
    "SigningCertURL" : "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem",
    "UnsubscribeURL" : "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh:32f7008b-bf69-48c0-84fd-872b708f0037",
    "MessageAttributes" : {
        "bucket" : {"Type":"String","Value":"css-protect-versioning"},
        "accountId" : {"Type":"String","Value":"<account-number>"},
        "notificationType" : {"Type":"String","Value":"scanResult"},
        "scanType" : {"Type":"String","Value":"Api"},
        "scanResult" : {"Type":"String","Value":"Infected"},
        "scanResultKind" : {"Type":"String","Value":"NotApplicable"},
        "key" : {"Type":"String","Value":"filename.ext"}
    }
}
```

Follow the steps below to set up your Topic Subscription utilizing an AWS provided protocol like email.

#### Create Subscription - Email Example

Subscribing to the real-time notifications sent out via our Notifications SNS Topic has been simplified by the wizard provided. You can still [manually set this up](#manual-setup-email) if desired, read below these instructions. Creating through the form still requires you to **confirm** the subscription.

1. Click the `Add Subscription` button

   <figure><img src="/files/j2qs8OOBNJOi0xDq7neg" alt=""><figcaption></figcaption></figure>
2. The `Add Proactive Notifications Subscription` popup will appear

   <figure><img src="/files/AxIVYZsig728dEaHflGv" alt=""><figcaption></figcaption></figure>
3. Specify the `Notification Type` of choice - for our example we will choose `ScanResu`

   <figure><img src="/files/1XvsbHKbKP3wDya9BEeg" alt=""><figcaption><p><mark style="background-color:blue;"><strong>Note</strong>:</mark> After selecting the <code>Notification Type</code> you will be presented other fields to populate. At a minimum, you must specify a <code>Protocol</code> and <code>Endpoint</code>. The other fields can be populated as described above.</p></figcaption></figure>
4. Choose `Email` as the protocol and enter your email address

   <figure><img src="/files/2ggtbiQ2ANMv984JJZax" alt=""><figcaption><p><mark style="background-color:blue;"><strong>Note:</strong></mark> If you left it as seen here, every scan result (clean, infected, unscannable, error and infectedAllowed) would be sent to your email. Generally, you may want to limit down to <code>infected</code> and <code>unscannable</code> to limit the number of emails received. This is up to your requirements, so do as you see fit. As described above, you can filter the results by result, bucket or account and proper combinations of those.</p></figcaption></figure>
5. Specify `Scan Results` values to limit emails sent<br>

   <figure><img src="/files/UgN5qQd5NqyFVs71BwSv" alt=""><figcaption></figcaption></figure>
6. Click the `Add Subscription` button

   <figure><img src="/files/T624QUThfVVo2F51kuAA" alt=""><figcaption></figcaption></figure>
7. You will now see a new entry in the table list showing as `Pending` under status

   <figure><img src="/files/VflMfOQ9hdSL6N49eCJP" alt=""><figcaption></figcaption></figure>
8. Check your email so you can **confirm** the subscription

   <figure><img src="/files/UmIvUza6rqiTDFU1oD2E" alt=""><figcaption></figcaption></figure>
9. Open the email and click the `Confirm subscription` link

   <div align="left"><figure><img src="/files/4CogFb74seZhaCFSlfiZ" alt=""><figcaption></figcaption></figure></div>
10. This action will open a browser window showing subscription confirmation

    <div align="left"><figure><img src="/files/UWYbqtng06DSpKUFq167" alt=""><figcaption></figcaption></figure></div>
11. Refresh the page list by clicking the little `Refresh` button and you will see your new subscription confirmed

    <figure><img src="/files/9rj9qLVBWalF3oaI495K" alt=""><figcaption></figcaption></figure>

You are all set now! Feel free to create more as needed for the different notifications needed.

{% hint style="warning" %}

#### Warning

AWS does not allow the same email address to be used for multiple subscriptions to the same topic. So you can leverage multiple addresses or you can use the "+" option most modern email providers (Gmail, O365, Exchange) support.

For example, instead of using `support@cloudstoragesec.com` as I did in the example steps I could do the following:

* *<support+scanresult@cloudstoragesec.com>* for all scan results
* *<support+updates@cloudstoragesec.com>* for system upgrade updates
* *<support+config@cloudstoragesec.com>* for notifications regarding new buckets or public buckets found
* etc.
  {% endhint %}

If you'd like to perform these steps manually or see what is going on behind the scenes on the AWS side, expand the section below and read on. If the GUI was enough for you, then skip it.

<details>

<summary><strong>Manual Setup - Email</strong></summary>

1. Login to the AWS console and navigate to the region where the console is deployed\
   \&#xNAN;*If you are unsure of which region the console is deployed in, you can view the* [*Console Settings*](/console-overview/configuration/console-settings) *page to find it.*

<img src="/files/AWneAbljk93BB3VUuk9T" alt="" data-size="original">

2. Navigate to the Simple Notification Service (SNS) service\
   \&#xNAN;*You can search for the service or find it under Application Integration*

![](/files/ZaNw9Bd8H7JobI0v5HrC)

*You'll land at the SNS Dashboard. You may have different numbers of existing Topics and Subscriptions*

![](/files/6Onb6cmJaePOrpfYsJJp)

3. Click on Topics as indicated above and then click on the Notifications Topic\
   \&#xNAN;*The Topic will be named `CloudStorageSecNotifications-<appID>`. You can find your `appID` in the* [*Console Settings*](/console-overview/configuration/console-settings) *as the value after the `-` of the Service Name.*\
   \&#xNAN;***Note**: I have more than one deployment in my account so I see more than one standard topic and more than one notifications topic.*

![](/files/2nXaaySLqj7svegBenDF)

*You will land on the details page for the Topic*

![](/files/vDfgYgiTVh79PgPuBHPw)

4. Click the `Create Subscription` button to be taken to the Create Subscription page

![](/files/yxQM6DliObz5E4CrRdPM)

5. Pick a Protocol of your choice\
   \&#xNAN;*We'll use `Email` for this example*

![](/files/6GBxbhF0eg9TWA4lcgOs)

6. Pick a Protocol of your choice\
   \&#xNAN;*We'll use `Email` for this example*

![](/files/fn9rGf3LPlm9uZLXoEze)

<mark style="background-color:blue;">**Note:**</mark> You will have to confirm your subscription as AWS indicates. Go to the email address you specified and click the link within it **after** you finish creating the subscription.

7. Setup a Filter Policy (optional)\
   \&#xNAN;*You can be done at this point, but without a filter policy you will get notified of every scan result. Look back above for scenarios where filtering makes sense*

```json
{
    "notificationType" : ["scanResult"],
    "scanResult" : ["Infected", "Error", "Unscannable", "Clean"],
    "bucket" : ["your_bucket_name(s)"],
    "key": [{"prefix": "folder_name/path(s) "}]
}
```

:pencil2: **Note**

You can copy and paste that JSON directly into the filter and it will work. **Remember** to pick which scan results you are filtering on and remove the others from the list.

*Copy the JSON and paste it into the filter policy JSON editor as seen below and edit as you see fit*

![](/files/0R8VbthKvJPlFXVwoT7D)

*You can read more about SNS Topic Subscription attribute matching in the* [*AWS Documentation*](https://docs.aws.amazon.com/sns/latest/dg/sns-subscription-filter-policies.html#string-value-matching) *on the subject.*

8. Click the `Create Subscription` button and you are done!\
   \&#xNAN;*Technically, you will now need to go confirm your subscription.*

![](/files/gt9WrieQqmC1Fxfm3OOE)

</details>

<details>

<summary><strong>Manual Setup - SQS</strong></summary>

**This is how you subscribe an SQS queue to an SNS topic from a linked account (SQS-LinkedAccount) -> (SNS-Primary)**

The way to manage the SQS-SNS, is by subscribing to the SQS from SNS, but not the other way around for some unknown reason, is the only way it works with AWS.

1. Add:\
   "sqs:GetQueueAttributes", "sqs:SetQueueAttributes" permissions to the **CloudStorageSecConsolePolicy** in the Primary account
2. Create an SQS queue in the Linked account with the following **SQS Access policy**:

<pre class="language-json"><code class="lang-json">{
<strong>"Version": "2008-10-17",
</strong>"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__owner_statement",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::&#x3C;PRIMARY_ACCOUNT_ID>:root"
},
"Action": "SQS:*",
"Resource": "arn:aws:sqs:&#x3C;region>:&#x3C;LINKED_ACCOUNT_ID>:&#x3C;SQS-Queue-Name>"
},
{
"Sid": "topic-subscription-arn:aws:sns:us-east-1:&#x3C; PRIMARY_ACCOUNT_ID>:&#x3C;CloudStorageSecNotificationsTopic-app-id>",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "SQS:SendMessage",
"Resource": "arn:aws:sqs:&#x3C;region>: &#x3C;LINKED_ACCOUNT_ID>:&#x3C;SQS-Queue-Name>",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:sns:&#x3C;region>:&#x3C; PRIMARY_ACCOUNT_ID>:&#x3C;CloudStorageSecNotificationsTopic-app-id>"
}
}
}
]
}
</code></pre>

3. Create an **SNS subscription** to an Amazon SQS in the CSSNotificationsTopic (Primary) with the filter policy:

```json
{
"notificationType": [
"scanResult"
],
"scanResult": [
"Infected", "Clean"
]
}
```

4. Go to the **SQS** **queue** in the Linked account and hit **Send and Receive Messages** you will see one Message available -> hit **Poll for messages**, and you will see:

![](/files/qnaZZfMTbJL5Y9NpuRJo)

Enter the message, and copy the **SubscribeURL** value

5. Go to the **SNS Topic** in the **Primary account**, choose the subscription, hit Confirm Subscription and paste the **SubscribeURL** value.

</details>

Managing an existing subscription is easy. Simply click the action button (![Manage Subscription button](/files/j5s7qefA0AlFzh7WOsyP)) to either `Edit` or `Delete` the subscription. Editing will allow you to make changes as are permitted to the subscription. Deleting will remove the subscription.

![Manage Subscription](/files/nXqJIFbLmay9iAGSjXOH)

#### Sample Email Protocol Messages

Once you have confirmed your subscription as objects get scanned you will see in your Inbox as follows.

<figure><img src="/files/NRI5XjpTeFqDyDULAj7X" alt=""><figcaption></figcaption></figure>

And here are the details of an infected email message received.

<div align="left"><figure><img src="/files/ylCEcaBsjiOAp2hNvjOk" alt=""><figcaption></figcaption></figure></div>

<details>

<summary><strong>EventBridge Notifications</strong></summary>

To send notifications to EventBridge, just go to **Configuration > Console Settings > AWS EventBridge Proactive Notifications**. Enable the toggle, specify an Event Bus (or leave the default) and click Save.

**Send ScanResults notifications to CloudWatch logs:**

1. **Setup Event Bus**

<figure><img src="/files/8hCzhdWPmxkz8PHjPDxl" alt=""><figcaption><p>Setup the Event Bus</p></figcaption></figure>

2. **Go to AWS EventBridge and Create a Rule for the Event Bus**\ <br>

   <figure><img src="/files/XSN8SjIQXBPd0G191H9r" alt=""><figcaption><p>Create Rule</p></figcaption></figure>
3. **Create Rule:**

**Step 1: Define rule detail**<br>

<figure><img src="/files/inbw0cgrVs4qXHufYYOg" alt=""><figcaption><p>Create Rule: Step 1 Details</p></figcaption></figure>

**Step 2. Build Event Pattern**

Leave the first options as they are and scroll down to the Event Pattern:\ <br>

<figure><img src="/files/rDxAM2lwDsVLqJBJDIee" alt=""><figcaption><p>Step2. Build Event Pattern</p></figcaption></figure>

```json
{
  "source": ["cloud-storage-security"],
  "detail-type": ["ScanResult"],
  "detail": {
    "MessageAttributes": {
      "scanResult": {
        "StringValue": ["Clean"]
      }
    }
  }
}
```

**Step 3. Select target(s)**

<figure><img src="/files/oFS5hdDYUxNyx66mYFFS" alt=""><figcaption><p>Step 3. Select target(s)</p></figcaption></figure>

#### Step 4. Configure tags - optional

<figure><img src="/files/uqKLuSjM5l2kvvwJoSz4" alt=""><figcaption><p>Step 4. Configure tags</p></figcaption></figure>

#### Step 5. Review and update

Just review that everything is setup as expected, and Submit the rule.

4. If you have already setup a Scan Result notification, you are good to go, otherwise setup a subscription for it as explained at the beggining of this page.
5. Scan a file, and check the Event Bridge log setup in CloudWatch:\ <br>

   <figure><img src="/files/ZxzsAyuvA6YlVWMLx6Kf" alt=""><figcaption><p>CloudWatch logs</p></figcaption></figure>

<figure><img src="/files/uwXJHlZY2GlVkQEyqYqf" alt=""><figcaption><p>CloudWatch Log Event Example</p></figcaption></figure>

</details>

<details>

<summary><strong>Slack Integration Setup</strong></summary>

It is a simple process (that may sound more complicated than it is) that took under 10 minutes to setup. Simply follow the process laid out in the AWS blogpost talking about how to leverage webhooks seen here: [AWS SNS + Slack / Teams / Chime setup](https://aws.amazon.com/premiumsupport/knowledge-center/sns-lambda-webhooks-chime-slack-teams/)

What it looks like in Slack. You can modify the format with [Slack Message Layouts](https://api.slack.com/messaging/composing/layouts).

<figure><img src="/files/elK0jPsLI6Y2gZ8MswQS" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><strong>Custom Formatted Email Alerts (Lambda + SES)</strong></summary>

The built-in Email subscription above is the quickest way to get notified, but the email you get looks like raw AWS output, and it always includes an unsubscribe link you can't remove. If you'd rather receive a clean, simple email that only shows the file name, scan result, and time it was scanned, you can do that by adding a small Lambda function between the Notifications Topic and Amazon SES.

{% hint style="info" %}

#### How it works

The Notifications Topic sends the message to a **Lambda function**. The Lambda function reads the message and builds a simple email. It then uses **Amazon SES** to send that email. You control exactly what the email says and how it looks.
{% endhint %}

There are three parts to set up, in this order: **SES**, then the **Lambda function**, then the **SNS subscription**.

**1. Set up SES**

SES needs to know which email addresses are allowed to send and receive this mail.

1. Open the **Amazon SES** console in the same AWS region your console is deployed in
2. Click **Verified identities** → **Create identity**
3. Choose **Email address** as the identity type - you do not need a domain for this
4. Enter the email address and click **Create identity**
5. Open the confirmation email AWS sends you and click the link inside it
6. Repeat these steps for the recipient's email address (it can be the same address while you're testing)

<figure><img src="/files/HtBGJkJT83rXMrfG5kWn" alt=""><figcaption><p>Create identity - Email address</p></figcaption></figure>

{% hint style="warning" %}

#### SES Sandbox

New AWS accounts start in **sandbox mode**. While in sandbox mode, both the sender and every recipient must be verified this way before you can email them. If you need to send to addresses you can't verify ahead of time, ask AWS for production access.
{% endhint %}

**2. Set up the Lambda function**

This function reads the scan result and sends the email.

1. Open the **AWS Lambda** console and click **Create function** → **Author from scratch**
2. Give it a name (for example `css-scan-result-notify`), choose the **Python 3.12** runtime, then click **Create function**
3. Delete the placeholder code, paste in the code below, and click **Deploy**

```python
import json, logging, os, boto3

logger = logging.getLogger()
logger.setLevel(logging.INFO)
ses_client = boto3.client("ses")

SENDER_EMAIL = os.environ["SENDER_EMAIL"]
RECIPIENT_EMAILS = [addr.strip() for addr in os.environ["RECIPIENT_EMAIL"].split(",")]

def lambda_handler(event, context):
    for record in event.get("Records", []):
        sns_message = record.get("Sns", {}).get("Message")
        if not sns_message:
            continue
        try:
            scan_result = json.loads(sns_message)
        except json.JSONDecodeError:
            logger.error("Failed to parse SNS message: %s", sns_message)
            continue
        send_scan_result_email(scan_result)

def send_scan_result_email(scan_result):
    file_name = scan_result.get("key", "Unknown")
    timestamp = scan_result.get("dateScanned", "Unknown")
    result = scan_result.get("result", "Unknown")
    color = "#c0392b" if result not in ("Clean", "clean") else "#27ae60"

    html = f"""<html><body style="font-family:Arial,sans-serif;background:#f4f4f4;padding:24px;">
    <table style="max-width:480px;margin:auto;background:#fff;border-radius:8px;border:1px solid #e0e0e0;">
    <tr><td style="background:#2c3e50;padding:16px 24px;">
    <span style="color:#fff;font-size:18px;font-weight:bold;">CloudStorageSec Scan Result</span></td></tr>
    <tr><td style="padding:24px;font-size:14px;color:#333;">
    <p><b>Result:</b> <span style="color:{color};font-weight:bold;">{result}</span></p>
    <p><b>File:</b> {file_name}</p>
    <p><b>Scanned At:</b> {timestamp}</p>
    </td></tr></table></body></html>"""

    ses_client.send_email(
        Source=SENDER_EMAIL,
        Destination={"ToAddresses": RECIPIENT_EMAILS},
        Message={
            "Subject": {"Data": f"CloudStorageSec scan result: {result} - {file_name}", "Charset": "UTF-8"},
            "Body": {"Html": {"Data": html, "Charset": "UTF-8"}},
        },
    )
```

4. Tell the function which email addresses to use, without hard-coding them into the code:
   * On the **Configuration** tab, open **Environment variables** → **Edit**
   * Add `SENDER_EMAIL` (the address you're sending from) and `RECIPIENT_EMAIL` (one or more addresses to send to, separated by commas)
   * Click **Save**
5. Give the function permission to send email through SES:
   * Still on the **Configuration** tab, click the execution role link under **Permissions** - this opens the role in IAM
   * Click **Add permissions** → **Create inline policy** → the **JSON** tab, and paste:

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ses:SendEmail",
            "Resource": "*"
        }
    ]
}
```

* Name the policy (for example `ses-send`) and click **Create policy**

{% hint style="info" %}
`"Resource": "*"` is fine while you're testing. For production use, narrow it down to the specific SES identity ARN(s) you verified in step 1.
{% endhint %}

**3. Connect the Notifications Topic to the Lambda function**

1. Open the **Amazon SNS** console → **Topics** → open `CloudStorageSecNotificationsTopic-<appID>` (see the [manual setup steps above](#manual-setup-email) if you're not sure where to find it)
2. Click **Create subscription**
3. Set **Protocol** to **AWS Lambda** and **Endpoint** to the function you just created
4. Expand **Subscription filter policy** and paste in a filter - for example, this only sends an email when a file comes back infected:

```json
{
    "notificationType": ["scanResult"],
    "scanResult": ["Infected"]
}
```

5. Click **Create subscription**

That's it. Scan a file that matches your filter and the email should arrive within a minute or two.

Here's an example of the email you'll get:

<figure><img src="/files/ERfLfS9blrlOF7C0TXdL" alt=""><figcaption><p>Custom formatted email sent via Lambda + SES</p></figcaption></figure>

</details>

### Sample Messages - JSON

<details>

<summary>Scan Result - Clean</summary>

```json
{
    "Type" : "Notification",
    "MessageId" : "bd433133-294e-52d9-9503-689132de2d6e",
    "TopicArn" : "arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh",
    "Subject" : "AV-for-S3: Clean object found",
    "Message" : "{\"guid\":\"5fe98fc2-685c-4f64-b9a0-8eedea8f42a4\",\"dateScanned\":\"2021-08-26T22:44:32.6856159Z\",\"bucketName\":\"css-protect-versioning\",\"key\":\"PCI Mandate Compliance Report Template_1586376538835.pdf\",\"versionId\":\"k751iw8YoEIGtZReV8JIsopfkjsFZ_Kf\",\"result\":0,\"scanResults\":[{\"result\":\"Clean\",\"virusName\":[],\"message\":[],\"dateScanned\":\"2021-08-26T22:44:32.6856159Z\",\"engine\":\"ClamAV\",\"engineVersion\":\"0.103.3\",\"virusDbVersion\":\"26275\",\"scanType\":\"GoFwd\"},{\"result\":\"Clean\",\"virusName\":[],\"message\":[],\"dateScanned\":\"2021-08-26T22:44:32.6158696Z\",\"engine\":\"Sophos\",\"engineVersion\":\"3.82.1\",\"virusDbVersion\":\"5.86\",\"scanType\":\"GoFwd\"}],\"actionTaken\":\"None\",\"virusUploadedBy\":\"\",\"fileExists\":true,\"movedTo\":\"\",\"region\":\"us-east-1\",\"accountId\":\"<account-number>\",\"allowOnceExemptionAdded\":false,\"permanentlyAllowed\":false}",
    "Timestamp" : "2021-08-26T22:44:32.986Z",
    "SignatureVersion" : "1",
    "Signature" : "vy0J32/9v0w813bdr7soNpn76V3f/AUw5uWwtgNK3k0wP9i7Usa/7atx1aeaLIcWYLe/LEJMfkYnXQTkq/5mjf0N8FJ9jXn9fkdUAGHf5iIovNKluf8xPDs6jrUo7rxg9Leskk2+EeNEi9wtQvXCtWeDEL20QA+1KsqcsQNGKPvUxF/m04BTr/jDO7YHK4FAHOc1DfY546dUA+z+t0DUYvSJqLHsUXQqHEqNpL7WHlzSvxIV+F1T0M525FbcZPZp3iLw5Qc3LlFZp/Yhy3V+2q6+JCJipzgLPGdN45EhwAYpvM5jNvqgjheKdiJkBONFByw1Hn4fIfIqc6olQr7u+w==",
    "SigningCertURL" : "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem",
    "UnsubscribeURL" : "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh:32f7008b-bf69-48c0-84fd-872b708f0037",
    "MessageAttributes" : {
        "bucket" : {"Type":"String","Value":"css-protect-versioning"},
        "accountId" : {"Type":"String","Value":"<account-number>"},
        "notificationType" : {"Type":"String","Value":"scanResult"},
        "scanResult" : {"Type":"String","Value":"Clean"}
    }
}
```

</details>

<details>

<summary>Scan Result - Infected</summary>

```json
{
    "Type" : "Notification",
    "MessageId" : "45927ed5-6884-542e-96c6-27777317db99",
    "TopicArn" : "arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh",
    "Subject" : "AV-for-S3: Infected object found",
    "Message" : "{\"guid\":\"a59f0da2-0fdd-4667-b272-618d79cd520d\",\"dateScanned\":\"2021-08-26T22:44:34.5595461Z\",\"bucketName\":\"css-protect-versioning\",\"key\":\"infected_bill.pdf\",\"versionId\":\"ohjRhn8aiPIjVTU1T6xOKWoJBR8i0v0w\",\"result\":1,\"scanResults\":[{\"result\":\"Infected\",\"virusName\":[\"Win.Ransomware.WannaCry-6313787-0\"],\"message\":[],\"dateScanned\":\"2021-08-26T22:44:34.5595461Z\",\"engine\":\"ClamAV\",\"engineVersion\":\"0.103.3\",\"virusDbVersion\":\"26275\",\"scanType\":\"GoFwd\"},{\"result\":\"Infected\",\"virusName\":[\"Troj/PDFJs-AIA\"],\"message\":[\"infected_bill.pdf\"],\"dateScanned\":\"2021-08-26T22:44:33.3838187Z\",\"engine\":\"Sophos\",\"engineVersion\":\"3.82.1\",\"virusDbVersion\":\"5.86\",\"scanType\":\"GoFwd\"}],\"actionTaken\":\"Move\",\"virusUploadedBy\":\"AWS:AIDA2T7AZ3IMGHBWXMN4W\",\"fileExists\":true,\"movedTo\":\"cloudstoragesecquarantine-pxlhbmh-<account-number>-us-east-1\",\"region\":\"us-east-1\",\"accountId\":\"<account-number>\",\"allowOnceExemptionAdded\":false,\"permanentlyAllowed\":false}",
    "Timestamp" : "2021-08-26T22:44:35.049Z",
    "SignatureVersion" : "1",
    "Signature" : "or+H3m1RpSvHe3GlccGjnckSj13iz+mFYaEMjwKWuE3uFhytHUkc6cIxk4E3lI7GwtOmuxTCQgc9ms7c/yp+487Chh0IM3nLGCD7WWNaW3W/8BnpFg1wkWQoSAPIh4EuhYLEWMzqF1ldENp6SNGZpG60vYyS/vNx9GnA5nrRDwLfQ76HDlRq/PQpbnzBPleaW61TOsRRhKpVpNZ1dKTRECqCtP9Tgno12XURZ8Li4PQP/w3IJ6EPZOKrva7A2vaaOe4hRyx4lWSagHtigqZ9RMIsTBOFXrCwG3iXopUhnylDgtaeODyepXTUEMHzw931hRMmcjGT+h1epJ10mraA8Q==",
    "SigningCertURL" : "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem",
    "UnsubscribeURL" : "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh:32f7008b-bf69-48c0-84fd-872b708f0037",
    "MessageAttributes" : {
        "bucket" : {"Type":"String","Value":"css-protect-versioning"},
        "accountId" : {"Type":"String","Value":"<account-number>"},
        "notificationType" : {"Type":"String","Value":"scanResult"},
        "scanResult" : {"Type":"String","Value":"Infected"}
    }
}
```

</details>

<details>

<summary>Scan Result - Infected with Mixed Result</summary>

```json
{
    "Type" : "Notification",
    "MessageId" : "52e1b014-a19d-5d32-8717-e9b6ba0d2df0",
    "TopicArn" : "arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh",
    "Subject" : "AV-for-S3: Infected object found",
    "Message" : "{\"guid\":\"9c2d3aca-7d9a-4d85-98bb-0954227c851b\",\"dateScanned\":\"2021-08-26T22:44:32.1855327Z\",\"bucketName\":\"css-protect-versioning\",\"key\":\"halock-av.pdf\",\"versionId\":\"cpThl8wDuSj2Ie4_CU0bR_x1ULCIXVhf\",\"result\":1,\"scanResults\":[{\"result\":\"Clean\",\"virusName\":[],\"message\":[],\"dateScanned\":\"2021-08-26T22:44:32.1855327Z\",\"engine\":\"ClamAV\",\"engineVersion\":\"0.103.3\",\"virusDbVersion\":\"26275\",\"scanType\":\"GoFwd\"},{\"result\":\"Infected\",\"virusName\":[\"EICAR-AV-Test\",\"EICAR-AV-Test\"],\"message\":[\"halock-av.pdf\",\"halock-av.pdf\"],\"dateScanned\":\"2021-08-26T22:44:32.1874844Z\",\"engine\":\"Sophos\",\"engineVersion\":\"3.82.1\",\"virusDbVersion\":\"5.86\",\"scanType\":\"GoFwd\"}],\"actionTaken\":\"Move\",\"virusUploadedBy\":\"AWS:AIDA2T7AZ3IMGHBWXMN4W\",\"fileExists\":true,\"movedTo\":\"cloudstoragesecquarantine-pxlhbmh-<account-number>-us-east-1\",\"region\":\"us-east-1\",\"accountId\":\"<account-number>\",\"allowOnceExemptionAdded\":false,\"permanentlyAllowed\":false}",
    "Timestamp" : "2021-08-26T22:44:32.905Z",
    "SignatureVersion" : "1",
    "Signature" : "SNSOWiex1hSWk6ooFjp3TI9OnO2S3LGSDRbUHqR6mzXptAcgiSIpdzKe9hbJZvttx0cNUBP3qajUWpuTPI2Toy0vPYo800HSnXBkW9pI7CIuTW8uVw+dN4OgsJJLN+Fh8LAY2uz1gsrofi7DMMRge9tyaerPIofyLCPTdEghQNpHWomfYF/fI5KLvIEetP5ROqlvL9rmzgvWY8AADKGGy+tki/4itzCfQBjBP5WpsyWWW0kQvw+TCXxZzogc+2h9YzBHKddQCdCUiMZNyiH/mJ+RjWJgfsZYws0MjkUgIb27Nv571TCQNpym3Z8d8ChTv7tb1jepkf5oBWuLph4uqA==",
    "SigningCertURL" : "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem",
    "UnsubscribeURL" : "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh:32f7008b-bf69-48c0-84fd-872b708f0037",
    "MessageAttributes" : {
        "bucket" : {"Type":"String","Value":"css-protect-versioning"},
        "accountId" : {"Type":"String","Value":"<account-number>"},
        "notificationType" : {"Type":"String","Value":"scanResult"},
        "scanResult" : {"Type":"String","Value":"Infected"}
    }
}
```

</details>

<details>

<summary>New Bucket Found</summary>

```json
{
    "Type" : "Notification",
    "MessageId" : "32373388-32b3-5303-a28e-6b3394954bc4",
    "TopicArn" : "arn:aws:sns:us-east-1:<account-number>:CloudStorageSecNotificationsTopic-y6uajej",
    "Subject" : "Discovered 1 new Buckets in Account 'Primary'",
    "Message" : "The following bucket(s) were discovered and are likely unprotected: css-webinar-new-bucket",
    "Timestamp" : "2021-03-05T03:22:14.713Z",
    "SignatureVersion" : "1",
    "Signature" : "UWQDpcdt82PEQw5B95rCh74gau0Nie8PITkDowLveGflTn7/LshJQ/854jL3gNKY9gpHVWh1deSWxHduI773gQdi4AbRMkJ68tum6PDg7/eYjcCS85RiJ4EeK7HH2xEsEdjTBFsXIs9W5rnXcnOB8wweYZ0IdaKrG4npYng0Qhnr6APFwq5uM4RoSOrwBhhS9iF6gHK++Ir8UNotq52K3RRIHBndYMXQIJL9t0vtcHpf3aAYgcjg+/+3PcjOH/fY974i1TD0h/EabmmKgxAnsggQ4rhGEintKrm/6vV1zFfGM+ehlRwRA5WG5KssyBYY2RxMLHbWCpfeakefmU0gjA==",
    "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem",
    "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:<account-number>:CloudStorageSecNotificationsTopic-y6uajej:1c22fb20-0d29-42a9-b7dd-1964d77dd99d",
    "MessageAttributes" : {
        "accountId" : {"Type":"String","Value":"<account-number>"},
        "notificationType" : {"Type":"String","Value":"bucketsDiscovered"}
    }
}
```

</details>

<details>

<summary>Public Bucket Found</summary>

```json
{
    "Type" : "Notification",
    "MessageId" : "861b8ed9-116c-5eef-b906-d662b742f907",
    "TopicArn" : "arn:aws:sns:us-east-1:<account-number>:CloudStorageSecNotificationsTopic-y6uajej",
    "Subject" : "Discovered PUBLIC bucket 'css-demo-eu-north-1' in account 'Primary'",
    "Message" : "The console has discovered bucket 'css-demo-eu-north-1' with public access. ",
    "Timestamp" : "2021-03-05T03:22:22.053Z",
    "SignatureVersion" : "1",
    "Signature" : "b1pYOKS3FJKl3DSelsVoL6ORzcDoPUfuMu72MIrK05sbGZB6eP5xkeZc3QScLSkAMjAzUum5bQAYtq30CbOxgrl9uClvKhvrOwst9Ia0fJ0sCXE4gj59Etnx3j7jrx3x1mR87UhiOjvqNTDJvcJyMKcALCpyf4JUPs7GNzmA5TjMh2xRSsntPuATdMlSlgIi5ApBr4tZUZBAUfxfSI9eGPt9oi44ix0rB8ghlbMNo1ZA5L9ynuC4fyMbPjritTNF7o8hQzQyC4397GC5kBuAn4kdiGMTRLy+UIO/SBGr8iKsb6+3PiUN1g6qyooWilIeAKQ8eJMjo8OVlvLU0+LzVg==",
    "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem",
    "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:<account-number>:CloudStorageSecNotificationsTopic-y6uajej:1c22fb20-0d29-42a9-b7dd-1964d77dd99d",
    "MessageAttributes" : {
        "accountId" : {"Type":"String","Value":"<account-number>"},
        "notificationType" : {"Type":"String","Value":"bucketsPublicAccess"}
    }
}
```

</details>

<details>

<summary>Bucket Protection Turned Off</summary>

```json
{
    "Type" : "Notification",
    "MessageId" : "2c547302-6e33-563d-b986-2aa07c26762a",
    "TopicArn" : "arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh",
    "Subject" : "Protection turned OFF for 1 buckets in account 'Primary'",
    "Message" : "Protection has been turned OFF for the following buckets: css-apsoutheast1-01",
    "Timestamp" : "2021-08-26T22:04:05.844Z",
    "SignatureVersion" : "1",
    "Signature" : "eF0dA/AGVgMp+S85UugidY+9FZ0UryqCGluWRHTtLEHXWM2L+o8AXO+2ipV5u0Jykd9fKEs0SAapDoNAM08X01aakpATR/Bg+1xglY1YGiB4xhhtD64gAGikfYxPDk3BbPS5qamfssXyu8YqJHRpn3xjc+VoYaJajOB1UAm3r0wkcjmapVzEVdvQF8fMx/hfA4sne3IJC5Szm/6g5KTQZ7RYHgrv3O1wB4GPAfNHM061Z5RbdSnKvjuUM8umEfcwOVa40fHIVz68Y1f8lNdPxDWUuY7fQwed8sx8DdRj3iqi1tSbLwYG72JDAiUPDTwEQDPldrQGac17M7aFlms0qA==",
    "SigningCertURL" : "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem",
    "UnsubscribeURL" : "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh:32f7008b-bf69-48c0-84fd-872b708f0037",
    "MessageAttributes" : {
        "accountId" : {"Type":"String","Value":"<account-number>"},
        "notificationType" : {"Type":"String","Value":"bucketProtection"}
    }
}
```

</details>

<details>

<summary>Product Upgrade Available</summary>

```json
{
    "Type" : "Notification",
    "MessageId" : "7b11beaf-0ca6-5c7c-b7d1-e73fbad71b86",
    "TopicArn" : "arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh",
    "Subject" : "Antivirus for Amazon S3 - Update(s) are available",
    "Message" : "Update(s) are available for the Antivirus of Amazon S3 product. Visit the console to apply them from the updates menu in the upper right of the page.",
    "Timestamp" : "2021-08-13T18:04:33.826Z",
    "SignatureVersion" : "1",
    "Signature" : "urNgfMcXt76qCsFrSMMhzeXQ3rEA6I3FYWBw+kOeDLgOdGW1vFcFFgii9XIytsdgI71fnCqkOdPe+sBcx1CpnDmdpG5F8oS6S5+bSVgnwp4f3srpghdR34gSMl8xeWZjqWCjcQd4zlcv7HcT4Jg1l1xDB3xD5KPUBhkEzwuvcQIVtpbXXhOJPbVjbUAMUqaI/lkq0x55Mh2D5ALN+1s9loQOC5R1/z/WFE043S037sQjea72rIs1zRouUUo1u+n4Jqo+GHARX51fJcDArcsEAA5INnxxVB5H6xoMAsYYv2LinpLIYRN8Vk/xlL7lfZXH2bYMsX/dJhlZ8crO1axZDA==",
    "SigningCertURL" : "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem",
    "UnsubscribeURL" : "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:<account-number>:CloudStorageSecNotificationsTopic-pxlhbmh:32f7008b-bf69-48c0-84fd-872b708f0037",
    "MessageAttributes" : {
        "notificationType" : {"Type":"String","Value":"updatesAvailable"}
    }
}
```

</details>

### Email Reports

For customers who want a daily summary of Anti-Virus scanning sent to their inboxes, we offer the ability to send daily email reports detailing recently found threats. We show a brief report including types of problem files found, malware detected, and threats found in the last week.

Enable this feature in the Email Reports tab in the Configuration > Proactive Notifications page. Enter in a comma separated list of email recipients and click 'Save'. Daily Email Reports will now be sent to those addresses.

<figure><img src="/files/lC2NC4XbErDNarIqCdXJ" alt=""><figcaption><p>Configure Email Report</p></figcaption></figure>

Here's an example of a daily Email Report.

<figure><img src="/files/WH1SNkurrXejFxhm8i4i" alt=""><figcaption><p>Email Report</p></figcaption></figure>
{% endtab %}

{% tab title="Classification for Amazon S3" %}

#### Proactive Notifications

![Proactive Notifications Dashboard](/files/QHiHs9ifes1f4DFlal8v)

The Dashboard is a great resource to monitor your environment while you are using the console. For all the times you are not in front of the console, it is critically important you are made aware of any system notifications such as `matching` classification results. Classification Results which could identify classified data is the most critical, but other system messages may be important enough for you to follow as well. The other types of information we notify on is: public / private status of buckets, newly discovered buckets, protection turned on / off for buckets, availability of system updates, trial expiration and low prepaid data counts. With this in mind, a Notifications SNS Topic is provided where Classification for Amazon S3 publishes these useful messages. You can simply subscribe to the Topic with the protocol (HTTP, HTTPS, Email, Email-JSON, Amazon SQS, AWS Lambda, Platform Application Endpoint, SMS) of your choice.

All notification messages we generate will have a `Notification Type` attribute as well as possible secondary attributes. These attributes along with their values can be leveraged for filtering the messages down. Along with the notification type attribute, there are other message attributes such as `classificationResult`, `bucket` and `account`. AWS SNS subscription filtering works in an ***and*** fashion with additional attributes. ***Or*** functionality is supported within attribute values, but as soon as you have more than one attribute those behave as ***and***. This is critical to be aware of as you may add combinations that will never occur and therefore never receive the messages you are expecting.

We have made our wizard so you cannot make these unusable combinations. The filtering that is allowed:

* **NotificationType** - on its own this is the highest level (generic) filter
  * You can get all classsification results by just setting this attribute to `ClassificationResult`, but you may truly not want all classification results, just `matching`
  * Possible values - \[ClassificationResult, BucketsDiscovered, BucketsPublicAccess, LowPrepaidData, TrialExpiring, UpdatesAvailable]
* **ClassificationResult** - allows you to filter by the result itself
  * You can filter by one or more values - \[Matching, NonMatching, Unclassifiable, Error]
* **Buckets** - filter by a particular bucket name
  * Useful if you want different subscriptions/notifications for different buckets to have different outcomes or go to different teams
* **Accounts** - filter by account number
  * For multi-account environments this allows you to filter at the account level
  * Similar to bucket, you could have different processes or teams responsible at the account level and so need separate subscriptions to notify those particular teams

#### Message Types

All possible message information:

<table><thead><tr><th width="200">Key Name</th><th>Description</th></tr></thead><tbody><tr><td>NotificationType</td><td><p>You can get all classification results but just setting this attribute to <code>ClassificationResult</code>, but you may truly not want all classification results, just <code>matching</code><br>Possible values:<br></p><ul><li>BucketsDiscovered</li><li>BucketProtection</li><li>BucketsPublicAccess</li><li>BucketAutoProtectionFailed</li><li>LowPrepaidData</li><li>TrialExpiring</li><li>UpdatesAvailable</li></ul></td></tr><tr><td>ClassificationResult</td><td><p>Secondary attribute to allow filtering by the scan result itself<br>Possible values:<br></p><ul><li>Matching</li><li>NonMatching</li><li>Unclassifiable</li><li>Error</li></ul></td></tr><tr><td>Buckets</td><td>Secondary attribute to provide filtering by bucket name. Useful if you want different subscriptions/notifications for different buckets to have different outcomes or go to different teams. You can provide more than 1 bucket name if desired in a comma separate list.<br><br>Possible values: <code>your_bucket_name(s)</code></td></tr><tr><td>Accounts</td><td>For multi-account environments this allows you to filter at the account level. Similar to bucket, you could have different processes or teams responsible at the account level and so need separate subscriptions to notify those particular teams. Can be used with ClassificationResults, BucketsDiscovered, BucketProtection, BucketCrawling, BucketPublicAccess</td></tr></tbody></table>

**Proper Combinations**

Proper combinations can be:

* **notificationType**,
* **notificationType**\['classficationResult'] + **classificationResult**\['Matching', 'NonMatching', 'Unclassifiable', 'Error'],
  * **notificationType** + **classificationResult** + **bucket**\[' < bucket-name(s) >'],
  * **notificationType** + **classificationResult** + **account**\['< account-number(s) >'],
* **notificationType**\['classificationResult'] + **bucket**\['< bucket-name(s) >'],
* **notificationType**\[any but updatesAvailable|lowPrepaidData|trialExpiring] + **account**\['< account-number(s) >'],

{% hint style="info" %}

#### Example

You may want your Support/IR team to be informed of infected files only so you setup a subscription that filters down to `classsificatonResult = Matching` and gets sent to their emails or distribution list.

While scan results of `Error` and `Unclassifiable` may get filtered down and sent to your infrastructure team since both of those results typically relate to access issues (either KMS related, password protection, file extension reading software, and non-text files)

You may want yet another subscription that either captures all classificationResult messages or just the NonMatching ones so you capture your own audit log of those files. So the endpoint could be an email not responded to or an application that gathers all this data.
{% endhint %}

Here is a sample message so you can see the format that gets sent. More samples for the other notification types below.

```json
2022-05-20 16:08:50.7409|INFO|MatchingClassificationResults|{
    "date": "2022-05-20",
    "guid": "60ea309d-b0f5-4b14-a0a2-76ff49bd210f",
    "dateTime": "2022-05-20T16:08:50.716198Z",
    "accountId": "351727022968",
    "region": "us-east-1",
    "container": "class-trigger-bucket-3",
    "objectPath": "Employee List.xlsx",
    "innerFilePath": null,
    "textMatchingSet": [
        {
            "cclName": "SocialsecuritynumbersUSA",
            "score": 1,
            "triggered": true,
            "matchesCount": 1
        }
    ],
    "error": null,
    "resultType": 1
}
```

Follow the steps below to set up your Topic Subscription utilizing an AWS provided protocol like email.

#### Create Subscription - Email Example

1. Click the `Add Subscription` button

   <figure><img src="/files/j2qs8OOBNJOi0xDq7neg" alt=""><figcaption></figcaption></figure>
2. The `Add Proactive Notifications Subscription` popup will appear

   <figure><img src="/files/AxIVYZsig728dEaHflGv" alt=""><figcaption></figcaption></figure>
3. Specify the `Notification Type` of choice - for our example we will choose `ClassificationResult`

   <figure><img src="/files/n74cikqE4RuH6obR6hZR" alt=""><figcaption><p><mark style="background-color:blue;">Note:</mark> After selecting the <code>Notification Type</code> you will be presented other fields to populate. At a minimum, you must specify a <code>Protocol</code> and <code>Endpoint</code>. The other fields can be populated as described above.</p></figcaption></figure>
4. Choose `Email` as the protocol and enter your email address<br>

   <figure><img src="/files/q798H8lYPQvUw7uFWiBI" alt=""><figcaption><p><mark style="background-color:blue;">Note:</mark> If you left it as seen here, every scan result (clean, infected, unscannable, error and infectedAllowed) would be sent to your email. Generally, you may want to limit down to <code>infected</code> and <code>unscannable</code> to limit the number of emails received. This is up to your requirements, so do as you see fit. As described above, you can filter the results by result, bucket or account and proper combinations of those.</p></figcaption></figure>
5. Specify `Classification Results` values to limit emails sent\
   ![Add Subscription Popup - Limited Results](https://github.com/cloudstoragesec/HelpDocs/blob/main/docs/img/proactive-notifications-addsub-limitedresults-dc.png)
6. Click the `Add Subscription` button

   <figure><img src="/files/25ibico63r8cSlAawEIS" alt=""><figcaption></figcaption></figure>
7. You will now see a new entry in the table list showing as `Pending` under status

   <figure><img src="/files/QHiHs9ifes1f4DFlal8v" alt=""><figcaption></figcaption></figure>
8. Check your email so you can **confirm** the subscription

   <figure><img src="/files/UmIvUza6rqiTDFU1oD2E" alt=""><figcaption></figcaption></figure>
9. Open the email and click the `Confirm subscription` link\
   \
   This action will open a browser window showing subscription confirmation

   <figure><img src="/files/4CogFb74seZhaCFSlfiZ" alt=""><figcaption></figcaption></figure>

   <figure><img src="/files/UWYbqtng06DSpKUFq167" alt=""><figcaption></figcaption></figure>
10. Refresh the page list by clicking the little `Refresh` button and you will see your new subscription confirmed

    <figure><img src="/files/aF6zTyOrIW699gY0gJrK" alt=""><figcaption></figcaption></figure>

You are all set now! Feel free to create more as needed for the different notifications needed.

{% hint style="warning" %}

#### Warning

AWS does not allow the same email address to be used for multiple subscriptions to the same topic. So you can leverage multiple addresses or you can use the "+" option most modern email providers (Gmail, O365, Exchange) support.

For example, instead of using `support@cloudstoragesec.com` as I did in the example steps I could do the following:

* *<support+scanresult@cloudstoragesec.com>* for all scan results
* *<support+updates@cloudstoragesec.com>* for system upgrade updates
* *<support+config@cloudstoragesec.com>* for notifications regarding new buckets or public buckets found
* etc.
  {% endhint %}

If you'd like to perform these steps manually or see what is going on behind the scenes on the AWS side, expand the section below and read on. If the GUI was enough for you, then skip it.

<details>

<summary><strong>Manual Setup - Email</strong></summary>

1. Login to the AWS console and navigate to the region where the console is deployed\
   \&#xNAN;*If you are unsure of which region the console is deployed in, you can view the* [*Console Settings*](/console-overview/configuration/console-settings) *page to find it.*<br>

   <figure><img src="https://help.cloudstoragesec.com/img/notifications-consoleinfo.png" alt=""><figcaption></figcaption></figure>
2. Navigate to the Simple Notification Service (SNS) service\
   \&#xNAN;*You can search for the service or find it under Application Integration*<br>

   <figure><img src="https://help.cloudstoragesec.com/img/notifications-sns-service.png" alt=""><figcaption><p><em>You'll land at the SNS Dashboard. You may have different numbers of existing Topics and Subscriptions</em></p></figcaption></figure>

   <figure><img src="https://help.cloudstoragesec.com/img/notifications-sns-dashboard.png" alt=""><figcaption></figcaption></figure>
3. Click on Topics as indicated above and then click on the Notifications Topic\
   \&#xNAN;*The Topic will be named `CloudStorageSecNotifications-<appID>`. You can find your `appID` in the* [*Console Settings*](/console-overview/configuration/console-settings) *as the value after the `-` of the Service Name.*\
   \&#xNAN;***Note**: I have more than one deployment in my account so I see more than one standard topic and more than one notifications topic.*

   <figure><img src="https://help.cloudstoragesec.com/img/notifications-sns-topic.png" alt=""><figcaption><p><em>You will land on the details page for the Topic</em></p></figcaption></figure>

   <figure><img src="https://help.cloudstoragesec.com/img/notifications-sns-topic-details.png" alt=""><figcaption></figcaption></figure>
4. Click the `Create Subscription` button to be taken to the Create Subscription page

   <figure><img src="https://help.cloudstoragesec.com/img/notifications-sns-sub-create.png" alt=""><figcaption></figcaption></figure>
5. Pick a Protocol of your choice\
   \&#xNAN;*We'll use `Email` for this example*<br>

   <div align="left"><figure><img src="https://help.cloudstoragesec.com/img/notifications-sns-sub-protocol.png" alt=""><figcaption></figcaption></figure></div>
6. Pick a Protocol of your choice\
   \&#xNAN;*We'll use `Email` for this example*<br>

   <figure><img src="https://help.cloudstoragesec.com/img/notifications-sns-sub-email.png" alt=""><figcaption><p><mark style="background-color:blue;"><strong>Note:</strong></mark> You will have to confirm your subscription as AWS indicates. Go to the email address you specified and click the link within it <strong>after</strong> you finish creating the subscription.</p></figcaption></figure>
7. Setup a Filter Policy (optional)\
   \&#xNAN;*You can be done at this point, but without a filter policy you will get notified of every scan result. Look back above for scenarios where filtering makes sense*<br>

   ```json
   {
       "notificationType" : ["classificationResult"],
       "classificationResult" : ["Matching", "Error", "Unclassifiable", "NonMatching"],
       "bucket" : ["your_bucket_name(s)"]
   }
   ```

*

```
<figure><img src="../../.gitbook/assets/Screenshot 2023-01-23 135508.jpg" alt=""><figcaption></figcaption></figure>
```

* 8\. Click the `Create Subscription` button and you are done!\
  \&#xNAN;*Technically, you will now need to go confirm your subscription.*

:pencil2: **Note**

You can copy and paste that JSON directly into the filter and it will work. **Remember** to pick which scan results you are filtering on and remove the others from the list.

*Copy the JSON and paste it into the filter policy JSON editor as seen below and edit as you see fit*

</details>

#### Manage Subscription

Managing an existing subscription is easy. Simply click the action button (![Manage Subscription button](/files/j5s7qefA0AlFzh7WOsyP)) to either `Edit` or `Delete` the subscription. Editing will allow you to make changes as are permitted to the subscription. Deleting will remove the subscription.

<br>

<figure><img src="/files/fDdtZG9xTjwNYU5OrMYv" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/pkRcm4Jc5TSOlSV7xnNR" alt=""><figcaption></figcaption></figure>

#### Sample Email Protocol Messages

Once you have confirmed your subscription as objects get scanned you will see in your Inbox as follows:

![Notifications Email Inbox](/files/JObMkFHDG82PPoeNsZdi)

And here are the details of an email message notification about discovering content in an object that is Matching one searched for by the chosen Classification rules. ![Notifications Email Inbox](/files/bixnDI8QobSwC8yYQ9fJ)

#### Slack Integration Setup

It is a simple process (that may sound more complicated than it is) that took under 10 minutes to setup. Simply follow the process laid out in the AWS blogpost talking about how to leverage webhooks seen here: [AWS SNS + Slack / Teams / Chime setup](https://aws.amazon.com/premiumsupport/knowledge-center/sns-lambda-webhooks-chime-slack-teams/)

What it looks like in Slack. You can modify the format with [Slack Message Layouts](https://api.slack.com/messaging/composing/layouts).

<figure><img src="/files/elK0jPsLI6Y2gZ8MswQS" alt=""><figcaption></figcaption></figure>

<details>

<summary>Sample Messages - JSON</summary>

```json
{ 
    "date": "2022-05-20",
    "guid": "60ea309d-b0f5-4b14-a0a2-76ff49bd210f",
    "dateTime": "2022-05-20T16:08:50.716198Z",
    "accountId": "351727022968",
    "region": "us-east-1",
    "container": "class-trigger-bucket-3", 
    "objectPath": "Employee List.xlsx",
    "innerFilePath": null, 
    "textMatchingSet": 
        [ 
            { 
                 "cclName": "SocialsecuritynumbersUSA",
                 "score": 1,
                 "triggered": true, 
                 "matchesCount": 1 
             }
        ],
    "error": null, 
    "resultType": 1 
       }

```

</details>
{% endtab %}
{% endtabs %}


# License Management

There are three main functions for the License Management page:

1. Monitoring your scanning and classification data usage
2. Applying a pre-paid license file to increase your data beyond our base monthly subscription which you can subscribe to through our PAYG listing in AWS Marketplace
3. Modifying the trial date and trial data cap when an extension is needed

All three of the above functions are tied to each unique Management Console that you deploy and each deployment has a unique Application ID (AppID) displayed on the License Management page. Each AppID allows you to differentiate your deployments apart (should you have more than one).

{% hint style="info" %}
If you are subscribed to our PAYG listing you will always receive 100GB of universal data scanning per month.

Any additional new data usage past your first 100GB each month, is an additional cost on a pay as you go basis, unless you work with our Sales team to purchase a custom license.
{% endhint %}

## Antivirus and Data Classification Metrics

The following metrics are displayed on the License Management page for your deployment:

### Standard GoFwd and Retro Data

Scanning using our solution falls under three categories.

1. New data, which we categorize as GoFwd data
2. Pre-existing data, which we categorize as Retro data
3. Universal data, which covers all engines, GoFwd, and Retro.

These three types of Standard data show up on the License Management page as the following:

* `Standard Prepaid GoFwd Data Remaining`: the balance you have remaining for new data scanned either through event-based scanning or API-based scanning
* `Standard Prepaid Retro Data Remaining`: the balance you have remaining for pre-existing data scanned using scheduled and on-demand Retro scanning
* `Universal Prepaid Data For All Scans Remaining` : the balance you have for remaining universal prepaid data

Standard GoFwd and Retro data applies to each file you are scanning and only includes ClamAV. If you are using Sophos or CSS Premium, usage of one or both of those premium commercial engines will be an additional cost.

{% hint style="info" %}
Note that historically, GoFwd and Retro data were charged at different rates. To reduce complication, we now charge the same amount for GoFwd and Retro data.
{% endhint %}

### Premium Engine Data

Sophos and CSS Premium are our premium commercial engines that we offer. Usage of this engines come at an additional cost and we track the amount of data you have left on the License Management page.

#### Sophos

* `Sophos Prepaid GoFwd Data Remaining`: if you've paid for Sophos engine scanning, this is the amount of data you have left to use with the Sophos engine for event-based and API-based scanning
* `Sophos Prepaid Retro Data Remaining`: if you've paid for Sophos engine scanning, this is the amount of data you have left to use with the Sophos engine for scheduled and on-demand Retro scanning

**CSS Premium**

* `CSS Premium Prepaid GoFwd Data Remaining`: if you've paid for CSS Premium engine scanning, this is the amount of data you have left to use with the CSS Premium engine for event-based and API-based scanning
* `CSS Premium Prepaid Retro Data Remaining`: if you've paid for CSS Premium engine scanning, this is the amount of data you have left to use with the CSS Premium engine for scheduled and on-demand Retro scanning

### Free Trial

When you first subscribe and launch the product through our PAYG or BYOL AWS Marketplace listing you will be operating under a 30 day free trial, which includes up to 100GB of scanning. This will allow you to run the product in a single Management Console across one or multiple regions to perform a thorough test and prep prior to going into production use. You can track the time remaining on your trial here.

<figure><img src="/files/WzFXQzxGXlcn4vTqKwyY" alt=""><figcaption><p>Trial Expiration Warning</p></figcaption></figure>

You will also be notified on the main dashboard view when your trial is within 7 days of expiration or within 20% of your trial data amount.

{% hint style="danger" %}

#### Warning for PAYG and BYOL trial expiration

When you surpass either the expiration date of your trial or the initial 500GB of scanning, you will automatically be subscribed to our base subscription if you are using our PAYG listing.

If you are leveraging the BYOL deployment option, when you're data runs out the product will continue to function and scan for an additional 14 days. When that window comes to a close, the agents will stop running and scanning. Please [Contact Us](/contact-us) to purchase additional data and update your licensing so the product continues to function.
{% endhint %}

{% hint style="info" %}

#### To Extend or Renew Your Free Trial

If you uninstall your deployment and redeploy our solution in the same AWS account, your free trial will no longer be valid.

Whether time ran out and you were unable to do your testing or you have an install that is not communicating with our trial validation process, you can [Contact Us](/contact-us) to have the trial refreshed. When you contact us we'll need the **AppID** found at the top of the License Management page within your Console.
{% endhint %}

The below metrics related to your free trial will be shown on your License Management page:

* `AV 30 Day Free Trial Expiration Date`: The expiration date of your 30 day free trial that you receive when subscribing to our PAYG or BYOL AWS Marketplace listings.
* `AV 30 Day Free Trial Data Remaining`: The amount of data you can scan through event-based, retro-based, and API-based scanning during your free trial. Usually, this amount is up to 100GB of data.

### Data Classification

If you have deployed our Data Classification solution you will also see:

* `Prepaid Classification Data Remaining`: the balance you have remaining for Data Classification.
* You will also see additional Data Classification trial expiration and data remaining values.

## License File History

If you upload a license file that we issue, you will see the details for each license file in this section. The details will include how much data is applied, the date you apply the license file, etc.

<figure><img src="/files/O9HxNy5PYxzdMwmEOsjP" alt=""><figcaption></figcaption></figure>

## Prepaid Data

Should you decide you'd like to pre-purchase a number of gigabytes rather than transact using AWS Marketplace, you can upload a custom license file on your License Management page. You will be able to monitor your current balance at all times by looking at each metric. As files are scanned we will track the number of GBs scanned and decrement your balance. Once you have exhausted the pre-purchased data, we'll start to bill you again through our base subscription/PAYG usage. You are welcome to buy another prepaid bundle at that time as well.

Please [Contact Us](https://help.cloudstoragesec.com/contact-us) to obtain a custom license file.

If you use the BYOL listing you will need to purchase more data to continue scanning as it's not possible for us to transact on a pay as you go basis using that listing.

{% hint style="danger" %}
As mentioned above, if you are leveraging the BYOL deployment option, when you're data runs out the product will continue to function and scan for an additional 14 days. When that window comes to a close, the agents will stop running and scanning. Please [Contact Us](/contact-us) to purchase additional data and update your licensing so the product continues to function.
{% endhint %}

![Low Prepaid Data Warning](/files/ha4VYbFDQWnmIO0l8bP5)

## Uploading and applying your license file

{% hint style="info" %}
If you are only transacting through our PAYG AWS Marketplace listing and do not want to prepay for additional scanning data you do not need a license file.
{% endhint %}

This is a simple process. You'll first [Contact Us](/contact-us) with your `AppID` to request a license file be generated. We'll return a license file to you and you'll drag it into the box that states `Drop your license file here, or click to choose a file`. Done!

## AWS Marketplace Private Offers

If you purchase a custom license we will use an AWS Marketplace Private Offer (MPPO) to set the terms of the purchase and complete the transaction. In order for the transaction to be completed you'll need to accept the MPPO in either the AWS account that you will be deploying our solution in, or from your management/payer AWS account.

If you are accepting the MPPO through a management/payer AWS account, you'll need to grant entitlement of your subscription to the AWS account where you will be deploying the solution.

{% hint style="info" %}
You must have the consolidated billing feature enabled in AWS Organizations to accept the private offer at the management/payer account level.
{% endhint %}

When communicating with our Sales team, please inform your Sales representative if you prefer accepting the MPPO at the production account level where you will deploy our solution or if you prefer accepting the private offer at the management/payer account level.

Once you accept the MPPO we will issue you a license file with the data that you purchased, which you can then upload to your License Management page.

### Accepting an MPPO

1. After you have come to an agreement of the terms of your purchase, your Sales representative will issue you a link that you can use to accept your MPPO
2. You must log into the AWS account you will be using to accept the MPPO and navigate to the AWS Marketplace Subscription manage page
3. You must then click into the link of the Private Offer to view and subscribe to the private offer

We recommend reviewing AWS' documentation that details accepting an MPPO through a seller provided link: <https://docs.aws.amazon.com/marketplace/latest/buyerguide/buyer-private-offers.html#from-a-seller-provided-link>

Once you accept the MPPO, we will receive a notification that your account has accepted the private offer, and we can issue you the license file that you will need to upload to your License Management page.

### Granting entitlement to other accounts in your AWS organization for your AWS Marketplace Subscription

If you prefer to accept the MPPO through the management/payer account, please ensure:

1. You have consolidated billing enabled within AWS Organizations and that the production account is linked to the management/payer account as part of your organization
2. You have set up AWS license manager to grant entitlements to linked accounts before.

{% hint style="info" %}
AWS License Manager will force you to grant entitlement through the `us-east-1` region, however entitlement will apply to all regions within the account you are granting it to.
{% endhint %}

After this, you can accept the MPPO in your management/payer account following the steps in the previous section. Once the MPPO is accepted you'll need to navigate to AWS License Manager using your management/payer account. Once there, you will need to view your granted licenses and grant entitlement to the Private Offer to the member/linked account where our console is deployed.

Once you've granted entitlement through the management/payer account, you must log into AWS Marketplace console of the member/linked account where our console is running.

After that, you must accept and activate the grant.

If you are new to granting entitlement for licenses in AWS we recommend you review the documentation AWS provides here: <https://docs.aws.amazon.com/license-manager/latest/userguide/granted-licenses.html#granted-licenses-views>

Once you accept the MPPO and entitlement is granted, we will receive a notification that your management/payer account has accepted the private offer. We can then issue you the license file that you will need to upload to your License Management page.


# Event Agent Settings

The Event Agent Settings page is used to make modifications to the agent task characteristics. Note that there are now Event Agent settings for AWS and Azure, respectively.

Settings include the CPU, Memory and Disk Size (for the AWS Fargate tasks), the VPC and Subnet(s) as well as the scaling characteristics including Scaling Threshold, Minimum # of Agents and Maximum # of Agents. This is typically used to make modifications to existing running infrastructure, but this page can also be used to `stage` regions in anticipation they will be used. This is useful so not just any user picks the VPCs and Subnets to use, but also to pre-configure regions that may be leveraged with [tag triggered bucket protection](/console-overview/protection/aws/protected-buckets#automating-bucket-protection). You also gain a bit of insight into your overall deployment as each region where scanning agents exist is displayed for Event Agents. You can get more detailed deployment info on the [Deployment Overview page](/console-overview/monitoring/deployment-overview).

![Agent Settings](/files/EVp3nuWzPDQ9IDDDWFrI)

## Deployed Agents

![Deployed Agents](/files/h4SFY5HhG6s0wr7hkyMp)

Displayed to you are any regions where event agents have been deployed. The Event Agents will be one of two colors, green or orange. Green indicates the agents in those regions are running off the default settings. Whereas orange indicates the agents in those regions are running with custom characteristics. This may occur for many reasons, but one simple example is adapting regions for the load they see. US-East-1 may see the brunt of your object handling and so you tune the scaling and up the `Max Agents`, whereas your other regions see much less traffic so you turn on [`Smart Scan`](#smart-scan) for those regions.

To see or manage a specific region's settings, click the pill for the desired region. The pill will fill-in to represent what you are looking at. In the image below, the `eu-west-1` region is selected.<br>

<figure><img src="/files/PtWHuGhq6smk82iyE0fv" alt=""><figcaption><p>Regions with Event Agents</p></figcaption></figure>

{% hint style="info" %}
This does not indicate whether the agents are running or whether any buckets in those regions are being protected. It does indicate that buckets in those given regions were scanned at one point and the agent has been deployed there.
{% endhint %}

## Staged Regions

![Deployed Agents](/files/h4SFY5HhG6s0wr7hkyMp)

The `Regions with Event Agents` (deployed agents as described above) represent regions that have event agent infrastructure in place. The `Staged Regions` represent the `default` settings for all new regions that come online, but also pre-defined regions. Pre-defined regions do not have infrastructure installed, but allow you to pre-define which networking should be used in those regions. Two primary use cases stand out: [automatic bucket protection](/console-overview/configuration/console-settings#automatic-bucket-protection) and allowing admins to determine the network to be used rather than the other users of the system. Automatic bucket protection turns event-based protection on for buckets as they are created or have tags added to them. This could be in any region and may happen in regions that are not already protecting buckets and are therefore not setup. Now you can create the setup ahead of time.

{% hint style="info" %}
Adding a `Staged Region` will not deploy infrastructure to those regions. It only saves the config details to a database table to be used in the event the region is needed.
{% endhint %}

To stage a region:

1. Click the `Add New Region` button ![Add Staged Region](/files/BRXZkGssJUX1nacWVf6c)
2. Select the Region to stage\
   ![Pick Staged Region](/files/FxZYtSkmr4OeYr03X58Y)
3. Select the VPC and at least 2 Subnets for this region\
   ![Set networking Staged Region](/files/tjEfWptEmjaibiEEOBya)
4. Save all the settings by click the `Change Settings` button ![Save staged settings](/files/qy56RNhnVdm8Wapt73JX)

The rest of the settings will be pre-populated from the `default` settings. You are welcome to keep those or make changes as you see fit.

If you need to delete a staged region, click the little red X in the desired region pill. ![Remove Staged Region](https://help-old.cloudstoragesec.com/img/agent-settings-remove-staged.png)

To learn more about the settings continue reading.

## Agent Task Settings

![Agent Setting Fields](/files/6VdzqpS5Qd1vVmjasvqB)

The `Task Settings` apply to the actual AWS Fargate Task (container) running the scanning agents. The default settings within the CloudFormation Template are to run the agents with 1vCPU and 3GB of Memory. This is suitable for all use cases and file types at this time. You also set the values for Scaling Threshold, Min Agents and Max Agents during the CloudFormation Stack creation. Whether you've determined you need to tune regions or reset all regions to new defaults, this section is to allow you to easily modify the running values of each of the scanning agents.

When you first [enable a bucket for protection](/console-overview/protection/aws/protected-buckets#enable-buckets-for-scanning) you are prompted to select a VPC and two Subnets to run the agents in for that region. There may be times you want to change these values after the fact which can easily be done on this page.

| Field             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Select Region     | Click the region pill in the `Regions with Event Agents` area above. The filled in pill is the currently selected field                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Scaling Threshold | This is the value that determines the number of entries in the work queue before a scaling event happens. There are a number of considerations here that can affect what this value should be. Review the [Sizing Discussion](/how-it-works/sizing#so-what-does-this-mean) to get more details on how to think through this                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Min Agents        | The minimum number of scanning agents you'd like running by default or in the given region. This value can be `0`. The scanning agents will not be running, but will scale up based on the Scaling Threshold setting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Max Agents        | The maximum number of scanning agents you would like to possibly scale to. This number can be anything greater or equal to the minimum (except 0).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| CPU               | The amount of vCPU you would like allocated to each agent. Each additional auto-scaled agent would also have this value.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Memory            | The amount of memory you would like allocated to each agent. Each additional auto-scaled agent would also have this value.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Disk Size (GB)    | <p>The amount of disk space assigned to each agent. Each additional auto-scaled agent would also have this value.<br><br>The default value and included in the AWS pricing is 20GB. If all files you will be scanning are under 15GB in size then keep the default. If there are regions or needs to scan files larger than 15GB in size, then increase this to a size larger enough to handle your largest files. 200GB is the current maximum this number can be set to. As a result, the maximum size file that can be scanned through this scanning method is 195GB. If you require the scanning of anything larger than 195GB, please refer to <a href="/pages/EaG45wuCtv8Xui4BTTK5#extra-large-file-scanning">==Extra Large File Scanning==</a> option. You can scan TB(s) sized files.<br><br><strong>NOTE:</strong> There are increased pricing costs for any GB above the 20GB size. Currently, this price per GB per hour is $0.000111, but refer to the <a href="https://aws.amazon.com/fargate/pricing/">AWS Fargate Pricing</a> page to get the latest costs.</p> |

### Agent Memory

The Memory must always be set to a value that is between 2x and 8x of the vCPU. The new minimum memory requirement for agents is 3GB.

#### Examples

```
    vCPU = 1, then 3gb <= memValue <= 8gb  
    vCPU = 2, then 4gb <= memValue <= 16gb
    vCPU = 3, then 6gb <= memValue <= 24gb
    vCPU = 4, then 8gb <= memValue <= 32gb
```

You'll notice a `Public` or `Private` associated with each VPC. This is an indicator of whether or not the VPC is tied to an Internet Gateway. Thought process being that with an IG in place you will have the required outbound access. The console does not require a public IP address or to be accessible from the public in general, but it does require outbound internet access to get to AWS ECR to pull new Task images.

<figure><img src="/files/lNWpHvtWsdEKHVT7F9Db" alt=""><figcaption><p>VPC</p></figcaption></figure>

You'll notice a `Public` or `Restricted` associated with each Subnet. This is an indicator of whether or not the Subnet is outbound routable to the internet. Minimally, the agent task must be able to reach the AWS ECR to pull new Task images and to be able to pull AV signature updates. Two validations are performed for this check. First, we check to see if the NACL associated with the Subnet(s) has outbound open for 0.0.0.0/0. Secondly, we check to see if there is a custom Route Table in place and verify it is routed to an internet gateway.

<figure><img src="/files/8EZBIvzAVIjmTGlJcmFI" alt=""><figcaption><p>Subnets</p></figcaption></figure>

Generally, the first indicator for a good configuration will be whether or not the VPC has an internet gateway or something that is taking its place. Secondly, check the subnets for their outbound access.

{% hint style="danger" %}
Changing these values will cause the agents to reboot.

If the VPC or Subnets are not proper for the agents, you could have trouble with the agents not booting up or entering a constant reboot cycle.
{% endhint %}

## Smart Scan

\
`Smart Scan` is an agent settings configuration that creates infrastructure cost optimizations. The idea behind it was to enable and support the scenario where you didn't want or need a scanning agent running full time in one or all of the regions you were protecting.

<figure><img src="/files/LXmr9R30YSawQNqHi0pb" alt=""><figcaption><p>Smart Scan</p></figcaption></figure>

This is the classic example of run the "server" only when you need it and taking advantage of scaling policies to do just that. `Smart Scan` can be enabled as the global `Default` so each and every region you protect is setup that way or on a one-off basis for each region that requires it.

### Examples of when Smart Scan is useful

* You only get new objects during the work day hours and nothing comes in at night. You can switch `Smart Scan` on and your scanning agents will only run while work is coming in. They may even shut down during stagnant times during the work day as well to add additional savings.
* Another scenario is where you may have one or two really busy regions and would like to have scanning agents running full time, but in other less used regions you want to take advantage of the scan on-demand settings.

This could easily be handled by just modify the scaling policies yourself, but we have simplified it for you with a simple toggle ![Smart Scan Toggle](/files/7OBa5HK8qg96xhCDQU8c). When you toggle on `Smart Scan`, whether as the global default or in an individual region, we automatically adjust the following values:

| Field                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Scaling Threshold           | <p>We set this value to 1 by default which states: any time there is work (at least 1 item in the queue) an agent will be spun up to process that work. While it is up if other work comes in it will continue to run and process all of the items in the queue.<br><br><em>You can set this value to something greater than 1. For example, you don't want a scanning agent to spin up and process the workload until you have a certain amount of work so you set this threshold to 50 or 100. This would indicate you will scan once you have 50 or 100 objects waiting.</em><br><br>This value translates to the LargeQueue CloudWatch Alarm which controls when to spin up scanning agents.</p> |
| Min Agents                  | This value is set to 0 which indicates that the agents can contract back down all the way to no running agents.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Max Agents                  | This value is set to 1, but can be modified to anything greater than 1 as well. This indicates how many agents you would permit to spin up. If you get objects in large sets, it may be useful to have this greater than 1.                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| SmallQueue CloudWatch Alarm | <p>This attribute is not visible on the page. The value for the CloudWatch Alarm that controls the scale down of the tasks will be set to 1. Meaning, whenever the queue is emptied and below 1 to stop by scaling down all tasks.<br><br><strong>Note:</strong><br>If you were to simply change the <code>Min Agents</code> to 0 on this page, it would not change this alarm setting. It would still accomplish a shutdown of all agents, but might have unexpected consequences depending on your <code>Scaling Threshold</code> settings.</p>                                                                                                                                                    |

{% hint style="info" %}
Turning off `Smart Scan` will allow you to go back to modifying all the fields. It also goes back to the default scaling up and down behaviors where both the LargeQueue and SmallQueue scaling threshold are set to the same value which is the `Scaling Threshold` value as you have defined in this page.
{% endhint %}


# Access Management

The Access Management page provides settings for Users, Accounts, and Groups.


# Manage Users

Everything you need to know about managing users within your deployment.

## Overview

A user was initially specified and created during the deployment process. As with any new user, you were required to change your password as you signed in for the first time. The `Manage Users` section of the console is to extend the management of user(s) beyond that initial setup. From the Manage Users page you can create additional users (assuming your user is an `Admin`), delete users and modify users in the form of assigning them to groups and changing their roles.

## Manage Users

Managing users involves creating, modifying, deleting or activating/deactivating their accounts. At the time of creation you will also assign them one or multiple [groups](/console-overview/access-management/group-mgmt) to belong to. You can change the group assignment later as well.

{% hint style="info" %}
You may not be using Groups to organize your accounts. There is always one group created by default, the Primary group. In this situation you would specify Primary as the group value.
{% endhint %}

As seen below you are presented a simple page with the list of existing users. Directly after install you will only have one user in the list that was created during deployment. You can add more users as desired from this page and they will be reflected here as well.

![User List](/files/HAg9CunwDlZkJauoUlnV)

### Create User

Creating a new account is a simple process. Click the `Create User` button.

![Create User Menu](/files/mXRfDlFyoLRKdcPSy1SP)

Provide a `User Name`, a valid `Email Address`, the `User Access Level` and a `Group` to belong to. An email will be sent to the specified email address with a login URL and `Temporary Password`. There are four`User Access Levels`: `Admin`, `User`, `Read Only`, and `API`. The difference being `Admin` has access to all screens and configuration capabilities, while the `User` will not be able to create additional users or modify any of the configuration. `Read Only` users cannot perform actions. They can view pages, metrics, etc. but they cannot protect buckets, make changes, etc. `API` access level allows a user to execute API calls, but not login to the console at all.

{% hint style="info" %}
`User` account types can see all dashboards and buckets and can enable / disable buckets.
{% endhint %}

![Create Account](/files/9qzx3XgmP8AYLCwQZ5Yp)

After creating the new user, they will be in a `pending` state until they have logged in and reset their password. They have 7 days to complete this with the password that was sent to them. After that time period, you will have to delete and recreate the user.

![Create Account Pending](/files/jM1mTk9uKIy6MWAusMGs)

### Modify User

To modify an existing user, select the action menu (![user menu](/files/ncp3jITfhAZNjA8rMJoG)) on the particular user's row. Now select the appropriate action you'd like to take: Change Groups, Change Role, Disable User or Enable API Access. If the user has already been disabled you will be given an option to delete the user.

![Modify User](/files/Ig6HbbkNaXKVPRl74qP0)

#### **Change Groups**

Selecting `Change Groups` pops open the following:<br>

<figure><img src="/files/yUkrdDRAs7MogpDsnQnc" alt=""><figcaption></figcaption></figure>

#### **Change Role**

Selecting `Change Role` pops open the following:<br>

<figure><img src="/files/A9AhDduhfI47iEk8IQg7" alt=""><figcaption></figcaption></figure>

#### **Disable and Delete User**

In order to delete a user, you must disable the user first.

<br>

<figure><img src="/files/au4DZUQNTHmeTFuwOb1i" alt=""><figcaption></figcaption></figure>

<br>

<figure><img src="/files/9b2rnztd4KV1tNjojlUo" alt=""><figcaption></figcaption></figure>

<br>

<figure><img src="/files/cYkw1NiStFIIjFxPfYfX" alt=""><figcaption></figcaption></figure>

#### **Setup for API Scanning Access**

Setting up API Access for a user enables their username and password to be used to send file scan requests against the configured API Agents. You must associate a user to an Account Number track usage. Because API scanning can operate outside the bounds of Amazon S3, we have to fabricate a usage tracking mechanism. So any API file scanning this user does will be tied to the Account Number associated.

To enable a user for API access you select the Actions menu for the user and select `Enable API Access`<br>

<figure><img src="/files/diPnKiIK5YySbaCeHj6D" alt=""><figcaption></figcaption></figure>

You'll be prompted to pick an account to associate to the user and then click the `Enable Access` button<br>

<figure><img src="/files/49EZsfsKAFMUwjPQGffC" alt=""><figcaption></figcaption></figure>

Afterwards you will notice they have an Account Number showing under the API Account column<br>

<figure><img src="/files/ohiptAgikAqYk875rx6L" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you want to create an api-only user without console access, make sure to set the role to `API`
{% endhint %}

For more information on API based file scanning and what APIs are available, check out the [API Scanning Overview](/how-it-works/object-scanning#api-driven-scanning) page.

## Change Password

To change your own password, you will select the user icon ![User icon](/files/BdCmf0qpXm030o3yMCwp) in the upper right corner of the console and select `Change Password` from the menu.

<br>

<figure><img src="/files/5eQaF5efTbf4fwWvLoLn" alt=""><figcaption></figcaption></figure>

\
Just as you did when you first logged into the console, you need to provide your current password and then what you'd like for your new password. Be sure to follow the rules as described at the bottom of the page.

![Password Reset](/files/fUbze11Sb6FtdCxmY5AU)

{% hint style="info" %}
You cannot reset another user's password from the console. Have the user leverage the `Forgot Password` link at the login screen.
{% endhint %}

## Setup MFA

To turn MFA on, you will select the user icon ![User icon](/files/BdCmf0qpXm030o3yMCwp) in the upper right corner of the console and select `Settings` from the menu.

<br>

<figure><img src="/files/qXiIeAhb4SKvwwpKlkiS" alt=""><figcaption></figcaption></figure>

\
You'll be presented your user information overview and the option to enable MFA. Clicking the `Enable...` link will start the process to setup MFA. You can also identify if you have saved the device you are currently accessing from as "remembered" so you do not have to use MFA each time.

<br>

<figure><img src="/files/JCFK2wu3QeavOJc9thia" alt=""><figcaption></figcaption></figure>

Enable MFA Settings:

1. Click `Enable...`
2. Enter your existing password and click `Generate Setup Key`<br>

   <figure><img src="/files/1an5Ylw9GmND7hltQtIq" alt=""><figcaption></figcaption></figure>
3. Use your one time password application of choice to scan the QR code and enter the first one time code and click the `Verify` button<br>

   <figure><img src="/files/I6oKN5994a7FqObHSZnk" alt=""><figcaption></figcaption></figure>
4. On the final screen, click the `Enable MFA` button<br>

   <figure><img src="/files/nSkj31Wx8afwFrAcPALg" alt=""><figcaption></figcaption></figure>

You will now be presented with your user settings showing MFA is enabled.<br>

<figure><img src="/files/gEWPM5GIS01eETnsBlNc" alt=""><figcaption></figcaption></figure>

The next time you login you will be prompted to enter the OTP after the standard username / password login screen. You can choose to save this computer off or not so you have to enter MFA each time you login.<br>

<figure><img src="/files/3hgBL6SbV4NfztAIDX2l" alt=""><figcaption></figcaption></figure>

## Sign out

To sign out of the console, you will select the user icon ![User icon](/files/BdCmf0qpXm030o3yMCwp) in the upper right corner of the console and select `Sign Out` from the menu.

![Signout](/files/40vqeZhCmjuoB3zJJJSd)

## Single Sign-On (SSO)

You can find more information on implementing Single Sign-On (SSO) for your deployment by going to [this FAQ answer](/faq/architecture-related#can-i-leverage-single-sign-on-sso-with-your-product).


# Manage Accounts

There are scenarios where it makes sense to centrally manage your security deployments.

![Linked Accounts](/files/HvFZrtLfdquOuhMYTk06)

Whether you just don't want to manage separate deployments across all of your AWS accounts or you want to follow an [AWS Landing Zone](https://aws.amazon.com/solutions/implementations/aws-landing-zone/) or an [AWS Control Tower](https://aws.amazon.com/controltower/) best practice implementation, the necessity to scan multiple accounts may be one of your requirements.

Cross account scanning is achieved by linking "remote accounts" (non-deployment accounts) through the console and then deploying a cross-account role within each remote account. This is a very simple process which will allow the console to see all of the buckets for the linked account as it would for the deployment account ("primary"). All aspects of management and protection and feedback are the same after these steps have been completed. Both event-based and retro-scanning fully work with linked accounts so you can scan both your go-forward data as well as any existing data. You can link as many accounts as desired.

Accounts can be linked and then added in stages as you want to roll them out. So feel free to link all of your remote accounts and then activate them singularly or in groups. And you can always deactivate / reactivate accounts later on as needed.

The same applies for linking Azure accounts, allowing you to scan Azure Blobs. Click one of the below links to learn more about linking accounts for each cloud provider.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Linking an AWS Account</strong></td><td>Learn more about linking additional AWS accounts and ingesting the associated storage volumes.</td><td></td><td><a href="/pages/fdknvtjW0ifF34NuBlMp">/pages/fdknvtjW0ifF34NuBlMp</a></td></tr><tr><td><strong>Linking an Azure Account</strong></td><td>Learn more about linking Azure accounts and ingesting associated Azure Blobs.</td><td></td><td><a href="/pages/BPS8G4A1XDNtIWSpbIZ5">/pages/BPS8G4A1XDNtIWSpbIZ5</a></td></tr><tr><td><strong>Linking a GCP Account</strong></td><td>Learn more about linking GCP accounts and ingesting associated GCP Buckets.</td><td></td><td><a href="/pages/0iGIwFTENsQdkKOFR7dN">/pages/0iGIwFTENsQdkKOFR7dN</a></td></tr></tbody></table>


# Linking an AWS Account

You can link additional AWS accounts in one deployment of your AV console.

## Linking Accounts

The Manage Accounts page can look as follows. The deployment account for your Management Console is labeled as `Primary` by default. Like any account though, that is a nickname and can be replaced if you see fit to be more meaningful.

![Initial Linked Accounts](/files/Rk7OAbn2mumRxfFE7g5F)

You can link another AWS account by clicking the `Link Another Account` button and filling in the `Account Number`, the `Nickname` and specifying which [group](/console-overview/access-management/group-mgmt) the account will belong to. Then click the `Link Account` button. If you'd like to link more at this same time, click the `Link Another Account` button within the popup and repeat the process of entering the account number, nickname and group.

![Linked Accounts Popup](/files/mA8FByi8JGIqWGgj12fF)

{% hint style="info" %}
You may not be using Groups to organize your accounts. There is always one group created by default, the Primary group. In this situation you would specify Primary as the group value.
{% endhint %}

## Deploying the Cross Account Role

After you click the `Link Account` button, the fields will be replaced with a link to directly launch the CloudFormation Template to create the cross-account role. If you do not wish to launch the stack at this time, you can do so later, but will need the values presented to manually enter into the Stack Launch.

![Linked Accounts Stack Message](/files/UGQETajdF6on7WzkGaiO)

You will now see the newly added account listed in the account list. Note the Primary account reflects a bucket count and ProdAcct shows N/A. Once you run the cross-account CloudFormation Template you can mark the account as active. The Console will attempt to assume the role and you will either get a message indicating the role might still need to be created or the account will be marked as active and a bucket count will be reflected. You will know it worked when you see that number populated.

![Linked Accounts Multiple](/files/AeExJaAD8FQ6liHV4p4R)

If the role cannot be assumed during activation, you will see the following message:\
![Linked Accounts No Role](/files/okYdeugvwVVqzIqdwaUv)

All actions are taken on individual accounts via the actions menu ellipses. You can launch the stack, change groups, activate the account and delete the account.

![Linked Accounts Action Menu](/files/DX6QHuehSOQNSSeS6rOo)

After clicking `Launch Stack` you will be directed to the AWS Console and right into the Stack creation wizard. If you are not already logged into the AWS Console, you will be prompted to login. Provide the credentials to the remote account you are linking. Then, just tick the box and click create.

![Linked Accounts Stack Create](/files/XD8XbV5qb57rWxS1PqTH)

Once the role is created head back to the Antivirus for Amazon S3 console and mark the account active from the action ellipses button. If you see the bucket count update you can feel confident the role is working appropriately. When you select to activate an account, you will see the button turn into a "spinner" while it is working.

Once complete the account will be shown as active and a bucket count provided.

![Linked Accounts new account](/files/ufneIiTAIeCM6wDcV8uw)

At this time, the [Bucket Protection page](/console-overview/protection/aws/protected-buckets) will reflect the new buckets found and distinguish them from the primary account by nickname.

![Linked Accounts Bucket Protection](/files/Dnlj1CbDgS9O1foN0PMK)

{% hint style="info" %}
All active accounts will be reflected throughout the rest of the console. All buckets from all accounts and all scan statuses will be shown. If you later deactivate a remote account (or even the primary) those buckets will not be reflected in the `Bucket Protection` page, but the data scanned is still counted in metrics and any "problem files" found will be reflected on the `Problem Files` page. Deactivating will also remove all event configuration from each bucket in the remote account.

Deleting an account will remove the account from the `Linked Accounts` pages. All data scanned within that account will still be reflected in the metrics and billing.

[Group](/console-overview/access-management/group-mgmt#filter-console-view-by-group) functionality can also impact what you see from the linked accounts throughout the console.
{% endhint %}

## Linked Account Role Version Management

<figure><img src="/files/DDLZcnmmJmQq54hnyAPU" alt=""><figcaption></figcaption></figure>

Simplified Linked Account Role management was introduced starting with Console version 5.08.000 and Linked Account Role version 1.06.000. With both of those versions (or greater) in place, you can simply upgrade a single account, multiple accounts or all accounts to the latest Linked Account Role. This removes the need to go to each and every linked account to do a Stack Update on the CloudFormation stack that initially created the role.

You can tell which account(s) are behind in their linked account role with both the version number in the `CFT Version` column and the red dot that shows there is an update available. You can upgrade one or multiple or all of the accounts very easily.

For a single account, you can simply click the row's action button and select `Update Stack`

<figure><img src="/files/Nks8LxEeQgnzC50kC8eZ" alt=""><figcaption></figcaption></figure>

For a multiple accounts, you can tick multiple checkboxes and select the top level Action menu and click the `Update Stacks` choice

<figure><img src="/files/vImCnQU7pYLeSObjvOC4" alt=""><figcaption></figcaption></figure>

In addition, we when check for product updates we are also checking for Linked Account Role updates which will now be reflected on the overall Updates Menu. Clicking this option will update all accounts that are available to be updated. If you want to roll updates out, then use the above on the Manage Accounts page.<br>

<figure><img src="/files/T1guqZKCbiRmqVG5oe1k" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you are still on a role version below 1.06, then you will have to upgrade all the linked accounts manually one last time.
{% endhint %}

{% hint style="danger" %}
We have programmed the Console to look for the default Linked Account Role CloudFormation Stack name, `CloudStorageSec-AV-for-S3-Linked-Account`, in the same AWS Region the Console is deployed in (but inside the linked account). If you changed the name of the Stack or deployed it in an alternate region, then you will have to update the values on the Manage Accounts page in order for this to work.

<img src="/files/CTN0ivBAKK8Sv8oMxOpp" alt="" data-size="original">
{% endhint %}

## Role Issues

If the role is deleted or changed in such a way in the linked account that the console can no longer assume it, the scanning agents will not be able to retrieve the objects and those objects will be reflected as `Error` files in the `Problem Files` page. The linked account buckets will still show on the `Bucket Protection` page and the events will continue to be pushed to the queue, but we will continue to error out in processing those files until the role is fixed.

![Linked Accounts Role Issue](/files/KIf6Xp6CgPTsz32Jvtw3)


# Linking an Azure Account

Linking an Azure account to ingest Blobs is similar to linking an AWS account.

There are two ways to link an Azure Account: Via Terraform or via Bicep. We recommend deployment via our Terraform Template. This guide presupposes the following:

* The Azure CLI is installed with the correct credentials
* The CSS Application has been installed
* The Azure Console is accessible

## Deploying Via Terraform

You'll need to perform the following steps to link an Azure account with Terraform:

1. Download the required Terraform template [here](https://css-cft.s3.amazonaws.com/Azure/LinkAzureAccountTerraformDev.zip)
2. Modify the 'main.tf' file to add your CSS Application ID
3. Fill in optional variables
4. Run the Template
5. Test the credentials in the CSS Console
6. Link the account

### Download the Terraform Template

1. In your CSS Console, navigate to Access Management > Manage Accounts > Link Account > Link Azure Account. You should see a page like this.<br>

   <figure><img src="/files/udmetx5LsQ7sEhYDVAxF" alt=""><figcaption></figcaption></figure>
2. Download the template file located under point 1 in the instructions.
3. Capture the `css_application_id` located under point 2 in the instructions for the next step.
4. Leave this page open, we will be filling out the form with Terraform output variables after deploying.

### Modify the main.tf file

1. Unzip the file downloaded from the previous step and open the files in the text editor of your choice.
2. Locate and open the `main.tf` file. Under the `css_application_id parameter`, enter in the value captured from the last section.

<figure><img src="/files/6Hysm6WapxrveD32V19e" alt=""><figcaption></figcaption></figure>

### Fill in optional Terraform variables

There are 3 main ways you can modify the Terraform files to configure the deployment to your specific needs.

1. Deployment Location: by default, the deployment stands up resources in region `eastus`. That can be modified in the terraform.tf file. Change the `default` value to the region of your choice.\
   \
   `variable "location" {`\
   `description = "The location of the resources created for the Project"`\
   `type = string`\
   `default = "eastus"`\
   `}`
2. Terraform Backend: by default, the backend is the machine that is running Terraform apply. The backend can be changed by adding a `backend` block. Read more from Terraform's documentation [here](https://developer.hashicorp.com/terraform/language/backend).
3. Tenant ID: by default, the tenant ID is set by the user making the Terraform calls. The AZ CLI detects the default subscription and tenant, which can be modified in the command line. If desired, the tenant ID can also be set in terraform.tf in the `provider "azuread"{}` block.

### Initiate and Deploy the Terraform stack

1. Login to the Azure CLI with `az login` and select the subscription and tenant of choice.
2. Run `terraform init`
3. Run `terraform validate` to validate there are no syntax errors
4. Run `terraform plan` to get an idea of what resources might deploy
5. Run `terraform apply` and enter in `yes` when Terraform asks you if you want to perform the above actions.
6. After deployment, run terraform output -json to access all the output variables. Capture the entire output in brackets for the next step\ <br>

   <figure><img src="/files/G82v6RcrxKtHrHBtlSf3" alt=""><figcaption></figcaption></figure>

### Input Terraform output variables into the CSS Console

1. Insert the paste the entire output captured in the previous step into the 'Terraform Output' field. The values should automatically populate. If not, manually enter in the values.

<figure><img src="/files/1cTiBFIccxitKrlRomD9" alt=""><figcaption></figcaption></figure>

2. Select the Group or Groups which this linked account should belong to.
3. Click 'Test Credentials' to confirm they are valid. If successful, you will see a string saying '`The provided credentials are valid!`'
4. Select '`Link Account`'. Congratulations, you have now linked your Azure account through Terraform!

## Deploying Via Bicep

The below video details how you can link in your Azure account to scan files stored in your Azure Blobs using the Bicep Template:

{% embed url="<https://www.youtube.com/watch?v=4XRUBAhVptQ>" %}

You can also follow the steps and information below:

You'll need to perform the following steps to link an Azure account and begin scanning your Azure Blobs:

1. Create a new user managed identity in the Azure portal
2. Assign the new identity permissions to create an Application Registration
3. Run our CSS Bicep Template
4. Link the account

## Create a new user managed identity in the Azure Portal

1. Navigate to Azure Portal ([portal.azure.com](http://portal.azure.com/)) and login
2. Create a Resource Group for Service Principal

   1. Go to Resource Group
   2. Add New
   3. Add a Resource Group Name (name it whatever you'd like)
   4. Click Create

   <figure><img src="/files/H9daJA8q9ndBsYe21Omp" alt=""><figcaption></figcaption></figure>
3. Create Managed Identity for Service Principal

   1. Navigate to the newly created resource group
   2. Click +Create
   3. Search for `Managed Identity` in Marketplace
   4. Find `User Assigned Managed Identity`

   <br>

   <figure><img src="/files/SHQ3ycLtGTd7NAV70E0l" alt=""><figcaption><p><br></p></figcaption></figure>
4. Click Create
   1. Add Name (name it whatever you'd like)
   2. Click Create

<figure><img src="/files/AHuwGtnRP4Kkxjhf9hiq" alt=""><figcaption></figcaption></figure>

## Assign the new identity permissions to create an Application Registration

First make sure to copy your Resource ID.

1. Go to the Resource Group created above
   1. Click Overview
   2. Select the created Managed Identity from Step 3
   3. Click the JSON View link in the top-right
   4. Copy the full Resource Id from the JSON View
2. Add Application Administrator permissions
   1. In new browser tab navigate to Entra ID
   2. Open the Manage menu on the left
   3. Select Roles and Administrators
   4. Find Application Administrator Role and click on it
   5. Click +Add Assignments
   6. Search and select the created Managed Identity and add it

{% hint style="info" %}
You will have to enter the name of the Managed Identity in the search bar.
{% endhint %}

## Run the CSS Bicep template

For this part we recommend using VS Code to edit and run your Bicep template.

1. Download the provided .zip file [here](https://css-cft.s3.amazonaws.com/Azure/LinkAzureAccountBicepTemplate.zip) and extract it
2. Open the Deployment.bicepparam file in your editor of choice
3. Update the following parameters:

* `Location` - (region) in which the LinkedAccount resources should be created (e.g. *eastus*)
* `CSS App Id` - your deployment's application ID
* `userManagedIdentityId` - ID of the user managed identity created earlier

After that, Save your changes, go to your terminal and login using `az login` and run the following command:

```
az stack sub create --name <your_stack_name> -l <location (e.g. eastus)> --template-file AzureLinkedAccount.bicep --parameters Deployment.bicepparam --deny-settings-mode none --action-on-unmanage deleteAll
```

## Link the Account

Enter the following parameters of the link account Bicep template output from the above command:

* Tenant ID
* Subscription ID
* App Registration Client ID
* App Registration Secret

{% hint style="info" %}
Optionally, enter a nickname for this account (i.e. "Testing"). If you do not enter one, it will be set to the Subscription ID.
{% endhint %}

<figure><img src="/files/sZce9jT4kxytIm5nWUt9" alt=""><figcaption></figcaption></figure>

Click the "Test Credentials" button. If the credentials are invalid, check the values entered and correct them. Then, test the credentials again.

Finally, click the "Link Account" button.

## Check that your Blobs are being ingested into your Management Console

Navigate to Protection > Azure > Blob Containers and verify we have ingested your Azure Blobs.

<figure><img src="/files/2rJUlMXI7kSIFUgcdBUe" alt=""><figcaption></figcaption></figure>

After this you're ready to start protecting your Azure Blobs.


# Linking a GCP Account

Linking a GCP account to ingest objects is similar to linking an AWS account.

The below video details how you can link in your Google Cloud account to scan files stored in your Google Cloud Storage Buckets:

{% embed url="<https://www.youtube.com/watch?v=lyzcu-CHoEk>" %}

You can also follow the steps and information below:

You'll need to perform the following steps to link a GCP account and begin scanning your objects:

1. Fill out GCP account details in the CSS Console
2. Download a Terraform file generated by the Console
3. Modify the values and run the Terraform file
4. Place the resulting output files from Terraform into the Console

## Prerequisites

* gcloud cli

Terraform utilizes the gcloud cli under the hood to stand up infrastructure. Ensure you have the gcloud cli downloaded.

Here's documentation from Google to get the cli: <https://cloud.google.com/sdk/docs/install>

## Download and unzip the Terraform Module

Click this link to download our GCP Terraform Module: <https://css-cft.s3.amazonaws.com/Gcp/LinkGcpAccountTerraformTemplateProd.zip>

Unzip the files in the directory of your choice.

<figure><img src="/files/1TJYF18nqv7QCzdqHZOy" alt=""><figcaption><p>Unzipped Module</p></figcaption></figure>

## Fill out the 'Link Google Cloud Platform' form in the CSS Console

1. In the CSS Console, navigate to Access Management > Manage Accounts
2. Select Link Account > Link GCP Account
3. Fill out the form

You will be asked to fill out 4 values:

* GCP Organization ID: the ID of the Organization you want to protect objects in.
* GCP Billing Account ID: the Billing Account you want to send infrastructure charges to.
* Nickname (Optional): the Project Name for the stack that will be created.
* GCP Project IDs to Protect: projects **within the organization** that you would like to protect.

<figure><img src="/files/aviR6K9hPpKaRoe4Yvnq" alt=""><figcaption><p>GCP Link Form</p></figcaption></figure>

4. Download the main.tf file

Click the 'Download main.tf file' button. You'll download a Terraform file generated by our Console.

5. Replace the default main.tf file with the new one

In your downloaded GCP module provided by CSS, replace the existing main.tf file with the new one you just downloaded.

## Initialize the gcloud cli and run Terraform

1. Using a terminal in the same location as the CSS GCP module:

`gcloud auth application-default login`

Authenticate and allow the Google Auth Library.

2. Initialize Terraform with `terraform init`

You should see the following output.

<figure><img src="/files/dIkgpDOaoXY9FRbOYz7K" alt=""><figcaption><p>Terraform Init</p></figcaption></figure>

3. validate Terraform with `terraform validate`

You should see the following output.

<figure><img src="/files/6P9eEf5Nyhv6Su7RBq7e" alt=""><figcaption><p>Terraform Validate</p></figcaption></figure>

4. apply Terraform with `terraform apply`

and answer with 'yes' when asked if you want to perform the actions of adding resources.

## Apply Terraform Outputs to CSS Console

After Terraform has applied, there are 3 module outputs that you must transfer to the CSS Console:

* Audience
* Project\_id
* Service\_Account\_Impersonation\_url

You will see these in the output of your terminal.

<figure><img src="/files/Ob0grehlN0cQHpGOTlCd" alt=""><figcaption></figcaption></figure>

1. For each key, copy the value and paste them in the corresponding section of your CSS Console.

<figure><img src="/files/EqqrGN85sERvh51XuAFp" alt=""><figcaption><p>Console Module Entry</p></figcaption></figure>

2. For Groups, choose groups to assign your linked accounts to. For access to all, select Primary.
3. Click 'Test Credentials' to validate that your credentials are good to go.
4. Click 'Link Account'.

Congratulations, you have successfully linked GCP Buckets! You can begin scanning your buckets at Protection > GCP in the CSS Console.


# Linking AWS Organizations

You can leverage AWS Organizations to automatically configure linked accounts.

## Overview

We offer the ability to automatically discover and link all accounts in AWS Organizations to the CSS Application. In practical terms, once this feature is configured, it'll automatically perform the [Linking an AWS Account](/console-overview/access-management/linked-accounts/linking-an-aws-account) function.

To do so we deploy the following pieces into the Organizations Management Account:

1. CloudFormation Stack to allow Console to interact with the Management Account
2. CloudFormation StackSet to deploy our linked stack into all accounts within the Organization

<figure><img src="/files/sDLuB1PwIwMiYuoGeQz5" alt=""><figcaption></figcaption></figure>

## Linking Organizations

To link your AWS Organization, go to `Manage Accounts` and choose the option to link an Organization. This opens the `Link AWS Organization for Automatic Account Discovery` popup.

<figure><img src="/files/n9mtwsZiHTXuf2yr5MHr" alt=""><figcaption></figcaption></figure>

1. Deploy the Organizations CloudFormation Template in your AWS Organizations management account by clicking `Launch Stack in AWS`, or click `Download Template` if you'd rather deploy it yourself.
2. Once the stack deployment completes, enter the `Management Account ID` where you deployed the template.
3. Optionally give the Organization a `Nickname`.
4. Select the `Default Group` where discovered accounts should be added.
5. Leave `Mirror OU structure as groups` checked if you'd like groups automatically created to match your AWS OU hierarchy - this is recommended.
6. Leave `Auto-activate discovered accounts` checked if you want newly discovered accounts to be automatically activated once their linked account stack is deployed.
7. Click `Link Organization` to complete the setup.

{% hint style="info" %}
Once linked, any new account added to the Organization will automatically be discovered and go through the same [Linking an AWS Account](/console-overview/access-management/linked-accounts/linking-an-aws-account) process without manual intervention.
{% endhint %}


# Manage Groups

You are able to separate users and accounts to specific groups.

## Overview

Groups are a mechanism to organize [Linked Accounts](/console-overview/access-management/linked-accounts) into a structure that makes sense for your organization. This could be by department, division or team. The group structure (picture it as a directory structure) is something you create that works specifically for you. Groups allow you to create a logical separation between linked accounts and the users who have access to them. Groups impact all aspects of the console (dashboard views, bucket lists, problem files) in the form of a filter. If you are at the top level group, `Primary`, then you will see an aggregate of all groups within the console. If you switch to a sub-group, the console will only reflect data for those linked accounts in that group and any sub-groups (if they exist) of that group.

In this model, Antivirus for Amazon S3 users can be tied to a specific group to limit their scope to that group and any down-line groups. Access to down-line groups is always inherited. A user placed in `Primary` will have access to all groups as that is the top-level group. A user placed in Primary-->Customers-->CompanyA will have access to CompanyA group resources as well as any group resources below that, but will see nothing and have no awareness of the other company groups listed directly under Customers.

![Groups Management](/files/TX7BmiIXjzm6DpBhLF23)

{% hint style="info" %}
Leveraging groups is not required for successful use of the product. If you have no need for groups, you can skip this section and operate as is.
{% endhint %}

## Managing Groups

Navigate to group management with the left navigation menus: `Access Management --> Manage Groups`. After the initial install of the product or after an upgrade from a pre-group deployment, there will be one group present by default called Primary. This is the root of the group tree structure.

If you have linked accounts or additional users you will see all of them as shown below because they all initially belong to Primary. Accounts linked after groups are in place will be asked for where they should be located.

All actions taken will be against the current group you are in. If you are in Primary and select `Create Group` then you will be create a sub-group inside of Primary. If you want to then create a sub-group of the sub-group, you have to click the sub-group to enter into it and then click `Create Group` again.

{% hint style="success" %}

#### Tip

Best practice is to create the groups needed first, then create the users and link the accounts that tie to those groups. You can create users and link accounts before creating the groups, but they have to reside inside a group, which would be the Primary group. This may temporarily not create the effect you were looking for.
{% endhint %}

![Groups Management Initial](/files/414q75nXt39X8HIjUTl7)

### Create New Group

From the Manage Groups page, select the `Actions` menu button and choose `Create Group`.

<figure><img src="/files/SuNWEfSyBHOI8SEgJxSk" alt=""><figcaption><p>Dropdown to create group</p></figcaption></figure>

You will be presented with the following screen where you can enter the new group name, assign existing users, assign existing accounts and assign existing groups. The latter three fields are optional so you can leave them blank.

![Groups Management Create Group](/files/eqUKJz72HgQIKy4KomeB)

Your Manage Groups page should now look as follows:

<figure><img src="/files/CkzPXo1gIfKFBQOpqeVO" alt=""><figcaption><p>Groups page with new group added</p></figcaption></figure>

{% hint style="info" %}

#### Note

The top left-most part of the menu bar is where the Group Picker (![Group Picker](/files/5Nkztxnr23BiBBvRaqGj)) is located. This will be leveraged to switch between groups. The picker will not be presented when there is only one group, the Primary group. Only after a second group has been created will it be available.
{% endhint %}

Repeat this process to create sibling groups to Engineering or child groups. Here is what it would look like with two additional child groups added to Engineering: Dev and Test.\
**Note:** I clicked into the Engineering sub-group before creating the two new groups.

<figure><img src="/files/AgSncrlyPakKMRhU5pQx" alt=""><figcaption><p>Grops page showing the Engineering sub-group selected</p></figcaption></figure>

{% hint style="info" %}
You can navigate your way down the tree by clicking into the groups within the table. You can walk your way back up the tree by utilizing the bread crumb trail (shown below) to go up levels. You can move up a single level or however many levels up that are needed.

<img src="/files/crdMovSgHoohQTMiS2Nz" alt="" data-size="original">
{% endhint %}

Here is what the Engineering line item looks like now:

<figure><img src="/files/BC1vXaCfAZldfunf9Dnk" alt=""><figcaption><p>Engineering group with 2 sub-groups</p></figcaption></figure>

When you add accounts and users they will be reflected on this line as well. Groups, users and linked accounts can be at any level of depth below this group and they will roll up to a single aggregate to give you an understanding of what exists in the group.

### Assigning Accounts

Linked accounts can be assigned to a group from within the group page here on Manage Groups or from the Manage Accounts page. When assigning an account from the Manage Groups page, you are adding an existing linked account to the group you are within. This does not `move` the account to this group, but rather add it to this group while leaving it associated with whichever group(s) it was already in. If you want the account to only be available from within the group selected, then you need to do that from the Manage Accounts page. The Manage Accounts page will allow you to assign it to a new group and remove the existing groups.

This behavior may be seen if you have linked the accounts prior to groups existing. You may have the linked accounts sitting in the Primary group because you did that operation first. So you assign it to the new group and then end up removing it from the Primary group.

{% hint style="info" %}

#### Note

If you do not have any linked accounts, navigate to the Manage Accounts page to first link accounts. From there, you can assign the accounts as they are being created or come back and follow along below.
{% endhint %}

#### **From Manage Groups**

Navigate to the group you'd like to add an account to by clicking through the groups listed on the page: Engineering --> Dev.

<figure><img src="/files/fNHMF3ZSLPkjxOjgWZVv" alt=""><figcaption></figcaption></figure>

You will see a popup that allows you to pick an account from your linked accounts list. You can choose more than one by clicking into the field to see the drop down list of accounts again.

<div align="left"><figure><img src="/files/dgWmqdlfYXfWm0jZAdXO" alt=""><figcaption></figcaption></figure></div>

Select the account(s) desired and click the `Assign Accounts` button.\
You will now see the following:

<figure><img src="/files/GaLo6vjdXC3sFS5fdILr" alt=""><figcaption></figcaption></figure>

Continue this process until you have all your linked accounts assigned to the groups of your choice.

<div align="left"><figure><img src="/files/pyBuWAJ3zKG1DrU09s2L" alt=""><figcaption></figcaption></figure></div>

Up one more level the Engineering row now looks like this:

<figure><img src="/files/hLfTNxMNa1JhLjXxqqK4" alt=""><figcaption></figcaption></figure>

That's it! You have now segmented 2 of your linked accounts into unique groups within the product. You can now more easily breakdown the usage between the accounts and the scan results. You can also nail product users down to each group, but that is unnecessary to see the value of groups themselves.

#### **From Manage Accounts**

Navigate to Manage Accounts by selecting `Access Management --> Manage Accounts` along the left navigation. This will land you on the `Linked Accounts` page as seen below.

![Linked Accounts page](/files/YC3hAvp8fgDBNpGm5aAC)

Notice the two accounts that were added to groups, DevAcct and TestAcct, now show 2 in the Groups column. This is because we just added them each to a new group we created, but also because they were a part of the Primary group already. You can easily modify which groups accounts are a part of by clicking the action menu on each group row and selecting `Change Groups`.

<figure><img src="/files/K8JonMwZAE3hWIUocod3" alt=""><figcaption></figcaption></figure>

This will pop open the following screen where you can simply `X` a group away or associate more groups to this account.

<div align="left"><figure><img src="/files/dA2Aql517e5W09tmowSF" alt=""><figcaption></figcaption></figure></div>

Remove groups or add more groups, click the `Assign Groups` button then you will see the linked account line updated to reflect. Here is how it looks after removing Primary from the associated groups.

<figure><img src="/files/WK0hAGASjHJFuIFLZXdm" alt=""><figcaption></figcaption></figure>

You can also assign groups at the time you initially link the account. A new field has been added to the Link Account screen to associate the new account to a group(s).

<figure><img src="/files/UbNnDfRjRoWDlz7eQupS" alt=""><figcaption></figcaption></figure>

### Assigning Users

Assigning users is much like assigning accounts as seen above in that you can do it from the Manage Groups page or alternately on the Manage Users page. The same implications of where you do it hold true for users in regards to the user being a part of multiple groups if assigning on the Manage Groups page.

#### **From Manage Groups**

Navigate into the group you'd like to assign the user to by clicking the group names in the list until you see group you are assigning to in the crumb trail.

<figure><img src="/files/GaLo6vjdXC3sFS5fdILr" alt=""><figcaption></figcaption></figure>

Now click the `Actions` menu button and select `Assign Users` to see the following popup.

<div align="left"><figure><img src="/files/dBNXOxWogZv2wzFeRmxu" alt=""><figcaption></figcaption></figure></div>

Click the `Assign Users` button and the user will be associated to the group and the view will be udpated.<br>

<figure><img src="/files/yTW50kcxoH0QEXXdF3EH" alt=""><figcaption></figcaption></figure>

#### **From Manage Users**

Assigning users can also be done from the Manage Users page. Navigate to that page by select `Access Management --> Manager Users` from the left navigation. This will land you on the Manage Users page as seen below.<br>

<figure><img src="/files/dvllep19p8pv6PqwRMfk" alt=""><figcaption></figcaption></figure>

Notice the user, dev-admin, we associated with the `Dev` group shows 2 in the Groups column. This is because we just added this user to a new group, but also because they were a part of the Primary group already. You can easily modify which groups users belong to by clicking the action menu on the user row and selecting `Change Groups`.

<figure><img src="/files/GkMmWueIdb6NNjpFFrs5" alt=""><figcaption></figcaption></figure>

This will pop open the following screen where you can simply `X` a group away or associate more groups to this user.

<div align="left"><figure><img src="/files/gCLBrSmiJrOEUp9R2zwC" alt=""><figcaption></figcaption></figure></div>

Remove groups or add more groups, click the `Assign Groups` button then you will see the linked account line updated to reflect. Here is how it looks after removing Primary from the associated groups.<br>

<figure><img src="/files/9vbVxgLh1J8htz7M4XUr" alt=""><figcaption></figcaption></figure>

You can also assign groups at the time you initially create a new user. A new field has been added to the Create User screen to associate the new user to a group(s).

<div align="left"><figure><img src="/files/fNKUJORfD3HOqW1xqIzK" alt=""><figcaption></figcaption></figure></div>

### Delete Groups

There may be times when you no longer need a group that was previously created. From the Manage Groups page you can "simply" select the group row action menu and click `Delete Group`.

<figure><img src="/files/beplO5ccpMgj1OWsHYPC" alt=""><figcaption></figcaption></figure>

The current caveat to this is the group must be completely empty before you can delete it. So you will have to ensure all of the children, however many generations down, are cleared out before the group can be deleted. If children still exist anywhere down the line, you will see a message as follows.

<div align="left"><figure><img src="/files/LRnxhucr19YlWZ9qxrMT" alt=""><figcaption></figcaption></figure></div>

Simply traverse you way down the tree and remove / delete users, linked accounts and other groups.

{% hint style="info" %}
If you want to keep particular users, linked accounts or groups move them to another location that you deem appropriate.
{% endhint %}

{% hint style="danger" %}
If a user, linked account or group is only a part of the particular group you are deleting, then those items will be truly deleted from the console **(like no longer exist deleted)**.

If a user, linked account or group is a part of another group, then they will simply be removed from the group you are deleting and **NOT** removed from the system.
{% endhint %}

## Filter Console View by Group

With more than one group in place, the Group Picker (![Group Picker](/files/5Nkztxnr23BiBBvRaqGj)) will be made available in the left-most portion of the top menu bar.

<figure><img src="/files/NIVStLg6q8R3vcQeDxaE" alt=""><figcaption></figcaption></figure>

To filter down into a group, simply click on the Group Picker to get to the Group Picker popup.

<div align="left"><figure><img src="/files/LjdPsW2vJONPo0bZmI6m" alt=""><figcaption></figcaption></figure></div>

Select the group you would like to filter to by click the circle next to the group name and then clicking `Set Group`. Click the group name to navigate further down the tree structure. If the group name is a link, then it has children. If it is not a link, there is no further down to go. Below I've navigated down Primary --> Engineering to see the two groups that reside inside the Engineering group. Note that neither is a link so this is the bottom of the tree structure.

<div align="left"><figure><img src="/files/G84JoPdZkqP7HRRPJpOp" alt=""><figcaption></figcaption></figure></div>

You can navigate back up the tree by selecting groups within the group bread crumb trail.

### Bucket List Filtering in Action

Let's look at this in action. There are 3 accounts within the system with different numbers of S3 buckets in them as seen below.

<figure><img src="/files/WLcX3weKz89hNnbFYxWo" alt=""><figcaption></figcaption></figure>

Therefore, we can easily see the filtering in action on the Bucket Protection page. Navigating to this page in the Primary group, which is the top level group containing all other groups, we should see an aggregate count of the buckets we saw on the Linked Accounts page (49+5+1=55 buckets). We should also see all 3 account represented in the bucket list.

<figure><img src="/files/9Hrjj9CoV6CsFnlP6Bqu" alt=""><figcaption></figcaption></figure>

Switching the selected group to `Dev` will take us down to 1 bucket.

<figure><img src="/files/qeuRxpfCm4DI1RyV1MqD" alt=""><figcaption></figcaption></figure>

Switching the selected group to `Test` will take us to 5 buckets.

<figure><img src="/files/hl8MOJ6dQx68RGDeZe21" alt=""><figcaption></figcaption></figure>

Switching the selected group to `Engineering`, the parent of both Dev and Test, will take us to 6 buckets.

<figure><img src="/files/DubFolQPCpeKJZzulVq5" alt=""><figcaption></figcaption></figure>

Groups create a logical separation between linked accounts. You can have one or many (or none if just parent node) linked accounts in a group and the filtering will break down an aggregate of all accounts. This applies system wide including the Dashboard, Problem Files and Bucket Protection pages (as seen above).

### Dashboard Filtering Example

{% tabs %}
{% tab title="Primary - total aggregate" %}

<figure><img src="/files/xq2CnQGSPZAcsB7NS9WL" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Dev sub-group" %}

<figure><img src="/files/wc44DVmcpXsj2duHJ1At" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Test sub-group" %}

<figure><img src="/files/xdoYXFufRQwIZz5N4Ahd" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Engineering parent group" %}

<figure><img src="/files/HJPVhJcp7tWkku6Xy5L3" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}


# Support

The Support page provides a quick checklist on getting started, ways to contact us, and links to our documentation (you are here now!).


# Getting Started

The Getting Started page provides a 6 item checklist for getting started with the product.

## Protect Your Cloud

This section provides four steps to get started with CSS.

1. Links to our Help Docs on getting started
2. Protecting storage containers with AV or classification
3. Links to our Help Docs on notes for each page of the console (you're here now!)
4. Links to our Help Docs on subdomain management

<figure><img src="/files/VuFD8hZ5lqJYmPY9sYvl" alt=""><figcaption></figcaption></figure>

## Stay Connected

The Stay Connected page will allow us to contact you when there are updates or changes to the product.

<figure><img src="/files/ZWgKD2fwqNRrOVDnFF86" alt=""><figcaption></figcaption></figure>

## Email Reports

For customers who want a daily summary of Anti-Virus scanning sent to their inboxes, we offer the ability to send daily email reports detailing recently found threats. We show a brief report including types of problem files found, malware detected, and threats found in the last week.

Enable this feature in the Email Reports tab in the Configuration > Proactive Notifications page. Enter in a comma separated list of email recipients and click 'Save'. Daily Email Reports will now be sent to those addresses.

<figure><img src="/files/AcDolgG06uGQv5yFC3V3" alt=""><figcaption></figcaption></figure>

Here's an example of a daily Email Report.

<figure><img src="/files/o6oYSdmwxvyAYwdB9B6y" alt=""><figcaption></figcaption></figure>

## AWS Monthly Budget Alert

This section provides a setting that notifies email addresses of your choice when the infrastructure costs incurred by the CSS application reach 50%, 75%, and 100% of a budget threshold that you set.

Set up the Budget Configuration with your budget name, email list, and threshold. We'll notify you when each threshold is met.

<figure><img src="/files/kMd00BU6C7RZktTHmwzX" alt=""><figcaption></figcaption></figure>

## Proactive Notifications

This section will recommend 3 types of Proactive Notifications to set:

1. Trial Expiration Date
2. Low Prepaid Data
3. Problematic Files

For a more comprehensive list of Proactive Notifications to set, navigate to Configuration > [Proactive Notifications](/console-overview/configuration/proactive-notifications).

## Proactive Notifications

This section provides a brief reminder for scanning charges.

<figure><img src="/files/i3HN9gYWcF9ASuEQZ8ZO" alt=""><figcaption></figcaption></figure>


# Stay Connected

The Stay Connected page will allow us to contact you when there are updates or changes to the product.

<figure><img src="/files/2Y7mmcv2nncMbcwlTK0a" alt=""><figcaption></figcaption></figure>


# Contact Us

The Contact Us page will forward you to our Help Docs, which will detail ways to reach our team.

<figure><img src="/files/GqeYFQeIe7K6JAIupfbm" alt=""><figcaption></figcaption></figure>


# Documentation

The Documentation page will lead you to our Help Docs, which is where you are at right now.

<figure><img src="/files/AL67tkZCeHt5d6nSIenv" alt=""><figcaption></figcaption></figure>


# Product Updates

Updating your console and agent is straightforward and easy to do.

{% hint style="danger" %}
\*\***IMPORTANT\*\***

**Please upgrade your Linked Account Roles to v1.14.001 or later BEFORE upgrading your console/agent to v8.**

If you do not upgrade your Linked Account Roles then you could experience problems when using EventBridge. [Click here](#linked-account-role-updates) to learn more about Linked Account Updates.

**Please also note, you'll also need to upgrade your console/agent to the** [**latest current version**](/trouble-shooting/error-when-upgrading-to-the-latest-major-version) **you're currently on before you can upgrade to the next major version.**

For example, if you are on v6, you'll need to upgrade to the latest version of v6, then upgrade to the latest of v7, then finally upgrade to v8.
{% endhint %}

## Types of Updates

There are 3 updates you could face: Major, Console Minor and Patch, and Agent Minor and Patch. All are performed from the top right corner of the console from the following icon: ![](/files/h0PxLijkd6cjjbs3y74R)

Notice the **red dot** as that is the indicator you have some form of update available. We are following the `Major.Minor.Patch` versioning number format. All updates are preformed through the simple click of a button in the Updates popup.

> `Major` updates are a larger update that forces both the console and the agent to update. The console and agent can be updated independently, but they can never deviate from having the same Major version number.

> `Minor` updates are those where we may have added new functionality. This applies to the console and the agents.

> `Patch` updates are those where we have mainly added bug fixes to the release. This applies to the console and the agents.

## Performing Updates

When you click any of the update buttons within the Updates popup, we will roll out a new Task Definition(s) pointing at the new version of the specified component. Major forces both the console and agents to update together. Console-only or Agent-only updates will just update that one component. This will span all regions you have agents running.

{% hint style="info" %}
When updating the `Scanning Agents` it will update all agents running globally.
{% endhint %}

{% hint style="warning" %}
AWS Fargate does not persist IPs across task refreshes or reboots. Therefore a new IP is always generated. We provide a dedicated `subdomain` URL to abstract this from you so you have a consistent access experience. You can leave this URL as the default that was provided or you can [specify a more useful name](/console-overview/configuration/console-settings#subdomain-management) that is easier to remember.
{% endhint %}

![Updates Popup](/files/vf4xtcH05RnPmYdaayhg)

You will see the following messages, or something similar, during the update:

<figure><img src="/files/So3AshBNMXhZh4eAMZe0" alt=""><figcaption><p>a popup showing 'Update has been started. Please wait for the update to complete...'</p></figcaption></figure>

Once the update is complete the popup will show `No Available Updates`:

<figure><img src="/files/I6XekiKwUSP1ILvPTXaa" alt=""><figcaption><p>the updates banner underneath the cloud icon showing 'No updates available'</p></figcaption></figure>

## Console Updates

Console updates are delivered via a CloudFormation Stack update. We automate this for you by executing the stack update against the stack used to create the current running deployment. If you'd like to better understand the specifics of what was updated, you will be able to see this in the CloudFormation Service area of the AWS Console as seen below. In the image below, you'll see the initial installation was done on 6/18 and then an update was performed on 07/09 along with each component that was involved in the update.

![Stack Updates](/files/k86GhT5EHhw7EeoJsBGO)

## Agent Updates

Whereas the Console updates are performed through a CloudFormation update, agent updates are done through the Console itself.

## Linked Account Role Updates

Linking AWS Accounts into the console is done by deploying a cross-account role CloudFormation stack in each account. Updates do come out for this role to provide the functionality to keep your data safe. This stack needs to be updated which can also be triggered from this updates menu. Clicking this option will attempt to update every linked account's role. If you'd like to roll the updates out in stages for your linked accounts, then perform the updates on a smaller scale on the Manage Accounts page. For more information on this, please refer to the [Managed Accounts](/console-overview/access-management/linked-accounts#role-version-management) page.

![Linked Accounts Role Top Updates Menu](/files/T1guqZKCbiRmqVG5oe1k)


# How It Works


# Scanning Overview

Learn more about our scan models and how object flow works for each type of scanning.

## Object Flow

There are a number of ways for objects to be placed into buckets including:

* Direct upload
* CLI
* Through applications providing interfaces and workflows with employees, customers, partners, etc.

However the objects arrive, Cloud Storage Security sees and deliver on three main interaction mechanisms with those objects:

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Event Driven Scanning</strong></td><td>For new files uploaded to a storage volume</td><td></td><td><a href="/pages/T1WuNLlcrPfhK7GEqxEH">/pages/T1WuNLlcrPfhK7GEqxEH</a></td></tr><tr><td><strong>Retro Scanning</strong></td><td>Via on-demand and/or scheduled requests for pre-existing files</td><td></td><td><a href="/pages/3OaQryec70w7bZrz2px4">/pages/3OaQryec70w7bZrz2px4</a></td></tr><tr><td><strong>API Driven Scanning</strong></td><td>Using a REST API interface</td><td></td><td><a href="/pages/QA5WjvMHq5gezSwVxaBp">/pages/QA5WjvMHq5gezSwVxaBp</a></td></tr></tbody></table>


# Event Driven Scanning for New Files

`Event driven` scanning is where an event, in this case the `All object create event`, is leveraged on the bucket so any time an object is created/modified within the bucket an event is raised. **Antivirus for Amazon S3** places and event destination / handler onto the protected buckets which listen for these events to trigger scanning. This allows `Antivirus for Amazon S3` to easily plugin to any existing workflow you have without modifications.

So this looks as follows:

1. An object is added to a protected bucket
2. An event is raised and sent to an SNS Topic
3. The Antivirus for Amazon S3 provides an SQS Queue which subscribes to the Topic
4. One or more `Antivirus for Amazon S3 Agents` are monitoring the queue
5. Entries are pulled from the queue identifying the object to scan. The object is retrieved and scanned
6. Objects are handled according to the [Scan Settings](/console-overview/configuration/scan-settings) you have set\
   a. All objects are tagged\
   b. Infected files are moved to a quarantine bucket (default behavior)

{% hint style="info" %}
This flow and behavior is irrespective of region. Amazon S3 buckets have a global view, but are regionally placed. This flow will be performed local to each region you enable buckets for scanning.
{% endhint %}

## Object Tagging

After a file has been scanned we will tag the object in the S3 bucket. These tags are how our solution recognizes whether we've previously scanned the file. If an object is tagged and is copied to another protected bucket, our solution will skip over scanning the object.

Here are examples of object tags based on scan results:

{% tabs %}
{% tab title="Clean" %}

<figure><img src="/files/2PMRWm5NIaLpAj0ovJxJ" alt=""><figcaption><p>Clean Object</p></figcaption></figure>
{% endtab %}

{% tab title="Infected" %}

<figure><img src="/files/y3T27vcJDVjXN0B9nT2W" alt=""><figcaption><p>Infected Object</p></figcaption></figure>
{% endtab %}

{% tab title="Unscannable" %}

<figure><img src="/files/4wFK3wc8lvh8gT6oJTXs" alt=""><figcaption><p>Unscannable Object</p></figcaption></figure>
{% endtab %}

{% tab title="Error" %}

<figure><img src="/files/BMHk598CBKUt2ilkZqfy" alt=""><figcaption><p>Error Object</p></figcaption></figure>
{% endtab %}
{% endtabs %}

## Document Flows

### Standard Document Flow

When a bucket is protected and event listener (SNS Topic) is added to the bucket. This will send S3 Events to the topic which in turn populates an SQS Queue. From there, everything is scanned in near real-time.<br>

<figure><img src="/files/sEemGMtwH5BvzB3BCiSu" alt=""><figcaption><p>Standard Document Flow</p></figcaption></figure>

1. Users or apps upload objects to an S3 bucket protected by our solution.
2. The S3 bucket has an event listener which pushes a notification to Amazon SNS. SNS pushes a message to an Amazon SQS Queue.
3. Our Event Agent monitors this queue for objects and will copy the object into itself, performing a scan of the object.
4. The Event Agent will tag the object with its verdict.
5. The Event Agent will send scan results to Amazon CloudWatch.
6. The Event Agent will send problematic scan results to the Console service for surfacing.
7. (If Proactive Notifications are configured) The Event Agent will forward scan results to Amazon SNS.
8. (Optional) The Event Agent will move infected files into a Quarantine S3 Bucket

### 2 Bucket (Two Bucket) System Document Flow

The Two Bucket System (2 Bucket System) allows a customer to physically separate the incoming files from the downstream users of the "production buckets". The separation lasts as long as it takes to scan the files and ensure they are clean. In this way, you can ensure nothing other than clean files makes it into your production buckets and therefore are safe to be consumed.

We have 2 options for a 2 bucket flow: Console approach and Lambda Approach.

The Console approach can be configured in the Console and moves files tagged as Clean to a designated destination bucket. This option is straightforward but cannot be tweaked for additional configurations.

Some customers opt to put a Lambda function into place for more granular control over objects. Moving multiple types of files or moving files to more than one bucket are common use cases for those who opt to utilize a Lambda instead of our console-managed two bucket functionality.

\
For guided steps on how to setup the 2 Bucket System [go here](/faq/architecture-related#can-i-setup-a-staging-bucket-for-all-of-my-files-to-first-land-in-and-then-move-them-to-a-production)

{% tabs %}
{% tab title="2 Bucket Flow: Console Approach" %}

<figure><img src="/files/1QYIAjIFs43S3hQkoiex" alt=""><figcaption><p>2 Bucket Console Flow</p></figcaption></figure>

1. Users or apps upload objects to an S3 bucket protected by our solution.
2. The S3 bucket has an event listener which pushes a notification to Amazon SNS. SNS pushes a message to an Amazon SQS Queue.
3. Our Event Agent monitors this queue for objects and will copy the object into itself, performing a scan of the object.
4. The Event Agent will tag the object with its verdict.
5. The Event Agent will send scan results to Amazon CloudWatch.
6. The Event Agent will send problematic scan results to the Console service for surfacing.
7. If the Event Agent deems an object as Clean, it will move that object from the staging S3 bucket into the destination S3 bucket.
8. (If Proactive Notifications are configured) The Event Agent will forward scan results to Amazon SNS.
9. (Optional) The Event Agent will move infected files into a Quarantine S3 Bucket.
   {% endtab %}

{% tab title="2 Bucket Flow: Lambda Approach" %}

<figure><img src="/files/T5BKbjjQswI5X2ykhBV2" alt=""><figcaption><p>2 Bucket Lambda Flow</p></figcaption></figure>

1. Users or apps upload objects to an S3 bucket protected by our solution.
2. The S3 bucket has an event listener which pushes a notification to Amazon SNS. SNS pushes a message to an Amazon SQS Queue.
3. Our Event Agent monitors this queue for objects and will copy the object into itself, performing a scan of the object.
4. The Event Agent will tag the object with its verdict.
5. The Event Agent will send scan results to Amazon CloudWatch.
6. The Event Agent will send problematic scan results to the Console service for surfacing.
7. SNS Can be configured to notify Lambda for Clean objects.
8. The Lambda function can then perform an S3 mv from source to destination buckets.
9. (If Proactive Notifications are configured) The Event Agent will forward scan results to Amazon SNS.
10. (Optional) The Event Agent will move infected files into a Quarantine S3 Bucket.
    {% endtab %}
    {% endtabs %}

## Storage Gateway Configuration

If you use Storage Gateway for S3 File Gateway, you will need some additional configurations to ensure Event-Based scanning works properly.

EventBridge and Event Notifications are insufficient to notify our application when files are uploaded because Storage Gateway utilizes multipart uploads. As per [AWS documentation](https://aws.amazon.com/blogs/storage/processing-file-upload-notifications-from-aws-storage-gateway-on-amazon-s3/):

> While [Amazon S3 event notifications](https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) are a great feature for many use cases, we do not recommend using them to notify you of file uploads to Amazon S3 via a File Gateway. When a File Gateway is required to prioritize cache usage, partial file uploads may temporarily occur to Amazon S3. While the File Gateway eventually fully uploads the files as part of this process, Amazon S3 event notifications still triggers upload notifications in the interim.

Storage Gateway offers its own notification system that must be enabled via the CLI. The following section will describe what needs to be done in order to enable Storage Gateway for S3 File Gateway scanning.

#### Prerequisites

1. Storage Gateway set up
2. File Share set up and pointing to an S3 bucket in the same region
3. CSS Console deployed ([How to Deploy](/getting-started/how-to-deploy))
4. AWS CLI is accessible with StorageGateway permissions

#### Overview

1. Enable Storage Gateway Notifications through the CLI
2. Set up an EventBridge rule to capture events and forward to CSS SNS Topic
3. Ensure SNS Topic Access policy allows EventBridge to publish events
4. Protect a bucket in File Share's region

#### Steps

1. **Enable Storage Gateway Notifications through the CLI**

At this time, it's only possible to enable Storage Gateway notifications through the CLI. In AWS, navigate to Storage Gateway > File Shares. Locate your file share and determine whether it is NFS or SMB. In the example provided below, the type is NFS.

<figure><img src="/files/gBxCktYO30cLt2W1fTSf" alt=""><figcaption></figcaption></figure>

Click into your File Share and copy the ARN. You will need to run an AWS CLI command to enable Storage Gateway upload notifications, and that command will change depending on your File Share type. Be sure to substitute {file-share-arn} for your file share's ARN.

**If your File Share is NFS:**

```
aws storagegateway update-nfs-file-share --file-share-arn "{file-share-arn}" --notification-policy '{"Upload": {"SettlingTimeInSeconds": 60}}'
```

**If your File Share is SMB:**

```
aws storagegateway update-smb-file-share --file-share-arn "{file-share-arn}" --notification-policy '{"Upload": {"SettlingTimeInSeconds": 60}}'
```

If performed successfully, the output will look like so:

```
{ "FileShareARN": "{file-share-arn}" }
```

2. **Set up an EventBridge rule to capture events and forward to SNS**

Storage Gateway will send notifications to the Default Event Bus for the region where it resides in. In EventBridge, we must create an EventBridge rule that captures Storage Gateway notifications and forwards it to the CSS SNS topic.

* Go to EventBridge > Event Buses > default
* Select 'Create Rule'

<figure><img src="/files/WvqoGrW2u5V5gkDao9vU" alt=""><figcaption></figcaption></figure>

* Set 'Triggering Events' as 'Storage Gateway Object Upload Event' and 'Storage Gateway File Upload Event'.
* Set 'Targets' as 'CloudStorageSecTopic-{your\_app\_id}'.

<figure><img src="/files/PU0VW02fN1yEbsMmwB3y" alt=""><figcaption></figcaption></figure>

3. **Allow EventBridge to publish to CSS SNS Topic**

* Navigate to SNS > CloudStorageSecTopic-{your\_app\_id} and select Access policy
* Modify the policy to allow events.amazonaws.com to sns:Publish to the SNS topic. Below is a sample Access policy, substitute bracketed values for your own.

```
{
  "Version": "2008-10-17",
  "Id": "css-sns-s3-eb-publish",
  "Statement": [
    {
      "Sid": "AllowBuckets",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "events.amazonaws.com",
          "s3.amazonaws.com"
        ]
      },
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:us-west-2:{account_id}:CloudStorageSecTopic-{your_appid}",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "{account_id}"
        }
      }
    }
  ]
}

```

4. **Protect bucket in Storage Gateway Region**

In order for the Event Agent to scan files, it must be running. For now, the best way to do this is protect an unused bucket with Event Protection. If buckets are already protected in this region, there is no need to protect additional buckets. **Do not protect the Storage Gateway Bucket**, the configuration set up above will handle notifications.

After this configuration, try uploading files via Storage Gateway. Files should be scanned and tagged with our solution.


# Retro Scanning for Pre-Existing Files

`Retro Scanning` is the scanning of existing objects. Whether you want to scan all your existing data the first time you setup the product or you have compliance requirements that dictate a regular cadence of data scanning, Retro Scanning will allow you to scan and re-scan your existing S3 objects. Unlike `event driven scanning` which looks at all "new" objects coming into buckets and has scanning triggered by events, `retro scanning` leverages S3 crawling to determine the work set. If it is the first time you are enabling a bucket for event scanning, you'll be prompted to scan existing data which will automatically default to a time window of the beginning of time (March 14, 2006) through the current time. We won't continue past the current time of activation as event scanning will take care of everything going forward. The default time window can be changed. If you are triggering retro scanning without a bucket activation, you will be prompted to pick a time slice for scanning. This can still be `all time` or a window of time of your choosing.

It looks as follows:

1. You have existing objects within your AWS account(s)
2. Via the console, you trigger a scan for existing objects (on-demand or through a schedule). This can be all objects within the bucket(s) or a subset based on a time window.
3. The Antivirus for Amazon S3 spins up a Fargate Run Task(s) for each on-demand request or schedule that will trigger the crawling process which will crawl all objects within the bucket(s) and add entries to a temporary Retro SQS Queue uniquely made for the job

   Amazon S3 doesn't allow for simple searching and segmenting of the objects to process so all objects must be crawled. Only the objects that match the time window will be added to the queue for processing. If you have 1 million objects in a bucket and the time window dictates such that only 50,000 are processed, all 1 million will be crawled, but only the 50,000 will be scanned.

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>Antivirus for Amazon S3 will spin up a number of Run Task scanning agents with the notion to complete the work in ~1 hour. Depending on the volume (# of buckets, # of objects, size of buckets) related to the job this could be a "lot" of agents. Ultimately, this has no affect on the cost as running 1 agent for 100 hours to complete the job is the same cost as running 100 agents for 1 hour to complete the job.</p><p>You may face service quota limits when running big jobs or multiple jobs at the same time. The default value for the number of these tasks is 1000 in most accounts. If it was needed to go beyond 1000 the process will not stop or break, it will just take longer than it would if you could spin more tasks up. If you know your loads will typically require more tasks beyond that, you can make a request to AWS to increase your limits.</p></div>
4. Once crawling has completed for a job, a new set of Fargate Run Tasks are spun up to perform the scanning. `Antivirus for Amazon S3` will automatically spin up the number of scanning agents to complete the scan.

   The `retro agents` are the same agent as the `event agents`, but run in as Fargate Run Tasks. These agents will destroy themselves when the job has completed.
5. Entries are pulled from the queue identifying the object to scan. The object is retrieved and scanned

<figure><img src="/files/UV2Z5UhzPoHCsM4Rrt4B" alt=""><figcaption></figcaption></figure>

### On-Demand Scanning

On-Demand Scanning is a user initiated scan from within the management console GUI. Triggered from the [Bucket Protection page](/console-overview/protection/aws/protected-buckets#scan-existing-objects), a user can on a one-off basis select one or many buckets and a time window to scan objects. This scan will be treated and tracked as a "job" on the [Jobs page](/console-overview/monitoring/jobs) under the Monitoring section of the console.

### Scheduled Scanning

Scheduled Scanning allows you to process new files or existing files based on a schedule. Instead of processing new files as they come in, your workflow may allow them to be scanned once per day. For compliance reasons you may be required to scan all of your files on a quarterly basis and Scheduled Scanning will allow you to do that. Learn more about [schedule based scanning](/console-overview/scheduled-scans). Scheduled scans will be treated and tracked as a "job" on the [Jobs page](/console-overview/monitoring/jobs) under the Monitoring section of the console.


# API Driven Scanning

You can programmatically implement antivirus scans and data classification in your application.

API driven scanning is the notion of scanning a file and receiving the verdict before it is written anywhere. We see this when your workflow demands a verdict at the time of uploaded. We often hear from customers that they want the file scanned before it resides in Amazon S3. Or they may have aspects of their workflow such that they just need an API driven verdict engine and Amazon S3 may not be in play at all. This is often necessary in applications where users are waiting to be told the upload was successful and the file accepted. APIs allow the application to make a direct handoff of the file to the scanning agent.

Ultimately, API driven scanning provides an API Endpoint verdict engine that can be used inside or out of AWS. You can send files to scan from on-prem or applications residing within AWS or from anywhere you grant access. The API scanning agents sit behind an AWS Load Balancer. You can make the Load Balancer `internet-facing` or `internal` depending on your requirements. Learn more about configuring and managing the API endpoint on the [API Agent Settings page](/console-overview/configuration/api-agent-settings).

### **Setup**

1. Create a user for API use - [How to](/console-overview/access-management/user-mgmt#setup-for-api-scanning-access)
2. Setup and configure API Agent Region - [How to](/console-overview/configuration/api-agent-settings)
3. Integrate HTTP Post calls into your applications - explore samples below

You can use the programming language of your choice as we only require you to leverage HTTP Post to submit the file for scanning. Below are very simple examples of how to submit a file and the results you will see back.

Please note that you can use Sophos, CSS Premium, or ClamAV for API driven scanning. If you are using ClamAV you can only scan files up to 2GB in size. If you need to scan a file larger than 2GB using API driven scanning, you must select either Sophos or CSS Premium

### **Steps to making the API call:**

1. Make request for Auth Token\
   a. Specify content type of JSON in headers\
   b. Capture username and password in JSON\
   c. HTTP Post the data block and headers to \<baseURL> + **/api/Token**

   ```python
   headers = {'Content-type': 'application/json'}
   json_foo: {"username": "<username here>", "password": "<pw here>"}
   r = session.post("https://<baseURL to load balancer or friendly URL>/api/Token", data=json_foo, headers=headers)
   ```

   This will return the following response text:

   ```json
   {
       "accessToken":"eyJraWQiOiI0Qk41QU1yVXdhWUUrZlBUZ0dhQTZWQUNXUmREMmh2dlMxWFgrUmNmTzd3PSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIyMDYyZDQxMC1kMGE0LTRiNTItYjc2Yi03M2FiNWQ5Njk4YWQiLCJjb2duaXRvOmdyb3VwcyI6WyJVc2VycyIsIlByaW1hcnkiXSwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbVwvdXMtZWFzdC0xX1haNWpVNXcwWSIsImN1c3RvbTpoaWRlX3RyaWFsX21zZyI6IjAiLCJjb2duaXRvOnVzZXJuYW1lIjoiZWRjIiwiY3VzdG9tOnVzZXJfZGlzYWJsZWQiOiIwIiwiY3VzdG9tOmF3c19hY2NvdW50X2lkIjoiNzMwMDc5MDI1Njg4IiwiY3VzdG9tOmhpZGVfd2VsY29tZV9tc2ciOiIwIiwiYXVkIjoiNXM2M29raWtodGJxdDR2cTFtMmV1bDk4Z2kiLCJldmVudF9pZCI6IjkwOTJlZjc4LTMzZTMtNDVhNS1hZTlhLTVmN2Y0NGY2NDZmNiIsInRva2VuX3VzZSI6ImlkIiwiYXV0aF90aW1lIjoxNjI1MjgyODU5LCJleHAiOjE2MjUyODY0NTksImlhdCI6MTYyNTI4Mjg1OSwiZW1haWwiOiJzdXBwb3J0QGNsb3Vkc3RvcmFnZXNlYy5jb20ifQ.QehudPO4zTphRq9ch3p6IopzRz7m72D5LquVgnzw8iHfDBbgZLQiAM7uWtkKGQw5fYV5dsB_U0fbcrW6F3ov_U4LcpvLgP88NXk7MR9PprzIQQjvnHRU9z6wy6wavgrK-VdPiqNF7dsKaAJGW6vVZCzFzVIEKaZCThHpqVYbKdiSfVm08nvWsWEM4fxAgCFY8sAr2pNxY5VHydGc_iP4On3H7MSFh1n7ee-lH88Ao8PLWMWQBYlbR6ZFLin7KKi6lhDOE-b4cAGDgPtl4acdw6ha_AWJPxozJILQkSAesl-BbxWquphTJ-oD_jRl7DvJBSbBw3DPNzXcO4w4SMnnLA",
       "tokenType":"Bearer",
       "expiresIn":3600
   }
   ```

   Save the access token off for the next call. It is valid for 1 hour if you choose to re-use it.
2. Send the file for scanning\
   a. Specify the headers - big thing here is the accessToken needs to be added, this is the minimum\
   b. Get the file as your language dictates, but should be multipart form upload\
   c. HTTP Post the file and headers \<baseURL> + **/api/Scan**

   ```python
   headers = {"Prefer": "respond-async", "Content-Type": form.content_type, 'Authorization': 'Bearer ' + accessToken}
   r = session.post("https://<baseURL to load balancer or friendly URL>/api/Scan", headers=headers, data=form, timeout=4000)
   ```

   This will return the following response text:

   ```json
   {
       "dateScanned": "2021-07-02T07:04:18.8896831Z",
       "detectedInfections": [],
       "errorMessage": null,
       "result": "Clean"
   }
   ```

### Available APIs

#### Antivirus

Currently, there are 4 available antivirus scanning API functions:

1. Token
2. Scan
3. Scan/Existing
4. Scan/URL

The `Scan` option has two uses: "scan and return" and "scan and upload". Read on to learn more about these APIs. For more technical docs on the APIs, please check out our [API Swagger Docs](/how-it-works/scanning-api).

<details>

<summary>api/Token</summary>

To execute the `api/Token` API, you need to pass the API-user `username` and `password` in to be

```python
headers = {'Content-type': 'application/json'}
json_foo: {"username": "<username here>", "password": "<pw here>"}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Token", data=json_foo, headers=headers)
```

This will return the following response text:

```python
headers = {'Content-type': 'application/json'}
json_foo: {"username": "<username here>", "password": "<pw here>"}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Token", data=json_foo, headers=headers)
```

Save the access token off for the next call. It is valid for 1 hour if you choose to re-use it.

</details>

<details>

<summary>api/Scan</summary>

**Scan and Return only**

```python
headers = {"Prefer": "respond-async", "Content-Type": form.content_type, 'Authorization': 'Bearer ' + accessToken}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Scan", headers=headers, data=form, timeout=4000)
```

This will return the following response text

```python
{
    "dateScanned": "2021-07-02T07:04:18.8896831Z",
    "detectedInfections": [],
    "errorMessage": null,
    "result": "Clean"
}
```

**Scan and Upload**\
To scan and upload (if clean) you need to add the `uploadTo` attribute to the form data. This is as simple as augmenting the sample code to include one more field as seen below.

```python
with open(sys.argv[4], 'rb') as f:
    form = encoder.MultipartEncoder({
        "documents": ("my_file", f, "application/octet-stream"),
        "composite": "NONE",
        "uploadTo": sys.argv[5],
    })
headers = {"Prefer": "respond-async", "Content-Type": form.content_type, 'Authorization': 'Bearer ' + accessToken}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Scan", headers=headers, data=form, timeout=4000)
```

If wanting to test this, add to the sample code below and use the following line to run the script:

```python
python ./scanWithAPI.py <username> <password> <base-URL> <file-to-scan> <bucket-name/full-path-to-file-including-filename.type>
```

Uploading Metadata and Tags

We also provide the option to upload Metadata and additional Tags to the uploaded object. The field will vary depending on the type of upload.

* Multipart-form uploads: include tag and metadata in the form-data
  * Metadata form field name is `metadata`
  * Tag form field is `tags`
* Binary file uploads: include the tag and metadata in the HTTPS request
  * Metadata should be indicated by `x-file-metadata` header
  * Tags should be indicated by `x-file-tags` header

Insert tags and metadata in a json key:value format

`{"tags":"Production"}`

`{"metadata":"my-metadata"}`

#### *The filename chosen must be in the variable uploadTo for it to be considered as it is in the S3 bucket (e.g: uploadTo: bucketname/filename.type). <mark style="color:red;">If the full path of the file is not indicated, the file will be considered a Binary data stream, and uploaded as a tmp file.</mark>*

</details>

<details>

<summary>api/Scan/Existing</summary>

To scan a file that already exists within an S3 bucket, you use the `api/Scan/Existing` API call. This call requires you to pass a block of json as seen below. `container` and `objectPath` are required. `versionID` is optional, but allows you to specify a particular version number to scan. If you do not specify this field, we will scan the latest. `uploadedBy` is also optional, but allows you to specify who is doing the scanning.

```python
{
    "container": "<bucket_containing_the_file>",
    "objectPath": "<path_in_bucket_to_file>",
    "versionId": "<version_id_to_scan>",
    "uploadedBy": "<user_performing_scan>"
}
```

To execute this call, capture the bucket name and full path to file

```python
json_foo: {"container": "<bucket-name>", "objectPath": "<object-key>"}
headers = {"Content-Type": "application/json", 'Authorization': 'Bearer ' + accessToken}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Scan/Existing", headers=headers, data=json_foo)
```

</details>

<details>

<summary>api/Scan/URL</summary>

There will be times when scanning a file existing by URL path is desired. Presigned URLs for Amazon S3 objects is a good use case or anything your applications have access to hanging out on a fully qualified URL. The `api/Scan/URL` API call will allow you to do this task. You simply need to add the URL field to the form data

To execute this call, capture the bucket name and full path to file

```python
# specify file URL in form data
form = encoder.MultipartEncoder({"url": "some-URL-here", })
headers = {"Content-Type": "application/json", 'Authorization': 'Bearer ' + accessToken}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Scan/URL", headers=headers, data=form)
```

</details>

#### Data Classification

Currently there are also 3 available data classification functions which you can use similar to the antivirus functions:

* /api/Classify
* /api/Classify/Existing
* /api/Classify/URL

The `Classify` option has two uses: "classify and return" and "classify and upload".

<details>

<summary>/api/Classify</summary>

**Classify and Return**

```python
headers = {"Prefer": "respond-async", "Content-Type": form.content_type, 'Authorization': 'Bearer ' + accessToken}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Classify", headers=headers, data=form, timeout=4000)
```

**Classify and Upload**

To classify and upload (if clean) you need to add the `uploadTo` attribute to the form data. This is as simple as augmenting the above sample code to include one more field as seen below.

```python
with open(sys.argv[4], 'rb') as f:
    form = encoder.MultipartEncoder({
        "documents": ("my_file", f, "application/octet-stream"),
        "composite": "NONE",
        "uploadTo": sys.argv[5],
    })
headers = {"Prefer": "respond-async", "Content-Type": form.content_type, 'Authorization': 'Bearer ' + accessToken}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Classify", headers=headers, data=form, timeout=4000)
```

If wanting to test this, add to the sample code below and use the following line to run the script:

```python
python ./classifyWithAPI.py <username> <password> <base-URL> <file-to-classify> <bucket-name/full-path-to-file-including-filename.type>
```

*The filename chosen must be in the variable uploadTo for it to be considered as it is in the S3 bucket (e.g: uploadTo: bucketname/filename.type). <mark style="color:red;">If the full path of the file is not indicated, the file will be considered a Binary data stream, and uploaded as a tmp file.</mark>*

</details>

<details>

<summary>/api/Classify/Existing</summary>

To classify a file that already exists within an S3 bucket, you use the `api/Classify/Existing` API call. This call requires you to pass a block of json as seen below. `container` and `objectPath` are required. `versionID` is optional, but allows you to specify a particular version number to scan. If you do not specify this field, we will scan the latest. `uploadedBy` is also optional, but allows you to specify who is doing the scanning.

```python
json_foo: {"container": "<bucket-name>", "objectPath": "<object-key>"}
headers = {"Content-Type": "application/json", 'Authorization': 'Bearer ' + accessToken}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Classify/Existing", headers=headers, data=json_foo)
```

</details>

<details>

<summary>/api/Classify/URL</summary>

There will be times when classifying an existing file by URL path is desired. Presigned URLs for Amazon S3 objects is a good use case or anything your applications have access to hanging out on a fully qualified URL. The `api/Classify/URL` API call will allow you to do this task. You simply need to add the URL field to the form data

To execute this call, capture the bucket name and full path to file:

```python
# specify file URL in form data
form = encoder.MultipartEncoder({"url": "some-URL-here", })
headers = {"Content-Type": "application/json", 'Authorization': 'Bearer ' + accessToken}
r = session.post("https://<baseURL to load balancer or friendly URL>/api/Classify/URL", headers=headers, data=form)
```

</details>

### Code Samples

{% hint style="info" %}
You can download and use our Postman collection and environment JSON files below to assist in your testing of our API Scanning functionality:

* [Click here to download Collection JSON](https://css-public-docs.s3.amazonaws.com/CloudStorageSecConsole.postman_collection+\(1\).json)
* [Click here to download Environment JSON](https://css-public-docs.s3.amazonaws.com/CloudStorageSecurity.postman_environment.json)

The below code samples are simple, but can give you a good start. If you need additional code samples you can generate examples in the programming language of your choice them using Postman.
{% endhint %}

{% tabs %}
{% tab title="Python /scan" %}
This is a simple command line example with the base URL and the file to scan passed in on the command line.

```python
python ./scanWithAPI.py <username> <password> <base-URL> <file-to-scan>
```

```python
import json
import requests
from requests_toolbelt.multipart import encoder
from requests_toolbelt.multipart.encoder import MultipartEncoder
import sys

# baseURL is the value found on the API Agent Settings page as the Default DNS
# this can also be a friendly URL which you've mapped within your DNS
baseURL = sys.argv[3]

# /api/Token is the API to retrieve the auth token
# the auth token is valid for 1 hour, so you can re-use if your application can manage it
getTokenURL = baseURL + '/api/Token'

# /api/Scan is the API to pass the file to for scanning
scanFileURL = baseURL + '/api/Scan'

# must specify the content type as JSON when retrieving the auth token
headers = {'Content-type': 'application/json'}

# as part of the /api/Token HTTP Post you must pass the username and password for the 
# user created and configured inside of the Antivirus for Amazon S3 console
# the data block must be passed in JSON format
uname = sys.argv[1]
pw = sys.argv[2]
foo = {"username": "", "password": ""}
foo["username"] = uname
foo["password"] = pw
json_foo = json.dumps(foo)

# make the HTTP post now passing in the username/pw data block and headers
session = requests.Session()
r = session.post(getTokenURL, data=json_foo, headers=headers)

# pull the auth token from the response to use in the scan call below
# valid for 1 hour if you want to re-use
jsonResponse = json.loads(r.text)
accessToken = jsonResponse["accessToken"]

# read file in from wherever it is coming from: form upload, in file system, etc
with open(sys.argv[4], 'rb') as f:
    form = encoder.MultipartEncoder({
        "documents": ("my_file", f, "application/octet-stream"),
        "composite": "NONE",
    })
# setup headers for /api/Scan HTTP Post.
# the only thing you really need is the 'Authorization': 'Bearer ' with the auth token
# assigned to that. Depending on how you are reading the file or the language, you may 
# need to pass more values in the header as seen below
    headers = {"Prefer": "respond-async", "Content-Type": form.content_type, 'Authorization': 'Bearer ' + accessToken}
    r = session.post(scanFileURL, headers=headers, data=form, timeout=4000)

# grab the text from the response and check however you will
# below converts the response to JSON for easy formatting and handling
parsed = json.loads(r.text)
print(json.dumps(parsed, indent=4, sort_keys=True))

# do the next portion of your workflow based on what the scan result is
if parsed['result'] == "Clean":
    print("file was clean")
    #do more work in the workflow here

session.close()
```

{% endtab %}

{% tab title="Python /scan with upload" %}

```python
python ./scanWithAPI-withUpload.py <username> <password> <base-URL> <file-to-scan> <bucket-name/file-name>
```

```python
import json
import requests
from requests_toolbelt.multipart import encoder
from requests_toolbelt.multipart.encoder import MultipartEncoder
import sys

# baseURL is the value found on the API Agent Settings page as the Default DNS
# this can also be a friendly URL which you've mapped within your DNS
baseURL = sys.argv[3]

# /api/Token is the API to retrieve the auth token
# the auth token is valid for 1 hour, so you can re-use if your application can manage it
getTokenURL = baseURL + '/api/Token'

# /api/Scan is the API to pass the file to for scanning
scanFileURL = baseURL + '/api/Scan'

# must specify the content type as JSON when retrieving the auth token
headers = {'Content-type': 'application/json'}

# as part of the /api/Token HTTP Post you must pass the username and password for the 
# user created and configured inside of the Antivirus for Amazon S3 console
# the data block must be passed in JSON format
uname = sys.argv[1]
pw = sys.argv[2]
foo = {"username": "", "password": ""}
foo["username"] = uname
foo["password"] = pw
json_foo = json.dumps(foo)

# make the HTTP post now passing in the username/pw data block and headers
session = requests.Session()
r = session.post(getTokenURL, data=json_foo, headers=headers)

# pull the auth token from the response to use in the scan call below
# valid for 1 hour if you want to re-use
jsonResponse = json.loads(r.text)
accessToken = jsonResponse["accessToken"]

# read file in from wherever it is coming from: form upload, in file system, etc
with open(sys.argv[4], 'rb') as f:
    form = encoder.MultipartEncoder({
        "documents": ("my_file", f, "application/octet-stream"),
        "composite": "NONE",
        "uploadTo": sys.argv[5],
    })
# setup headers for /api/Scan HTTP Post.
# the only thing you really need is the 'Authorization': 'Bearer ' with the auth token
# assigned to that. Depending on how you are reading the file or the language, you may 
# need to pass more values in the header as seen below
    headers = {"Prefer": "respond-async", "Content-Type": form.content_type, 'Authorization': 'Bearer ' + accessToken}
    r = session.post(scanFileURL, headers=headers, data=form, timeout=4000)

# grab the text from the response and check however you will
# below converts the response to JSON for easy formatting and handling
parsed = json.loads(r.text)
print(json.dumps(parsed, indent=4, sort_keys=True))

# do the next portion of your workflow based on what the scan result is
if parsed['result'] == "Clean":
    print("file was clean")
    #do more work in the workflow here

session.close()
```

{% endtab %}

{% tab title="Python /scan/existing" %}

```python
python ./scanWithAPI-Existing.py <username> <password> <base-URL> <bucket-name> <file-name>
```

```python
import json
import requests
import sys

# baseURL is the value found on the API Agent Settings page as the Default DNS
# this can also be a friendly URL which you've mapped within your DNS
baseURL = sys.argv[3]

# /api/Token is the API to retrieve the auth token
# the auth token is valid for 1 hour, so you can re-use if your application can manage it
getTokenURL = baseURL + '/api/Token'

# /api/Scan is the API to pass the file to for scanning
scanFileURL = baseURL + '/api/Scan'
scanExistingFileURL = baseURL + '/api/Scan/Existing'
print("scan existing URL = " + scanExistingFileURL)

# must specify the content type as JSON when retrieving the auth token
headers = {'Content-type': 'application/json'}

# as part of the /api/Token HTTP Post you must pass the username and password for the 
# user created and configured inside of the Antivirus for Amazon S3 console
# the data block must be passed in JSON format
uname = sys.argv[1]
pw = sys.argv[2]
foo = {"username": "", "password": ""}
foo["username"] = uname
foo["password"] = pw
json_foo = json.dumps(foo)

# make the HTTP post now passing in the username/pw data block and headers
session = requests.Session()
r = session.post(getTokenURL, data=json_foo, headers=headers)

# pull the auth token from the response to use in the scan call below
# valid for 1 hour if you want to re-use
jsonResponse = json.loads(r.text)
accessToken = jsonResponse["accessToken"]
print("access token = " + accessToken)

# Setup existing file
foo = {"container": "", "objectPath": ""}
foo["container"] = sys.argv[4]
foo["objectPath"] = sys.argv[5]
json_foo = json.dumps(foo)
print("json foo = " + json_foo)

# setup headers for /api/Scan HTTP Post.
# the only thing you really need is the 'Authorization': 'Bearer ' with the auth token
# assigned to that. Depending on how you are reading the file or the language, you may 
# need to pass more values in the header as seen below
headers = {"Content-Type": 'application/json', 'Authorization': 'Bearer ' + accessToken}
r = session.post(scanExistingFileURL, data=json_foo, headers=headers)

# grab the text from the response and check however you will
# below converts the response to JSON for easy formatting and handling
print("r.status_code = " + str(r.status_code))
parsed = json.loads(r.text)
print(json.dumps(parsed, indent=4, sort_keys=True))

# do the next portion of your workflow based on what the scan result is
if parsed['result'] == "Clean":
    print("file was clean")
    #do more work in the workflow here

session.close()
```

{% endtab %}

{% tab title="Python /scan/url" %}

```python
python ./scanWithAPI-byURL.py <username> <password> <base-URL> <full-URL>
```

```python
import json
import requests
from requests_toolbelt.multipart import encoder
from requests_toolbelt.multipart.encoder import MultipartEncoder
import sys

# baseURL is the value found on the API Agent Settings page as the Default DNS
# this can also be a friendly URL which you've mapped within your DNS
baseURL = sys.argv[3]

# /api/Token is the API to retrieve the auth token
# the auth token is valid for 1 hour, so you can re-use if your application can manage it
getTokenURL = baseURL + '/api/Token'

# /api/Scan is the API to pass the file to for scanning
scanFileURL = baseURL + '/api/scan/URL'

# must specify the content type as JSON when retrieving the auth token
headers = {'Content-type': 'application/json'}

# as part of the /api/Token HTTP Post you must pass the username and password for the 
# user created and configured inside of the Antivirus for Amazon S3 console
# the data block must be passed in JSON format
uname = sys.argv[1]
pw = sys.argv[2]
foo = {"username": "", "password": ""}
foo["username"] = uname
foo["password"] = pw
json_foo = json.dumps(foo)
print("user stuff: " + json_foo)

# make the HTTP post now passing in the username/pw data block and headers
session = requests.Session()
r = session.post(getTokenURL, data=json_foo, headers=headers)

# pull the auth token from the response to use in the scan call below
# valid for 1 hour if you want to re-use
jsonResponse = json.loads(r.text)
accessToken = jsonResponse["accessToken"]
print("accessToken: " + accessToken)

# specify file URL in form data
form = encoder.MultipartEncoder({"url": sys.argv[4], })

# setup headers for /api/Scan HTTP Post.
# the only thing you really need is the 'Authorization': 'Bearer ' with the auth token
# assigned to that. Depending on how you are reading the file or the language, you may 
# need to pass more values in the header as seen below
headers = {"Prefer": "respond-async", "Content-Type": form.content_type, 'Authorization': 'Bearer ' + accessToken}
r = session.post(scanFileURL, headers=headers, data=form, timeout=4000)

# grab the text from the response and check however you will
# below converts the response to JSON for easy formatting and handling
parsed = json.loads(r.text)
print(json.dumps(parsed, indent=4, sort_keys=True))

# do the next portion of your workflow based on what the scan result is
if parsed['result'] == "Clean":
    print("file was clean")
    #do more work in the workflow here

session.close()
```

{% endtab %}

{% tab title="Python /scan with Azure upload" %}
This example scans a file via `/api/scan` and, only if the scan result is clean, uploads that same file to an Azure Blob Storage container. Fill in the configuration values at the top of the script, then run:

```python
pip install requests azure-storage-blob
python ./scan_and_upload_to_azure.py
```

```python
import os
import sys

import requests
from azure.core.exceptions import AzureError
from azure.storage.blob import BlobServiceClient

# Base URL of your API Agent. Console -> API Agent Settings -> Default DNS.
SCAN_API_URL = "<base-URL to load balancer or friendly URL>"

# Credentials for the API-scanning user configured in the Console.
USERNAME = "<username here>"
PASSWORD = "<pw here>"

# Only needed if the above user has MFA enabled. Otherwise leave as None.
MFA_CODE = None

# Local file to scan and (maybe) upload.
FILE_PATH = r"<path-to-file-to-scan>"

# Scan result values that permit the Azure upload. Mirrors the Console's
# API Agent Settings -> API Upload Results setting (default: Clean only).
# Valid values: Clean, Infected, InfectedAllowed, Error, Unscannable, Unknown,
# Pending, ErrorAllowed, UnscannableAllowed.
ALLOWED_RESULTS = ["Clean"]

# Azure Storage connection string.
# Portal: Storage Account -> Security + networking -> Access keys -> Show -> Connection string.
AZURE_CONNECTION_STRING = "<azure-storage-connection-string>"

# Target Azure Blob Storage container name.
# Portal: Storage Account -> Data storage -> Containers.
AZURE_CONTAINER = "<azure-container-name>"

# Blob name to upload as. Leave as None to reuse the local file's base name.
AZURE_BLOB_NAME = None

# Set to False only when testing against a lab/test agent with a self-signed certificate.
VERIFY_TLS = True


def main():
    if not os.path.isfile(FILE_PATH):
        sys.exit(f"File not found: {FILE_PATH}")

    try:
        payload = {"username": USERNAME, "password": PASSWORD}
        if MFA_CODE:
            payload["mfaCode"] = MFA_CODE
        token_response = requests.post(f"{SCAN_API_URL}/api/token", json=payload, verify=VERIFY_TLS, timeout=30)
        token_response.raise_for_status()
        token = token_response.json()["accessToken"]

        with open(FILE_PATH, "rb") as file_handle:
            scan_response = requests.post(
                f"{SCAN_API_URL}/api/scan",
                headers={"Authorization": f"Bearer {token}"},
                files={"file": (os.path.basename(FILE_PATH), file_handle)},
                verify=VERIFY_TLS, timeout=None)
        scan_response.raise_for_status()
    except requests.exceptions.RequestException as ex:
        sys.exit(f"Error communicating with the API Agent: {ex}")

    scan_result = scan_response.json()
    verdict = scan_result.get("result", "Unknown")
    print(f"Scan result: {verdict}")
    for engine_result in scan_result.get("results", []):
        for infection in engine_result.get("infections") or []:
            print(f"  Infection found: {infection.get('infection')} in {infection.get('file')}")

    if verdict not in ALLOWED_RESULTS:
        print(f"Result '{verdict}' not in {ALLOWED_RESULTS}. Skipping Azure upload.")
        return

    blob_name = AZURE_BLOB_NAME or os.path.basename(FILE_PATH)
    try:
        blob_client = BlobServiceClient.from_connection_string(AZURE_CONNECTION_STRING) \
            .get_container_client(AZURE_CONTAINER).get_blob_client(blob_name)
        with open(FILE_PATH, "rb") as file_handle:
            blob_client.upload_blob(file_handle, overwrite=True)
        print(f"Uploaded to Azure container '{AZURE_CONTAINER}' as '{blob_name}'.")
    except AzureError as ex:
        sys.exit(f"Error uploading to Azure Blob Storage: {ex}")


if __name__ == "__main__":
    main()
```

Note that this does not use the `uploadTo` attribute at all — the API Agent only knows how to upload back to S3 or a presigned URL, not to Azure Blob Storage. Instead, `/api/scan` is called plain, the JSON verdict is inspected client-side, and the upload to Azure is performed directly with the `azure-storage-blob` SDK.
{% endtab %}

{% tab title="C# /scan" %}

```csharp
// Host URL will either be the default DNS for your Load Balancer or the DNS CNAME you registered on your own domain
const string hostUrl = "https://your-lb-or-registered-dns-name";
// If you are using this in an on-demand per-user basis, ideally you would have users provide their own username and password
// If you are using this inside an application, it would be recommended to make a console user solely for this application
const string username = "av-console-username";
// Hard-coding the password is not a recommended practice, 
// ideally it would be stored in something like AWS Secrets Manager, and retrieved by the application to use here,
// or provided by the user if being done on an on-demand basis
const string password = "av-console-password"; 
// This handler is only needed if you are using the default load balancer DNS, as your SSL certificate will not be valid for it.
// If you've registered your own DNS CNAME that is valid for your certificate, this is not needed.
HttpClientHandler handler =
    new()
    {
        ClientCertificateOptions = ClientCertificateOption.Manual,
        ServerCertificateCustomValidationCallback = (_, _, _, _) => true
    };
// Timeout is set to infinite as the file upload may take a long time. This could be lowered if desired, just be aware that
// any file uploads taking longer than that will then fail.
HttpClient httpClient = 
    new(handler)
    {
        Timeout = System.Threading.Timeout.InfiniteTimeSpan
    };
HttpResponseMessage resp = 
    await httpClient.PostAsync(
        $"{hostUrl}/api/token",
        new StringContent(
            JsonConvert.SerializeObject(
                new Dictionary<string, string>
                {
                    {"username", username},
                    {"password", password}
                }),
            Encoding.UTF8,
            "application/json"));
string tokenResponse = await response.Content.ReadAsStringAsync();
JObject responseJson = JObject.Parse(tokenResponse);
string accessToken = responseJson["accessToken"]?.Value<string>();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
// This example is using a file that is stored on disk.
// If for example you already have a stream to the file, just pass that to the new StreamContent() constructor
FileStream fileStream = File.OpenRead("path/to/your/file");
MultipartFormDataContent content =
    new()
    {
        {new StreamContent(fileStream), tmpFile, tmpFile}
    };
HttpResponseMessage scanResult =
    await httpClient.PostAsync(
        scanUrl,
        content);
Console.WriteLine(await scanResult.Content.ReadAsStringAsync());
fileStream.Dispose();
```

{% endtab %}
{% endtabs %}

### Scan Results - JSON formatted

{% tabs %}
{% tab title="Clean" %}

```json
{
    "dateScanned": "2021-07-02T07:04:18.8896831Z",
    "detectedInfections": [],
    "errorMessage": null,
    "result": "Clean"
}
```

{% endtab %}

{% tab title="Infected" %}

```json
{
    "dateScanned": "2021-07-02T07:09:53.8972969Z",
    "detectedInfections": [
        {
            "file": "DemoFiles/eicarcom2.zip/eicar_com.zip/eicar.com",
            "infection": "EICAR-AV-Test"
        },
        {
            "file": "DemoFiles/eicar_com.zip/eicar.com",
            "infection": "EICAR-AV-Test"
        },
        {
            "file": "DemoFiles/infected_bill.pdf",
            "infection": "Troj/PDFJs-AIA"
        },
        {
            "file": "DemoFiles/eicar.com",
            "infection": "EICAR-AV-Test"
        },
        {
            "file": "DemoFiles/urgent_payment.pdf",
            "infection": "Troj/PDFJs-AIA"
        },
        {
            "file": "DemoFiles/eicar.com.txt",
            "infection": "EICAR-AV-Test"
        },
        {
            "file": "DemoFiles/eicar-from-vincent/eicar_-_wiki.txt",
            "infection": "EICAR-AV-Test"
        },
        {
            "file": "DemoFiles/eicar-from-vincent/eicar_-_milestone.txt",
            "infection": "EICAR-AV-Test"
        },
        {
            "file": "DemoFiles/eicar-from-vincent/eicar_-_snippet.txt",
            "infection": "EICAR-AV-Test"
        }
    ],
    "errorMessage": null,
    "result": "Infected"
}
```

{% endtab %}
{% endtabs %}


# Architecture Overview

An in-depth overview of our architecture.

## Architecture

The architecture seen below supports the object flow as described in the [Object Scanning](/how-it-works/object-scanning) section both in a single region as well as across all regions supported. The Console region will have all components deployed to it. Any additional regions only require the scanning Agent(s) which will report back to the centrally located Console. In addition to this high-level architecture, you can get more details on routing and the public access required on the [Deployment Details page](/how-it-works/deployment-details).

### Architecture - High-level Overview

{% tabs %}
{% tab title="Single Region Architecture" %}

<figure><img src="/files/BHKRORdPdpftR7UQzmew" alt=""><figcaption><p>Single-Region Architecture</p></figcaption></figure>

1. ECS is the core of our application, which hosts 4 types of services.
   1. The Console service is utilized for configuration of our product and provides the main communication to other AWS services. It also surfaces data from our product for user analysis.
   2. The API Agent provides an endpoint where files can be sent and scanned before entering a storage volume.
   3. The Event Agent scans files as they land into an S3 bucket by leveraging SNS and SQS.
   4. The Scheduled & On-demand Agent scans pre-existing objects in a storage volume using Fargate Run Tasks.
2. Users and apps can log into our management console service through Cognito, or send files directly to our API scanning agent through a load balancer.
3. Objects can be uploaded either directly into the supported storage volumes or uploaded to S3 via our API Agent.
4. In AWS, we currently scan S3, EBS, EFS, and FSx.
5. [Integrations](/how-it-works/integrations) are handled through our Console service.
6. The Console stores and reads configuration details from DynamoDB and Parameter Store, for example to ensure consistency when scaling agents or restarting tasks.
7. The Console logs all application activity in CloudWatch, which can be integrated with most SIEM tools.
   {% endtab %}

{% tab title="Multi-Region Architecture" %}

<figure><img src="/files/8nph0n3Ocly23D6ERQ8U" alt=""><figcaption><p>Multi-Region Architecture</p></figcaption></figure>

1. ECS is the core of our application, which hosts 4 types of services.
   1. The Console service is utilized for configuration of our product and provides the main communication to other AWS services. It also surfaces data from our product for user analysis.
   2. The API Agent provides an endpoint where files can be sent and scanned before entering a storage volume.
   3. The Event Agent scans files as they land into an S3 bucket by leveraging SNS and SQS.
   4. The Scheduled & On-demand Agent scans pre-existing objects in a storage volume using Fargate Run Tasks.
2. Users and apps can log into our management console service through Cognito, or send files directly to our API scanning agent through a load balancer.
3. Objects can be uploaded either directly into the supported storage volumes or uploaded to S3 via our API Agent.
4. In AWS, we currently scan S3, EBS, EFS, and FSx.
5. [Integrations](/how-it-works/integrations) are handled through our Console service.
6. The Console stores and reads configuration details from DynamoDB and Parameter Store, for example to ensure consistency when scaling agents or restarting tasks.
7. The Console logs all application activity in CloudWatch, which can be integrated with most SIEM tools.
8. To scan objects in regions separate from the Intial Deployment Region, we spin up Scanning Agents in that region to perform scans so the files never leave the region. Results are then sent back to the Console service.
9. All application information that takes place in secondary deployment regions are logged into that region's CloudWatch log groups.
   {% endtab %}

{% tab title="Multi-Account Architecture" %}

<figure><img src="/files/TVXEUg25XQzPVHsnWb5r" alt=""><figcaption><p>Multi-Account Architecture</p></figcaption></figure>

1. ECS is the core of our application, which hosts 4 types of services.
   1. The Console service is utilized for configuration of our product and provides the main communication to other AWS services. It also surfaces data from our product for user analysis.
   2. The API Agent provides an endpoint where files can be sent and scanned before entering a storage volume.
   3. The Event Agent scans files as they land into an S3 bucket by leveraging SNS and SQS.
   4. The Scheduled & On-demand Agent scans pre-existing objects in a storage volume using Fargate Run Tasks.
2. Users and apps can log into our management console service through Cognito, or send files directly to our API scanning agent through a load balancer.
3. Objects can be uploaded either directly into the supported storage volumes or uploaded to S3 via our API Agent.
4. In AWS, we currently scan S3, EBS, EFS, and FSx.
5. [Integrations](/how-it-works/integrations) are handled through our Console service.
6. The Console stores and reads configuration details from DynamoDB and Parameter Store, for example to ensure consistency when scaling agents or restarting tasks.
7. The Console logs all application activity in CloudWatch, which can be integrated with most SIEM tools.
8. To scan objects in regions separate from the Intial Deployment Region, we spin up Scanning Agents in that region to perform scans so the files never leave the region. Results are then sent back to the Console service.
9. All application information that takes place in secondary deployment regions are logged into that region's CloudWatch log groups.
10. For multiple accounts, the Console deploys a Cross Account Role with permissions so that CSS services can access and scan storage volumes from separate accounts. Note that scanning infrastructure remains in the primary AWS account where your Console was deployed. Similar to a multi-region deployment, CSS will spin up Scanning Agents in each region where data is scanned.
    {% endtab %}

{% tab title="Azure Architecture" %}
When linking an account in the CSS console, we deploy resources in the new CSS Resource Group created in Azure. Those resources will have access to the Blob Containers that reside within the linked Azure Account.

Once the Azure Account is linked, Azure Blob Containers will be made available to be scan through the CSS Console in the Protection > Azure Blob Containers page. You can select blob containers to scan or run scans on a schedule basis.

We offer two types of scanning for Azure: Event-Scanning and Retro Scanning.

**Event-based scanning scans files as they drop into the Blob Container.**

<figure><img src="/files/Wm7cWLcpymGnywHZC4Nt" alt=""><figcaption><p>Azure Event-Based Scanning</p></figcaption></figure>

1. Users upload data to storage containers.
2. The storage account's system topic has an Event Grid Subscription tied to it that points to Azure Queue Storage as its event handler.
3. The Azure Queue Storage receives information about the object via the Event Grid Subscription.
4. The Container Application pulls information from the queue and scans the object that the notification refers to.
5. Results are tagged onto the object.
6. Results and metering are sent back to the CSS Console.

**Retro-based scanning scans the entire Blob Container.**

<figure><img src="/files/PU4NmsUwsa9wVEdT6qO5" alt=""><figcaption><p>Azure Retro-Based Scanning</p></figcaption></figure>

1. Users upload data to storage containers.
2. The Container Application runs a Crawl Job that evaluates the items to be scanned.
3. The Crawl Job places objects in Azure Queue Storage.
4. The Container Application pulls information from the queue and runs a Scan Job to scan the objects in the Queue.
5. Results and metering are sent back to the CSS Console.

Excluding the Event Grid Subscription, note that all of these resources and cross-permissions are only deployed inside of the CSS Resource Group through the Azure Resource Manager. The rest of the organizations and projects inside of your Azure account remain untouched.
{% endtab %}

{% tab title="GCP Architecture" %}
When linking an account in the CSS console, we deploy resources in a new CSS Project created in GCP through our terraform module. Those resources will have access to the customer project(s) denoted in the deployments parameters (projects\_to\_protect).

Once the projects are linked, GCP buckets will be made available to be scan through the CSS Console in the Protection > GCP Buckets page. You can select buckets to scan or run scans on a schedule basis.

We offer Retro and Event-Based scanning for GCP.

**Event-based scanning scans files as they drop into the GCP Bucket.**

<figure><img src="/files/3c9b3qlxMotOyffPOd4P" alt=""><figcaption></figcaption></figure>

1. Users or apps place files into Google Cloud Storage.
2. The Pub/Sub service has a Topic set up to notify whenever new objects are created in designated Buckets.
3. The Cloud Run Job's subscription to the Topic activates whenever a new file is created.
4. The Cloud Run Job accesses the designated Bucket and loads that new object in memory to scan.
5. Files in the protected Bucket are tagged with their scan result.
6. (Optional) The Cloud Run Job will move infected files to a Quarantine Cloud Storage that resides in CSS' Project.
7. Results are returned to the Console service for processing.

**Retro-based scanning scans the entire GCP Bucket.**

<figure><img src="/files/GjSeGmD0a9uXSp0XlsWi" alt=""><figcaption><p>GCP Retro Architecture</p></figcaption></figure>

1. Users or apps place files into Google Cloud Storage.
2. The Console Service initiates a scan request to the Cloud Run service that resides in CSS' Project that is provisioned via Terraform.
3. The Cloud Run Job accesses the customer's Cloud Storage and loads a list of its objects in memory, procedurally scanning each item.
4. Results are returned to the Console service for processing.
5. (Optional) The Cloud Run Job will move infected files to a Quarantine Cloud Storage that resides in CSS' Project.

All scan results are logged in AWS CloudWatch logs Agent.ScanResults, Problem Files are reported in the console, and objects in Google Cloud Storage are tagged with the scan result as well via the file metadata.

Note that all of these resources and cross-permissions are only deployed inside of the CSS Project through Terraform. The rest of the organizations and projects inside of your GCP account remain untouched.
{% endtab %}
{% endtabs %}

## Scan Engines

[Antivirus for Amazon S3](https://aws.amazon.com/marketplace/pp/B089QBV2GC/?ref=_ptnr_help_doc_) has been built in such a way that the underlying scanning engine can be exchanged with other scanning engines as needed or desired. There are three engines included out of the box:

* [Sophos](https://www.sophos.com/) - a well known enterprise solution that offers speed, great accuracy and large file scanning
* [ClamAV](https://www.clamav.net/) - a widely used open source antivirus engine for detecting trojans, viruses, malware & other malicious threats
* CSS Premium - our latest scanning engine that can be used as either a primary scanning engine or as a secondary scanning engine to increase the efficacy of your scan

{% embed url="<https://www.youtube.com/watch?v=7304AZrG4So>" %}

| Engine                           | Update Frequency                                                                                 | Max File Size                                                                                                                                                                                 | Speed                                                                       | Type            | API Endpoint |
| -------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------- | ------------ |
| ![](/files/wvMlXOg1bb90Uexb6i3I) | <p>Agent checks every 15 minutes<br><br><em>Vendor typically updates 4 times per day</em></p>    | <p>195GB<br><br>5TB with <a href="/pages/EaG45wuCtv8Xui4BTTK5#extra-large-file-scanning">extra large file scanning</a><br><br><a href="/pages/AqGCtFnHh7DCSFSVkl42#sophos">File Types</a></p> | Faster engine; refer to [Sizing Discussion](/how-it-works/sizing)           | Signature Based | Yes          |
| ![](/files/VQM4m3Eywa2KHvLnrg01) | <p>Agent checks every hour<br><br><em>Vendor typically updates once per day</em></p>             | <p>2GB<br><br><a href="/pages/AqGCtFnHh7DCSFSVkl42#clamav">File Types</a></p>                                                                                                                 | Good performance engine; refer to [Sizing Discussion](/how-it-works/sizing) | Signature Based | Yes          |
| ![](/files/zkLFC6DNh6VOEezD2qQO) | <p>Agent checks every 15 minutes<br><br><em>Typically updates one to four times per day</em></p> | <p>195GB through an ECS task<br><br>5TB with extra large file scanning<br><br><a href="/pages/AqGCtFnHh7DCSFSVkl42">File Types</a></p>                                                        | Great performance; data to be released in the near future                   | Signature Based | Yes          |

**Antivirus for Amazon S3** has the ability to use multiple scanning engines configured serially to ensure the highest level of efficacy and protection. Antivirus for Amazon S3 updates virus definitions as defined above as well as with each reboot / new spin up.

{% hint style="info" %}
If you are a scan engine vendor and would like to partner with us to get your engine integrated into our solution or if you are a customer who would prefer another engine, please [Contact Us](/contact-us).
{% endhint %}


# Logging and Permissions

Details on Log Groups and Console + Agent Permissions

## Platform Services <a href="#platform-services" id="platform-services"></a>

While many services are used ([ECS Fargate](https://aws.amazon.com/fargate/), [App Config](https://aws.amazon.com/about-aws/whats-new/2019/11/simplify-application-configuration-with-aws-appconfig/), [CloudWatch](https://aws.amazon.com/cloudwatch/), [CloudFormation](https://aws.amazon.com/cloudformation/), [DynamoDB](https://aws.amazon.com/dynamodb/), [SNS](https://aws.amazon.com/sns/), [SQS](https://aws.amazon.com/sqs/), [IAM](https://aws.amazon.com/iam/)) to deliver the `Antivirus for Amazon S3` solution, two will be called out here. CloudWatch and IAM are leveraged for logging and permissions respectively. These are the usual questions we get from customers:

1. How do I check the logs?
2. What are you doing behind the scenes (permissions wise)?

We wanted to make sure you had those bases covered with the information below.

### CloudWatch Log Group Overview

#### Log groups for the Console

<details>

<summary>Console.AgentConfig</summary>

Logs of changes to agent configuration performed through the console.

```
2020-08-19T23:01:08.246-06:00 2020-08-20 05:01:08.2466|INFO|AgentConfig|Updated Configured Subnets for Agents in region 'ap-northeast-1': {"region":"ap-northeast-1","vpcId":"vpc-6902080e","subnets":[{"subnetId":"subnet-1673ac3d","availabilityZone":"ap-northeast-1d","cidrBlock":"172.31.16.0/20"},{"subnetId":"subnet-bd66b2f5","availabilityZone":"ap-northeast-1a","cidrBlock":"172.31.32.0/20"}]}
2020-08-19T23:01:08.322-06:00 2020-08-20 05:01:08.3225|INFO|AgentConfig|Updated Configured Subnets for Agents in region 'eu-west-3': {"region":"eu-west-3","vpcId":"vpc-e9677880","subnets":[{"subnetId":"subnet-232b114a","availabilityZone":"eu-west-3a","cidrBlock":"172.31.0.0/20"},{"subnetId":"subnet-266a0c6b","availabilityZone":"eu-west-3c","cidrBlock":"172.31.32.0/20"}]}
2020-08-19T23:01:08.409-06:00 2020-08-20 05:01:08.4092|INFO|AgentConfig|Updated Configured Subnets for Agents in region 'us-west-1': {"region":"us-west-1","vpcId":"vpc-1c55a17a","subnets":[{"subnetId":"subnet-b8c563de","availabilityZone":"us-west-1b","cidrBlock":"172.31.16.0/20"},{"subnetId":"subnet-3c59aa66","availabilityZone":"us-west-1a","cidrBlock":"172.31.0.0/20"}]}
2020-08-19T23:01:08.490-06:00 2020-08-20 05:01:08.4899|INFO|AgentConfig|Updated Configured Subnets for Agents in region 'us-west-2': 
{
    "region": "us-west-2",
    "vpcId": "vpc-2f007457",
    "subnets": [
        {
            "subnetId": "subnet-f6f91abc",
            "availabilityZone": "us-west-2a",
            "cidrBlock": "172.31.32.0/20"
        },
        {
            "subnetId": "subnet-f0408688",
            "availabilityZone": "us-west-2b",
            "cidrBlock": "172.31.16.0/20"
        }
    ]
}
2020-08-20 05:01:08.4899|INFO|AgentConfig|Updated Configured Subnets for Agents in region 'us-west-2': {"region":"us-west-2","vpcId":"vpc-2f007457","subnets":[{"subnetId":"subnet-f6f91abc","availabilityZone":"us-west-2a","cidrBlock":"172.31.32.0/20"},{"subnetId":"subnet-f0408688","availabilityZone":"us-west-2b","cidrBlock":"172.31.16.0/20"}]}
```

</details>

<details>

<summary>Console.AuditLogging</summary>

Logs audit trail entries for security-relevant user actions in the Console.

```
2026-03-25 21:29:21.3817|INFO|AuditLogging|Event: UserSignIn
User: admin
Details: User 'admin' signed in with password
```

</details>

<details>

<summary>Console.Buckets</summary>

Logs of changes to bucket protection status and any errors that may occur while trying to turn on/off buckets.

```
2020-08-13T10:31:12.309-06:00 2020-08-13 16:31:12.3094|INFO|Buckets|Turned on protection for bucket 'css-webinar-new-files' 
2020-08-13T10:39:55.290-06:00 2020-08-13 16:39:55.2901|INFO|Buckets|Turned off protection for bucket 'css-webinar-new-files'
2020-08-13T10:47:56.726-06:00 2020-08-13 16:47:56.7262|INFO|Buckets|Turned on protection for bucket 'css-webinar-new-files'
2020-08-13T10:59:48.397-06:00 2020-08-13 16:59:48.3969|INFO|Buckets|Turned off protection for bucket 'css-webinar-new-files'
2020-08-13T11:36:53.512-06:00 2020-08-13 17:36:53.5125|INFO|Buckets|Turned on protection for bucket 'webinar-other-account-bucket'
2020-08-13T11:36:56.921-06:00 2020-08-13 17:36:56.9212|INFO|Buckets|Turned on protection for bucket 'webinar-other-account-bucket-2'
2020-08-13T12:26:51.700-06:00 2020-08-13 18:26:51.7006|INFO|Buckets|Turned on protection for bucket 'css-webinar-existing-files'
2020-08-13T12:27:18.104-06:00 2020-08-13 18:27:18.1044|INFO|Buckets|Turned on protection for bucket 'css-webinar-new-files'
2020-08-17T15:53:25.588-06:00 2020-08-17 21:53:25.5884|INFO|Buckets|Turned off protection for bucket '100kb-bucket'
2020-08-17T15:53:25.755-06:00 2020-08-17 21:53:25.7552|INFO|Buckets|Turned off protection for bucket 'demo-destination-bucket'
```

</details>

<details>

<summary>Console.BlobContainers</summary>

Logs Azure Blob Container discovery and management operations.

```
2026-04-13 19:21:42.5627|INFO|BlobContainers|Starting Blob Containers collection
2026-04-13 19:22:04.0511|INFO|BlobContainers|Finished Blob Containers collection. Total time (ms): 21488, Total containers collected: 8. Deleted: 0
2026-04-13 19:51:42.3017|INFO|BlobContainers|Starting Blob Containers collection
2026-04-13 19:52:02.6331|INFO|BlobContainers|Finished Blob Containers collection. Total time (ms): 20331, Total containers collected: 8. Deleted: 0
```

</details>

<details>

<summary>Console.EbsVolumes</summary>

Logs EBS volume scanning configuration and discovery.

```
2026-04-13 19:54:34.6136|INFO|EbsVolumes|Updated EBS volume details for account 
2026-04-13 19:54:35.1187|ERROR|EbsVolumes|System.Net.Http.HttpRequestException: No route to host (ec2.me-south-1.amazonaws.com:443)
 ---> System.Net.Sockets.SocketException (113): No route to host
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
```

</details>

<details>

<summary>Console.EfsVolumes</summary>

Logs EFS volume scanning configuration and discovery.

```
2026-04-13 20:59:26.7799|INFO|EfsVolumes|Updated EFS volume details for account 
2026-04-13 21:01:05.8560|ERROR|EfsVolumes|Timed out while trying to describe EFS volumes in 'me-south-1'|System.TimeoutException: A task was canceled.
 ---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
```

</details>

<details>

<summary>Console.EcsConfig</summary>

Logs of actions taken to enable or disable Agents in a region. This includes creation of clusters, task definitions, services, sns topics, sqs queues, quarantine buckets, and autoscaling policies.

```
2020-08-21T13:19:45.296-06:00 2020-08-21 19:19:45.2960|INFO|EcsConfig|Put a new metric alarm for CloudStorageSecLargeQueue-pk913wa.
2020-08-21T13:19:45.296-06:00 2020-08-21 19:19:45.2960|INFO|EcsConfig|Set Large Queue threshold to '1' in us-west-1
2020-08-21T13:19:45.331-06:00 2020-08-21 19:19:45.3307|INFO|EcsConfig|Setting Large Queue threshold to '1' in ap-northeast-1
2020-08-21T13:19:45.331-06:00 2020-08-21 19:19:45.3307|INFO|EcsConfig|Putting a new metric alarm for CloudStorageSecLargeQueue-pk913wa.
2020-08-21T13:19:46.136-06:00 2020-08-21 19:19:46.1364|INFO|EcsConfig|Put a new metric alarm for CloudStorageSecLargeQueue-pk913wa.
2020-08-21T13:19:46.136-06:00 2020-08-21 19:19:46.1364|INFO|EcsConfig|Set Large Queue threshold to '1' in ap-northeast-1 
2020-08-21T13:19:46.195-06:00 2020-08-21 19:19:46.1947|INFO|EcsConfig|Setting Large Queue threshold to '1' in us-west-2
2020-08-21T13:19:46.195-06:00 2020-08-21 19:19:46.1947|INFO|EcsConfig|Putting a new metric alarm for CloudStorageSecLargeQueue-pk913wa.
2020-08-21T13:19:46.556-06:00 2020-08-21 19:19:46.5567|INFO|EcsConfig|Put a new metric alarm for CloudStorageSecLargeQueue-pk913wa.
2020-08-21T13:19:46.556-06:00 2020-08-21 19:19:46.5567|INFO|EcsConfig|Set Large Queue threshold to '1' in us-west-2
2020-08-21T13:19:58.631-06:00 2020-08-21 19:19:58.6311|INFO|EcsConfig|Setting Min and Max agents to '0' and '3' respectively in us-east-1
2020-08-21T13:19:58.908-06:00 2020-08-21 19:19:58.9080|INFO|EcsConfig|Set Min and Max agents to '0' and '3' respectively in us-east-1
2020-08-21T13:20:09.553-06:00 2020-08-21 19:20:09.5536|INFO|EcsConfig|Setting Min and Max agents to '0' and '1' respectively in us-east-1
2020-08-21T13:20:09.826-06:00 2020-08-21 19:20:09.8262|INFO|EcsConfig|Set Min and Max agents to '0' and '1' respectively in us-east-1
```

</details>

<details>

<summary>Console.Error</summary>

Logs of when activities and actions intitiated by the Console encounter an error.

```
2025-04-18 19:54:25.5953|ERROR|Buckets|Error trying to track newly discovered bucket 'blocked-bucket' in account '123456789/Primary'|Amazon.S3.AmazonS3Exception: User: arn:aws:sts::123456789:assumed-role/CloudStorageSecConsoleRole-abcdefg/3558581af7224d5289fbc82a18ec0444 is not authorized to perform: s3:GetBucketLocation on resource: "arn:aws:s3:::blocked-bucket" with an explicit deny in a resource-based policy
```

</details>

<details>

<summary>Console.FsxVolumes</summary>

Logs of when activities and actions intitiated by the Console encounter an error.

```
2025-04-18 19:54:25.5953|ERROR|Buckets|Error trying to track newly discovered bucket 'blocked-bucket' in account '123456789/Primary'|Amazon.S3.AmazonS3Exception: User: arn:aws:sts::123456789:assumed-role/CloudStorageSecConsoleRole-abcdefg/3558581af7224d5289fbc82a18ec0444 is not authorized to perform: s3:GetBucketLocation on resource: "arn:aws:s3:::blocked-bucket" with an explicit deny in a resource-based policy
```

</details>

<details>

<summary>Console.GcpBuckets</summary>

Logs GCP bucket disvovery and management operations.

```
2026-04-08 05:20:25.4175|INFO|GcpBuckets|Starting GcpBucketsDiscoveryService
```

</details>

<details>

<summary>Console.Metering</summary>

Logs of when metering is submitted, and any errors that may occur during metering.

```
2020-08-21T14:03:01.665-06:00 2020-08-21 20:03:01.6647|INFO|Metering|Metering submitted at 08/21/2020 20:03:01 for Dimension FreeTrial and Quantity 43
2020-08-21T15:03:00.950-06:00 2020-08-21 21:03:00.9503|INFO|Metering|Metering submitted at 08/21/2020 21:03:00 for Dimension FreeTrial and Quantity 43
2020-08-21T16:03:00.108-06:00 2020-08-21 22:03:00.1084|INFO|Metering|Metering submitted at 08/21/2020 22:03:00 for Dimension FreeTrial and Quantity 44
2020-08-21T17:03:00.290-06:00 2020-08-21 23:03:00.2903|INFO|Metering|Metering submitted at 08/21/2020 23:03:00 for Dimension FreeTrial and Quantity 44
2020-08-21T18:03:00.539-06:00 2020-08-22 00:03:00.5393|INFO|Metering|Metering submitted at 08/22/2020 00:03:00 for Dimension FreeTrial and Quantity 1
2020-08-21T19:03:00.782-06:00 2020-08-22 01:03:00.7815|INFO|Metering|Metering submitted at 08/22/2020 01:03:00 for Dimension GoFwdTier1 and Quantity 0
```

</details>

<details>

<summary>Console.Metrics</summary>

Logs of when cache for Console dashboard chart data is updated.

```
2020-08-21T13:19:01.171-06:00 2020-08-21 19:19:01.1714|INFO|Metrics|Getting chart values for time window: 08/20/2020 19:19:01-08/21/2020 19:19:01
2020-08-21T13:19:08.774-06:00 2020-08-21 19:19:08.7737|INFO|Metrics|Updated cache for time window: 08/20/2020 19:19:01-08/21/2020 19:19:01
2020-08-21T13:19:09.932-06:00 2020-08-21 19:19:09.9316|INFO|Metrics|Getting chart values for time window: 08/21/2020 18:19:09-08/21/2020 19:19:09
2020-08-21T13:19:09.971-06:00 2020-08-21 19:19:09.9708|INFO|Metrics|Updated cache for time window: 08/21/2020 18:19:09-08/21/2020 19:19:09
2020-08-21T13:19:09.972-06:00 2020-08-21 19:19:09.9708|INFO|Metrics|Getting chart values for time window: 08/14/2020 19:19:09-08/21/2020 19:19:09
2020-08-21T13:19:10.566-06:00 2020-08-21 19:19:10.5661|INFO|Metrics|Getting chart values for time window: 08/14/2020 19:19:10-08/21/2020 19:19:10
2020-08-21T13:19:10.678-06:00 2020-08-21 19:19:10.6781|INFO|Metrics|Updated cache for time window: 08/14/2020 19:19:09-08/21/2020 19:19:09
2020-08-21T13:19:10.679-06:00 2020-08-21 19:19:10.6781|INFO|Metrics|Getting chart values for time window: 07/22/2020 19:19:10-08/21/2020 19:19:10
2020-08-21T13:19:10.680-06:00 2020-08-21 19:19:10.6781|INFO|Metrics|Getting chart values for time window: 07/22/2020 19:19:10-08/21/2020 19:19:10
2020-08-21T13:19:11.355-06:00 2020-08-21 19:19:11.3548|INFO|Metrics|Updated cache for time window: 07/22/2020 19:19:10-08/21/2020 19:19:10
```

</details>

<details>

<summary>Console.Notifications</summary>

Logs notification configuration changes and dispatch events from the Console.

```
2025-09-19 00:58:09.9152|ERROR|Notifications|Error trying to get security hub findings: Amazon.SecurityHub.Model.InvalidInputException: InvalidInputException: Invalid NextToken: Input Query has changed
```

</details>

<details>

<summary>Console.RetroScan</summary>

Logs of when retro scanning starts and finishes per bucket as well as when queue entries are added.

```
2020-08-13T11:37:05.123-06:00 2020-08-13 17:37:05.1233|INFO|RetroScan|Starting to crawl bucket 'webinar-other-account-bucket-2' in region 'us-east-1' for account '7xxxxxxxxxx7'
2020-08-13T11:37:05.187-06:00 2020-08-13 17:37:05.1871|INFO|RetroScan|Fetching next set of objects from 'webinar-other-account-bucket-2' in region 'us-east-1'
2020-08-13T11:37:05.247-06:00 2020-08-13 17:37:05.2463|INFO|RetroScan|Finished crawling bucket 'webinar-other-account-bucket-2' in region 'us-east-1'
2020-08-13T12:26:59.689-06:00 2020-08-13 18:26:59.6883|INFO|RetroScan|Starting to crawl bucket 'css-webinar-existing-files' in region 'us-east-1' for account '7xxxxxxxxxx8'
2020-08-13T12:26:59.712-06:00 2020-08-13 18:26:59.7125|INFO|RetroScan|Fetching next set of objects from 'css-webinar-existing-files' in region 'us-east-1'
2020-08-13T12:26:59.774-06:00 2020-08-13 18:26:59.7742|INFO|RetroScan|Sending message to queue 'https://sqs.us-east-1.amazonaws.com/7xxxxxxxxxx8/CloudStorageSecRetroQueu
```

</details>

<details>

<summary>Console.ScheduledScans</summary>

Logs scheduled AV scan job configuration and trigger events.

```
2026-04-13 06:00:00.0011|INFO|ScheduledScans|Running schedule 'Daily Scan of Files' now.
2026-04-13 06:00:00.0011|INFO|ScheduledScans|Running scheduling 'Daily Scan of Files'
2026-04-13 06:00:00.0484|INFO|ScheduledScans|Refreshing resources on schedule 'Daily Scan of Files'
```

</details>

<details>

<summary>Console.ScheduledClassifications</summary>

Logs scheduled Classification scan job configuration and trigger events.

```
2026-04-11 23:59:59.9986|INFO|ScheduledClassifications|Running schedule '2dca14ac-b10e-44ef-b3b4-f8598ae8d354 - One time scan'
2026-04-12 00:02:06.9281|INFO|ScheduledClassifications|Run schedule '2dca14ac-b10e-44ef-b3b4-f8598ae8d354 - One time scan'
2026-04-12 00:02:08.1615|INFO|ScheduledClassifications|Saving modified schedule '2dca14ac-b10e-44ef-b3b4-f8598ae8d354 - One time scan'
```

</details>

<details>

<summary>Console.StorageAssessment</summary>

Logs storage assessment orchestration and result processing from the Console.

```
2026-03-11 19:18:18.2443|INFO|StorageAssessment|y6uajej - dontscanme-lfs-on-fargate-test-eu-1 has had inventory config deleted
2026-03-11 19:18:18.5769|INFO|StorageAssessment|y6uajej - dcapiscanningresults has had inventory config deleted
2026-03-11 19:18:19.0328|INFO|StorageAssessment|y6uajej - telavivlargefiles has had inventory config deleted
2026-03-11 19:18:19.4330|INFO|StorageAssessment|y6uajej - css-bucket-stockholm-01 has had inventory config deleted
```

</details>

<details>

<summary>Console.Subdomain</summary>

Logs of each time the console is assigned a new IP and when the subdomain is renamed.

```
2020-08-17T13:03:28.291-06:00 2020-08-17 19:03:28.2911|INFO|Subdomain|Updating IP address for console subdomain
2020-08-17T13:03:32.106-06:00 2020-08-17 19:03:32.1056|INFO|Subdomain|Updated IP address for console subdomain
2020-08-17T13:16:49.080-06:00 2020-08-17 19:16:49.0797|INFO|Subdomain|Checking if 'preview' is available.
2020-08-17T13:26:13.256-06:00 2020-08-17 19:26:13.2559|INFO|Subdomain|Checking if 'preview' is available.
2020-08-17T13:26:20.703-06:00 2020-08-17 19:26:20.7027|INFO|Subdomain|Checking if 'preview' is available.
2020-08-17T13:28:07.726-06:00 2020-08-17 19:28:07.7258|INFO|Subdomain|Checking if 'preview' is available.
2020-08-17T13:28:10.089-06:00 2020-08-17 19:28:10.0888|INFO|Subdomain|Setting console subdomain to 'preview'
2020-08-17T13:28:13.710-06:00 2020-08-17 19:28:13.7098|INFO|Subdomain|Set console subdomain to 'preview'
```

</details>

<details>

<summary>Console.System</summary>

Logs of general Console system information and errors and the return of the entitlement verification.

```
2020-08-21T13:25:58.374-06:00 2020-08-21 19:25:58.3713|INFO|System|Entitlement Verified.
```

</details>

<details>

<summary>Console.Updates</summary>

Logs of what updates are available and when an update is being performed.

```
2020-08-21T13:19:00.532-06:00 2020-08-21 19:19:00.5309|INFO|Updates|Getting version of CloudStorageSecAgentService-pk913wa
2020-08-21T13:19:00.532-06:00 2020-08-21 19:19:00.5309|INFO|Updates|CloudStorageSecAgentService-pk913wa is version v3.01.003
2020-08-21T13:19:00.533-06:00 2020-08-21 19:19:00.5309|INFO|Updates|Getting version of CloudStorageSecConsoleService-pk913wa
2020-08-21T13:19:00.585-06:00 2020-08-21 19:19:00.5847|INFO|Updates|CloudStorageSecConsoleService-pk913wa is version v3.02.005
2020-08-21T13:19:00.586-06:00 2020-08-21 19:19:00.5865|INFO|Updates|Looking for minor or patch update of CloudStorageSecAgentService-pk913wa greater than v3.01.003
2020-08-21T13:19:00.631-06:00 2020-08-21 19:19:00.6313|INFO|Updates|No minor or patch update available
2020-08-21T13:19:00.631-06:00 2020-08-21 19:19:00.6313|INFO|Updates|Looking for minor or patch update of CloudStorageSecConsoleService-pk913wa greater than v3.02.005
2020-08-21T13:19:00.664-06:00 2020-08-21 19:19:00.6644|INFO|Updates|No minor or patch update available
2020-08-21T13:19:00.665-06:00 2020-08-21 19:19:00.6644|INFO|Updates|Looking for major update greater than v3.02.005
2020-08-21T13:19:00.685-06:00 2020-08-21 19:19:00.6853|INFO|Updates|No major update available
```

</details>

<details>

<summary>Console.Users</summary>

Logs of all user activity including user creates/deletes, password resets, role changes.

```
2020-06-17T12:44:19.526-06:00 2020-06-17 18:44:19.5262|INFO|Users|Password changed for user 'admin'.
2020-06-17T20:06:32.240-06:00 2020-06-18 02:06:32.2403|INFO|Users|User 'aaron' created.
2020-06-17T23:57:25.905-06:00 2020-06-18 05:57:25.9051|INFO|Users|User 'ed' created.
2020-06-17T23:58:41.204-06:00 2020-06-18 05:58:41.2038|INFO|Users|Password changed for user 'ed'.
2020-06-17T23:58:58.252-06:00 2020-06-18 05:58:58.2527|INFO|Users|Submitted forgot password request for ed
2020-06-18T00:00:17.405-06:00 2020-06-18 06:00:17.4055|INFO|Users|Password reset for user 'ed'.
```

</details>

#### Log groups for the Agent

<details>

<summary>Agent.ClassificationResults</summary>

Records the outcome of each individual data classification scan, split into four streams: matching, non-matching, error, and unclassifiable.

```
2026-01-31 01:09:22.3268|INFO|ClassifyDiscoveredFilesJob_2026-01-31T00:01:56.7619987Z|NonMatchingClassificationResults|
{
    "date": "2026-01-31",
    "guid": "c909804b-0348-46f2-b6be-8ad248c18d13",
    "dateTime": "2026-01-31T01:09:22.2996548Z",
    "scanningAgentId": null,
    "accountId": "",
    "region": "us-east-1",
    "container": "classification-scaling",
    "objectPath": "740_SourceCodeExample.docx",
    "processedSize": 5616,
    "innerFilePath": null,
    "textMatchingSet": [],
    "error": null,
    "resultType": "NonMatching",
    "isUnscannable": false,
    "resultKind": "NotApplicable",
    "result": 0,
    "accountIdResultType": "#0",
    "dateScanned": "2026-01-31T01:09:22.2996548Z",
    "message": [
        null
    ],
    "trueFileType": "Unknown",
    "isMatch": false,
    "isError": false
}
```

</details>

<details>

<summary>Agent.ClassificationStatistics</summary>

Logs aggregated per-bucket data classification object and byte counts, flushed on a configurable checkpoint interval.

```
2026-01-31 01:03:47.6242|INFO|ClassifyDiscoveredFilesJob_2026-01-31T00:01:56.7619987Z|ClassificationStatistics|
{
    "bucketName": "classification-scaling",
    "date": "2026-01-31T00:00:00Z",
    "accountId": "",
    "appId": "",
    "numObjectsClassified": 5545,
    "numObjectsClassifiedMatching": 2075,
    "numObjectsClassifiedNonMatching": 3470,
    "numObjectsClassifiedError": 0,
    "numFilesClassifiedMatching": 2765,
    "numFilesClassifiedNonMatching": 4848,
    "numFilesClassifiedError": 0,
    "numObjectsClassifiedUnclassifiable": 0,
    "totalBytesClassified": 2957222491
}
```

</details>

<details>

<summary>Agent.Jobs</summary>

Logs job lifecycle events: creation, config, progress, and completion across both AV and Classification jobs.

```
2026-04-13 21:14:55.1873|INFO|ScanQueueJob_2026-04-13T21:12:46.5062498Z|Jobs|Gathering Remote Store Agent Config
```

</details>

<details>

<summary>Agent.Notifications</summary>

Logs outbound notifications sent to SNS topics, webhooks, and SecurityHub.

```
2025-10-20 07:49:18.3383|ERROR||Notifications|Unable to refresh subscriptions cache. Amazon.SimpleNotificationService.Model.InternalErrorException: Request could not be completed
```

</details>

<details>

<summary>Agent.ScanConfig</summary>

Scan settings for the agent.

Settings include, but are not limited to:

* Tags for the objects scanned
* Actions taken on objects
* Scan and skip lists
* Bucket handling configuration
* Classification Rules configuration for DLP

Note that the following snippet below has been shortened for brevity.

```
2024-07-23 18:07:31.9485|INFO|ScanConfig|
{
    "scanTaggingEnabled": true,
    "scanTagsExcluded": [],
    "classificationTaggingEnabled": true,
    "classificationTagsExcluded": [],
    "objectTagKeys": {
        "result": "scan-result",
        "dateScanned": "date-scanned",
        "virusName": "virus-name",
        "virusUploadedBy": "uploaded-by",
        "errorMessage": "message",
        "classificationResult": "classification-result",
        "dateClassified": "date-classified",
        "classificationMatches": "classification-matches",
        "classificationErrorMessage": "classification-message"
    },
    "quarantine": {
        "action": "Move",
        "moveBucketPrefix": "cloudstoragesecquarantine-aocxfe6"
    },
    "scanList": {},
    "skipList": {},
    "classifyList": {},
    "classifySkipList": {},
    "avEventProtectedBuckets": [
        "my-bucket"
    ],
    "classificationCustomRulesLastUpdated": "0001-01-01T00:00:00.0000000Z",
    "classificationRuleSets": {
        "canadian health service": [
            "PersonalhealthnumberBCCanada",
            "PersonalhealthnumberBCnearDOBCanada"
        ],
        "document classification": [
            "ConfidentialdocumentmarkersAustralia",
            "ConfidentialdocumentmarkersBelgium"
        ]
    },
    "dcEventBucketRuleSets": {},
    "dcScheduledBucketRuleSets": {},
    "efsClassificationRuleSets": {},
    "ebsClassificationRuleSets": {},
    "fsxClassificationRuleSets": {},
    "twoBucketConfig": {
        "regions": {},
        "buckets": {
            "my-bucket": {
                "destinationBucket": "destination-bucket"
            }
        }
    }
}
```

</details>

<details>

<summary>Agent.ScanResults</summary>

Scan results for clean, infected, error, or unscannable files.

<img src="/files/Re5H5Rz7TY2ciOUYtoc4" alt="" data-size="original">

Infected:

```
2020-08-24T15:15:33.067-06:00 2020-08-24 21:15:33.0672|INFO|InfectedScanResults|{"guid":"e132dc70-4582-476a-bb52-c57425c9792e","dateScanned":"2020-08-24T21:15:32.7952943Z","bucketName":"demo-destination-bucket","key":"virus/7hXNy9okVjpszoFP_virus_388_eicarcom2.zip","scanResult":"Infected","actionTaken":"Move","detectedVirus":"Win.Test.EICAR_HDB-1","virusUploadedBy":"AWS:AROA3K5IVNMVEDVQSN5PM:demo-bucket-transfer","errorMessage":"","fileExists":true,"movedTo":"cloudstoragesecquarantine-y6uajej-7xxxxxxxxxxx8-us-east-1","region":"us-east-1","accountId":"7xxxxxxxxxxx8"}

2020-08-24T15:15:33.067-06:00 2020-08-24 21:15:33.0672|INFO|InfectedScanResults|
{
    "guid": "e132dc70-4582-476a-bb52-c57425c9792e",
    "dateScanned": "2020-08-24T21:15:32.7952943Z",
    "bucketName": "demo-destination-bucket",
    "key": "virus/7hXNy9okVjpszoFP_virus_388_eicarcom2.zip",
    "scanResult": "Infected",
    "actionTaken": "Move",
    "detectedVirus": "Win.Test.EICAR_HDB-1",
    "virusUploadedBy": "AWS:AROA3K5IVNMVEDVQSN5PM:demo-bucket-transfer",
    "errorMessage": "",
    "fileExists": true,
    "movedTo": "cloudstoragesecquarantine-y6uajej-7xxxxxxxxxxx8-us-east-1",
    "region": "us-east-1",
    "accountId": "7xxxxxxxxxxx8"
}
```

Clean:

```
2020-08-24T15:15:33.243-06:00 2020-08-24 21:15:33.2432|INFO|CleanScanResults|{"guid":"5cab2514-5982-4323-bdbc-77540dca973d","dateScanned":"2020-08-24T21:15:33.186175Z","bucketName":"demo-destination-bucket","key":"1mb/xglRNavTNgA67qim_temp_1mb_file94857.txt","scanResult":"Clean","actionTaken":"None","detectedVirus":"","virusUploadedBy":"","errorMessage":"","fileExists":true,"movedTo":"","region":"us-east-1","accountId":"7xxxxxxxxxxx8"}

2020-08-24T15:15:33.344-06:00 2020-08-24 21:15:33.3444|INFO|CleanScanResults|
{
    "guid": "b589b129-ac54-493c-886c-30016899f3b9",
    "dateScanned": "2020-08-24T21:15:33.2737108Z",
    "bucketName": "demo-destination-bucket",
    "key": "1mb/xRP72vFa1Ays2Qr9_temp_1mb_file94075.txt",
    "scanResult": "Clean",
    "actionTaken": "None",
    "detectedVirus": "",
    "virusUploadedBy": "",
    "errorMessage": "",
    "fileExists": true,
    "movedTo": "",
    "region": "us-east-1",
    "accountId": "7xxxxxxxxxxx8"
}
```

Error:

```
2020-08-24T15:15:00.132-06:00 2020-08-24 21:15:00.1314|INFO|ErrorScanResults|{"guid":"5806ced2-688a-45d0-a2cb-71717176e66e","dateScanned":"2020-08-24T21:14:59.6058615Z","bucketName":"webinar-other-account-bucket-2","key":"ConsoleCloudFormationTemplate.yaml","scanResult":"Error","actionTaken":"None","detectedVirus":"","virusUploadedBy":"","errorMessage":"Unable to access the remote account.","fileExists":true,"movedTo":"","region":"us-east-1","accountId":"7xxxxxxxxxxx7"}

2020-08-24T15:15:00.206-06:00 2020-08-24 21:15:00.2055|INFO|ErrorScanResults|
{
    "guid": "c95dfbb1-2853-49e1-ace9-c2ae05bbf32a",
    "dateScanned": "2020-08-24T21:14:59.6058615Z",
    "bucketName": "webinar-other-account-bucket-2",
    "key": "ConsoleCloudFormationTemplate.yaml",
    "scanResult": "Error",
    "actionTaken": "None",
    "detectedVirus": "",
    "virusUploadedBy": "",
    "errorMessage": "Unable to access the remote account.",
    "fileExists": true,
    "movedTo": "",
    "region": "us-east-1",
    "accountId": "7xxxxxxxxxx7"
}
```

</details>

<details>

<summary>Agent.ScanStatistics</summary>

Every-hour statistics of an agents activity for each bucket being monitored. These include the number of files scanned, the number of clean/infected/error files, and the total bytes scanned.

```
2020-08-24T15:47:05.224-06:00 2020-08-24 21:47:05.2239|INFO|ScanStatistics|
{
    "bucketName": "preview-destination-bucket",
    "accountId": "7xxxxxxxxxx8",
    "numFilesScanned": 98,
    "numCleanFiles": 95,
    "numInfectedFiles": 3,
    "numErrors": 0,
    "totalBytesScanned": 9500560
}
```

</details>

<details>

<summary>Agent.StorageAssessment</summary>

Every-hour statistics of an agents activity for each bucket being monitored. These include the number of files scanned, the number of clean/infected/error files, and the total bytes scanned.

```
2020-08-24T15:47:05.224-06:00 2020-08-24 21:47:05.2239|INFO|ScanStatistics|
{
    "bucketName": "preview-destination-bucket",
    "accountId": "7xxxxxxxxxx8",
    "numFilesScanned": 98,
    "numCleanFiles": 95,
    "numInfectedFiles": 3,
    "numErrors": 0,
    "totalBytesScanned": 9500560
}
```

</details>

<details>

<summary>Agent.SystemEvents</summary>

Logs of general Agent system information and errors.

```
2020-08-24T15:24:35.368-06:00 2020-08-24 21:24:35.3568|INFO|SystemEvents|{"event":"Scanner Started","details":"Scanner is online and able to process files. ClamAV 0.102.3/25909/Mon Aug 24 13:26:24 2020","instanceId":"arn:aws:ecs:us-east-1:779353418538:task/7965e996-d967-4d7f-be11-e05679534f2e","eventDate":"2020-08-24T21:24:35.2518636Z"}

2020-08-24T15:28:09.355-06:00 2020-08-24 21:28:09.3554|INFO|SystemEvents|
{
    "event": "Scanner Stopped",
    "details": "Scanner is going offline.",
    "instanceId": "arn:aws:ecs:us-east-1:779353418538:task/7965e996-d967-4d7f-be11-e05679534f2e",
    "eventDate": "2020-08-24T21:28:09.3554279Z"
}
```

</details>

#### Log groups for ECS <a href="#iam-permissions-review" id="iam-permissions-review"></a>

As of version 6.06 we enable ECS logging by default. These logs will be shown in the following log groups.

For each of these log groups you will see your seven character application ID in the title of each log group as noted below by the `AppID` between the `ECS` and type of ECS service the log is for.

<details>

<summary>ECS.AppID.API</summary>

Log groups related to the ECS API Agent Service

</details>

<details>

<summary>ECS.AppID.Console</summary>

Log groups related to the ECS Console Service

</details>

<details>

<summary>ECS.AppID.AVEvent</summary>

Log groups related to the ECS AV Event Agent Service

</details>

<details>

<summary>ECS.AppID.DCEvent</summary>

Log groups related to the ECS DC Event Agent Service

</details>

<details>

<summary>ECS.AppID.LargeFile</summary>

Log groups related to the Large File scan jobs

</details>

### IAM Permissions Review <a href="#iam-permissions-review" id="iam-permissions-review"></a>

We have been able to simplify the management and delivery of the solution such that there are very few tasks the administrator is required to perform inside the AWS Console. As a result, the Console and EventAgent have a number of permissions assigned to them within their respective roles to allow them to perform the actions needed on your behalf. In all cases, we went with a `least privilege` model wherever possible. There are a few instances where we have assigned `*` when it is required. Below you will find a review of the two IAM Roles we create and assign to the Console and scanning Agents.

Please review and [Contact Us](/contact-us) if you have any questions we can clear up for you.

**The permission descriptions below follow the format:**

```
- system-name
    - permission 1
        - reason it is needed
    - ...
        - reason it is needed
    - permission n
        - reason it is needed
```

<details>

<summary>Console Roles (All Resources)</summary>

```
* application-autoscaling
    * PutScalingPolicy
        * For attaching auto scaling policies to the Agent services
    * RegisterScalableTarget
        * For allowing Agent services to be scalable
* aws-marketplace
    * MeterUsage
        * For submitting application data usage
* cloudwatch
    * GetMetricStatistics
        * For getting bucket size information
* ec2
    * CreateSecurityGroup
        * For creating a security group for the Agent services
    * DescribeNetworkInterfaces
        * For getting the IP of the new Console after an update has been applied
    * DescribeSubnets
        * For getting the list of subnets for Agent service configuration
    * DescribeVpcs
        * For getting the list of VPCs for Agent service configuration
* ecs
    * CreateCluster
        * For creating clusters in regions other than the region the console is in, for Agent services in those regions
    * DescribeTaskDefinition
        * For checking the current version of the Console and Agents
    * DescribeTasks
        * For getting the details of a new console task while applying updates
    * ListTasks
        * For getting the list of running console tasks while applying updates
    * RegisterTaskDefinition
        * For creating new Agent services and applying updates to the Console and Agents
* logs (all of the below are needed for creating and monitoring cloudwatch logs)
    * CreateLogStream
    * DescribeLogGroups
    * DescribeLogStreams
    * GetLogEvents
    * GetLogRecord
    * GetQueryResults
    * PutLogEvents
    * StartQuery
    * StopQuery
* s3
    * CreateBucket
        * For creating a quarantine bucket in each region that has protected buckets
    * GetBucketAcl
        * For checking if a bucket is public
    * GetBucketLocation
        * For finding the region of the bucket
    * GetBucketNotification
        * For detecting events attached to the bucket
    * GetBucketPolicy
        * For checking if a bucket is public
    * GetBucketPolicyStatus
        * For checking if a bucket is public
    * GetObjectAcl
        * For checking if objects are public
    * ListAllMyBuckets
        * For listing buckets in the Console
    * ListBucket
        * For identifying files to scan
    * PutBucketAcl
        * For making buckets non-public
    * PutBucketNotification
        * For setting events on buckets to enable protection
    * PutBucketPolicy
        * For making buckets non-public
    * PutBucketPublicAccessBlock
        * For making buckets non-public
    * PutObjectAcl
        * For making objects non-public
* sns
    * ListSubscriptions
        * For unsubscribing the CloudStorageSec SQS Queue from a non CloudStorageSec SNS Topic
    * ListSubscriptionsByTopic
        * For unsubscribing the CloudStorageSec SQS Queue from a non CloudStorageSec SNS Topic
    * ListTopics
        * For unsubscribing the CloudStorageSec SQS Queue from a non CloudStorageSec SNS Topic
    * Subscribe
        * For subscribing the CloudStorageSec SQS Queue to a SNS Topic
    * Unsubscribe
        * For unsubscribing the CloudStorageSec SQS Queue from a SNS Topic
* ssm
    * CreateDocument
        * For creating the initial AppConfig document for CloudStorageSec Agents
    * ListDocuments
        * For creating the initial AppConfig document for CloudStorageSec Agents
```

</details>

<details>

<summary>Console Permissions (Targeted Resources)</summary>

```
* appconfig
    * CreateConfigurationProfile
        * For one-time creation of Configuration Profile for CloudStorageSec Agents
    * ListConfigurationProfiles
        * For retreiving the Configuration Profile ID upon Console startup
    * StartDeployment
        * For deploying new version of Agent configuration
* cloudwatch
    * PutMetricAlarm
        * For creating Agent autoscaling alarm based on SQS queue size
* dynamodb (all of the below are needed for various dynamodb operations on CloudStorageSec tables)
    * DeleteItem
    * DescribeTable
    * GetItem
    * PutItem
    * Query
    * Scan
    * UpdateItem
* ecr
    * ListImages
        * For checking if there are new versions of the Console or Agent available
* ecs
    * CreateService
        * For creating the Agent service in a region that did not previously have any protected buckets
    * DescribeClusters
        * For checking if a cluster for Agents already exists in a given region
    * DescribeServices
        * For checking if the Agent service already exists in a given cluster
    * UpdateService
        * For updating the Console or Agent service(s) to point at a new application version
* iam
    * PassRole
        * For assigning the appropriate role to the created AppConfig Document
* sns
    * AddPermission
        * For allowing S3 buckets to send messages to the CloudStorageSec SNS Topic
    * CreateTopic
        * For creating the CloudStorageSec SNS Topic
    * SetTopicAttributes
        * For attaching the policy allowing S3 buckets to send messages to the CloudStorageSec SNS Topic
* sqs
    * CreateQueue
        * For creating the CloudStorageSec SQS Queue
    * GetQueueAttributes
        * For getting the ARN and current Policy of the CloudStorageSec SQS Queue
    * SendMessage
        * For adding messages to the CloudStorageSec SQS Queue
    * SendMessageBatch
        * For batch adding messages to the CloudStorageSec SQS Queue 
    * SetQueueAttributes
        * For setting the Policy
* ssm (all of the below are for updating the Agent config document)
    * DescribeDocument
    * GetDocument
    * UpdateDocument
```

</details>

<details>

<summary>Agent Permissions (All Resources)</summary>

```
* appconfig (all of the below are for requesting an Agent config deployment)
    * ListApplications
    * ListDeploymentStrategies
* s3
    * DeleteObject
        * For deleting infected objects
    * GetObject
        * For getting objects to scan
    * GetObjectTagging
        * For getting current tags of an object (needed when moving objects to quarantine)
    * ListBucket
        * For listing objects in a bucket
    * PutObject
        * For copying object to quarantine
    * PutObjectAcl
        * For copying object ACLs to quarantine
    * PutObjectTagging
        * For tagging objects with scan results (and when moving an object to quarantine)
* ssm
    * ListDocuments
        * For requesting an Agent config deployment
```

</details>

<details>

<summary>Agent Permissions (Targeted Resources)</summary>

```
* appconfig (the below are for receiving Agent configuration)
    * GetApplication
    * GetConfiguration
    * GetConfigurationProfile
    * GetDeploymentStrategy
    * GetEnvironment
    * ListConfigurationProfiles
    * ListDeployments
    * ListEnvironments
* dynamodb (the below are for submitting agent scan data into the Agent tables for the console)
    * DescribeTable
    * PutItem
    * UpdateItem
* logs (the below are needed for creating cloudwatch logs)
    * CreateLogStream
    * DescribeLogGroups
    * PutLogEvents
* sqs (the below are for processing the CloudStorageSec SQS queue)
    * DeleteMessage
    * GetQueueAttributes
    * ReceiveMessage
* ssm
    * GetDocument
        * For accessing the app config document for Agent configuration
```

</details>

### Permissions Policies

### **Console Role**

<details>

<summary>Trust Relationships</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "ecs.amazonaws.com",
                    "ecs-tasks.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        },
        {
            "Sid": "AllowSelfAssume",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::{AwsAccount}:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::{AwsAccount}:role/CloudStorageSecConsoleRole-{appId}"
                }
            }
        }
    ]
}
```

</details>

#### Customer Inline Policies

<details>

<summary>PoliciesCreation</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "iam:TagPolicy",
                "iam:UntagPolicy",
                "iam:CreatePolicy",
                "iam:DeletePolicy",
                "iam:DeletePolicyVersion",
                "iam:ListPolicyVersions",
                "iam:CreatePolicyVersion"
            ],
            "Resource": [
                "arn:aws:iam::{AwsAccount}:policy/CloudStorageSecConsolePolicy-{appId}-EC2-Management-Policy",
                "arn:aws:iam::{AwsAccount}:policy/CloudStorageSecConsolePolicy-{appId}-Infrastructure-Management-Policy",
                "arn:aws:iam::{AwsAccount}:policy/CloudStorageSecConsolePolicy-{appId}-Logging-And-Monitoring-Policy",
                "arn:aws:iam::{AwsAccount}:policy/CloudStorageSecConsolePolicy-{appId}-Application-Resources-Policy",
                "arn:aws:iam::{AwsAccount}:policy/CloudStorageSecConsolePolicy-{appId}-Security-And-Access-Policy"
            ],
            "Effect": "Allow",
            "Sid": "IAMCSSPoliciesAction"
        }
    ]
}
```

</details>

<details>

<summary>ApiLb</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ec2:DescribeAccountAttributes",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeTargetGroups"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "AllResources"
        },
        {
            "Action": [
                "elasticloadbalancing:Create*",
                "elasticloadbalancing:Delete*",
                "elasticloadbalancing:Modify*",
                "elasticloadbalancing:*Tags",
                "elasticloadbalancing:SetSubnets",
                "iam:CreateServiceLinkedRole"
            ],
            "Resource": [
                "arn:aws:elasticloadbalancing:*:*:listener/*/*{console-appid}/*",
                "arn:aws:elasticloadbalancing:*:*:loadbalancer/*/*{console-appid}/*",
                "arn:aws:elasticloadbalancing:*:*:targetgroup/*i{console-appid}/*",
                "arn:aws:iam::*:role/aws-service-role/elasticloadbalancing.amazonaws.com/AWSServiceRoleForElasticLoadBalancing"
            ],
            "Effect": "Allow",
            "Sid": "RestrictedResources"
        }
    ]
}
```

</details>

<details>

<summary>AwsLicensing</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "license-manager:CheckoutLicense",
                "license-manager:ListReceivedLicenses"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "AllResources"
        }
    ]
}
```

</details>

<details>

<summary>CloudTrailLake</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "cloudtrail:*DataStore*",
                "cloudtrail:*Quer*",
                "cloudtrail:*Channel*",
                "cloudtrail-data:*Audit*",
                "iam:ListRoles",
                "iam:GetRolePolicy",
                "iam:GetUser"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "CloudTrail"
        },
        {
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "cloudtrail.amazonaws.com"
                }
            },
            "Action": [
                "iam:PassRole"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "PassRole"
        }
    ]
}
```

</details>

#### Customer Managed Policies

<details>

<summary>Application-Resources-Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:CreateBucket",
                "s3:PutObject",
                "s3:PutObjectTagging",
                "s3:DeleteBucket",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:DeleteObjectTagging",
                "s3:PutBucketTagging",
                "s3:GetBucketTagging"
            ],
            "Resource": [
                "arn:aws:s3:::{applicaction-Bucket}",
                "arn:aws:s3:::{applicaction-Bucket}/*"
            ],
            "Effect": "Allow",
            "Sid": "CloudStorageSecS3Bucket"
        },
        {
            "Action": [
                "s3:CreateBucket",
                "s3:DeleteBucket",
                "s3:ListBucket",
                "s3:PutLifecycleConfiguration",
                "s3:PutEncryptionConfiguration",
                "s3:PutBucketTagging",
                "s3:GetBucketTagging",
                "s3:GetObject",
                "s3:GetObjectTagging",
                "s3:GetObjectAttributes",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:PutObjectTagging",
                "s3:PutObjectVersionAcl",
                "s3:PutObjectVersionTagging",
                "s3:PutBucketPolicy",
                "s3:DeleteObject",
                "s3:DeleteObjectTagging",
                "s3:DeleteObjectVersion",
                "s3:DeleteObjectVersionTagging",
                "s3:DeleteBucketPolicy"
            ],
            "Resource": [
                "arn:aws:s3:::{quarantine-Bucket}-*",
                "arn:aws:s3:::{quarantine-Bucket}-*/*"
            ],
            "Effect": "Allow",
            "Sid": "CloudStorageSecS3QuarantineBucket"
        },
        {
            "Action": [
                "dynamodb:BatchWriteItem",
                "dynamodb:CreateTable",
                "dynamodb:DeleteItem",
                "dynamodb:DeleteTable",
                "dynamodb:DescribeContinuousBackups",
                "dynamodb:DescribeTable",
                "dynamodb:GetItem",
                "dynamodb:ListTagsOfResource",
                "dynamodb:PutItem",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:TagResource",
                "dynamodb:UntagResource",
                "dynamodb:UpdateContinuousBackups",
                "dynamodb:UpdateItem",
                "dynamodb:UpdateTable"
            ],
            "Resource": [
                "arn:aws:dynamodb:{Aws-Region}:{AwsAccount}:table/{appId}.*"
            ],
            "Effect": "Allow",
            "Sid": "DynamoDb"
        },
        {
            "Action": [
                "sqs:CreateQueue",
                "sqs:DeleteQueue",
                "sqs:DeleteMessage",
                "sqs:GetQueueAttributes",
                "sqs:GetQueueUrl",
                "sqs:ListQueueTags",
                "sqs:ListQueues",
                "sqs:SetQueueAttributes",
                "sqs:SendMessage",
                "sqs:TagQueue",
                "sqs:ReceiveMessage",
                "sqs:UntagQueue"
            ],
            "Resource": [
                "arn:aws:sqs:*:{AwsAccount}:CloudStorageSecQueue-{appId}*",
                "arn:aws:sqs:*:{AwsAccount}:CloudStorageSecQueue-DC-{appId}*",
                "arn:aws:sqs:*:{AwsAccount}:CloudStorageSecQueue-EFS-{appId}*",
                "arn:aws:sqs:*:{AwsAccount}:CloudStorageSecQueue-FSx-{appId}*",
                "arn:aws:sqs:*:{AwsAccount}:CloudStorageSecQueue-ScannedItems-{appId}*",
                "arn:aws:sqs:*:{AwsAccount}:CloudStorageSecRetroQueue-{appId}*"
            ],
            "Effect": "Allow",
            "Sid": "SQS"
        },
        {
            "Action": [
                "elasticfilesystem:CreateTags",
                "elasticfilesystem:CreateMountTarget",
                "elasticfilesystem:CreateAccessPoint",
                "elasticfilesystem:DescribeFileSystems",
                "elasticfilesystem:DescribeMountTargets",
                "elasticfilesystem:DescribeMountTargetSecurityGroups",
                "elasticfilesystem:DescribeTags",
                "elasticfilesystem:TagResource",
                "elasticfilesystem:UntagResource",
                "elasticfilesystem:ListTagsForResource",
                "elasticfilesystem:ModifyMountTargetSecurityGroups"
            ],
            "Resource": [
                "arn:aws:elasticfilesystem:*:*:file-system/*"
            ],
            "Effect": "Allow",
            "Sid": "EFSActions"
        },
        {
            "Action": [
                "elasticfilesystem:DeleteAccessPoint",
                "elasticfilesystem:DescribeAccessPoints"
            ],
            "Resource": [
                "arn:aws:elasticfilesystem:*:*:file-system/*",
                "arn:aws:elasticfilesystem:*:*:access-point/*"
            ],
            "Effect": "Allow",
            "Sid": "EFSAccessPointsActions"
        },
        {
            "Action": [
                "ecr:ListImages"
            ],
            "Resource": [
                "arn:aws:ecr:{Aws-region}:564477214187:repository/cloudstoragesecurity/*"
            ],
            "Effect": "Allow",
            "Sid": "ECR"
        },
        {
            "Action": [
                "bedrock:InvokeModel",
                "bedrock:GetFoundationModel",
                "bedrock:ListFoundationModels"
            ],
            "Resource": "arn:aws:bedrock:*::foundation-model/*",
            "Effect": "Allow",
            "Sid": "Bedrock"
        }
    ]
}
```

</details>

<details>

<summary>EC2-Management-Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/CloudStorageSecExtraLargeFileScanning": "ExtraLargeFileScanning"
                }
            },
            "Action": [
                "ec2:DeleteVolume",
                "ec2:TerminateInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:*",
            "Effect": "Allow",
            "Sid": "DeleteLargeFileScanningVolumes"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/CloudStorageSec-{appID}": "Snapshot"
                }
            },
            "Action": [
                "ec2:CreateTags",
                "ec2:CreateSnapshot"
            ],
            "Resource": [
                "arn:aws:ec2:*::snapshot/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2CreateSnapshot"
        },
        {
            "Action": [
                "ec2:CreateSnapshot"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:volume/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2CreateSnapshotForAnyVolume"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/CloudStorageSec-{appId}": "Snapshot"
                }
            },
            "Action": [
                "ec2:DeleteSnapshot"
            ],
            "Resource": [
                "arn:aws:ec2:*::snapshot/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2DeleteSnapshot"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/CloudStorageSec-{appId}": "Volume"
                }
            },
            "Action": [
                "ec2:CreateTags",
                "ec2:CreateVolume"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:volume/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2VolumeCreate"
        },
        {
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/CloudStorageSec-{appId}": "Volume"
                }
            },
            "Action": [
                "ec2:DeleteVolume"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:volume/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2VolumeDelete"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/CloudStorageSec-{appId}": "SecurityGroupRule"
                }
            },
            "Action": [
                "ec2:CreateTags",
                "ec2:AuthorizeSecurityGroupIngress"
            ],
            "Resource": [
                "arn:aws:ec2:*:{awsAccount}:security-group-rule/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2CreateSecurityGroupRule"
        },
        {
            "Action": [
                "ec2:CreateTags",
                "ec2:DeleteTags",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:ModifyNetworkInterfaceAttribute",
                "ec2:RevokeSecurityGroupIngress"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:{awsAccount}:security-group/*",
                "arn:aws:ec2:*:*:{awsAccount}:network-interface/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2CreateSecurityGroupRuleIngress"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/CloudStorageSec-{appId}": "SecurityGroup"
                }
            },
            "Action": [
                "ec2:CreateTags",
                "ec2:CreateSecurityGroup"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:{awsAccount}:security-group/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2CreateSecurityGroup"
        },
        {
            "Action": [
                "ec2:CreateTags",
                "ec2:CreateSecurityGroup"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:{awsAccount}:vpc/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2CreateSecurityGroupVPC"
        },
        {
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:{awsAccount}:security-group/*",
                "arn:aws:ec2:*:*:{awsAccount}:subnet/*",
                "arn:aws:ec2:*::image/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2RunInstanceInfrastructure"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/CloudStorageSec-{appId}": "EC2Instance"
                }
            },
            "Action": [
                "ec2:RunInstances",
                "ec2:CreateTags",
                "iam:PassRole",
                "ssm:GetParameters"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:{awsAccount}:instance/*",
                "arn:aws:ec2:*:*:{awsAccount}:network-interface/*",
                "arn:aws:ec2:*:*:{awsAccount}:volume/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2RunInstance"
        },
        {
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/CloudStorageSec-{appId}": "EC2Instance"
                }
            },
            "Action": [
                "ec2:TerminateInstances"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:{awsAccount}:instance/*"
            ],
            "Effect": "Allow",
            "Sid": "EC2TerminateInstance"
        }
    ]
}
```

</details>

<details>

<summary>Infrastructure-Management-Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "cloudformation:DescribeStacks",
                "cloudformation:UpdateStack"
            ],
            "Resource": [
                "arn:aws:cloudformation:{Aws-Region}:*:stack/{CloudFormationStack-name}/*"
            ],
            "Effect": "Allow",
            "Sid": "CloudFormation"
        },
        {
            "Action": [
                "ecs:TagResource",
                "ecs:ListTagsForResource",
                "ecs:UntagResource",
                "ecs:CreateCluster",
                "ecs:DeleteCluster",
                "ecs:DescribeClusters",
                "ecs:ListContainerInstances",
                "ecs:CreateService",
                "ecs:DeleteService",
                "ecs:DescribeServices",
                "ecs:UpdateService",
                "ecs:ListTasks",
                "ecs:DescribeTasks",
                "ecs:StopTask"
            ],
            "Resource": [
                "arn:aws:ecs:*:{AwsAccount}:cluster/CloudStorageSecCluster-{appId}",
                "arn:aws:ecs:*:{AwsAccount}:service/CloudStorageSecCluster-{appId}/*",
                "arn:aws:ecs:*:{AwsAccount}:container-instance/CloudStorageSecCluster-{appId}/*",
                "arn:aws:ecs:*:{AwsAccount}:task/CloudStorageSecCluster-{appId}/*"
            ],
            "Effect": "Allow",
            "Sid": "ECSCluster"
        },
        {
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "aws:RequestTag/CloudStorageSec-{appId}": [
                        "TaskDefinition",
                        "ConsoleTaskDefinition"
                    ]
                }
            },
            "Action": [
                "ecs:TagResource",
                "ecs:RegisterTaskDefinition"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "ECSRegisterTask"
        },
        {
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "aws:ResourceTag/CloudStorageSec-{appId}": [
                        "TaskDefinition",
                        "ConsoleTaskDefinition"
                    ]
                }
            },
            "Action": [
                "ecs:TagResource",
                "ecs:ListTagsForResource",
                "ecs:UntagResource",
                "ecs:RunTask",
                "ecs:DeleteTaskDefinitions"
            ],
            "Resource": "arn:aws:ecs:*:{Aws-Account}:task-definition/*-{appId}:*",
            "Effect": "Allow",
            "Sid": "ECSRunDeleteTask"
        },
        {
            "Condition": {
                "StringEquals": {
                    "application-autoscaling:scalable-dimension": "ecs:service:DesiredCount"
                }
            },
            "Action": [
                "application-autoscaling:DeregisterScalableTarget",
                "application-autoscaling:PutScalingPolicy",
                "application-autoscaling:RegisterScalableTarget"
            ],
            "Resource": [
                "arn:aws:application-autoscaling:*:{Aws-Account}:scalable-target/*"
            ],
            "Effect": "Allow",
            "Sid": "ApplicationAutoscaling"
        },
        {
            "Condition": {
                "ForAllValues:StringEquals": {
                    "aws:TagKeys": "CloudStorageSec-{appId}"
                }
            },
            "Action": [
                "application-autoscaling:TagResource",
                "application-autoscaling:UntagResource"
            ],
            "Resource": [
                "arn:aws:application-autoscaling:*:{Aws-Account}:scalable-target/*"
            ],
            "Effect": "Allow",
            "Sid": "ApplicationAutoscalingTagging"
        },
        {
            "Action": [
                "appconfig:DeleteConfigurationProfile",
                "appconfig:GetLatestConfiguration",
                "appconfig:ListConfigurationProfiles",
                "appconfig:StartDeployment",
                "appconfig:StartConfigurationSession",
                "appconfig:TagResource",
                "appconfig:UpdateApplication",
                "appconfig:UpdateConfigurationProfile",
                "appconfig:UpdateDeploymentStrategy",
                "appconfig:UpdateEnvironment",
                "appconfig:UntagResource"
            ],
            "Resource": [
                "arn:aws:appconfig:*:{Aws-Account}:application/{appId}/*",
                "arn:aws:appconfig:*:{Aws-Account}:application/{appId}",
                "arn:aws:appconfig:*:{Aws-Account}:deploymentstrategy/{appId}"
            ],
            "Effect": "Allow",
            "Sid": "AppConfig"
        },
        {
            "Action": [
                "ssm:AddTagsToResource",
                "ssm:ListTagsForResource",
                "ssm:RemoveTagsFromResource",
                "ssm:CreateDocument",
                "ssm:DeleteDocument",
                "ssm:DescribeDocument",
                "ssm:DescribeDocumentParameters",
                "ssm:DescribeDocumentPermission",
                "ssm:ModifyDocumentPermission",
                "ssm:GetDocument",
                "ssm:ListDocuments",
                "ssm:UpdateDocument",
                "ssm:UpdateDocumentDefaultVersion",
                "ssm:UpdateDocumentMetadata",
                "ssm:DeleteParameter",
                "ssm:DeleteParameters",
                "ssm:DescribeParameters",
                "ssm:GetParameter",
                "ssm:GetParameterHistory",
                "ssm:GetParameters",
                "ssm:GetParametersByPath",
                "ssm:LabelParameterVersion",
                "ssm:PutParameter",
                "ssm:UnlabelParameterVersion",
                "secretsmanager:CreateSecret",
                "secretsmanager:DeleteSecret",
                "secretsmanager:DescribeSecret",
                "secretsmanager:GetSecretValue",
                "secretsmanager:PutSecretValue",
                "secretsmanager:RestoreSecret",
                "secretsmanager:TagResource"
            ],
            "Resource": [
                "arn:aws:ssm:*:{AwsAccount}:parameter/aws/service/ecs/optimized-ami/amazon-linux*/recommended/image_id",
                "arn:aws:ssm:*:{AwsAccount}:document/*{appId}",
                "arn:aws:ssm:*:{AwsAccount}:parameter/*{appId}/*",
                "arn:aws:ssm:*:{AwsAccount}:parameter/*{appId}",
                "arn:aws:ssm:*::parameter/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id",
                "arn:aws:secretsmanager:{Aws-Region}:*:secret:cloudstoragesec/*"
            ],
            "Effect": "Allow",
            "Sid": "SSMActions"
        },
        {
            "Action": [
                "events:CreateEventBus",
                "events:DeleteEventBus",
                "events:DeleteRule",
                "events:DescribeEventBus",
                "events:DescribeRule",
                "events:DisableRule",
                "events:EnableRule",
                "events:ListRuleNamesByTarget",
                "events:ListRules",
                "events:ListTagsForResource",
                "events:PutPermission",
                "events:PutRule",
                "events:PutTargets",
                "events:RemovePermission",
                "events:RemoveTargets",
                "events:TagResource",
                "events:UntagResource",
                "events:UpdateEventBus"
            ],
            "Resource": [
                "arn:aws:events:*:*:*/*{appId}*",
                "arn:aws:events:*:*:*/default",
                "arn:aws:events:*:*:rule/*"
            ],
            "Effect": "Allow",
            "Sid": "EventBridgeActions"
        }
    ]
}
```

</details>

<details>

<summary>Logging-And-Monitoring-Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogStream",
                "logs:GetLogEvents",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:{AwsAccount}:log-group:CloudStorageSecurity.*:log-stream:*",
            "Effect": "Allow",
            "Sid": "CloudWatchLogStream"
        },
        {
            "Action": [
                "logs:ListTagsForResource",
                "logs:TagResource",
                "logs:DescribeLogStreams",
                "logs:FilterLogEvents",
                "logs:CreateLogGroup",
                "logs:DeleteLogGroup",
                "logs:PutRetentionPolicy",
                "logs:TagLogGroup",
                "logs:UntagLogGroup",
                "logs:UntagResource"
            ],
            "Resource": [
                "arn:aws:logs:*:{AwsAccount}:log-group:CloudStorageSecurity.*"
            ],
            "Effect": "Allow",
            "Sid": "CloudWatchLog"
        },
        {
            "Action": [
                "logs:StartQuery",
                "logs:GetQueryResults"
            ],
            "Resource": [
                "arn:aws:logs:*:{AwsAccount}:log-group:CloudStorageSecurity.Agent.Jobs:*",
                "arn:aws:logs:*:{AwsAccount}:log-group:CloudStorageSecurity.Agent.ScanStatistics:*",
                "arn:aws:logs:*:{AwsAccount}:log-group:CloudStorageSecurity.Agent.ClassificationStatistics:*",
                "arn:aws:logs:*:{AwsAccount}:log-group:CloudStorageSecurity.Agent.SystemEvents:*",
                "arn:aws:logs:*:{AwsAccount}:log-group:CloudStorageSecurity.Agent.ScanResults:*",
                "arn:aws:logs:*:{AwsAccount}:log-group:CloudStorageSecurity.Agent.ClassificationResults:*"
            ],
            "Effect": "Allow",
            "Sid": "CloudWatchLogQuery"
        },
        {
            "Action": [
                "cloudwatch:DeleteAlarms",
                "cloudwatch:DescribeAlarms",
                "cloudwatch:PutMetricAlarm"
            ],
            "Resource": [
                "arn:aws:cloudwatch:*:{AwsAccount}:alarm:CloudStorageSecLargeQueue-{appId}",
                "arn:aws:cloudwatch:*:{AwsAccount}:alarm:CloudStorageSecSmallQueue-{appId}",
                "arn:aws:cloudwatch:*:{AwsAccount}:alarm:CloudStorageSecLargeQueue-DC-{appId}",
                "arn:aws:cloudwatch:*:{AwsAccount}:alarm:CloudStorageSecSmallQueue-DC-{appId}",
                "arn:aws:cloudwatch:*:{AwsAccount}:alarm:CloudStorageSecConsole-HealthCheck-Alarm-{appId}",
                "arn:aws:cloudwatch:*:{AwsAccount}:alarm:TargetTracking-service/CloudStorageSecCluster-{appId}/CloudStorageSecApiAgentService-{appId}*"
            ],
            "Effect": "Allow",
            "Sid": "CloudWatchAlarm"
        },
        {
            "Action": [
                "securityhub:GetFindings",
                "securityhub:DisableImportFindingsForProduct",
                "securityhub:BatchImportFindings",
                "securityhub:EnableImportFindingsForProduct"
            ],
            "Resource": [
                "arn:aws:securityhub:{AwsRegion}:{AwsAccount}:product/cloud-storage-security/antivirus-for-amazon-s3",
                "arn:aws:securityhub:{AwsRegion}:{AwsAccount}:product-subscription/cloud-storage-security/antivirus-for-amazon-s3",
                "arn:aws:securityhub:{AwsRegion}:{AwsAccount}:hub/default"
            ],
            "Effect": "Allow",
            "Sid": "SecurityHubActions"
        },
        {
            "Condition": {
                "StringEquals": {
                    "cloudwatch:Namespace": "AWS/ECS"
                }
            },
            "Action": "cloudwatch:PutMetricData",
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "PutECSMetricData"
        },
        {
            "Action": [
                "sns:Subscribe",
                "sns:AddPermission",
                "sns:CreateTopic",
                "sns:DeleteTopic",
                "sns:SetTopicAttributes",
                "sns:GetTopicAttributes",
                "sns:GetSubscriptionAttributes",
                "sns:SetSubscriptionAttributes",
                "sns:ListSubscriptionsByTopic",
                "sns:Publish",
                "sns:TagResource",
                "sns:UnTagResource"
            ],
            "Resource": [
                "arn:aws:sns:*:{AwsAccount}:CloudStorageSecNotificationsTopic-{appId}",
                "arn:aws:sns:*:{AwsAccount}:CloudStorageSecTopic-{appId}"
            ],
            "Effect": "Allow",
            "Sid": "SNS"
        },
        {
            "Action": [
                "servicequotas:GetServiceQuota"
            ],
            "Resource": [
                "arn:aws:servicequotas:*:{AwsAccount}:ebs/L-D18FCD1D",
                "arn:aws:servicequotas:*:{AwsAccount}:ebs/L-7A658B76"
            ],
            "Effect": "Allow",
            "Sid": "ServiceQuotas"
        },
        {
            "Action": [
                "budgets:ViewBudget",
                "budgets:ModifyBudget"
            ],
            "Resource": [
                "arn:aws:budgets::{AwsAccount}:budget/Cloud Storage Security Application Cost Budget - Application {appId}"
            ],
            "Effect": "Allow",
            "Sid": "Budgets"
        }
    ]
}
```

</details>

<details>

<summary>Security-And-Access-Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "cognito-idp:AdminGetUser",
                "cognito-idp:AdminCreateUser",
                "cognito-idp:AdminAddUserToGroup",
                "cognito-idp:AdminDeleteUser",
                "cognito-idp:AdminDeleteUserAttributes",
                "cognito-idp:AdminDisableUser",
                "cognito-idp:AdminEnableUser",
                "cognito-idp:AdminRemoveUserFromGroup",
                "cognito-idp:AdminListGroupsForUser",
                "cognito-idp:AdminUpdateUserAttributes",
                "cognito-idp:ListTagsForResource",
                "cognito-idp:ListUsers",
                "cognito-idp:ListUsersInGroup",
                "cognito-idp:CreateGroup",
                "cognito-idp:DeleteGroup",
                "cognito-idp:DescribeUserPoolClient",
                "cognito-idp:DescribeUserPool",
                "cognito-idp:UpdateUserPool",
                "cognito-idp:ListIdentityProviders",
                "cognito-idp:SetUserPoolMfaConfig",
                "cognito-idp:AdminSetUserMFAPreference"
            ],
            "Resource": [
                "arn:aws:cognito-idp:{AwsRegion}:{AwsAccount}:userpool/{UserPool-Id}"
            ],
            "Effect": "Allow",
            "Sid": "Cognito"
        },
        {
            "Action": [
                "iam:AddRoleToInstanceProfile",
                "iam:CreateInstanceProfile",
                "iam:DeleteInstanceProfile",
                "iam:GetInstanceProfile",
                "iam:RemoveRoleFromInstanceProfile",
                "iam:TagInstanceProfile",
                "iam:UntagInstanceProfile",
                "iam:UpdateAssumeRolePolicy",
                "iam:AttachRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:DetachRolePolicy",
                "iam:GetRolePolicy",
                "iam:PutRolePolicy",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:GetRole",
                "iam:PassRole",
                "iam:TagRole",
                "iam:UntagRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/CloudStorageSecUserPoolRole-{appId}",
                "arn:aws:iam::{AwsAccount}:role/AppConfigAgentConfigurationDocumentRole-{appId}",
                "arn:aws:iam::{AwsAccount}:role/CloudStorageSecExecutionRole-{appId}",
                "arn:aws:iam::{AwsAccount}:role/CloudStorageSecConsoleRole-{appId}",
                "arn:aws:iam::{AwsAccount}:role/CloudStorageSecAgentRole-{appId}",
                "arn:aws:iam::*:role/CloudStorageSecEc2ContainerRole-{appId}",
                "arn:aws:iam::*:instance-profile/CloudStorageSecEc2ContainerRole-{appId}",
                "arn:aws:iam::*:role/CloudStorageSecEventBridgeRole-{appId}"
            ],
            "Effect": "Allow",
            "Sid": "IAMAction"
        },
        {
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": "arn:aws:iam::*:role/*{appId}",
            "Effect": "Allow",
            "Sid": "CrossAccountAssumeRole"
        },
        {
            "Condition": {
                "StringLike": {
                    "kms:ViaService": "s3.*.amazonaws.com"
                }
            },
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:GenerateDataKey"
            ],
            "Resource": "arn:aws:kms:*:{AwsAccount}:key/*",
            "Effect": "Allow",
            "Sid": "KmsConsole"
        },
        {
            "Action": [
                "application-autoscaling:DescribeScalableTargets",
                "aws-marketplace:MeterUsage",
                "acm:DescribeCertificate",
                "acm:RequestCertificate",
                "cloudformation:GetTemplateSummary",
                "cloudwatch:GetMetricStatistics",
                "ec2:DescribeTags",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeInstances",
                "ec2:DescribeNetworkAcls",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeRegions",
                "ec2:DescribeRouteTables",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVolumes",
                "ec2:DescribeVpcs",
                "ec2:DescribeInstanceTypeOfferings",
                "ec2:DescribeSnapshots",
                "ecs:DescribeTaskDefinition",
                "ecs:DeregisterTaskDefinition",
                "ecs:ListTaskDefinitions",
                "fsx:DescribeFileSystems",
                "fsx:DescribeVolumes",
                "fsx:DescribeStorageVirtualMachines",
                "logs:DescribeLogGroups",
                "sns:ListSubscriptions",
                "sns:ListSubscriptionsByTopic",
                "sns:ListTopics",
                "sns:Unsubscribe",
                "sqs:ListQueues"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "ReadOnlyGlobal"
        },
        {
            "Action": [
                "s3:GetBucketAcl",
                "s3:GetBucketLocation",
                "s3:GetBucketLogging",
                "s3:GetBucketNotification",
                "s3:GetBucketPolicy",
                "s3:GetBucketPolicyStatus",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetInventoryConfiguration",
                "s3:GetBucketTagging",
                "s3:GetBucketVersioning",
                "s3:GetBucketWebsite",
                "s3:GetLifecycleConfiguration",
                "s3:GetObject",
                "s3:GetObjectTagging",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "arn:aws:s3:::*",
            "Effect": "Allow",
            "Sid": "S3ReadOnly"
        },
        {
            "Action": [
                "s3:PutObject",
                "s3:PutObjectTagging",
                "s3:PutBucketLogging",
                "s3:PutBucketNotification",
                "s3:PutBucketPolicy",
                "s3:PutBucketPublicAccessBlock",
                "s3:PutInventoryConfiguration"
            ],
            "Resource": "arn:aws:s3:::*",
            "Effect": "Allow",
            "Sid": "S3Write"
        }
    ]
}
```

</details>

#### AWS Managed Policies

<details>

<summary>AmazonECSInfrastructureRolePolicyForVolumes</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CreateEBSManagedVolume",
            "Effect": "Allow",
            "Action": "ec2:CreateVolume",
            "Resource": "arn:aws:ec2:*:*:volume/*",
            "Condition": {
                "ArnLike": {
                    "aws:RequestTag/AmazonECSCreated": "arn:aws:ecs:*:*:task/*"
                },
                "StringEquals": {
                    "aws:RequestTag/AmazonECSManaged": "true"
                }
            }
        },
        {
            "Sid": "CreateEBSManagedVolumeFromSnapshot",
            "Effect": "Allow",
            "Action": "ec2:CreateVolume",
            "Resource": "arn:aws:ec2:*:*:snapshot/*"
        },
        {
            "Sid": "TagOnCreateVolume",
            "Effect": "Allow",
            "Action": "ec2:CreateTags",
            "Resource": "arn:aws:ec2:*:*:volume/*",
            "Condition": {
                "ArnLike": {
                    "aws:RequestTag/AmazonECSCreated": "arn:aws:ecs:*:*:task/*"
                },
                "StringEquals": {
                    "ec2:CreateAction": "CreateVolume",
                    "aws:RequestTag/AmazonECSManaged": "true"
                }
            }
        },
        {
            "Sid": "DescribeVolumesForLifecycle",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeVolumes",
                "ec2:DescribeAvailabilityZones"
            ],
            "Resource": "*"
        },
        {
            "Sid": "DescribeInstancesForAttachingVolume",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ManageEBSVolumeLifecycle",
            "Effect": "Allow",
            "Action": [
                "ec2:AttachVolume",
                "ec2:DetachVolume"
            ],
            "Resource": "arn:aws:ec2:*:*:volume/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/AmazonECSManaged": "true"
                }
            }
        },
        {
            "Sid": "ManageVolumeAttachmentsForEC2",
            "Effect": "Allow",
            "Action": [
                "ec2:AttachVolume",
                "ec2:DetachVolume"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*"
        },
        {
            "Sid": "DeleteEBSManagedVolume",
            "Effect": "Allow",
            "Action": "ec2:DeleteVolume",
            "Resource": "arn:aws:ec2:*:*:volume/*",
            "Condition": {
                "ArnLike": {
                    "aws:ResourceTag/AmazonECSCreated": "arn:aws:ecs:*:*:task/*"
                },
                "StringEquals": {
                    "aws:ResourceTag/AmazonECSManaged": "true"
                }
            }
        }
    ]
}
```

</details>

### Agent Role

<details>

<summary>Trust Relationships</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::{AwsAccount}:role/CloudStorageSecConsoleRole-{appID}",
                "Service": "ecs-tasks.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

</details>

#### Customer Inline Policies

<details>

<summary>Agent Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "aws-marketplace:MeterUsage",
                "ec2:DescribeVpcs",
                "ec2:DescribeAvailabilityZones",
                "elasticfilesystem:DescribeMountTargets"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "AllResources"
        },
        {
            "Action": [
                "appconfig:ListApplications",
                "appconfig:ListDeploymentStrategies",
                "ssm:ListDocuments"
            ],
            "Resource": [
                "arn:aws:appconfig:*:*:*",
                "arn:aws:ssm:*:*:*"
            ],
            "Effect": "Allow",
            "Sid": "ListActions"
        },
        {
            "Action": [
                "s3:GetBucketAcl",
                "s3:GetBucketLocation",
                "s3:GetObject*",
                "s3:GetEncryptionConfiguration",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::*",
            "Effect": "Allow",
            "Sid": "S3ReadOnly"
        },
        {
            "Action": [
                "s3:DeleteObject",
                "s3:DeleteObjectVersion",
                "s3:PutObject*",
                "s3:PutEncryptionConfiguration"
            ],
            "Resource": "arn:aws:s3:::*",
            "Effect": "Allow",
            "Sid": "S3Write"
        },
        {
            "Action": [
                "s3:ListBucket",
                "s3:PutLifecycleConfiguration",
                "s3:PutEncryptionConfiguration",
                "s3:PutBucketTagging",
                "s3:GetBucketTagging",
                "s3:GetObject",
                "s3:GetObjectTagging",
                "s3:GetObjectAttributes",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:PutObjectTagging",
                "s3:PutObjectVersionAcl",
                "s3:PutObjectVersionTagging",
                "s3:DeleteObject",
                "s3:DeleteObjectTagging",
                "s3:DeleteObjectVersion",
                "s3:DeleteObjectVersionTagging"
            ],
            "Resource": [
                "arn:aws:s3:::cloudstoragesecquarantine-{appID}-*",
                "arn:aws:s3:::cloudstoragesecquarantine-{appID}-*/*"
            ],
            "Effect": "Allow",
            "Sid": "CloudStorageSecS3AgentQuarantineBucket"
        },
        {
            "Action": [
                "appconfig:GetApplication",
                "appconfig:StartConfigurationSession",
                "appconfig:GetLatestConfiguration",
                "appconfig:GetConfiguration*",
                "appconfig:GetDeploymentStrategy",
                "appconfig:GetEnvironment",
                "appconfig:ListConfigurationProfiles",
                "appconfig:ListDeployments",
                "appconfig:ListEnvironments",
                "cognito-idp:*",
                "dynamodb:DeleteItem",
                "dynamodb:DescribeTable",
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:BatchGetItem",
                "dynamodb:BatchWriteItem",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:UpdateItem",
                "logs:CreateLogStream",
                "logs:DescribeLogGroups",
                "logs:PutLogEvents",
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret",
                "securityhub:BatchImportFindings",
                "sns:ConfirmSubscription",
                "sns:Publish",
                "sns:GetSubscriptionAttributes",
                "sns:ListSubscriptionsByTopic",
                "sqs:*Message",
                "sqs:GetQueueAttributes",
                "ssm:GetDocument",
                "ssm:GetParameters",
                "ssm:GetParametersByPath"
            ],
            "Resource": [
                "arn:aws:appconfig:*:*:application/{appID}/configurationprofile/*",
                "arn:aws:appconfig:*:*:application/{appID}/environment/looy5rt",
                "arn:aws:appconfig:*:*:application/{appID}/environment/looy5rt/configuration/oqm6f3i",
                "arn:aws:appconfig:*:*:application/{appID}",
                "arn:aws:appconfig:*:*:deploymentstrategy/8zbcjo3",
                "arn:aws:cognito-idp:*:*:userpool/{region}_30QNgMaZO",
                "arn:aws:dynamodb:{region}:*:table/4d03isr.*",
                "arn:aws:logs:*:*:*",
                "arn:aws:securityhub:{Region}::product/cloud-storage-security/antivirus-for-amazon-s3",
                "arn:aws:sns:*:*:*4d03isr",
                "arn:aws:sqs:*:*:*4d03isr*",
                "arn:aws:ssm:*:*:document/*4d03isr",
                "arn:aws:ssm:*:*:parameter/*4d03isr/*",
                "arn:aws:ssm:*:*:parameter/*4d03isr",
                "arn:aws:secretsmanager:{Region}:*:secret:cloudstoragesec/*"
            ],
            "Effect": "Allow",
            "Sid": "RestrictedResources"
        },
        {
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:*:*:*",
            "Effect": "Allow",
            "Sid": "Logs"
        },
        {
            "Action": "sts:AssumeRole",
            "Resource": [
                "arn:aws:iam::*:role/*4d03isr"
            ],
            "Effect": "Allow",
            "Sid": "CrossAccount"
        },
        {
            "Condition": {
                "StringLike": {
                    "kms:ViaService": "s3.*.amazonaws.com"
                }
            },
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:GenerateDataKey"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "Kms"
        }
    ]
}
```

</details>

### EC2 Container Role&#x20;

<details>

<summary>Trust Relationships</summary>

```json
{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}       
```

</details>

#### Customer Inline Policies

<details>

<summary>EC2 Container Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/CloudStorageSecExtraLargeFileScanning": "ExtraLargeFileScanning"
                }
            },
            "Action": [
                "ec2:TerminateInstances",
                "ec2:DeleteSnapshot",
                "ec2:DeleteVolume",
                "ec2:DescribeVolumeAttribute",
                "ec2:DetachVolume",
                "ec2:ModifySnapshotAttribute",
                "ec2:ModifyVolumeAttribute",
                "ec2:ModifyInstanceAttribute"
            ],
            "Resource": [
                "arn:aws:ec2:*:{AWSAccount}:*",
                "arn:aws:ec2:*:{AWSAccount}:volume/*",
                "arn:aws:ec2:*::snapshot/*"
            ],
            "Effect": "Allow",
            "Sid": "TagRestrictedResources"
        },
        {
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": [
                "arn:aws:ec2:*:{AWSAccount}:*",
                "arn:aws:ec2:*::image/*",
                "arn:aws:ec2:*::snapshot/*",
                "arn:aws:ec2:*:{AWS Account}:volume/*"
            ],
            "Effect": "Allow",
            "Sid": "TagResources"
        },
        {
            "Action": [
                "ec2:AttachVolume",
                "ec2:CopySnapshot",
                "ec2:CreateSnapshot",
                "ec2:CreateVolume",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeInstances",
                "ec2:DescribeSnapshotAttribute",
                "ec2:DescribeSnapshots",
                "ec2:DescribeTags",
                "ec2:DescribeVolumes",
                "ec2:DescribeVolumeStatus"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "AllResources"
        },
        {
            "Condition": {
                "StringLike": {
                    "kms:ViaService": "ec2.*.amazonaws.com"
                }
            },
            "Action": [
                "kms:CreateGrant"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "KmsAccess"
        }
    ]
}
```

</details>

#### AWS Managed Policies

<details>

<summary>AmazonEC2ContainerServiceforEC2Role</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeTags",
                "ecs:CreateCluster",
                "ecs:DeregisterContainerInstance",
                "ecs:DiscoverPollEndpoint",
                "ecs:Poll",
                "ecs:RegisterContainerInstance",
                "ecs:StartTelemetrySession",
                "ecs:UpdateContainerInstancesState",
                "ecs:Submit*",
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "ecs:TagResource",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "ecs:CreateAction": [
                        "CreateCluster",
                        "RegisterContainerInstance"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ecs:ListTagsForResource"
            ],
            "Resource": [
                "arn:aws:ecs:*:*:task/*/*",
                "arn:aws:ecs:*:*:container-instance/*/*"
            ]
        }
    ]
}
```

</details>

### Event Bridge Role

<details>

<summary>Trust Relationships</summary>

```json
{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "events.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

</details>

#### Customer Inline Policies

<details>

<summary>Event Bridge Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "events:PutEvents"
            ],
            "Resource": [
                "arn:aws:events:*:{AWSAccount}:event-bus/*{appID}"
            ],
            "Effect": "Allow",
            "Sid": "PutEvents"
        }
    ]
}
```

</details>

### Execution Role

<details>

<summary>Trust Relationships</summary>

```json
{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ecs-tasks.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

</details>

#### AWS Managed Policies

<details>

<summary>AmazonECSTaskExecutionRolePolicy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}
```

</details>

### User Pool Role

<details>

<summary>Trust Relationships</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "cognito-idp.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

</details>

#### Customer Inline Policies

<details>

<summary>User Pool Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "sns:publish",
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}
```

</details>

### App Config Agent Configuration Document Role

<details>

<summary>Trust Relationships</summary>

```json
{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "appconfig.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

</details>

#### Customer Inline Policies

<details>

<summary>App Config Agent Configuration Document Policy</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ssm:GetDocument"
            ],
            "Resource": [
                "arn:aws:ssm:*:*:document/CloudStorageSecConfig-Doc-{appID}"
            ],
            "Effect": "Allow"
        }
    ]
}
```

</details>


# Deployment Details

Learn more about our flexible deployment options.

We offer a number of flexible deployment options based on what you need. This includes:

* The `Standard Deployment` which requires filling out only 5 fields in the CloudFormation Template
* This also includes a completely `Private Deployment` where all of our components run in private VPCs and private Subnets with no public IPs assigned at all
* An in-between option where you have public access (public Load Balancer) while still running all solution components in a private VPC and Subnets

You can mix and match as well as incorporate VPC Endpoints to keep as much traffic as possible going over the AWS backbone.

{% hint style="warning" %}
All components deployed, created and installed run inside of your account. We do not host any of them and we never send any of your objects/files outside of your account. All scanning is performed close to the data inside your account(s) and in-region.

Our console requires specific permissions to manage its own infrastructure and integrate with your AWS services. To provide the most secure environment, we recommend deploying it in a dedicated AWS account. This isolates the product's permissions and prevents any unintended impact on other resources.

As you'll learn below, we may send some data (IP address, account email, version numbers) to a Cloud Storage Security AWS account to assist you and your users with accessing your application. ***You can opt out of this if you don't want that information to be reported.***

No matter the deployment option you choose, you can also leverage local signature updates for both the Sophos engine and the ClamAV engine through our [private mirror functionality](/console-overview/configuration/scan-settings#private-mirror-local-signature-updates).
{% endhint %}

## Standard Deployment

The `Standard Deployment` is the simplest deployment. After providing only 5 inputs to the CloudFormation Template you will have a deployed and running solution in \~5 minutes. This deployment expects the Console and the Agent(s) to be placed in VPCs and Subnets that have an Internet Gateway (IGW) allowing for outbound traffic.

This a typical setup for VPCs and Subnets.The outbound routing allows ECS to pull down images from ECR, allows the Console and Agent(s) to communicate with required AWS Services and provides access to the management UI. Although public IPs are assigned, control is still done through Security Groups and access can be limited through IP ranges.

With this deployment, we register your application subdomain with a Route53 Hosted Zone we host and manage in one of the Cloud Storage Security AWS accounts. This allows you to have consistent access to your application. If you'd prefer to manage the domain and SSL cert yourself, you can leverage the Application Load Balancer options discussed below.

{% tabs %}
{% tab title="Standard Deployment: " %}

<figure><img src="/files/48hQXnYlVBNrI7oHTajf" alt=""><figcaption><p>Standard Deployment Single Region</p></figcaption></figure>
{% endtab %}

{% tab title="Standard Multi-Region Deployment: \`Public Routing" %}

<figure><img src="/files/A6L7ngniGtLQ1cZKqPGA" alt="Standard Deployment Multi Region"><figcaption><p>Standard Deployment Multi Region</p></figcaption></figure>

{% endtab %}
{% endtabs %}

## Private Deployment

`Private Deployments` are defined by locking down the solution components (Console and Agents) such that they do not have public IPs. You can still provide public access if desired while locking everything else down. Whether it is best practices, compliance or internal rules you can deploy and leverage the solution as needed.

You'll see the deployment options below leveraging Application Load Balancers. These can be `internet-facing` or `internal` and can even be leveraged with the `Standard Deployment`. You do not have to leverage an ALB in a private deployment, but there are a number of reasons you might want to.

First off, AWS Fargate tasks do not get assigned persistent IP addresses. As a result, the IP address can change underneath you requiring you to look it up. You may also decide you'd like to manage or apply your own domain and SSL certificate for accessing the application. A load balancer allows you to accomplish all of these things: a persistent access point, apply your own domain and leverage your own certificates.

### Public Load Balancer Option

With this option we deploy an `internet-facing` load balancer on your behalf that will be publicly available based on your Security Group rules. Easy access over HTTPs.

{% tabs %}
{% tab title="Public LB with Private Console and Agent(s)" %}

<figure><img src="/files/28jDgJxdJUtdGnUywcX3" alt=""><figcaption><p>Private LB Single Region</p></figcaption></figure>
{% endtab %}

{% tab title="Multiregion - Public LB, Private Console and Agent(s) " %}

<figure><img src="/files/AehhZncXLFErmWr66imD" alt=""><figcaption><p>Private LB Multi Region</p></figcaption></figure>
{% endtab %}
{% endtabs %}

### Private Load Balancer Option

With this option we deploy an `internal` load balancer on your behalf that will be assigned only internal/private IPs. You must be able to access this network, typically through VPN or Direct Connect, in order to access the application.

{% tabs %}
{% tab title="Private LB with Private Console and Agent(s)" %}

<figure><img src="/files/6So4bsvYuNVNOlgkqyJJ" alt=""><figcaption><p>Private LB Single Region</p></figcaption></figure>
{% endtab %}

{% tab title="Multiregion Private LB with Private Console and Agent(s)" %}

<figure><img src="/files/JcYwzoWQSIVU2LYrFP3s" alt=""><figcaption><p>Private LB Multi Region</p></figcaption></figure>
{% endtab %}
{% endtabs %}

## Leveraging VPC Endpoints

In the previous deployment options you either assigned public or private IPs to the solution components and you controlled their privacy by utilizing either an Internet Gateway or a NAT Gateway. In either scenario, all AWS API calls went out over the internet. There are times when you may want to limit internet traffic as much as possible. For this use case, AWS provides VPC Endpoints to keep the API call traffic on the AWS backbone, not over the open internet. VPC Endpoints can be mixed and matched into any of the deployment options, public or private. Note that the application reaches out to some non-AWS endpoints and will still require external access for full functionality. However, this implementation is a great reduction in the amount of traffic over the public internet so it is worth considering.

{% hint style="warning" %}
&#x20;**Important:** The Security Group associated with the endpoints **ecr.dkr** and **ecr.api** must have an inbound rule allowing all traffic from the CIDR range of the VPC.\
Also, the subnets used for the console must be the ones included in the VPC Endpoints.
{% endhint %}

{% hint style="info" %}
Even though Marketplace has an endpoint now, need for access to AWS Marketplace can be bypassed if you choose to subscribe to our BYOL listing. A VPC Endpoint for Security Hub is optional and only required if you choose to use our Security Hub integration.&#x20;
{% endhint %}

<details>

<summary>Recommended VPC Endpoints</summary>

**Essential VPC Endpoints**

In the case that subnet traffic is restricted, access to the following VPC endpoints are necessary for our application to function. Replace {region} with your region where you are deployed.

| com.amazonaws.{region}.s3                      |
| ---------------------------------------------- |
| com.amazonaws.{region}.cognito-idp             |
| com.amazonaws.{region}.dynamodb                |
| com.amazonaws.{region}.sts                     |
| com.amazonaws.{region}.sqs                     |
| com.amazonaws.{region}.events                  |
| com.amazonaws.{region}.cloudformation          |
| com.amazonaws.{region}.sns                     |
| com.amazonaws.{region}.application-autoscaling |
| com.amazonaws.{region}.ec2                     |
| com.amazonaws.{region}.ecs                     |
| com.amazonaws.{region}.fsx                     |
| com.amazonaws.{region}.ebs                     |
| com.amazonaws.{region}.cloudtrail              |
| com.amazonaws.{region}.ecr.dkr                 |
| com.amazonaws.{region}.ecr.api                 |
| com.amazonaws.{region}.elasticfilesystem       |
| com.amazonaws.{region}.logs                    |
| com.amazonaws.{region}.autoscaling             |
| com.amazonaws.{region}.elasticloadbalancing    |
| com.amazonaws.{region}.ecs-agent               |
| com.amazonaws.{region}.ssm                     |
| com.amazonaws.{region}.monitoring              |
| com.amazonaws.{region}.kms                     |

**Situational VPC Endpoints**

The following endpoints are situational and dependent on your configuration.

| com.amazonaws.{region}.appconfigdata        | Only necessary if \<v9.00.000. After upgrading to v9.00.000 or above, you can remove this endpoint. |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| com.amazonaws.{region}.appconfig            | Only necessary if \<v9.00.000. After upgrading to v9.00.000 or above, you can remove this endpoint. |
| com.amazonaws.{region}.license-manager      | Only necessary if using PayGo or Private Offer. Not necessary in GovCloud / BYOL.                   |
| com.amazonaws.{region}.metering-marketplace | Only necessary if using PayGo or Private Offer. Not necessary in GovCloud / BYOL.                   |
| com.amazonaws.{region}.securityhub          | Only necessary if utilizing the Security Hub integration.                                           |

</details>

<figure><img src="/files/jOBCaNBOMxJUM4dB4EnL" alt="Private Deployment with VPC Endpoints"><figcaption><p>Private Deployment with VPC Endpoints</p></figcaption></figure>

**Setting up a VPC Endpoints Deployment**

1. The user must configure either AWS Direct Connect, a VPN, or a jumpbox to access the private subnet.
2. All AWS services can be accessible over VPC Endpoint. The Console and Agent will attempt to contact all endpoint-enabled services using that method. All requests going through endpoints will be traveling over the AWS global network infrastructure.
3. For non-AWS endpoints, we require a customer-created proxy, which the Console and Agent will use to forward those requests to the configured NAT Gateway. Place the proxy in a private subnet in the same VPC where the stack is deployed. Once the proxy is up, use the 'proxy' and 'proxy port' parameters in CFT or Terraform to indicate where the application should look to contact the proxy.

**Starter VPC Endpoint Script**

Below is a starter script used to deploy VPC endpoints into the VPC of your choice. Replace the Profile with your profile name and the environment-specific variables.

```
import boto3

def create_vpc_endpoints(vpc_id, subnets, interface_service_names, gateway_service_names, route_table_id):
#Replace the aws-cli-profile-name with your profile name

    #if using cloudshell, comment out the below line
    boto3.setup_default_session(profile_name='aws-cli-profile-name')

    ec2_client = boto3.client('ec2')

    try:
        vpc_endpoint_ids_interface = []

        for service_name in interface_service_names:

            response = ec2_client.create_vpc_endpoint(
                VpcId=vpc_id,
                ServiceName=service_name,
                SubnetIds= subnets,
                VpcEndpointType='Interface'
            )
            vpc_endpoint_ids_interface.append(response['VpcEndpoint']['VpcEndpointId'])
            print(f"VPC Endpoint for {service_name} created with ID: {response['VpcEndpoint']['VpcEndpointId']}")

        print("Interface VPC Endpoints created successfully!")

        vpc_endpoint_ids_gateway = []

        for service_name in gateway_service_names:
            response = response = ec2_client.create_vpc_endpoint(
                VpcId=vpc_id,
                ServiceName=service_name,
                VpcEndpointType='Gateway',
                RouteTableIds= [route_table_id]
            )
            vpc_endpoint_id = response['VpcEndpoint']['VpcEndpointId']
            vpc_endpoint_ids_gateway.append(vpc_endpoint_id)
            print(f"VPC Endpoint for {service_name} created with ID: {vpc_endpoint_id}")

        print("Gateway VPC Endpoints Created Succesfully!")

        print("All VPC Endpoints created and associated with Route Table successfully!")     

        return vpc_endpoint_ids_interface, vpc_endpoint_ids_gateway
    
    except Exception as e:
        print("Error creating VPC endpoints:", str(e))
        return None

if __name__ == "__main__":
    # Replace these variables with your actual VPC ID and the desired regions
    vpc_id = 'vpc-id'
    subnets_id = ['subnet-id-A', 'subnet-id-B', 'subnet-id-C' ]
    console_region = 'console-region'
    route_table = 'route-table-id'
    
    #   OPTIONAL: Tightening Permissions #
        # You can remove fsx, elasticfilesystem, and ebs if you're not planning to scan those services
        # You can remove marketplace if you're using BYOL
        # You can remove Securityhub endpoint if not using Security Hub

    interface_services_to_create = [ 
                        f'com.amazonaws.{console_region}.s3', f'com.amazonaws.{console_region}.cloudformation',f'com.amazonaws.{console_region}.logs', 
                        f'com.amazonaws.{console_region}.ssm',f'com.amazonaws.{console_region}.application-autoscaling', f'com.amazonaws.{console_region}.ecs',
                        f'com.amazonaws.{console_region}.ecs-agent', f'com.amazonaws.{console_region}.kms', f'com.amazonaws.{console_region}.sts',  
                        f'com.amazonaws.{console_region}.ecr.dkr', f'com.amazonaws.{console_region}.autoscaling',f'com.amazonaws.{console_region}.ecr.api', 
                        f'com.amazonaws.{console_region}.sns', f'com.amazonaws.{console_region}.sqs', 
                        f'com.amazonaws.{console_region}.ec2', f'com.amazonaws.{console_region}.elasticloadbalancing',
                        f'com.amazonaws.{console_region}.monitoring', f'com.amazonaws.{console_region}.ebs',
                        f'com.amazonaws.{console_region}.appconfig', f'com.amazonaws.{console_region}.cognito-idp',
                        f'com.amazonaws.{console_region}.fsx',f'com.amazonaws.{console_region}.elasticfilesystem', 
                        f'com.amazonaws.{console_region}.securityhub', f'com.amazonaws.{console_region}.metering-marketplace']
    
    
    
    gateway_services_to_create = [f'com.amazonaws.{console_region}.s3', f'com.amazonaws.{console_region}.dynamodb']

    created_endpoint_ids = create_vpc_endpoints(vpc_id, subnets_id, interface_services_to_create, gateway_services_to_create, route_table)
```

## Using our Private Deployment Template

If you need a way to deploy privately but aren't sure which subnets to use from your current VPCs or which VPC endpoints to setup, you can use our private deployment CFT to create a new VPC with all of the resources (subnets, VPC endpoints, etc.) needed to deploy your Management Console and scanning agents in a fully private environment.

This template will first deploy the following networking pieces before deploying the software:

* A VPC and public + private subnets
* All necessary VPC endpoints in a single region
* An AWS network firewall
* An application load balancer that will sit in front of your management console. You will need a valid SSL certificate from AWS Certificate Manager to be able to deploy.

{% hint style="warning" %}
AWS Network Firewalls can be costly. If you are only performing testing make sure you don't forget about the deployment and properly tear it down.
{% endhint %}

Below is a screenshot of the parameters you can expect within the private deployment CloudFormation template.

<figure><img src="/files/br1Yy3v8C8sBXF66i2k5" alt="" width="188"><figcaption><p>Select the image to expand it</p></figcaption></figure>

You can always find the latest version of our private deployment template [here](https://css-cft.s3.amazonaws.com/ConsoleCloudFormationTemplate-PrivateDeployment.yaml).

## API Endpoint

The API Endpoint is another Agent Service that allows for an [API Driven scan](/how-it-works/object-scanning#api-driven-scanning) of files and objects. It can be mixed into any of the deployment options above. It earns a special call out because it has its own Application Load Balancer deployed for and associated with it. So you can have a deployment that has an ALB fronting the Console and then another ALB fronting the API Endpoint. Like previously discussed load balancers, you can choose to make the ALB `internet-facing` or `internal`, it all depends on your needs.

{% hint style="info" %}
We are not showing a multi-region deployment below, but if your requirements dictate it, you can deploy as many API Endpoints as needed so scanning can be close to users/applications/data.
{% endhint %}

{% tabs %}
{% tab title="API Endpoint - Publicly Accessible" %}

<figure><img src="/files/RdT39ynBPUsQDKwTNuYZ" alt=""><figcaption><p>Public API</p></figcaption></figure>

1. Users can configure their application to upload their file to an API endpoint that the Scanning Agent sits behind via an HTTPS request.
2. The request and file is processed through the Internet Gateway sitting at the entrance of the VPC where the API Agent resides.
3. The request and file reach the Application Load Balancer which resides in the public subnet.
4. The file included in the request is scanned with the API Agent and a verdict is rendered by the Agent.
5. Using the same channels, the Agent returns a JSON response via HTTPS with the decision on the file: Infected, Clean, etc.
6. (Optional) The API Agent can upload Clean files to the S3 bucket of your choice.
   {% endtab %}

{% tab title="API Endpoint - Privately Accessible" %}

<figure><img src="/files/nujjxBYuQ4empSceb6Os" alt=""><figcaption><p>Private API</p></figcaption></figure>

1. The user must configure either AWS Direct Connect, a VPN, or a jumpbox to access the private subnet. Using a method of choice, the user uploads the file to an API endpoint that the Scanning Agent sits behind via an HTTPS request.
2. The request and file is processed through the Internet Gateway sitting at the entrance of the VPC where the API Agent resides.
3. The request and file reach the Application Load Balancer which resides in the private subnet.
4. The file included in the request is scanned with the API Agent and a verdict is rendered by the Agent.
5. Using the same channels, the Agent returns a JSON response via HTTPS with the decision on the file: Infected, Clean, etc.
6. (Optional) The API Agent can upload Clean files to the S3 bucket of your choice.
   {% endtab %}
   {% endtabs %}

Read more about our API Scanning [here](https://help.cloudstoragesec.com/how-it-works/object-scanning/api-driven-scanning).


# Sizing Discussion

File size and the number of files you plan on scanning will impact how you scale your deployment to fit your needs.

To get a feel for scale and performance we ran a series of tests with a number of file sizes: 100kb, 1mb, 10mb, 100mb, 500mb, 1gb, 1.5gb, and 2gb (the current maximum file size) with the ClamAV engine. We tested all the same file sizes, but also added 5gb, 10gb and 15gb files for the Sophos engine. The goal here was to find two things:

1. What was the throughput in GB and object counts?
2. Is the scale linear as you add scanning agents?

We did this systematically with a number of agents in a strict environment. We later similarly tested with auto-scaling in place to see the scanning agents spin up and down as the load backed off and similar results were found with greater numbers of agents.

We tested uniquely generated junk files with the hashing function turned off to ensure that each file would be fully scanned. This allows for more accurate throughput metrics for our scanner agents.

## Your Mileage May Vary

These tests are not real world tests with your particular data sets. This is purely to give you a feel for how your environment may behave and allow you to make deployment decisions. Please test with files similar to what you will see in production. We'd love to have you [Contact Us](/contact-us) to report findings and see how your environment matches up or how we may help you get the most out of it.

Event Driven and Existing (Retro) were both tested and had similar results for the scanning per agent per hour time. Event Driven Scanning does **NOT** include time spent copying nor uploading to the bucket. Scan Existing does NOT include bucket crawling.

In practice, scan existing will start many agents, usually enough to complete scanning the entire bucket of objects, however large, within an hour or less.

{% hint style="warning" %}

* Where 300 Gb/hr is reported, we actually observed initial speeds from 200 Gb/hr to 600 Gb/hr.
* After throttling (1 - n hours later) we observed speeds as low as 100 Gb/hr (and as high as 300 Gb/hr)
* Testing was done in us-east-1, but a few tests in us-east-2 ran about 20% faster
  {% endhint %}

## Throughput Table

Here are the average of results we observed before throttling:

{% hint style="info" %}
Throughput results for the CSS Premium engine will be released in the future. If you have specific questions on throughput for a scanning agent using the CSS Premium engine please [Contact Us](/contact-us).
{% endhint %}

| File Size Tests Throughput | ClamAV Engine S3 Integrated | ClamAV Engine S3 Integrated | Sophos Engine S3 Integrated | Sophos Engine S3 Integrated |
| :------------------------: | :-------------------------: | :-------------------------: | :-------------------------: | :-------------------------: |
|                            |         **in GB/hr**        |      **in \~Files/hr**      |         **in GB/hr**        |      **in \~Files/hr**      |
|         100kb files        |            \~1.75           |           \~17,500          |            \~2.25           |           \~22,500          |
|          1mb files         |            \~6.5            |           \~6,500           |             \~20            |           \~20,000          |
|         10mb files         |             \~9             |            \~900            |            \~100            |           \~10,000          |
|         100mb files        |             \~9             |             \~90            |            \~200            |           \~2,000           |
|         500mb files        |             \~9             |             \~18            |           \~300\*           |            \~600            |
|         1 gb files         |             \~9             |             \~9             |           \~300\*           |            \~300            |
|         2 gb files         |             \~9             |            \~4.5            |           \~300\*           |            \~150            |
|         5 gb files         |              X              |              X              |           \~300\*           |             \~60            |
|         10 gb files        |              X              |              X              |           \~300\*           |             \~30            |
|         50 gb files        |              X              |              X              |           \~300\*           |             \~6             |
|        100 gb files        |              X              |              X              |           \~300\*           |             \~3             |
|        150 gb files        |              X              |              X              |           \~300\*           |             \~2             |

## Linear Scale Out for S3 Integrated

The table above shows the results of a single scanning agent running and be bombarded with objects to get to upper end, but sustainable throughput value. We noticed in our testing that as you add scanning agents, you simply increase the throughput by the same values above for that second scanning agent. Just multiply the GBs / hr and the Files / hr values to see what it would be like with 2 to N scanning agents.

{% hint style="info" %}
With the testing we've done on the API file scanning, we have seen significant performance increases at all file sizes up through 1.5GB. We have not done extended testing at this time so cannot post full results of testing. And your mileage will vary based on network performance and latency.

We are happy to have a discussion with you on these metrics. Please [Contact Us](/contact-us) if you'd like to learn more.
{% endhint %}

## So what does this mean?

There have always been questions around what is required to meet the business needs when adopting a new solution.

* How much infrastructure do I need?
* Do I scale up or scale out?
* Do I need to run it all the time?
* Am I trying to get a certain amount of work done in a particular window of time or can it take as long as it wants?

The answers to these questions can help you determine how you want to run the solution. The simple answer is, and taken with a `your mileage may vary` consideration, is to look at your environment and see the types of files you deal with and the average size. Apply that to the chart above to get a baseline to the amount of given work the scanning agents can achieve.

For example, let's say most of your files are approximately 1mb in size. A single agent can do \~7000 of those files an hour. How many files per hour or per day are you receiving? Do you need to do them in "realtime" as they come in throughout the day or in a certain scan window? How old will you allow an object to get before it is scanned?

Extending the example, let's say 7001 files come in all at once. A single agent will evaluate those in an hour (2 per second), but many of the files will sit there for tens of minutes to even a full hour for that 7001th file. Is that ok? If not, then we have to judge the impacts of scaling additional agents in this scenario. Adding a second agent in this case then roughly doubles the throughput so we're now at 14k per hour (4 per second) and therefore you can now evaluate the files in \~30 minutes instead of 60. You're oldest file would be at most 30 minutes before getting scanned. Adding a third agent takes you down to \~20 minutes and so on.

With that, you can start to think through how you want to drive your system. The main configuration available to you today for this is modifying the Number of Messages in Queue to Trigger Agent Auto-Scaling during deployment. This can be modified after the fact if you find your original choice is not allowing you to meet your goals. The way the auto-scaling works is the queue must have the number of entries you specified during deployment sitting there for at least 1 minute to trigger the alarm that will then generate the scaling event. Similarly this works in much the same, but opposite fashion for backing off the scaling events.

In the scenario above, how could you ensure no item was more than 4 minutes old? Looking at the numbers, a single agent can do \~120 of those files per minute and therefore \~480 in 4 minutes. As soon as you see more than 120 entries in the queue for longer than 1 minute's time you are starting to fall behind. It isn't until the queue has had \~480 entries in it for longer than a minute you may no longer hit that 'at most 4 minute' scan window. So the queue value you may want to specify could be between 240-360. This allows for the time it takes to spin another agent up. If the files are coming in so fast your queue is backed up and is now sitting above 700 entries for a minute, then another alarm triggers a scaling event for another agent to spin up and so on it goes. So the queue value you pick during deployment is used in multiples of queue entries for triggering scaling events up and down. This choice should allow for scanning agents to spin up on demand to continue to serve that 4 minute old window. As entries drop below those `multiples` in the queue, scanning agents will start to spin down.

In this scenario, you are receiving more than 120 files per minute. If you never have this type of inflow, then a single agent will always keep up and you are always within a few seconds to a minute of scanning. The idea to take away from this section is to evaluate the inflow of objects along with the size of the objects and determine your acceptable scan window. Maybe it isn't 4 minutes, but rather 4 seconds. Thinking through how that changes your deployment allows you to determine the scaling values.

The alternative to good queue choices is to just ***brute force*** it by upping the minimum running agents. This will add infrastructure costs, but you'll have the agents ready and waiting for the loads to come in.

{% hint style="info" %}
As items are peeled off the queue, scaling contractions will happen and the scanning agents will drop off. There is a cool down period so you may notice they don't immediately drop off, but how AWS manages it seem reasonable.

In the brute force scenario the agents won't contract as you have set the minimum. You'd have to change that value directly if you wanted it reduced.
{% endhint %}

Other Sample Scenarios (using the slower ClamAV throughputs):

* 100GB 1GB files (100 files) in 4 hours: 3 agents with an autoscaling queue of 10
  * Baseline: 1 agent = 10gb/hr, 3 agents = 30gb/hr
* 200GB 100kb files (2,000,000 files) in 3 hours: 34 agents with an autoscaling queue of 17,000
  * Baseline: 1 agent = 1.77gb/hr, Assume 5 agents = 10gb/hr, 50 agents = 100gb/hr
* 1TB of 100MB files (10,000 files) in 2 hours: 50 agents with an autoscaling queue of 100
  * Baseline: 1 agent = 10gb/hr, 50 agents = 500gb/hr


# Integrations

Cloud Storage Security is focused on creating a great user experience with functionally useful integrations with key AWS Services. Read on to learn more.

You can view our list of available integrations below.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>AWS Security Hub</td><td></td><td></td><td><a href="/pages/y48PkqVTAHLONDQkY5kl">/pages/y48PkqVTAHLONDQkY5kl</a></td></tr><tr><td>AWS CloudTrail Lake</td><td></td><td></td><td><a href="/pages/ExAHKlxjFuJU5MdcXygR">/pages/ExAHKlxjFuJU5MdcXygR</a></td></tr><tr><td>AWS Transfer Family</td><td></td><td></td><td><a href="/pages/jA3e2rcK1Ah3Ob5mMlWN">/pages/jA3e2rcK1Ah3Ob5mMlWN</a></td></tr><tr><td>Amazon GuardDuty</td><td></td><td></td><td><a href="/pages/hDftXHMrVRo7LqbRswck">/pages/hDftXHMrVRo7LqbRswck</a></td></tr><tr><td>Amazon Bedrock</td><td></td><td></td><td><a href="/pages/TilWLolp6M1ttt5Zlz54">/pages/TilWLolp6M1ttt5Zlz54</a></td></tr><tr><td>ICAP Service</td><td></td><td></td><td><a href="/pages/AGLYl7WHkwVf8wxxaXsw">/pages/AGLYl7WHkwVf8wxxaXsw</a></td></tr></tbody></table>


# AWS Security Hub CSPM

Antivirus for Amazon S3 and Data Classification for Amazon S3 both support AWS Security Hub CSPM.

You can enable Security Hub CSPM by going to Configuration > AWS Integrations. Read on here for more information on implementing it.

<figure><img src="/files/rdZNxzV3eNvG8aWsmyoA" alt=""><figcaption></figcaption></figure>

AWS Security Hub CSPM provides a consolidated view of your security status in AWS. Automate security checks, manage security findings, and identify the highest priority security issues across your AWS environment. We have integrated with AWS Security Hub CSPM to allow your Amazon S3 object findings (infected files and data matching classified data patterns) to be posted to this central location. Any infected or matching files found within your Amazon S3 storage can be shown and managed alongside the rest of the findings coming from all other aspects of your infrastructure.

It is very simple to start sending infected or matching scan results to AWS Security Hub CSPM. Simply toggle the switch on (becomes purple and text changes from Disabled to Enabled) and we will activate Accept Findings inside of AWS Security Hub CSPM and immediately start sending findings. You will not have to manually accept, although you can, the findings service inside the AWS Console. If you accept the service beforehand, you will still need to enable the toggle in the management console.

## **Example Finding within AWS Security Hub** CSPM **Console**

<figure><img src="/files/18z2RHxj55yZ2nlYLm3K" alt=""><figcaption></figcaption></figure>

## **Integration as seen inside the AWS Security Hub** CSPM **Console**

<figure><img src="/files/06EYbWjDTJeuKVJkcZZN" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
We expect AWS Security Hub CSPM to be subscribed to in the region the console is running within.

Any incident found, no matter the region, will be posted to the console region's AWS Security Hub CSPM. [Contact Us](/contact-us) if you'd like the findings written out to the region they were found in.

Flipping the toggle to enabled when AWS Security Hub CSPM is not subscribed to will be reflected with an error.

If you Stop Accepting Findings for our solution inside the AWS Security Hub CSPM console, but do not also disable it in the Console Settings page, we will continue to try to send events and errors will be sent to logs.
{% endhint %}


# AWS CloudTrail Lake

We have an available CloudTrail Lake integration that you can use for your deployment.

Ingest events from the Antivirus for Amazon S3 console into AWS CloudTrail Lake to enhance incident response, simplify audits, and streamline operational troubleshooting related to malware and sensitive data discovery.

With the newly launched PutAuditEvents API for AWS CloudTrail Lake, CSS has created a simple integration for you to capture user activity and events from the CSS console. In just a few steps, you can consolidate CSS activity logs together with AWS activity logs in CloudTrail Lake without having to build or manage the event data pipeline.

<figure><img src="/files/H9KpZophitInGmOLNpfX" alt=""><figcaption><p>Single Region Architecture: AWS CloudTrail Lake Integration</p></figcaption></figure>

### Getting Started

CSS uses the AWS PutAuditEvents API to send application activity from CSS to CloudTrail and we’ve streamlined integration setup in the CSS console. After you [subscribe, deploy and configure](/getting-started/how-to-subscribe) the CSS console, simply go to Configuration in the main menu, select Console Settings, and in the CloudTrail Lake Integration section, enable the integration and follow the prompts to connect CSS and CloudTrail Lake. By enabling the integration in CSS, everything is done for you, including creation of the [event data store](https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_EventDataStore.html).

<figure><img src="/files/Ge9mT0mUz0yptgDtFTEE" alt=""><figcaption><p>CloudTrail Lake Integration in the Management Console</p></figcaption></figure>

Alternatively, you can set up the integration in AWS CloudTrail. Before you can ingest events into CloudTrail, you will need to [create an event data store](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/query-event-data-store.html) in CloudTrail Lake to log events. Next, discover and enable the CSS integration by navigating to the CloudTrail console where you have a CloudTrail Lake event data store enabled. From there, you will be guided on how to stream events from the CSS console.

No matter which integration process you follow, once the event data store is created and CSS events are loaded into CloudTrail Lake, you will be able to search, query, and analyze a consolidated view of activity relating to security, audit, or operational incidents using CloudTrail Lake.


# AWS Transfer Family

Ensure the data that is moved into Amazon S3 via AWS Transfer Family is free of ransomware, viruses, trojans and other payloads by scanning it inline with Antivirus for Amazon S3

## Deployment Options

Deploy AWS Transfer Family and antivirus scanning at the same time in 5-15 minutes via our AWS CloudFormation Template. If you are new to Transfer Family, everything you need to be up and running will be deployed for you. If you are already using Transfer Family, it is easy to select the S3 buckets linked with your Server to deploy antivirus scanning.

If you're just getting started with our solution you'll need to [subscribe to dedicated AWS Transfer Family listing](/getting-started/how-to-subscribe/aws-transfer-family) on AWS Marketplace. After you've subscribed you'll be able to [deploy the AWS Transfer Family CloudFormation Template](/getting-started/how-to-deploy/aws-transfer-family).

{% hint style="info" %}
If you are currently subscribed to the Antivirus for Amazon S3 product and have a Transfer Family Server deployed, all you need to do is [protect the S3 bucket](https://help.cloudstoragesec.com/console-overview/protected-buckets) linked to your Transfer Family Server to ensure its contents are clean.
{% endhint %}

## Architecture

<figure><img src="/files/5zgZ3AMhzE5bJpS7f8WN" alt=""><figcaption></figcaption></figure>


# Amazon GuardDuty

If you are a GuardDuty user you can integrate GuardDuty into our solution. Users can leverage us to perform the following:

* Scan against our engines for increased efficacy
* Quarantine findings without having to stand up additional handling through GuardDuty
* Initiate on-demand and scheduled Retro Scans on their pre-existing data

<figure><img src="/files/fXSn90dQ5jM0bfpDVgKE" alt=""><figcaption></figcaption></figure>


# Amazon Bedrock

We have integrated Amazon Bedrock's AI functionality into our solution for two purposes:

1. Helping create custom data classification regular expression (RegEx) rules
2. When Malware is discovered you can “Ask Bedrock” for more information on the finding

## **Amazon Bedrock Integration for Custom Classification Rules**

Effective data classification requires policies and rulesets that are written for particular types of information. Yet, crafting RegEx policies is often challenging because the syntax can be complex and dense. Our integration with Amazon Bedrock simplifies this process by leveraging the power of artificial intelligence. All you need to do is enter a simple text prompt to identify patterns or text and the exact value you need for the rule will be created.

To get started, you’ll need to enable the Amazon Bedrock integration. Then you can navigate to Configuration in the navigation of your AV console and click on Classification Custom Rules. From there, click the “Create Rule” button. In the popup, enter a name and description, then click on “Create expression using Amazon Bedrock” to have the RegEx built for you.

For example, to create a RegEx rule that identifies certain credit card numbers, enter the Prompt “create a regular expression that discovers all American Express credit card numbers”. Then select Send Prompt to generate a RegEx rule that can be used. Each response is accompanied by an explanation of the RegEx. Click “save”.

<figure><img src="/files/kc2a26ZTadywCZM8qrOg" alt=""><figcaption></figcaption></figure>

If you’re a RegEx pro, custom classification rules can be created without the assistance of Bedrock—simply enter the regular expression, add a name plus description, and hit “save” to create the rule.

## **Amazon Bedrock Integration for Malware Definitions & Remediation**

Suspicious or malicious files can be cryptic, requiring additional analysis to understand what the malware does and its level of impact. Yet, using tools like Google search or VirusTotal to get that additional context can slow down an investigation, require data transfers, or increase potential for manual error.

Now, customers can “Ask Bedrock” by utilizing our integration with Amazon Bedrock to analyze found malware and obtain risk mitigation strategies in just a few seconds. No need to worry about data that’s transferred over the public internet or sent to a third party because the Bedrock instance runs in your account. Malware forensics includes, but is not limited to, information about:

* What strain of malware has been detected
* If executed, what actions that piece of malware could take
* What to do to properly remediate the threat

To access this information, Amazon Bedrock must be enabled. To use this feature, navigate to the Findings page in the main menu of the CSS console, click the three dots on the right side of any finding and select “Show Amazon Bedrock Analysis”.

<figure><img src="/files/jjmNGIH5WVh6hPxXlwMj" alt=""><figcaption></figcaption></figure>

## Enabling Amazon Bedrock and Supported Regions

This integration is disabled by default but you can enable it by going to Configuration > AWS Integrations. From there you can click the toggle to turn it on.

<figure><img src="/files/p5WlVN7QxsMQnhGiDI7u" alt=""><figcaption></figcaption></figure>

The console must be deployed in one of the following regions to have access to Bedrock:

* US East (N. Virginia)
* US West (Oregon)
* Asia Pacific (Tokyo)
* Europe (Frankfurt)
* AWS GovCloud (US-West)


# ICAP Service

Scan files inline from any ICAP-capable application, proxy, or network appliance with the CSS ICAP server — powered by the same scanning engines used by Antivirus for Amazon S3.

The CSS ICAP Service lets any application that speaks ICAP (Internet Content Adaptation Protocol, RFC 3507) scan files for malware inline — before they are stored or delivered. It is a standards-compliant ICAP server that you deploy into your own AWS account with a single CloudFormation template. Your ICAP client (a custom application, proxy such as Squid, or a network appliance) hands each file to the server, the server scans it against your existing [API Agent](/console-overview/configuration/api-agent-settings), and the verdict determines whether the file is allowed through or blocked.

Common use cases include scanning file uploads before your application accepts them, scanning downloads before they reach end users, and adding malware scanning to proxies and gateways that already support ICAP.

### How It Works

Your ICAP client sends each HTTP message (an upload via `REQMOD` or a download via `RESPMOD`) to the ICAP server. The server streams the file to your API Agent (the [Cloud Storage Security Scanning API](/how-it-works/scanning-api)) for scanning and answers with a standard ICAP verdict:

| Scan result                          | ICAP response                                                                                                              | What your application should do               |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| **Clean** (client sent `Allow: 204`) | `204 No Content`                                                                                                           | Forward the original file                     |
| **Clean** (no `Allow: 204`)          | `200 OK` echoing the original message                                                                                      | Forward the original file                     |
| **Infected**                         | `200 OK` carrying an encapsulated **`HTTP 403 Forbidden`** with an XML error body (`<Error><Code>VirusDetected</Code>...`) | Block: deliver the 403 to the end client      |
| **Scanner unreachable / error**      | ICAP `500` (**fail closed** — a file is never passed through unscanned)                                                    | Treat as a failure; retry or surface an error |

The server supports the full RFC 3507 feature set your client may use: `OPTIONS` discovery, `REQMOD` and `RESPMOD`, Preview (advertised at 4096 bytes), `Allow: 204`, and persistent connections. Files are streamed to disk rather than memory, so multi-gigabyte objects are handled without special configuration.

### Architecture

Everything deploys inside your VPC: an ECS Fargate service running the ICAP server behind an **internal** Network Load Balancer, a Secrets Manager secret holding the scan-API credentials, and CloudWatch logging. Nothing is exposed outside your VPC.

<figure><img src="/files/UUR0kbqo8YJmpBupkioa" alt=""><figcaption></figcaption></figure>

### Prerequisites

Before deploying, make sure you have:

1. A **Cloud Storage Security Console** deployed and active in your environment.
2. An [API Agent](/console-overview/configuration/api-agent-settings) deployed, configured, and reachable — this is the backend the ICAP server sends files to for scanning. Note its **base URL** and confirm it is healthy.
3. A console user with [**API Access enabled**](/console-overview/access-management/user-mgmt#setup-for-api-scanning-access) — the ICAP server uses this username and password to authenticate to the Scanning API.
4. An AWS account and the **VPC where your ICAP client runs**, with **two or more subnets** for the load balancer and the Fargate task.
5. **Outbound HTTPS (443) connectivity** from those subnets to the API Agent. Public subnets work as-is; private subnets need a NAT gateway route. If your API Agent is deployed behind an internal load balancer (a different VPC or an internal endpoint), you are responsible for connectivity between the two — VPC peering, Transit Gateway, or a shared VPC.
6. **Pull access to the CSS ICAP server image.** [Contact Us](/contact-us) with the region(s) you will deploy in and your AWS Organization ID (grants every account in your org) or one or more AWS account IDs. There is no image URI to paste — the template already references the correct in-region image.

### Deploying the ICAP Server

The CloudFormation template is published at a stable public URL:

```
https://css-cft.s3.us-east-1.amazonaws.com/Icap/css-icap-server-1.0.0.yaml
```

To deploy from the AWS Console:

1. Go to **CloudFormation > Create stack > With new resources (standard)**, choose **Amazon S3 URL**, and paste the template URL above.
2. Name the stack (e.g. `css-icap-server`) and fill in the parameters (see the table below).
3. Acknowledge the IAM capabilities notice and click **Submit**. The stack reaches `CREATE_COMPLETE` in about 5 minutes.
4. Open the **Outputs** tab — `IcapEndpoint` is the address your ICAP client will target.

You can provide the scan-API credentials in either of two ways:

* **Secrets Manager (recommended):** create a secret containing `{"username":"...","password":"..."}` with the API Access user's credentials and pass its ARN in the `ScanApiSecretArn` parameter.
* **Stack parameters:** enter the username and password directly in the `ApiUser` and `ApiPass` fields. Both are masked, and the stack creates the Secrets Manager secret for you.

In both cases credentials are injected at task launch from Secrets Manager — they are never stored in the container image or the task definition.

#### Key Parameters

| Parameter                                   | Required        | Meaning                                                                                                                                                                                                                                                 |
| ------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `VpcId`, `SubnetIds`                        | Yes             | Where the server and internal load balancer live. Use the same VPC as your ICAP client.                                                                                                                                                                 |
| `ApiUrl`                                    | Yes             | The base URL of your API Agent.                                                                                                                                                                                                                         |
| `ScanApiSecretArn` or `ApiUser` + `ApiPass` | Yes             | Scan-API credentials (see the two options above).                                                                                                                                                                                                       |
| `AllowedClientCidr`                         | Optional        | Restricts which addresses may connect on port 1344. Defaults to `0.0.0.0/0`, which means anything that can route to the internal load balancer (your VPC and peered networks — never the internet). Tighten to your client subnets for least privilege. |
| `DesiredCount`                              | Default 1       | Number of server tasks; the load balancer spreads connections across them. Scale horizontally for throughput.                                                                                                                                           |
| `EphemeralStorageGiB`                       | Default 30      | Scratch disk. Set to at least **2× your largest file**.                                                                                                                                                                                                 |
| `AssignPublicIp`                            | Default ENABLED | `ENABLED` for public subnets; `DISABLED` for private subnets with a NAT route.                                                                                                                                                                          |
| `DebugLogging`                              | Default false   | Set `true` to log full ICAP request lines and headers (never file content) for troubleshooting.                                                                                                                                                         |

{% hint style="info" %}
To deploy in a different region, launch the same template there — the server image is pulled automatically from that region's ECR replica, so there is no cross-region data transfer.
{% endhint %}

### Pointing Your ICAP Client at the Server

The stack output `IcapEndpoint` is your target:

```
icap://<nlb-dns-name>:1344/avscan
```

Any service name is accepted; `avscan` is conventional. For best results your client should:

* Send `REQMOD` (or `RESPMOD`) with the encapsulated HTTP message
* Send `Allow: 204` (recommended — the cheaper clean-file path)
* Reuse connections (persistent connections are supported and recommended)
* Optionally use Preview — the server advertises `Preview: 4096` in its `OPTIONS` response

### Validating the Deployment

From any machine inside the VPC with an ICAP client installed (for example `c-icap-client`, available in the `c-icap` package on Ubuntu), run three checks:

**1. Handshake** — expect `ICAP/1.0 200 OK` with `Methods: REQMOD, RESPMOD`:

```bash
c-icap-client -i <nlb-dns> -p 1344 -s avscan
```

**2. Clean file** — expect "No modification needed (Allow 204 response)":

```bash
echo "clean test" > /tmp/clean.txt
c-icap-client -i <nlb-dns> -p 1344 -s avscan -f /tmp/clean.txt -req http://example.com/clean.txt
```

**3. EICAR test file** — the industry-standard, harmless antivirus test file; expect an HTTP **403** block page:

```bash
printf '%s%s' 'X5O!P%@AP[4\PZX54(P^)7CC)7}$' 'EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > /tmp/eicar.com
c-icap-client -i <nlb-dns> -p 1344 -s avscan -f /tmp/eicar.com -req http://example.com/eicar.com
```

All three passing means the full chain — client → ICAP server → API Agent → verdict — is working. CSS can also provide a .NET reference ICAP client with the same checks and script-friendly exit codes (0 = clean, 1 = blocked); [Contact Us](/contact-us) if you would like a copy.

### Sizing and Performance

Scanning is inline: total latency is the upload to the ICAP server plus the scan itself. As a rule of thumb, allow **about 2 minutes per GB** and set your client's ICAP timeout to roughly 3× the expected worst case (we recommend at least 30 minutes for multi-gigabyte objects).

| To increase              | Adjust                                                                    |
| ------------------------ | ------------------------------------------------------------------------- |
| Throughput               | `DesiredCount` — the server is stateless, so adding tasks scales linearly |
| Maximum file size        | `EphemeralStorageGiB` — at least 2× your largest file                     |
| Concurrent scan capacity | `TaskCpu` / `TaskMemory` — CPU matters most for many concurrent scans     |

{% hint style="warning" %}
Make sure the idle timeout on your API Agent's load balancer covers your worst-case scan duration — the AWS default of 60 seconds will cut off large-file scans.
{% endhint %}

### Operations

* **Logs:** the CloudWatch log group `/css-icap-server/icap` records one line per request with the verdict (`CLEAN` / `INFECTED` / scan-API errors).
* **Health:** every task runs a real health probe every 30 seconds (ICAP `OPTIONS` answered and API Agent reachable). Unhealthy tasks are replaced automatically.
* **Debug logging:** if a client integration misbehaves, redeploy with `DebugLogging=true`, reproduce the issue, and send CSS the logs. File content is never logged. Set it back to `false` when done.

### Troubleshooting

| Symptom                              | Likely cause / fix                                                                                                                                                                                      |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Stack `CREATE_FAILED` on the service | The task can't pull the container image because the subnets have no egress. Add a NAT route, or use public subnets with `AssignPublicIp=ENABLED`.                                                       |
| Tasks cycle unhealthy                | The health probe is failing. Check the CloudWatch logs — "scan API unreachable" indicates an egress or DNS problem; verify the NAT route and `ApiUrl`.                                                  |
| Client receives ICAP `500`           | The API Agent is unreachable or the credentials were rejected (fail closed by design). Verify the username/password and `ApiUrl`.                                                                       |
| Client can't connect on port 1344    | `AllowedClientCidr` doesn't cover the client, or the client is in a different VPC (the load balancer is internal). If the tasks are healthy but the client can't connect, it is almost always the CIDR. |
| Large uploads stall or reset         | The client-side ICAP timeout is too low, or `EphemeralStorageGiB` is too small for the object.                                                                                                          |

### Security Posture

* The load balancer is **internal** — nothing is reachable from the internet.
* The container image contains **no credentials**; they are injected from Secrets Manager at task launch.
* The container runs as a **non-root** user.
* Verdicts are **fail closed**: if the file cannot be scanned, it is not passed through.


# Demo Videos

Check out some of our video content to get a better feel for our solution.

Please check out the [Cloud Storage Security YouTube Channel](https://www.youtube.com/channel/UCZyPwq0OKaqJQluGRctLcKw?view_as=subscriber) for our full catalog of videos.

{% embed url="<https://www.youtube.com/watch?v=xS3AsVJx-zI>" %}

{% embed url="<https://www.youtube.com/watch?v=3iZ1CWN8rN4>" %}

{% embed url="<https://www.youtube.com/watch?v=k3ZcAFRwHN0>" %}

{% embed url="<https://www.youtube.com/watch?v=MrpCwYCb3vc>" %}

{% embed url="<https://www.youtube.com/watch?v=7304AZrG4So>" %}

{% embed url="<https://www.youtube.com/watch?v=TdW2qelUGg8>" %}


# Scanning APIs

## Cloud Storage Security Scanning API

v1 OAS3

[css\_scanning\_api\_openapi\_doc.json](https://css-public-docs.s3.amazonaws.com/css_scanning_api_openapi_doc.json)

## HealthCheck

{% openapi src="/files/4mIiUK5l9zgTstqXOsOr" path="/health" method="get" %}
[css\_scanning\_api\_openapi\_doc.json](https://905555942-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlGcQw8I2CHyi1loKBlfi%2Fuploads%2FF2XGQmkXm6fHrzWir9Xw%2Fcss_scanning_api_openapi_doc.json?alt=media\&token=1b5feace-a0e1-481c-a34c-823a5f9ec310)
{% endopenapi %}

## Scan

{% openapi src="/files/4mIiUK5l9zgTstqXOsOr" path="/api/Scan/JobStatus" method="get" %}
[css\_scanning\_api\_openapi\_doc.json](https://905555942-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlGcQw8I2CHyi1loKBlfi%2Fuploads%2FF2XGQmkXm6fHrzWir9Xw%2Fcss_scanning_api_openapi_doc.json?alt=media\&token=1b5feace-a0e1-481c-a34c-823a5f9ec310)
{% endopenapi %}

{% openapi src="/files/4mIiUK5l9zgTstqXOsOr" path="/api/Scan/Existing" method="post" %}
[css\_scanning\_api\_openapi\_doc.json](https://905555942-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlGcQw8I2CHyi1loKBlfi%2Fuploads%2FF2XGQmkXm6fHrzWir9Xw%2Fcss_scanning_api_openapi_doc.json?alt=media\&token=1b5feace-a0e1-481c-a34c-823a5f9ec310)
{% endopenapi %}

{% openapi src="/files/4mIiUK5l9zgTstqXOsOr" path="/api/Scan" method="post" %}
[css\_scanning\_api\_openapi\_doc.json](https://905555942-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlGcQw8I2CHyi1loKBlfi%2Fuploads%2FF2XGQmkXm6fHrzWir9Xw%2Fcss_scanning_api_openapi_doc.json?alt=media\&token=1b5feace-a0e1-481c-a34c-823a5f9ec310)
{% endopenapi %}

{% openapi src="/files/4mIiUK5l9zgTstqXOsOr" path="/api/Scan/url" method="post" %}
[css\_scanning\_api\_openapi\_doc.json](https://905555942-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlGcQw8I2CHyi1loKBlfi%2Fuploads%2FF2XGQmkXm6fHrzWir9Xw%2Fcss_scanning_api_openapi_doc.json?alt=media\&token=1b5feace-a0e1-481c-a34c-823a5f9ec310)
{% endopenapi %}

## Token

{% openapi src="/files/4mIiUK5l9zgTstqXOsOr" path="/api/Token" method="post" %}
[css\_scanning\_api\_openapi\_doc.json](https://905555942-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlGcQw8I2CHyi1loKBlfi%2Fuploads%2FF2XGQmkXm6fHrzWir9Xw%2Fcss_scanning_api_openapi_doc.json?alt=media\&token=1b5feace-a0e1-481c-a34c-823a5f9ec310)
{% endopenapi %}


# SSO Integrations

Here are some guides on how to integrate SSO into the CSS application.

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td>Entra ID</td><td></td><td><a href="/pages/f5MxC294Yx8FDiwNjZui">/pages/f5MxC294Yx8FDiwNjZui</a></td></tr><tr><td></td><td>Okta</td><td></td><td><a href="/pages/FbKoX0D93ErkofPJ5rCN">/pages/FbKoX0D93ErkofPJ5rCN</a></td></tr></tbody></table>


# Entra ID SSO Integration

This page teaches you how to integrate Entra ID into your Amazon Cognito User Pool.

The below video covers setting up Azure Entra ID with your Amazon Cognito User Pool:

{% embed url="<https://www.youtube.com/watch?v=yOjqljiGBCc>" %}

You can also follow the information and steps below:

### Create the Cognito Domain

1. Capture the Congito User Pool ID

In the AWS Console, navigate to the User Pool created by your application. It'll generally look like "CloudStorageSecUserPool-{appid}".

Copy the **User Pool ID**.

<figure><img src="/files/aFY4O563PMzPNOYa9HwH" alt=""><figcaption><p>Cognito User Pool ID</p></figcaption></figure>

2. Create a Cognito Domain

In the User Pool, navigate to Domain and select 'Create Cognito Domain'.

<figure><img src="/files/VVdG8BsJ9svDUGQdSHGF" alt=""><figcaption><p>Creating Cognito domain</p></figcaption></figure>

Create the domain of your choice.

<figure><img src="/files/gmj9OqyWn7JPsNiIN7Bo" alt=""><figcaption><p>Creating Cognito domain 2</p></figcaption></figure>

### Azure: Create SSO App

1. Create a New Application

Navigate to Microsoft Entra ID in your Azure console and select 'Enterprise Applications'. Select 'New Application'.

<figure><img src="/files/qRsfYmWrjBtBUL5JLPk8" alt=""><figcaption></figcaption></figure>

Select 'Create your own application' and enter in a name of your choice.

<figure><img src="/files/oYzpcETcex4DpIjx7zYf" alt=""><figcaption></figcaption></figure>

2. Set up SSO for your application

After this application is created, select 'Set up single sign on'.

<figure><img src="/files/QdQfFFYnfSnvhPVXzqHv" alt=""><figcaption></figcaption></figure>

Select SAML and select 'edit' on the Basic SAML Configuration, entering in the following:

* Identifier (Entity ID) as 'urn:amazon:cognito:sp:' plus your **Cognito user pool ID that you copied earlier**
* Reply URL (Assertion Consumer Service URL) as your **Cognito domain name that you created earlier** (it should end in ...auth.{region}.amazoncognito.com)

<figure><img src="/files/LQUxIlAXaSFLPelFBFyG" alt=""><figcaption></figcaption></figure>

Save this configuration.

In the 'SAML Certificates' box, copy the 'App Federation Metadata URL'.

<figure><img src="/files/Rkx13IirSEgBWjW2nw7q" alt=""><figcaption><p>Cognito App Federation Metadata URL</p></figcaption></figure>

### AWS: Add Identity Provider

In the AWS Console:

Navigate back to your Cognito User Pool and select 'Social and external providers'.

Select 'Add Identity Provider'

<figure><img src="/files/wECTZ0YPPWMBCIBBz0B7" alt=""><figcaption></figcaption></figure>

Select 'SAML' and enter in a provider name. Do not add spaces.

Select 'Enter metadata document endpoint URL' and paste in the App Federation Metadata URL that you copied from Azure.

Add the identity provider.

<figure><img src="/files/34X09sP9SFALMeJCABMU" alt=""><figcaption></figcaption></figure>

In Cognito, navigate to App Clients -> {your user pool} and select 'Login pages'.

<figure><img src="/files/1MA86FsJGCGqDeqKxoeg" alt=""><figcaption></figcaption></figure>

Select the 'Edit' button and enter in the following:

* Allowed callback URLs: CSS Console URL
* Allowed sign-out URLs: CSS Console URL
* Identity Providers: Identity Provider you just created
* Oauth 2.0 grant types: 'Authorization code grant', 'implicit grant'
* OpenID Connect scopes: 'OpenID, 'Email'

Select 'Save changes'.

<figure><img src="/files/an0iZeYwvisNTe3XwJWq" alt=""><figcaption></figcaption></figure>

### Azure: Add user to Entra ID

In the Azure console:

Navigate back to your Enterprise Application and select 'Users and groups'.

Select 'Add user/group'.

<figure><img src="/files/oQ8jkmxcp0UknIBg4AAr" alt=""><figcaption></figcaption></figure>

Select 'None Selected' and choose your Azure user.

After selecting the user, click 'Assign'.

### CSS Console: Verify Changes

In the CSS Console:

View the sign-in page and note that your Azure-created application now appears.

<figure><img src="/files/UuZv38UoehID9ulODDDN" alt=""><figcaption></figcaption></figure>

### CSS Console: Set Up User

1. Click on the 'Sign In With {sso}' button. This will create a user in Cognito but permissions need to be initiated first.
2. Log in as a user that has Admin permissions.
3. Go to Access Management -> Manage Users. There will be a new user created with the the format {provider\_name}\_*{entra*\_user\_email} in the Manage Users page.
4. Click the 3 buttons next the Status and choose Groups. Select Primary and assign the user to the group.

<figure><img src="/files/oYjfBQkCUkEcudXKBgwS" alt=""><figcaption></figcaption></figure>

5. Enable the user by clicking the button with 3 dots on the rightmost column and selecting 'Enable User'.
6. (Optional) Click the 3 buttons next to the Status and choose 'Change Role'. The user defaults at 'User' permissions and can be adjusted to another role if needed.

Your user is now set up! Log out and click the SSO button. You are now logged in as the SSO user!


# Okta SSO Integration

This page teaches you how to integrate Okta into your Amazon Cognito User Pool.

The below video covers setting up Okta SSO with your Cognito User Pool:

{% embed url="<https://www.youtube.com/watch?v=iSFwRqzpXuc>" %}

You can also follow the information and steps below:

This article has been adapted from <https://repost.aws/knowledge-center/cognito-okta-saml-identity-provider>, which contains some legacy or non-applicable information.

### Set up Cognito

1. Capture the Congito User Pool ID

In the AWS Console, navigate to the User Pool created by your application. It'll generally look like "CloudStorageSecUserPool-{appid}".

Copy the User Pool ID.

<figure><img src="/files/aFY4O563PMzPNOYa9HwH" alt=""><figcaption><p>Cognito User Pool Overview</p></figcaption></figure>

2. In the User Pool, navigate to Domain and select 'Create Cognito Domain'.

<figure><img src="/files/MTfGJsN3lNrFxbDHy8Mg" alt=""><figcaption></figcaption></figure>

Create the domain of your choice.

<figure><img src="/files/wgBZdzd5UZ4dG8e91h3s" alt=""><figcaption></figcaption></figure>

### Create a SAML app in Okta

1. In your Okta dashboard, select Applications > Applications

<figure><img src="/files/s7qLSqFui3hXzXePgEp6" alt=""><figcaption></figcaption></figure>

2. Select 'Create App Integration', and in the menu select 'SAML 2.0'
3. Create an app name of your choice. Upload an app logo if you would like. Select 'next'.
4. Configuring SAML:

Here's a chart for the items that must be entered in. After these three values, select 'Next'.

| Key                             | Value                                                                                                                                                                      | Example                                                                                      |
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| Single sign-on URL              | enter ' https\://{cognito\_domain\_prefix}.auth.{your\_region}.amazoncognito.com/saml2/idpresponse'. Refer back to the domain created in the 'Create Cognito Domain' step. | <https://css\\_demo.auth.us-west-2.amazoncognito.com/saml2/idpresponse>                      |
| Audience URI                    | enter 'urn:amazon:cognito:sp:{userpoolid}                                                                                                                                  | urn:amazon:cognito:sp:us-west-2\_abcd123                                                     |
| Attribute statements (optional) | for name enter in '<http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress>' and for value enter in 'user.email'                                               | <p><http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress></p><p>user.email</p> |

<figure><img src="/files/wDXSoNkv1RZvuFWN182e" alt=""><figcaption></figcaption></figure>

5. Provide feedback to Okta if you wish, or just select 'Finish'.

### Assign a user in Okta

1. In the 'Assignments' page, select 'Assign' and 'Assign to People'.

<figure><img src="/files/QcigaWRBgaihURdYD3LJ" alt=""><figcaption></figcaption></figure>

2. Select the user you would like to access this application.
3. Select 'Done'.

### Capture Okta IdP metadata

1. Click the 'Sign On' tab and copy the 'Metada URL' value.

<figure><img src="/files/nWw4wCjmZCz2ZQljf6Xu" alt=""><figcaption></figcaption></figure>

### Set up Okta in Cognito

In Cognito:

1. Select your user pool
2. Select 'Social and external providers' and select 'Add identity provider'. Select 'SAML'.
3. Fill out 'Okta' as the provider name, and select 'Enter metadata document endpoint URL'. Paste the Metadata URL we copied from the last step.

<figure><img src="/files/i4OBh1n7Ki03Oo0ZvmVs" alt=""><figcaption></figcaption></figure>

4. Add the identity provider.
5. Add an Attribute by clicking 'Edit' on the Attribute Mapping box:

<figure><img src="/files/oPBTc35BCkzYqycyX0Jl" alt=""><figcaption></figcaption></figure>

6. Select 'Add another attribute' and enter in the following into the SAML attribute: <http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress\\>
   select 'Email' as the User pool attribute.\
   \
   Your form should look like below. Save changes.

<figure><img src="/files/yTRFVEbGpKBEmDB8qySU" alt=""><figcaption></figcaption></figure>

### Configure Cognito App Client

In Cognito > App Clients:

1. Select the 'Login pages' tab and click 'Edit'.

<figure><img src="/files/s6yxxs1uKEHJQrUrNzpz" alt=""><figcaption></figcaption></figure>

2. In the 'Managed login pages' section, ensure the Allowed callback URLs and Allowed sign-out URLs are both the Console URL.
3. Under 'Identity providers', select 'Okta' and 'Cognito user pool'.
4. Under 'OAuth 2.0 grant types' ensure 'Implicit grant' is selected.
5. Under 'OpenID Connect scopes' ensure 'Email' and 'OpenID' are selected.
6. Save changes.

### CSS Console: Set Up User

1. Click on the 'Sign In With Okta' button. This will create a user in Cognito but permissions need to be initiated first.
2. Log in as a user that has Admin permissions.
3. Go to Access Management -> Manage Users. There will be a new user created with the the format Okta\_{email} in the Manage Users page.
4. Click the 3 buttons next the Status and choose Change Groups. Select Primary and assign the user to the group.

<figure><img src="/files/eSg8GkzrGTkoDPEfoktH" alt=""><figcaption></figcaption></figure>

5. Enable the user by clicking the button with 3 dots on the rightmost column and selecting 'Enable User'.
6. (Optional) Click the 3 buttons next to the Status and choose 'Change Role'. The user defaults at 'User' permissions and can be adjusted to another role if needed.

Your user is now set up! Log out and click the SSO button. You are now logged in as the SSO user!


# Frequently Asked Questions

In this section you'll find answers to common questions that may come up when using our solutions.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Getting Started</td><td></td><td></td><td><a href="/pages/eF8CUh11skhXRdUYXRjd">/pages/eF8CUh11skhXRdUYXRjd</a></td></tr><tr><td>Product Functionality</td><td></td><td></td><td><a href="/pages/0BqfA8uOZYvY0p6QfVdy">/pages/0BqfA8uOZYvY0p6QfVdy</a></td></tr><tr><td>Architecture Related</td><td></td><td></td><td><a href="/pages/YvpHWV2urpSjBPHFtuO9">/pages/YvpHWV2urpSjBPHFtuO9</a></td></tr><tr><td>Supported File Types</td><td></td><td></td><td><a href="/pages/AqGCtFnHh7DCSFSVkl42">/pages/AqGCtFnHh7DCSFSVkl42</a></td></tr></tbody></table>

{% hint style="info" %}
If you can't find an answer to your question or you have consulted the FAQ information and have additional questions, please [contact](/contact-us) our support team so we can provide assistance.
{% endhint %}


# Getting Started

Below are some of the most common questions related to getting started with our products.

## Do my objects ever leave my account?

No. Antivirus for Amazon S3 is designed and deployed in such a way that your Amazon S3 objects never leave your account(s).

{% hint style="info" %}
If you are utilizing Linked Accounts, the objects will be pulled from `Account X` to the deployed account for scanning. But these are maintained within your realm of linked accounts.
{% endhint %}

## Is there a free trial?

Yes, we offer a 30 day period of time or up to 100GB of scanning (whichever comes first) to try the product. Trial extensions may be requested, please [Contact Us](/contact-us).

[Start a Trial](https://aws.amazon.com/marketplace/pp/B089QBV2GC/?ref=_ptnr_help_doc_)

{% hint style="warning" %}
Like AWS' trial policy, the trial is good for only one deployment within an account. Any following deployments will result in immediate charges for any data scanned by those deployments. The initial deployment will remain within the trial period and data.
{% endhint %}

{% hint style="info" %}
You can see the status of your trial on the [Config->License Management page](/console-overview/configuration/license-mgmt). You will also be warned with a banner warning on the main dashboard when you are within 7 days of the trial ending or within 20% of the trial data allotment.

You can also subscribe to the [Proactive Notifications](/console-overview/configuration/proactive-notifications) to specifically receive emails when the free trial is approaching its end due to date or data.
{% endhint %}

## How do you charge for the product?

We leverage a true consumption model. We charge for each gigabyte you scan with the product. This may be from one object or one thousand objects.

Review the public pricing on the [AWS Marketplace Listing](https://aws.amazon.com/marketplace/pp/B089QBV2GC/?ref=_ptnr_help_doc_). Please [Contact Us](/contact-us) for custom pricing.

For **PAYG** Subscriptions, **Billing cycles** are every 30 days. This means that if your payment took place on the 1st of the month, the next one will be either the 31st or the 1st of the next month, depending on each month.

## Do you have a detailed deployment guide?

You can follow allow the [Getting Started](https://github.com/cloudstoragesec/HelpDocs2/blob/main/faq/broken-reference/README.md) contained within the Help Docs you are currently within or you can download the PDF Deployment Guide if that is easier to follow. There are a number of topics that are covered in the deployment guide (more details on TCO and recovery strategies if ever needed) that you will not find within the Help Docs.

[Detailed Deployment Guide](https://css-public-docs.s3.amazonaws.com/CloudStorageSecurity-AV-for-S3-DeploymentGuide_v4.pdf)

## Do you support AWS GovCloud?

Yes, we now have an option to deploy Antivirus for Amazon S3 inside of GovCloud. You can leverage the [`BYOL and GovCloud` Listing](http://aws.amazon.com/marketplace/pp/B08SPXP292) in AWS Marketplace or launch the template directly from [here](https://console.amazonaws-us-gov.com/cloudformation/home?region=us-gov-west-1#/stacks/create/review?stackName=CloudStorageSecurity\&templateURL=https://css-cft.s3.amazonaws.com/ConsoleCloudFormationTemplate-GovCloud.yaml).

{% hint style="info" %}
AWS Marketplace doesn't currently support metering for Fargate containers inside of GovCloud, so you must purchase a license (pre-purchase GBs) to operate within GovCloud. Please contact us at <sales@cloudstoragesec.com> or one of our partners to procure a license.

Amazon Cognito is only supported in GovCloud US West, so the console must be deployed in this region. Scanning can be done in West or East, but the console deployment must be done in West.
{% endhint %}

## Is this software as a service (SaaS)?

No, this solution is installed within your AWS account. Please refer to the [Architecture](/how-it-works/architecture-review) section for more details.

We are exploring a SaaS version for those who are willing, but there is still a majority of companies who want their objects to stay "within their 4 walls" (in this case their own VPC) for the scanning process. Cloud Storage Security has delivered the solution to meet this initial need. We do see SaaS as a viable alternative for those that are willing so we are pursuing it.

{% hint style="info" %}
There is a mechanism where we could offer this to you as a SaaS today. If interested, please [contact us](/contact-us). If you're willing to work with us, we can explore delivering it to you this way.
{% endhint %}

## Which browsers are supported?

Any modern browser of your choice is supported (Chrome, Firefox, Edge, Safari, etc.)

## Can I use Terraform to deploy the product?

Yes, we have a Terraform Module available to deploy [here](https://registry.terraform.io/modules/cloudstoragesec/cloud-storage-security/aws/latest).

## Where can I get the CloudFormation Template to deploy the product?

As seen in the [How to Subscribe](/getting-started/how-to-subscribe) section, you'll be directly linked to the deployment CloudFormation Template. You can go to `Manage Subscriptions` within the AWS Console and launch additional software from there.

Templates:

* PAYG Deployments:
  * Download the CloudFormation Template [here](https://css-cft.s3.amazonaws.com/ConsoleCloudFormationTemplate.yaml) or launch it directly [here](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?stackName=CloudStorageSecurity\&templateURL=https://css-cft.s3.amazonaws.com/ConsoleCloudFormationTemplate.yaml).
* BYOL or GovCloud Deployments:
  * Use this Marketplace Listing: [`BYOL and GovCloud` Listing](http://aws.amazon.com/marketplace/pp/B08SPXP292)
  * Download the Cloudformation Template [here](https://css-cft.s3.amazonaws.com/ConsoleCloudFormationTemplate-BYOL.yaml) or launch the template directly from [here](https://console.amazonaws-us-gov.com/cloudformation/home?region=us-gov-west-1#/stacks/create/review?stackName=CloudStorageSecurity\&templateURL=https://css-cft.s3.amazonaws.com/ConsoleCloudFormationTemplate-BYOL.yaml).
* Transfer Family Integrated Deployments:
  * Use this Marketplace Listing: [`Antivirus for Managed File Transfers`](https://aws.amazon.com/marketplace/pp/prodview-s56hvqbcyj5qe)
  * Download the Cloudformation Template [here](https://css-pub-us-east-1.s3.amazonaws.com/templates/css-mft.template.yaml) or launch the template directly from [here](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?stackName=CloudStorageSecurity\&templateURL=https://css-pub-us-east-1.s3.amazonaws.com/templates/css-mft.template.yaml).
* Cross-Account Role:
  * Download the CloudFormation Template [here](https://css-cft.s3.amazonaws.com/LinkedAccountCloudFormationTemplate.yaml) or launch it directly [here](https://css-cft.s3.amazonaws.com/LinkedAccountCloudFormationTemplate.yaml).
* Private Deployment Template:
  * Download the CloudFormation Template [here](https://css-cft.s3.amazonaws.com/ConsoleCloudFormationTemplate-PrivateDeployment.yaml).

{% hint style="info" %}
You will be able to launch and deploy the Antivirus for Amazon S3 product from the above templates, but the product will not run unless you are subscribed.
{% endhint %}

## What do all the CloudFormation parameters mean?

| Parameter                                                                      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Stack Name                                                                     | Name to identify this particular stack                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| **Network Configuration**                                                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Virtual Private Cloud (VPC) ID                                                 | Choose which VPC the Console should be deployed to                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Subnet A ID                                                                    | Choose the first Subnet the Console could be deployed to.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| Subnet B ID                                                                    | Choose the second Subnet the Console could be deployed to. **\*Make sure the second subnet is different from the first**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Console Security Group CIDR Block                                              | <p>The IP address range that can access the Console management website (e.g. X.X.X.X/24 for a single given IP, 0.0.0.0/0 for open access).</p><p>It is always a good idea to specify a network tied to your company as opposed to being wide open.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| **Console Configuration**                                                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Console vCPU                                                                   | CPU desired for the Console container. There isn't much overhead to this container, so try the minimums and grow up as needed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Console Memory                                                                 | <p>Memory desired for the Console container. There isn't much overhead to this container, so try the minimums and grow up as needed.</p><p><strong>Memory Requirement:</strong> Allowed memory size is a factor of the selected vCPU size. You <strong>must</strong> pick a value that is 2x - 8x of the vCPU selection.</p><p>Example: .5vCPU, then memory must be between 1GB and 4GB in memory.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| UserName                                                                       | Name used to login to the Management Console.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| Email                                                                          | <p>This email address will be sent the initial password and all subsequent <code>password reset</code> requests.</p><p>Ensure you can access this email address.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Console Auto Assign Public IP                                                  | <p>Allow public IP addresses to be assigned to the Console<br></p><ul><li>Enabled - assign public IP</li><li>Disabled - do not assign public IP</li></ul><p><strong>Note:</strong> If you disable, your must still have access to the VPC private network or you will be unable to access the console</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| Enable CloudTrail Lake                                                         | Choose whether you want audit logs sent to CloudTrail Lake.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| DynamoDB Point In Time Recovery                                                | Choose whether to enable point in time recovery (PTIR) for DynamoDB tables.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Allow Console To Run Storage Assessment                                        | Choose whether you would like Storage Assessment to run within your console, providing details for your S3 deployment.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Buckets to Protect                                                             | <p>Enter any pre-existing buckets that you would like to have event-based protection enabled on when the console is launched.</p><p>For multiple buckets, separate bucket names by commas (e.g. bucket1,bucket2,bucket3).</p><p>Note that this only works for buckets in the same region as this deployment.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| **Agent Configuration**                                                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Agent vCPU                                                                     | <p>CPU desired for the Agent container. Sizing the Agents can vary based on load volumes, object sizes or scan windows. Refer to the <a href="/pages/1L2gUTAoSgwkL64VDLE5">Sizing Discussion</a> for more details.<br><strong>Note:</strong> There is no reason to increase the agent vCPU at this time. 1 vCPU is enough for scanning at this time</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| Agent Memory                                                                   | <p>Memory desired for the Agent container. Sizing the Agents can vary based on load volumes, object sizes or scan windows. Refer to the <a href="/pages/1L2gUTAoSgwkL64VDLE5">Sizing Discussion</a> for more details.<br><strong>Note:</strong> At this time the default of 3GB memory is a good working amount. From testing, we do not see a need to go up. You'll scale out with more aents running before scaling up provides more value. In the future, tweaks may be made where more memory makes sense.<br><br><strong>Memory Requirement:</strong> Allowed memory size is a factor of the selected vCPU size. You <strong>must</strong> pick a value that is 2x - 8x of the vCPU selection.<br>Example: 1vCPU, then memory must be between 2GB and 8GB in memory.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| Agent Scanning Engine                                                          | Choose the AV Engine to execute scans.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Multi-Engine Scanning Mode                                                     | <p>Choose how many engines you would like to scan your files:</p><ul><li>Disabled will use a single engine.</li><li>All will scan every file with both engines.</li><li>LargeFiles will scan files larger than 2GB using the Sophos engine.</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Agent Disk Size                                                                | <p>Choose the size of the disk used to scan files. Any files discovered that are larger than the Agent Disk Size will try to be scanning by the Large Scanning File process (if enabled).</p><p>This setting only applies when using the Sophos scanning engine.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Enable Large File Scanning                                                     | Choose whether you would like an EC2 instance launched to scan files that are too large to be processed by the normal agent.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| Extra Large File Disk Size                                                     | <p>Choose the size of the disk used to scan large files.</p><p>If a file is larger than the disk it will be classified as “unscannable”.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| Extra Large File EC2 Tags                                                      | Enter an optional comma-separated list of key=value tags to place on extra large file scanning EC2 instances.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| Allow Access to All KMS Keys                                                   | Allows the solution access to any KMS key only within the context of the Amazon S3 service. Permissions will be put in place so that we can decrypt and encrypt objects as needed during the scanning process.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Agent Auto Assign Public IP                                                    | <p>Allow public IP addresses to be assigned to the scanning agents</p><ul><li>Enabled - assign public IP</li><li>Disabled - do not assign public IP</li></ul><p><strong>Note:</strong> The agent has no real need for a public IP (unlike the Console for access), but the network it resides in must have "public" routing or enough routing to execute AWS API calls. This could be through a VPC Endpoint for supported services or by locating behind a NAT Gateway. Without that routing the agent will fail to spin up</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Quarantine objects into the primary account for infections in linked accounts? | For linked accounts, choose whether you would like quarantine buckets created within the primary account to capture infected files.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Expire (delete) quarantined objects after a specified number of days?          | Choose how many days quarantined files will be retained before they are deleted. Enter 0 if you would like auto-delete disabled.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| **Agent Auto-Scaling Configuration**                                           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Only Run Scanning Agents When Files are in Queue?                              | Smart Scan - Yes/No: This will impact how the scanning agents will run. The default of `No` will deploy and run the minimum number of agents defined below 24x7 so you have an agent(s) up and running and ready to scan. Setting Smart Scan to `Yes` will require you to set the Minimum Number of Running Agents to `0` and agents will spin up only when there is work to do in the queue that surpasses the Number of Messages in Queue to Trigger Auto-Scaling. When select `Yes`, the number of messages in queue should typically be set to a smaller number like `1`. This would indicate any time items come into the queue, meaning any time there is work to do, spin up an agent and scan it. But, when there is no work to be done it will spin all agents down for efficiencies. You can read more about this [here](/console-overview/configuration/agent-settings#smart-scan).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Minimum Number of Running Agents Per Region                                    | <p>Minimum number of Agents you'd like running. This will be determined by scan volumes and scan windows. Refer to the <a href="/pages/1L2gUTAoSgwkL64VDLE5">Sizing Discussion</a> for more details.<br></p><p><em>Setting this above 1 will incur more infrastructure costs as more agents will be running full time</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Maximum Number of Running Agents Per Region                                    | <p>Maximum number of Agents you'd like running. This will be determined by scan volumes and scan windows. Refer to the <a href="https://help.cloudstoragesec.com/how-it-works/sizing/">Sizing Discussion</a> for more details.<br></p><p><em>Default value of 12 is an arbitrary number at this time, change this as needed. Smaller if you want to ensure to never scale above a certain number (to lock down on possible costs) and larger if you need more agents running to process the load</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| Number of Messages in Queue to Trigger Agent Auto-Scaling                      | The number of entries that should sit in the queue for at least 1 minute before more Agents are triggered to scale-up. Based on how long it is taking to process the individual objects, you may make this number larger or smaller so you don't have too much scaling activity. Refer to the [Sizing Discussion](/how-it-works/sizing) for more details.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **Optional Load Balancer Configuration**                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Use a Load Balancer for the Console?                                           | A Yes/No answer determining whether or not to deploy a load balancer                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| SSL Certificate ARN                                                            | In order to create a secure connection, you must provide an SSL certificate to register with the load balancer. This can be one created inside AWS Certificate Manager or from a third party                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| Load Balancer Subnet A ID                                                      | <p>Choose the first Subnet the Load Balancer could be deployed to.<br></p><p><em><strong>NOTE:</strong> The load balancer subnets need to reside in the same Availability Zones as the Console subnets for them to properly communicate.</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Load Balancer Subnet B ID                                                      | <p>Choose the second Subnet the Load Balancer could be deployed to.</p><p><br><em>\*Make sure the second subnet is different from the first.</em></p><p><br><em><strong>NOTE:</strong> The load balancer subnets need to reside in the same Availability Zones as the Console subnets for them to properly communicate.</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Register a Subdomain on Route53                                                | A Yes/No answer for whether the domain associated to the load balancer is managed by Route53. If **yes**, then you can directly register it from the CloudFormation deployment                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Hosted Zone Name                                                               | <p>The Route53 hosted zone value for the domain.<br><em>i.e. my-hosted-domain.com</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| Subdomain                                                                      | <p>The value created as a subdomain on the hosted zone for application access.<br><em>i.e. av-for-s3.my-hosted-domain.com</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Info Opt-Out                                                                   | <p>The option to not register with our Route53 and check in with our Free Trial. This is only available with the Load Balancer deployment option, otherwise we couldn't ensure access to your Console.<br><strong>Note:</strong> As a result of not communicating with our backend service, your Free Trial will be shown as having ended. Follow <a href="/pages/hnWGpxnifgP3gU1tSiAE#trial">these instructions</a> to get your trial reinstated.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| **Optional Custom Hosting of Docker Container Images**                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Custom ECR Account                                                             | <p>The value placed here should be the AWS Account Number where you are hosting the Console and Scanning Agent images.</p><p><br><strong>Note:</strong> When this field is given a value, the Console and Scanning Agents will only look to the specified account repo for updates (and for the initial install). You are responsible for updating this repo</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| **Optional AWS Resource Renaming**                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Various Resources                                                              | <p>Rename deployed resources to match your defined naming scheme.<br><br>Resources to Rename (Prefix):</p><ul><li>DynamoDB Tables</li><li>Quarantine Bucket Name</li><li>AppConfig Application</li><li>AppConfig Environment</li><li>AppConfig Deployment Strategy</li><li>AppConfig Document</li><li>AppConfig Document Schema</li><li>AppConfig Document Role</li><li>AppConfig Document Policy</li><li>User Pool</li><li>User Pool Client</li><li>User Pool Role</li><li>User Pool Policy</li><li>Console Task Role</li><li>Console Task Policy</li><li>Agent Task Role</li><li>Agent Task Policy</li><li>Cross Account Role</li><li>Cross Account Policy</li><li>Execution Role</li><li>Cluster Name</li><li>Service Name</li><li>Task Definition</li><li>Console Security Group</li><li>Load Balancer Name</li><li>Target Group Name</li><li>Load Balancer Group Name</li><li>Parameters</li><li>Notifications Topic</li><li>Event Based Scan Topic</li><li>Event Based Scan Queue</li><li>Retro Scan Queue</li><li>Event Agent Task</li><li>Event Agent Service</li><li>Retro Agent Task</li><li>Retro Agent Service</li><li>Large Event Queue Alarm</li><li>Small Event Queue Alarm</li><li>Decrease Agent Scaling Policy</li><li>Increase Agents Scaling Policy</li><li>Retro Queue Not Empty Alarm</li><li>Retro Queue Empty Alarm</li><li>Remove Retro Agents Scaling Policy</li><li>Set Retro Agent Scaling Policy</li><li>Agent Security Group Name</li></ul> |
| **Transfer Family Specific Parameters**                                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Existing Transfer Family Server                                                | Set this option to ‘No’ and a Transfer Family Server, and corresponding S3 bucket will automatically be deployed for you.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| Quick Start Disable Auto-Protect                                               | When set to 'No', the bucket which is created to store files uploaded to the Transfer Server is automatically protected by the console.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |


# Product Functionality

Below are some of the most common questions related to product functionality.

## Which of my data do you scan: new or existing?

Both. Brand new objects will be scanned via an event-based trigger as soon as they arrive in the bucket. Existing objects will be scanned via the `Retro Scanning` feature where you can define to look back at all objects within the bucket or a subset based on date-time.

For more information, check out the [Object Scanning](/how-it-works/object-scanning) overview.

You can also setup scanning (new or existing files) based on a schedule. Review the [Schedule Scanning](/how-it-works/object-scanning#scheduled-scanning) documentation.

## Do I have to scan all the objects in my buckets or can I scan a subset?

You can scan all objects, existing or newly coming in, or you can scan a subset. Antivirus for Amazon S3 provides Scan Lists and Skip Lists that will allow you to create [Bucket Path Definitions](/console-overview/configuration/scan-settings#scan-and-skip-lists) to determine which folders within buckets you'd like to include for scanning (Scan List) or exclude from scanning (Skip List).

You can also pick a subset of items based on time with the [Scan Existing Objects](/console-overview/protection/aws/protected-buckets#scan-existing-objects) feature.

## Can I scan the files before I write them to Amazon S3?

Yes, with [API Driven Scanning](/how-it-works/object-scanning#api-driven-scanning) you can send files for scanning directly. This is useful if you have a workflow where the file scan dictates whether the file should be stored in Amazon S3. There are a number of additional useful scenarios where an API comes in handy: scan on read (leveraging [Amazon S3 Object Lambda](https://aws.amazon.com/s3/features/object-lambda/))

## Can I scan files even if I don't use Amazon S3?

Yes, with [API Driven Scanning](/how-it-works/object-scanning) you can send files for scanning directly. Whether you intend to use this file within Amazon S3 or not. You could have an on-prem workflow or one such that Amazon S3 is not your end destination, you can still leverage the API scan to return a file verdict.

## Do you integrate with AWS Transfer Family?

Yes, we integrate with AWS Transfer Family in multiple ways. If you are already using the Transfer Family service, you can deploy our console and enable event-driven bucket protection on the S3 bucket(s) linked to your Transfer Family Sever(s) to ensure its contents are clean.

If you are new to AWS Transfer Family, we have a version of our console that will automatically deploy and protect a Transfer Family Server for you. You can learn more about this specific solution at our [Antivirus for Managed File Transfers Marketplace listing](https://aws.amazon.com/marketplace/pp/prodview-s56hvqbcyj5qe).

## Do you have an API for file scanning?

Yes, with [API Driven Scanning](/how-it-works/object-scanning#api-driven-scanning) you can send files for scanning directly. This is useful if you have a workflow where the file scan dictates whether the file should be stored in Amazon S3. There are a number of additional useful scenarios where an API comes in handy: scan on read (leveraging [Amazon S3 Object Lambda](https://aws.amazon.com/s3/features/object-lambda/))

## Do you have an API for management and configuration?

Yes, it is a limited set at this time, but more will be rolled out as new releases are pushed out. Check out the Management API page for more details, by adding "/swagger" at the end of your Console's URL

{% hint style="info" %}
The most current list available will be within your own deployment. Navigate to your deployment Console and add /swagger to the end of the URL as seen here: `https://<deployment-URL\>/swagger/index.html`
{% endhint %}

## For API, Are the files stored in memory?

No, we have found that performance is faster when files are saved to disk (internal Fargate instance/container) in your own AWS account and region. As soon as the file is scanned, it's get deleted from the containers disk.

## Can I organize linked accounts into groups?

Yes, Antivirus for Amazon S3 allows for the organization and logical separation of linked accounts. This allows you to create a made-for-you organization structure to ease tracking, usage and where issues are originating. Groups also allow you to tie Antivirus for Amazon S3 users down to views and activities for specific sets of linked accounts.

Check out the [Manage Groups](/console-overview/access-management/group-mgmt) documentation for more details.

## How can I tell if files are being scanned?

There are 6 ways to tell files are being scanned: the [Dashboard](broken://pages/Yv5W5DOs5U8QvVNtSOik#dashboard-review), the [Problem Files](/console-overview/see-whats-infected/problem-files) page, Tags on the objects themselves, CloudWatch Logs, AWS Security Hub integration and [Proactive Notifications](/console-overview/configuration/proactive-notifications).

The dashboard is a simple view into how much data you have scanned, how many objects you have scanned and whether you've found any infected files. Often when testing you are using small numbers of objects that are of a smaller size. It can be difficult to see those reflected on the charts, but you will see data points that you can zoom in on. They are there, just hard to see sometimes.

The problem files page is used to identify the infected, unscannable and errored files.

We do not have a page identifying all the clean files, so it is best to look directly at the object itself to see if it has had [Object Tags](/console-overview/configuration/scan-settings#object-tag-keys) applied to it.

{% hint style="info" %}
You may also [subscribe to the Notifications SNS Topic](/console-overview/configuration/proactive-notifications#proactive-notifications) to be informed in real-time of the scan results.

You can review the [CloudWatch Logs - Agent.ScanResults](/how-it-works/architecture-review#cloudwatch-loggroup-overview)
{% endhint %}

## Will I be notified of infected and other problem files?

Yes. You can always monitor the [Dashboard](/console-overview/console-overview#top-row-informationals) for any updates that come in regarding `infected` files along with the other scan results: `unscannable`, `error` and `clean`.

Proactively, you can subscribe to the `Notifications` SNS Topic to get real-time updates sent directly to you or the destination of your choice. More information on [Proactive Notifications](/console-overview/configuration/proactive-notifications#proactive-notifications) is located here.

## Can I send Scan Results to Slack / Teams / other services?

Yes. It is a simple process (that may sound more complicated than it is) that took under 10 minutes to setup. Simply follow the process laid out in the AWS blogpost talking about how to leverage webhooks seen here: [AWS SNS + Slack / Teams / Chime setup](https://aws.amazon.com/premiumsupport/knowledge-center/sns-lambda-webhooks-chime-slack-teams/)

Below is what the notification looks like in Slack:

<figure><img src="/files/YPy9Dl0qiro3nQXfKqaT" alt=""><figcaption></figcaption></figure>

You can modify the format with [Slack Message Layouts](https://api.slack.com/messaging/composing/layouts).

If you run into any trouble please [Contact Us](/contact-us).

## Can I send Logs/ScanResults to Splunk?

Yes. It's a very simple process. There's a Lambda BluePrint to set up straight from our CloudWatch Logs to Splunk:

1. Create a Lambda function > Use a blueprint > Blueprint name "Send CloudWatch logs to a Splunk host" nodejs18.x
2. Add the following import to the code already present next to the other imports:\
   `import { createRequire } from "module"; const require = createRequire(import.meta.url);`
3. Select the Log group **CloudStorageSecurity.Agent.ScanResults**
4. Complete the values for the 2 Splunk Keys at the end.

<figure><img src="/files/eGEufeKGZhDIT0VvG4w5" alt=""><figcaption></figcaption></figure>

That's it, any scan result you get, will be logged in Cloudwatch and copied into your Splunk space

## Can I only run the scanning agent when needed to save on costs?

Yes. You can change all aspects of the scaling setup on the [Agent Settings](/console-overview/configuration/agent-settings) page. There is specifically a [`Smart Scan`](/console-overview/configuration/agent-settings#smart-scan) option that will change the scaling values for this very configuration with the default Scaling Threshold of 1. With the value being set to 1, that would mean any time an object is placed in the queue the agent would spin up and process it (and whatever other work may show up) and then spin down once the work is completed. If you were to set this value to 50, the agent would wait for 50 new objects to show up before spinning up to process the work. Click [here](/console-overview/configuration/agent-settings#smart-scan) to see how to modify the scaling settings.

There is also a scheduling option that allows you to define when the agents should run. This can be used for new objects or all objects in the bucket(s).

## Can I setup schedules to scan my objects?

The ability to scan all files or new files (since last scan) based on a schedule. Whether it is because compliance is driving you to scan on a regular basis or it is that your workflow allows for non-real-time scanning, scheduled scanning provides flexibility for how you scan your data. You get to decide whether you want real-time, one-off on demand, schedule driven scanning or a combination of all the above.

Scheduled Scanning allows you to determine when your agents run. Your workflow and requirements will determine what you pick. If you need real-time scanning then a schedule is not for you. If you can have delays in your scanning [Smart Scan](/console-overview/configuration/agent-settings#smart-scan) or [Scheduled Scans](/console-overview/scheduled-scans) could fit your workflow well.

## Do you offer an overview of the Antivirus for Amazon S3 deployment?

Yes. The [Deployment Overview](broken://pages/XY0bp6ohW8Zy3ZOOL7TS#overview) page quickly and easily shows you which regions have infrastructure installed and buckets being protected.

## How do I cleanup certain aspects of the product or do a complete uninstall?

Yes. The [Deployment Overview](broken://pages/XY0bp6ohW8Zy3ZOOL7TS#solution-cleanup-uninstall) page gives you the option to uninstall a particular aspect of the product (like event scanning) in a particular region, cleanup the entire region or completely uninstall the product.

## How often do you get new signature definitions?

The product pulls new signature updates every 1 hour for the ClamAV engine and every 15 minutes for the Sophos engines and each time the agents come online or reboot. Generally, we have seen ClamAV update once per day (typically mornings) and Sophos about 4 times per day. This is not a hard and fast rule, but what we are seeing regularly.

## Can I switch to 'local' repository for signature updates?

It may be the case where you do not want each scanning agent to reach out to the internet to gather signature updates. Rather, you would like them to be able to retrieve updates locally from within your account. This could be you do not want the agents, that touch your data, to also have an internet connection. The Private Mirror / Local Updates feature supports changing the internet calls to local lookups within a specified S3 bucket. For more information, check out the [Private Mirror (local updates)](/console-overview/configuration/scan-settings#private-mirror-local-signature-updates) help page.

## Can I eliminate public internet access to the solution? Can I run it completely privately?

Yes . . . for the most part. You can eliminate all non-AWS services public internet connections, but there are still three AWS services (Marketplace, AppConfig and Cognito) that you must have outbound internet access to interact with. The Console VPC will require access to these three services, but the agents do not. So you can lock the more prevalent agent VPCs down to have no outbound internet access.

Of course your Subnets can sit behind a NAT Gateway to help control this.

Check out the [Deployment Options](/how-it-works/deployment-details) help page for more details.

## Can you scan encrypted objects?

Yes. The Agent Role will need to be granted access to the keys. This can be done in two main ways: one-off direct access or global, but limited access.

One-off access can be given to individual keys. The process can be seen [here](/trouble-shooting/objects-show-unscannable-with-access-denied).

Global access grants the solution access to all KMS keys, but only in the context of Amazon S3. Leveraging the `viaService` option in the permissions gives us access to the keys, but only while using the Amazon S3 service. Granting access this way will allow the solution to decrypt and encrypt objects even as keys changes. This option is available to set during the CloudFormation deployment. If you'd like to change the value afterwards, please update the stack with the steps found [here](/trouble-shooting/objects-show-unscannable-with-access-denied#global-kms-access-by-default).

## What AV engine(s) do you scan with?

We currently support the following scan engines:

* Sophos
* CSS Premium (this is based on a proprietary commercially available engine)
* ClamAV

Check out the [Scan Engines](/how-it-works/architecture-review#scan-engines) section for more details.

Please [Contact Us](/contact-us) if you'd like to see additional engines added.

## Can you scan with multiple AV engines at the same time?

Yes, we do offer multi-engine scanning with two triggers: `All Files` and `By File Size`. `All Files` indicates every file that is event-based scanned or on-demand/schedule scanned will be processed by the enabled engines.

`By File Size` indicates smaller files (<2GB) will be scanned by ClamAV-only (since ClamAV has a size limitation and can't scan above 2GB). Larger files (>2GB) will be scanned by Sophos-only. This allows you to take advantage of the scan cost savings offered by ClamAV for part of your files, but still allow for those files that are too big for ClamAV to still be scanned.

{% hint style="warning" %}
If scanning files larger than 15gb, you will need to increase the disk size of the scanning agents, either globally or regionally, in the [Event Agent Settings](/console-overview/configuration/agent-settings#agent-task-settings) page.
{% endhint %}

Check out more details in the [Scan Settings → Scan Engine](/console-overview/configuration/scan-settings#scanning-engine) section.

Please [Contact Us](/contact-us) if you have additional scenarios for how multiple engines could be used.

## What is the max file size you can process?

It depends on which engine you are leveraging. There are three engines that can be used with the Antivirus for Amazon S3 solution. The Sophos engine will currently scan up to the max allowed Amazon S3 object size (5TB). While the ClamAV engine can process up to 2GB for any individual file. If you need to process files larger than 2GB then you have to go with the Sophos engine.

So depending on the engine any file under the max cap will be scanned. Any file over the cap will be tagged as `unscannable`.

## Can I setup MFA for my user?

Yes, we do support user MFA. Check out the [User Management](/console-overview/access-management/user-mgmt#setup-mfa) page for details on how to set this up.

## Can I detonate files? Do you have a cloud sandbox?

Yes, we have an OEM'd slice of the Sophos Cloud Sandbox where we can do static and dynamic analysis of files. Check out the [Static and Dynamic Analysis](/console-overview/see-whats-infected/problem-files#static-and-dynamic-analysis) page for more details.

## How can I access the Family Transfer Server created during my deployment?

When deploying the Antivirus for Managed File Transfers solution, you can configure the CloudFormation Template to automatically deploy a Transfer Family Server for you. Once the deployment is complete, you can obtain your Transfer Family Server Id by reviewing the Outputs tab from the CloudFormation Template. Navigate to the Transfer Family service within the AWS console, select the correct server, and review its configuration.

You can connect to the Server using a file transfer service of your choice. Please note:

* The username and password entered to connect to the console is the same username and password that will be used to connect to the Transfer Family Server.
* The server's protocol will be SFTP (SSH File Transfer Protocol) - file transfer over Secure Shell.
* A Lambda function is created during the deployment and will validate authentication for secure file transfers.

## Which storage tiers of S3 do you support scanning for?

Currently, we only support scanning for:

* S3 Standard
* Intelligent-Tiering
* Reduced Redundancy

We do not support scanning for the following S3 storage types:

* Standard-IA
* One Zone-IA
* Glacier Instant Retrieval
* Glacier Flexible Retrieval (formerly Glacier)
* Glacier Deep Archive

If you have a need to scan files in the non-supported storage types please let us know.


# Architecture Related

Below are some of the most common questions related to Architecture

## Do I need to make any changes to my application to use the product?

No. The Antivirus for Amazon S3 solution will fit into your existing workflow. You do not have to make any changes to your current workflow.

## Can I scan S3 objects from more than one account from within the same deployment?

Yes, Antivirus for Amazon S3 supports `cross-account` scanning. This means you can centrally install the console and scanning agents to protect not only the account you are deployed within, but also any other AWS account where you can install a cross-account role.

Check out the [Linked Accounts](/console-overview/access-management/linked-accounts) documentation for more details.

## Can I setup a staging bucket for all of my files to first land in and then move them to a production bucket after they have been found to be clean?

#### Two Bucket System <a href="#architecture-related-can-i-setup-a-staging-bucket-for-all-of-my-files-to-first-land-in-and-then-move" id="architecture-related-can-i-setup-a-staging-bucket-for-all-of-my-files-to-first-land-in-and-then-move"></a>

Yes, it is very easy to setup a two bucket system and we have many customers using this approach. We provide two methods of achieving this.

**Method 1: CSS Console Approach**

First, within the Configuration > Scan Settings menu there is a configuration option for [AV Two-Bucket System Configuratio](https://help.cloudstoragesec.com/console-overview/configuration/scan-settings#av-two-bucket-system-configuration)[n](https://help.cloudstoragesec.com/console-overview/configuration/scan-settings#av-two-bucket-system-configuration). This allows for a quick and easy way to choose your source region or bucket(s) and a destination bucket to promote your clean files. With this option, our agent will handle promoting the clean files as part of the scanning process.

**Method 2: Lambda Approach**

Alternatively, you can also implement this approach with a combination of [Event Based scanning](/console-overview/configuration/agent-settings) and [Proactive Notifications](/console-overview/configuration/proactive-notifications), as described below.

1. Create `staging bucket` or utilize existing bucket
2. Turn [bucket protection on for this bucket](/console-overview/protection/aws/protected-buckets#enable-buckets-for-scanning) from the Antivirus for Amazon S3 console
3. Create a Python (latest version) Lambda Function with sample code provided below
4. Make adjustments to the Lambda settings with the information below
5. Subscribe Lambda to SNS Notifications Topic
6. Add IAM permissions to Lambda with provided permission blocks below
7. Modify Topic Subscription to filter down to `clean` objects with provided filter block below
8. Test clean and "not clean" files to ensure behavior is as expected

\*LinkedAccountBuckets: Optionally you can make your two-bucket-system on linked accounts buckets as well, adding this pieces.\
\*\*Multi-partFiles Lambda: This lambda also involves step functions to handle multi-part files and large files

{% tabs %}
{% tab title="3. Sample Copy Lambda" %}
**Sample Copy Lambda**

The code below is a starting point and does work out of the box, but more can be done with it and to it. Feel free to do so.

```python
import json
import boto3
import os
from botocore.exceptions import ClientError, ParamValidationError
import random
from urllib import parse

def lambda_handler(event, context):

    try:
        print(json.dumps(event))

        SOURCE_BUCKET = os.getenv("SOURCE_BUCKET", 'any')
        DESTINATION_BUCKET = os.getenv("DESTINATION_BUCKET", '<some failover bucket>')
        DELETE_STAGING = os.getenv("DELETE_STAGING", 'no')

        #print("Source bucket is:" + SOURCE_BUCKET)
        #print("Destination bucket is:" + DESTINATION_BUCKET)

        record = event['Records'][0]
        messageBucket = record['Sns']['MessageAttributes']['bucket']

        print("The messageBucket value is:")
        print(messageBucket['Value'])

        if (messageBucket['Value'] == SOURCE_BUCKET or SOURCE_BUCKET == 'any'):

            message = json.loads(record['Sns']['Message'])

            #print("The message content is:" + str(message))
            #print("The message key is: " + message['key'])

            s3 = boto3.resource('s3')

            copy_source = {
                'Bucket': messageBucket['Value'],
                'Key': message['key']
                }

            if 'PartsCount' in s3.meta.client.head_object(Bucket=messageBucket['Value'], Key=message['key'], PartNumber=1):
                # get the tags, then copy with tags specified
                #print("doing a multipart copy with tags")
                try:

                    tagging = s3.meta.client.get_object_tagging(Bucket=messageBucket['Value'], Key=message['key'])
                    #print("get object tagging = " + str(tagging))

                    s3.meta.client.copy(copy_source, DESTINATION_BUCKET, message['key'], ExtraArgs={'Tagging': parse.urlencode({tag['Key']: tag['Value'] for tag in tagging['TagSet']})})

                except Exception as e:
                    print(e)
                    raise(e)
            else:
                # copy as normal
                #print("doing a normal copy")
                try: 
                    s3.meta.client.copy_object(CopySource=copy_source, Bucket=DESTINATION_BUCKET, Key=message['key'])

                except Exception as e:
                    print(e)
                    raise(e)



            print("Copied:  " + message['key'] + "  to production bucket:  " + DESTINATION_BUCKET)

            #print("Delete files: " + DELETE_STAGING)

            if (DELETE_STAGING == 'yes'):
                try:

                    s3.meta.client.delete_object(Bucket=SOURCE_BUCKET, Key=message['key'])
                    print("Deleted:  " + message['key'] + "  from source bucket:  " + SOURCE_BUCKET)

                except Exception as e:
                    print(e)
                    raise(e)

            return {
            'statusCode': 200,
            'body': json.dumps('Non-infected object moved to production bucket')
            }   


        return {
                'statusCode': 200,
                'body': json.dumps('Not from the Staging bucket')
            }

    except ClientError as e:
        return {
            'statusCode': 400,
            'body': "Unexpected error: %s" % e}
    except ParamValidationError as e:
        return {
            'statusCode': 400,
            'body': "Parameter validation error: %s" % e}
```

{% endtab %}

{% tab title="4. Make Adjustments to Lambda Settings" %}
**Make Adjustments to Lambda Settings**

There are some adjustments to the Lambda you'll probably need to make:

* Set the environment variables for the Staging Bucket and Production Bucket names as seen here:

| Field               | Description                                                                                                                                                                                                                                                                                               |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DELETE\_STAGING     | `yes` or `no` value based on whether you want the original file to be deleted after the copy has occurred                                                                                                                                                                                                 |
| DESTINATION\_BUCKET | Clean or Production bucket name identifying where to copy clean files to                                                                                                                                                                                                                                  |
| SOURCE\_BUCKET      | <p>Dirty or Staging bucket name identifying the originating bucket<br><br><em><strong>Note: you can leverage SNS Topic Filtering to eliminate the need for this value and the</strong><strong> </strong><strong><code>if</code></strong><strong> </strong><strong>check inside the code</strong></em></p> |

* Change the Time Out under General Configuration to a value that will work for the typical file sizes you deal with. The larger the file size, the longer you may want to make it so the lambda doesn't time out before the copy finishes.
  {% endtab %}

{% tab title="6. Permissions to add to Lambda Role" %}
**Permissions to add to Lambda Role**

Add an Inline Policy to the Lambda Role that was created when you created the Lambda. Paste the below into the JSON screen and change the sections that have `<>` to match your staging bucket name and production destination buckets

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObjectTagging",
                "s3:GetObject",
                "s3:GetObjectTagging",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::<staging bucket name>",
                "arn:aws:s3:::<staging bucket name>/*"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:PutObjectTagging"
            ],
            "Resource": [
                "arn:aws:s3:::<production destination bucket name>/*",
                "arn:aws:s3:::<production destination bucket name>"
            ]
        }
    ]
}
```

{% endtab %}

{% tab title="7. Subscription Filter for Clean Results" %}
**Subscription Filter for Clean Results**

Go to the SNS Topic itself and find the subscription created for the Lambda. Edit the filter settings by pasting the below value in. You can modify the filter further to include more scan results and even filter down by bucket. Bucket filtering is a good idea if you have event based scanning setup for any other bucket and you do not want the lambda to copy those clean files over as well.

```json
{
    "notificationType": [
        "scanResult"
    ],
    "scanResult": [
        "Clean"
    ]
}
```

Alternatively, with bucket filtering:

```json
{
    "notificationType": [
        "scanResult"
    ],
    "scanResult": [
        "Clean"
    ],
    "bucket": [
        "<staging bucket name>"
    ]
}
```

{% endtab %}

{% tab title="\* Linked Account buckets" %}
**Permissions on linked account buckets:**

* **Staging bucket policy:**

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "<lambda-role-arn>"
            },
            "Action": [
                "s3:DeleteObjectTagging",
                "s3:GetObject",
                "s3:GetObjectTagging",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::<staging-bucket>",
                "arn:aws:s3:::<staging-bucket>/*"
            ]
        }
    ]
}
```

* **Production bucket policy:**

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "<lambda-role-arn>"
            },
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:PutObjectTagging"
            ],
            "Resource": [
                "arn:aws:s3:::<production-bucket>/*",
                "arn:aws:s3:::<production-bucket>"
            ]
        }
    ]
}
```

{% endtab %}

{% tab title="\*\*Multi-part files Lambda" %}
**Full Lambda for multi-part files handling**

```python
import json
import boto3
from botocore.exceptions import ClientError, ParamValidationError
from urllib import parse
import time
import math

def lambda_handler(event, context):

    try:
        print(json.dumps(event))

        record = event['Records'][0]
        message = json.loads(record['Sns']['Message'])

        # Modify destination Bucket as appropriate
        sourceBucket = str(message['bucketName'])
        destinationBucket = sourceBucket

        # Modify destination key as appropriate
        sourceKey = str(message['key'])
        destinationKey = sourceKey.replace("incoming", "landing", 1)

        # Set to appropriate step function state machine ARN
        stateMachineArn = 'arn:aws:states:<region>:<account_id>:stateMachine:<stateMachineName>'

        print("The source bucket is:  " + sourceBucket)
        print("The destination bucket is:  " + destinationBucket)
        print("The source key is:  " + sourceKey)
        print("The destination key: " + destinationKey)
        print("The State Machine ARN: " + stateMachineArn)

        s3 = boto3.resource('s3')

        copy_source = {
            'Bucket': sourceBucket,
            'Key': sourceKey
        }

        meta_data = s3.meta.client.head_object(
            Bucket=sourceBucket, Key=sourceKey)
        parts_meta = s3.meta.client.head_object(
            Bucket=sourceBucket, Key=sourceKey, PartNumber=1)

        partsCount = parts_meta["PartsCount"] if 'PartsCount' in parts_meta else 0

        if partsCount > 0:
            totalContentLength = meta_data["ContentLength"]
            partSize = math.floor(totalContentLength / partsCount)

            print(f'FileSize: {totalContentLength} -- PartSize: {partSize} -- PartsCount: {partsCount}')

            tagging = s3.meta.client.get_object_tagging(
                Bucket=sourceBucket, Key=sourceKey)
            tagging_encoded = parse.urlencode(
                {tag['Key']: tag['Value'] for tag in tagging['TagSet']})

            if totalContentLength >= 25_000_000_000:
                source_bucket_and_key = f'{sourceBucket}/{sourceKey}'

                try:
                    # 25GB or larger file, use step function to copy due to lambda run time limit
                    print("Using step function to copy extra large file")

                    # Initiate multi-part upload
                    kwargs = dict(
                        Bucket=destinationBucket,
                        Key=destinationKey,
                        Tagging=tagging_encoded,
                        Metadata=meta_data['Metadata'],
                        StorageClass=meta_data['StorageClass'] if 'StorageClass' in meta_data else None,
                        ServerSideEncryption=meta_data['ServerSideEncryption'] if 'ServerSideEncryption' in meta_data else None,
                        SSEKMSKeyId=meta_data['SSEKMSKeyId'] if 'SSEKMSKeyId' in meta_data else None,
                        BucketKeyEnabled=meta_data['BucketKeyEnabled'] if 'BucketKeyEnabled' in meta_data else None,
                        ObjectLockMode=meta_data['ObjectLockMode'] if 'ObjectLockLegalHoldStatus' in meta_data and 'ObjectLockRetainUntilDate' in meta_data else None,
                        ObjectLockRetainUntilDate=meta_data['ObjectLockRetainUntilDate'] if 'ObjectLockLegalHoldStatus' in meta_data and 'ObjectLockRetainUntilDate' in meta_data else None,
                        ObjectLockLegalHoldStatus=meta_data[
                            'ObjectLockLegalHoldStatus'] if 'ObjectLockLegalHoldStatus' in meta_data else None
                    )

                    multipart_upload_response = s3.meta.client.create_multipart_upload(
                        **{k: v for k, v in kwargs.items() if v is not None}
                    )

                    uploadId = multipart_upload_response['UploadId']

                    # kick off step function executions
                    sfn_client = boto3.client('stepfunctions')

                    parts = []
                    baseInput = {
                        'Bucket': destinationBucket,
                        'Key': destinationKey,
                        'CopySource': source_bucket_and_key,
                        'SourceBucket': sourceBucket,
                        'SourceKey': sourceKey,
                        'UploadId': uploadId,
                        'PartsCount': partsCount,
                        'CompleteUpload': False
                    }

                    for partNumber in range(1, partsCount + 1):
                        byteRangeStart = (partNumber - 1) * partSize
                        byteRangeEnd = byteRangeStart + partSize - 1

                        if byteRangeEnd > totalContentLength or partNumber == partsCount:
                            byteRangeEnd = totalContentLength - 1

                        parts.append({
                            'PartNumber': partNumber,
                            'CopySourceRange': f'bytes={byteRangeStart}-{byteRangeEnd}'
                        })

                        if len(parts) == 250 and partNumber != partsCount:
                            executionInput = dict(baseInput)
                            executionInput['Parts'] = parts

                            sfn_client.start_execution(
                                stateMachineArn=stateMachineArn,
                                name=f'copy_parts_{time.time() * 1000}',
                                input=json.dumps(executionInput)
                            )

                            parts.clear()

                    executionInput = dict(baseInput)
                    executionInput['Parts'] = parts
                    executionInput['CompleteUpload'] = True

                    sfn_client.start_execution(
                        stateMachineArn=stateMachineArn,
                        name=f'copy_parts_{time.time() * 1000}',
                        input=json.dumps(executionInput)
                    )

                    print("Step function execution started.")

                    return {
                        'statusCode': 200,
                        'body': json.dumps('Non-infected object moved to production bucket')
                    }
                except Exception as e:
                    print(
                        f'Failed to execute step function to copy {source_bucket_and_key}')
                    print(e)
                    raise (e)
            else:
                # get the tags, then copy with tags specified
                print("Performing a multipart copy with tags")
                try:
                    s3.meta.client.copy(copy_source, destinationBucket, destinationKey, ExtraArgs={
                                        'Tagging': tagging_encoded})

                except Exception as e:
                    print(e)
                    raise (e)
        else:
            # copy as normal
            print("Performing a normal copy")
            try:
                s3.meta.client.copy_object(
                    CopySource=copy_source, Bucket=destinationBucket, Key=destinationKey)

            except Exception as e:
                print(e)
                raise (e)

        print(
            f'Copied: {source_bucket_and_key} to destination: {destinationBucket}/{destinationKey}')

        try:
            s3.meta.client.delete_object(Bucket=sourceBucket, Key=sourceKey)
            print(f'Deleted: {source_bucket_and_key}')

        except Exception as e:
            print(e)
            raise (e)

        return {
            'statusCode': 200,
            'body': json.dumps('Non-infected object moved to production bucket')
        }

    except ClientError as e:
        return {
            'statusCode': 400,
            'body': "Unexpected error: %s" % e}
    except ParamValidationError as e:
        return {
            'statusCode': 400,
            'body': "Parameter validation error: %s" % e}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Custom/own Quarantine Bucket**

If you decide to use your own quarantine bucket, you can use these same steps for a 2-bucket-system. You only need to go to **Configuration > Scan Settings** and change the action for infected files to **Keep** and change the "Clean" subscription on **step 7** for "Infected"
{% endhint %}

If you need any help getting this setup, please [Contact Us](/contact-us) as we are happy to help.

How the 2 Bucket System Flows:

<figure><img src="/files/TQkjhKVbl8z405NlIrZk" alt=""><figcaption></figcaption></figure>

## What ports do I need open for the product to function properly?

Port 443 for:

* Outbound for Lambda calls
* Outbound Console and Agent access to Elastic Container Repository (ECR)
* Inbound access to Console for public access
  * Public access is not required as long as you have access via private IP

Port 80 for:

* ClamAV signature updates

{% hint style="info" %}
You can now setup [local signature updates](/console-overview/configuration/scan-settings#private-mirror-local-signature-updates) rather than reach out over the internet. This will allow you to setup an Amazon S3 bucket for the solution to look at.
{% endhint %}

You can get a more detailed view and additional options for routing on the [Deployment Details page](/how-it-works/deployment-details). In either the standard deployment or the VPC Endpoints deployment, with local signature updates you can remove all non-AWS calls from the application run space. With VPC Endpoint you can remove almost all public calls as well.

## Can I change the CIDR range, VPC or Subnets post deployment for the console and agents?

Yes. The [Console Settings](/console-overview/configuration/console-settings) page gives you the option to modify the inbound Security Group rules, the VPC and Subnets and the specs of the task (vCPU and Memory). The [Agent Settings](/console-overview/configuration/agent-settings) page allows you to change the VPC and Subnets the agents run in, the specs of the task (vCPU and Memory) as well as all the scaling configuration aspects.

## Do you use AWS Lambdas or EC2 Instances?

**Neither**. Antivirus for Amazon S3 infrastructure is built around AWS Fargate containers. We wanted to be serverless like Lambda and faster and more flexible than EC2s. Fargate containers give you persistence and other benefits that Lambdas aren't prepared to give you yet. We explored Lambda and do see some advantages there, but not enough to win out over AWS Fargate containers.

We do leverage two lambdas for the [subdomain registration](/console-overview/configuration/console-settings#subdomain-management), but not for any of the workload at this time. If you are interested in a lambda-driven solution, please [Contact Us](/contact-us) to let us know. We are always exploring the best way to build and run our solution.

## Do you support AWS Control Tower or Landing Zone?

A landing zone is a well-architected, multi-account AWS environment that's based on security and compliance best practices. AWS Control Tower automates the setup of a new landing zone using best-practices blueprints for identity, federated access, and account structure.

Antivirus for Amazon S3 is now tightly integrated with [AWS Control Tower](https://aws.amazon.com/controltower/), and is designed to work within the landing zone context. Antivirus for Amazon S3 can be centrally deployed in a `Security Services` account while leveraging [Linked Accounts](/console-overview/access-management/linked-accounts) to scan all other accounts. You can learn more about [AWS Control Tower](https://aws.amazon.com/about-aws/whats-new/2022/11/aws-control-tower-account-customization/) here.

## Can I leverage Single Sign On (SSO) with your product?

Yes you can leverage SSO with our solution. Antivirus for Amazon S3 utilizes Amazon Cognito for user management. Amazon Cognito allows SAML integrations. Leveraging this capability we can utilize various providers as part of SSO into our solution, both from the SSO Dashboard as well as from within the application itself.

We've documented SSO integration for Entra ID and Okta below:

* For [Okta](/how-it-works/sso-integrations/okta-sso-integration)
* For [Entra ID](broken://spaces/r8b7RIievC7L6WwV0lDh)

#### Examples below:

<figure><img src="/files/QgbA5tAeOBGlw5R0QCyc" alt=""><figcaption><p>Sign In lookslike</p></figcaption></figure>

#### Okta

<figure><img src="/files/5KRhDzD5y4yIPx5yYuQA" alt=""><figcaption><p>Okta UI</p></figcaption></figure>

#### Entra ID

<figure><img src="/files/iFHKuem3bZq0ztEPZLSH" alt=""><figcaption><p>portal.azure.com > Enterprise Applications</p></figcaption></figure>

Upon customer request, we have documented the steps to get GSuite working as your SSO provider. Please leverage the document below. We have had other customers leverage these steps (along with the Okta and Entra ID write up) to setup other providers as well such as Keycloak.\
[GSuite Setup Instructions](https://css-public-docs.s3.amazonaws.com/SSO-GSuite_GoogleWorkspace_v1.pdf)

### Additional Actions Required

Okta identities will be auto-created within Amazon Cognito (and therefore Antivirus for Amazon S3) as simple `Users` and not `Admins`. They are also not assigned to a particular Group. This state enables them to login, but manage nothing. One-time only you will need to assign the user to a group and the admin role. After this initial assignment, each subsequent login will allow for proper management.

SSO users will also standout as their username will be created from the SSO sign in process.

<figure><img src="/files/CYnfRu8cBK6JXO2IqnYE" alt=""><figcaption></figcaption></figure>

## How can we scan your console/agent images for vulnerabilities?

You can access our images by either [downloading them locally to your ECR](/getting-started/how-to-deploy/advanced-deployment-considerations#how-to-setup-local-ecr-mirroring-for-css-console-and-agent-repositories) or using the Container images commands on the `Launch this software` page on our AWS Marketplace listing.

{% hint style="info" %}
You'll need to install and use the AWS CLI to authenticate to Amazon Elastic Container Registry and download the container images using the commands.
{% endhint %}

Below is a sample of the commands to pull our images from ECR for v7.01.001. However, you'll need to navigate to the `Launch this software` page on our AWS Marketplace listing to get the commands for our latest release.

```
aws ecr get-login-password \
    --region us-east-1 | docker login \
    --username AWS \
    --password-stdin 564477214187.dkr.ecr.us-east-1.amazonaws.com
    
CONTAINER_IMAGES="564477214187.dkr.ecr.us-east-1.amazonaws.com/cloud-storage-security/console:v7.01.001,564477214187.dkr.ecr.us-east-1.amazonaws.com/cloud-storage-security/agent:v7.01.001"    

for i in $(echo $CONTAINER_IMAGES | sed "s/,/ /g"); do docker pull $i; done
```

<figure><img src="/files/l1BGJCvqyqs6c3qxC736" alt="" width="375"><figcaption></figcaption></figure>

## How do I completely tear down CSS Infrastructure?

If using CloudFormation, the action of just deleting the stack may miss additional infrastructure created throughout the course of using our product. We recommend that you go to Monitoring > Deployment and Delete Application so we can clean up infrastructure for you before you delete the stack.

More details are located at [this page](https://help.cloudstoragesec.com/console-overview/monitoring/deployment-overview#delete-application).


# Supported File Types

Below you can find the file types supported by each scanning engine that powers Antivirus for Amazon S3.

## Antivirus for Amazon S3

Even if a file type is not on this list we will still attempt to scan the file byte for byte.

<details>

<summary>Sophos</summary>

```
Adobe Portable Document Format (PDF)  
Graphic interchange format  
JPEG Interchange Format  
PNG (Portable Network Graphics) image format  
SafeGuard encrypted file (self-extracting)  
Windows executable  
Windows Prefetch file  
Windows Auxiliary File (.AUX)  
WinSxS FileMaps (.CDF-MS)  
Microsoft Content Index Format  
Windows Cursor  
Microsoft SKLM Resource File (.DAT)  
Windows Event Log (EVTX)  
Generic Printer Description (.GPD)  
Icon for 32-bit Windows  
Windows WBEM MAP File (.MAP)  
National Language Support File (.NLS)  
Precompiled INF File (.PNF)  
Windows NT Registry File (REGF)  
Software Quality Management File (SQM)  
Windows Thumbnail Cache (.DB)  
Windows regedit file (.reg)  
WILO file  
UTF-16/UCS-2 16-bit Unicode Transformation Format  
Device-independent bitmap (DIB) file  
Markup Language  
Hypertext Markup Language  
DAISY ebook ANSI/NISO Z39.86  
FictionBook (Fb2)  
Open Electronic Package  
Text Encoding Initiative (TEI)  
Microsoft Office XML Containing Macros  
Microsoft Office XML Containing Embedded Objects  
Encoded Visual Basic Script  
Extensible Markup Language (XML)  
JavaServer Page  
Advanced Systems Format (ASF)  
Windows Animated Cursor  
Microsoft Audio Video Interleave (AVI) file  
Corel DRAW graphics file  
Waveform Audio Format (WAV)  
Resource Interchange File Format (RIFF)  
MPEG Video stream  
Internet Relay Chat (IRC) script  
Configuration Data File (generic)  
Data Log File (generic)  
Internet Shortcut (.URL)  
Windows HOSTS file  
Cascading Style Sheet  
Macromedia Shockwave Flash (SWF) file  
Adobe Portable Document Format (PDF)  
Macromedia Flash Video (FLV)  
Microsoft Word Containing Macros  
Microsoft Excel Containing Macros  
Android application package (APK) file  
JAR archive file  
Microsoft Office 2007 Encrypted Package (password protected)  
RealVideo / RealAudio  
Autodesk Inventor  
MicroStation V8 DGN File  
SolidWorks design file (2D and 3D models)  
Microsoft Word 95 to 2003 (password protected)  
Microsoft Excel 95 to 2003 (password protected)  
Microsoft PowerPoint 95 to 2003 (password protected)  
Microsoft Word 95 to 2003  
Microsoft Excel 95 to 2003  
Microsoft Outlook 97 to 2003  
Microsoft Windows Installer Package  
Microsoft PowerPoint 95 to 2003  
Microsoft Office Visio  
Microsoft Office Project  
Microsoft OLE2 file format  
Executable and Linkable Format (ELF)  
JPEG image file with Exif metadata  
Lossless JPEG (JPEG-LS)  
MPEG-1 System stream  
MPEG-2 System stream  
Office Suite - Open Office StarView metafile (SVM)  
Microsoft Excel 2007 onwards [encrypted]  
Microsoft PowerPoint 2007 onwards [encrypted]  
Microsoft Word 2007 onwards [encrypted]  
Microsoft Excel 2007 onwards  
Microsoft PowerPoint 2007 onwards  
Microsoft Word 2007 onwards  
Microsoft XML Paper Specification (XPS)  
Office Suite - Open Office Base (password protected)  
Office Suite - Open Office Calc (password protected)  
Office Suite - Open Office Draw (password protected)  
Office Suite - Open Office Impress (password protected)  
Office Suite - Open Office Math (password protected)  
Office Suite - Open Office Writer (password protected)  
Office Suite - Open Office Base  
Office Suite - Open Office Calc  
Office Suite - Open Office Draw  
Office Suite - Open Office Impress  
Office Suite - Open Office Math  
Office Suite - Open Office Writer  
Microsoft CAB archive  
InstallShield CAB archive  
RAR compressed archive (password protected)  
Open Packaging Convention file format (OPC) [encrypted]  
EPUB eBook  
Open Packaging Convention file format (OPC)  
RAR compressed archive  
Open Document Format for Office Applications [encrypted]  
Open Document Format for Office Applications  
PK ZIP archive [encrypted]  
PK ZIP archive  
Java class file  
GZIP compressed file  
Apple QuickTime (.MOV/QT)  
QuickTime video  
Symbian SIS file  
XZ compressed file  
Encoded certificate  
Certificate  
Microsoft Compiled HTML Help  
Exchangeable image file format  
Apple Mac executable  
Musical Instrument Digital Interface file  
Still Picture Interchange File Format (SPIFF)  
SafeGuard encrypted file  
SafeGuard PrivateDisk Container  
MPEG Audio Stream  
Basic audio/sound file format  
BinHex compressed archive (.HQX)  
MS-DOS executable  
3GP Video for mobile phones  
Apple iTunes AAC-LC Audio  
Sony / Mobile QuickTime (.MQV)  
Rich Text Format (RTF)  
TAR archive  
Tagged Image File Format  
UU-encoded  
ZOO Archive  
ACE archive [encrypted]  
Extensible Storage Engine (ESE) File  
ACE archive  
Application Compatibility Database  
AC-3 Digital Audio aka ATSC A/52  
Microsoft Access 2007  
Monkey's Audio format  
AppleDouble encoded  
AppleSingle encoded  
Windows Event Viewer Log  
HA compressed archive  
Windows Help File  
Interchange File Format (IFF)  
.JOB File Format  
Windows Shortcut file (.LNK)  
LZH compressed archive  
Microsoft Jet database V4  
Apple iTunes Video (.M4V) Video  
Microsoft MSFT Storage  
MacBinary archive format  
Program Information File (PIF)  
StuffIt compressed archive  
Microsoft Jet database V3  
Aldus Placeable Metafile  
Free Lossless Audio Codec (FLAC)  
Microsoft web archive - Multipurpose Internet Mail Extension HTML (MHTML) format  
OGG multimedia container format  
PCX lossless image format  
PostScript  
Windows Enhanced Metafile  
DCX image file format  
Portable Bitmap image format  
Portable Pixelmap format  
Adobe Photoshop File Format  
yEnc encoding  
ARC, PAK Format  
ARJ/ARJ32 archiver  
Base64 encoded  
UNIX compressed archive  
Microsoft Agent Character file  
Windows Media metafile playlist  
Windows color matching control  
Advanced Video Coding  
Casio Digital Camera  
MP4 Base Media v1 / v2  
JPEG 2000 image  
Apple iTunes AAC-LC (.M4B) Audio Book  
Motion JPEG 2000  
Photo Player Multimedia Application Format (MAF)  
MPEG-4 (.MP4) for SonyPSP  
MPEG-4 for Nero  
OMA DCF (DRM Content Format)  
SD Memory Card Video  
Transport Neutral Encapsulation Format  
MPEG-4 audio-visual media  
Oracle IRM sealed file  
ID3 audio file data tagging format  
Multipurpose Internet Mail Extensions (MIME) email message  
7z archive format  
Arc File Format  
BlackHole Archive Format File  
Chrome Extension CRX Package Format  
Adobe InDesign  
QuarkXpress project  
Lotus 1-2-3 spreadsheet  
MIME internet media  
email message (RFC822)  
Autodesk Design Web Format (DWF)  
Autodesk study file  
Microsoft Outlook Express mailbox file  
AutoCAD Drawing Database (DWG file)  
Adobe Framemaker  
Kremlin encrypted file  
Microsoft Outlook personal folder file  
Corel Wordperfect Document  
xBase Database File (DBF) [encrypted]  
xBase Database File (DBF)  
AutoCAD Slide  
AutoCAD Drawing Interchange Format (DXF)  
GDS II stream format  
Lotus Notes database file  
ArchiCAD File  
Computational Fluid Dynamics DTF File  
Intergraph V7 DGN File  
Microsoft Excel 95 to 2003 (password protected)  
Microsoft Excel 95 to 2003  
Initial Graphics Exchange Specification (IGES)  
Pro/ENGINEER  
Adobe Reader ebook  
Broadband eBook (BBeB)  
DNL e-Book Format  
DjVu Document  
IMP ebook Format  
Microsoft ITOL/ITLS format  
MOBI ebook  
Palm Document File  
Plucker ebook  
Rocket eBook  
TEBR eBook  
TealDoc  
TomeRaider ebook  
eReader ebook  
APP data file  
CAL data file  
CHS data file  
FON data file  
OGL data file  
PFA data file  
Palm Database File  
01 data file  
VER data file  
CD-ROM disk image file  
F1-P1-T1-S1 data file  
Digital Imaging and Communications in Medicine (DICOM)  
WINDEV Hyper Database File (.FIC)  
GIP file  
CISO compressed ISO CD image  
CloneCD image control file  
PowerISO Direct-Access-Archive CD image file  
DAX compressed ISO CD image  
Apple HFS filesystem  
isoBuster IBP image file  
JSO compressed ISO CD image  
Alcohol CD-ROM image configuration file  
Apple disk image file  
Windows disk image  
WINDEV File  
Wise installer script  
bzip compressed archive  
PGP encrypted file (binary)  
xar compressed archive  
OpenPGP/GPG encrypted file  
AutoCAD file  
Interbase Database Backup file  
Interbase Database file  
BitTorrent torrent file  
Microsoft Word for Windows 1989-1995  
ACID encryption  
AxCrypt Encrypted File  
CryptoGram File encryption  
Compressed Microsoft Office File (.MSO)  
Apple Newton Package File  
Sysinternals Performance Monitor Log File  
ProjectLibre POD Project File  
Microsoft .QUERY File  
SecurityBox encrypted file  
Microsoft SQL Server Database File  
SQLite Database File  
Mac .DS_Store (Desktop Services Store) File  
Libpcap Packet capture (PCAP) file  
CATIA (Computer Aided Three dimensional Interactive Application) document  
Siemens JT Data Format  
Standard for the Exchange of Product model data (STEP)  
Stereo Lithography File (STL)  
Comma-separated values  
Data Log File (generic)  
Active server page  
JavaScript  
PHP Script  
Visual Basic Script  
Kernel Registry Services (KRS) system file for HP servers  
HP log file  
Matlab Script  
Obfuscated script (VBS/JavaScript)  
PGP encrypted message (ASCII-Armored)  
Language File (.LNG)  
UTF-32/UCS-4 32-bit Unicode Transformation Format  
UTF-16/UCS-2 16-bit Unicode Transformation Format  
Split File Shell Extension - split file archive  
OpenType Font File  
ASCII text / 8-bit Unicode Transformation Format  
Windows Codepage 1252  
Nero CD image file  
ISO 9660 CD-ROM image file  
Unspecified Markup Language  
TGA File Format  
```

</details>

<details>

<summary>ClamAV</summary>

Please refer to [this link](https://docs.clamav.net/appendix/FileTypes.html) for the latest list.

</details>

<details>

<summary>CSS Premium</summary>

This engine has standard unpacking methods for the most popular file types, but will scan files byte-for-byte if the file is not "natively supported".

</details>

## Data Classification for Amazon S3

Our data classification functionality supports scanning and classification of most text-based files. This includes the following:

* TXT
* DOC/DOCX
* PDF
* HTML
* CSV
* XLS/XLSX
* XML
* RTF
* ODT
* PPT/PPTX

Even if a file type is not on this list you can still upload it and attempt to classify it to see if it's supported.


# Troubleshooting

In this section are common troubleshooting steps you can take to investigate and resolve common issues.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Stack Creation Failures</td><td></td><td></td><td><a href="/pages/ZB9kqVNGqIvWSyAeffqC">/pages/ZB9kqVNGqIvWSyAeffqC</a></td></tr><tr><td>Conflicted Buckets</td><td></td><td></td><td><a href="/pages/bxBPBDMeFCh0vzPpIq9E">/pages/bxBPBDMeFCh0vzPpIq9E</a></td></tr><tr><td>Modifying scaling info post-deployment</td><td></td><td></td><td><a href="/pages/ZPgB5lC9qYYp9QFRdqYS">/pages/ZPgB5lC9qYYp9QFRdqYS</a></td></tr><tr><td>Objects show unscannable with access denied</td><td></td><td></td><td><a href="/pages/FLopt62MiBaTxGhYguv6">/pages/FLopt62MiBaTxGhYguv6</a></td></tr><tr><td>Remote account objects not scanning</td><td></td><td></td><td><a href="/pages/1ojteaSUmNC0xzioQWUY">/pages/1ojteaSUmNC0xzioQWUY</a></td></tr><tr><td>My scanning agents keep starting up and immediately shutting down</td><td></td><td></td><td><a href="/pages/pkjpkUha5E9G9HgSCAIF">/pages/pkjpkUha5E9G9HgSCAIF</a></td></tr><tr><td>I cannot access the management console</td><td></td><td></td><td><a href="/pages/5s7J3ZdN2Kh9TpEsdR03">/pages/5s7J3ZdN2Kh9TpEsdR03</a></td></tr><tr><td>Linked Account Out of Date</td><td></td><td></td><td><a href="/pages/DQ9i4Cg7GmumqS42iFge">/pages/DQ9i4Cg7GmumqS42iFge</a></td></tr><tr><td>Rebooting the Management Console</td><td></td><td></td><td><a href="/pages/GxaU36JRPMAaea9gbfUm">/pages/GxaU36JRPMAaea9gbfUm</a></td></tr><tr><td>Error when upgrading to the latest major version</td><td></td><td></td><td><a href="/pages/SQbRyJiY2IYKcZjkiWTO">/pages/SQbRyJiY2IYKcZjkiWTO</a></td></tr><tr><td>API Scanning: Could not connect to SSL?TLS (v7)</td><td></td><td></td><td><a href="/pages/iaN3pqtlryKlRxtv0NYU">/pages/iaN3pqtlryKlRxtv0NYU</a></td></tr></tbody></table>

{% hint style="info" %}
If you can't find a troubleshooting resource for your issue or you have consulted the troubleshooting information and continue to have issues, please [contact](/contact-us) our support team so we can provide assistance.
{% endhint %}


# SSL Certificate Expiry

If you have any version less than **v9.08.002**, you will see this error:

<figure><img src="/files/zD6gyBIaUDAg3gr2DcaA" alt=""><figcaption></figcaption></figure>

If you are experiencing a SEC\_ERROR\_EXPIRED\_CERTIFICATE for either the Console or the API Agent and you are both running a version <**v9.08.002** AND using our domain name to deploy your Console and/or our API Agent, here's how to resolve this error.

### Fix 1: Upgrade

The key bundled with the application was renewed as of v9.08.002. Upgrade your deployment to this version or above to access the new key for our certificate and to avoid this error.

Most browsers allow you to bypass the SEC\_ERROR\_EXPIRED\_CERTIFICATE error. Bypass it and log in to the Console.

To upgrade, use CloudFormation and grab the latest template for your version in [Release Notes](/release-notes). **Keep in mind you must move to the latest minor version of your major version prior to moving to the next major version**. In this example, v7.11 is already the latest version of v7, so we can just go to v8.00.000 and then the latest v8 version. Then, you want to move to v9.08.002.

You can check the version you are on by clicking the cloud icon in the top right corner.

<figure><img src="/files/oNcCB0LQTgj4ebbtAIg4" alt=""><figcaption></figcaption></figure>

For more information on upgrading, please refer to the [Product Updates](/product-upgrades) page.

### Fix 2: Use Self-Managed SSL Certificates

We provide our own domain name to register Console and API Agent services, but you can use your own self-managed SSL Certificates to manage these services. This way, you won't encounter issues when our certificates expire. Keep in mind, you will have to manage your own certificate renewal.

**Setting Custom SSL Certs for the Console**

If you want to use your own certificate for the Console, we require a valid certificate imported into ACM. In the CloudFormation stack for our application, we provide an Optional Load Balancer Configuration page. Select 'Yes' for 'Use a Load Balancer for the Console?' and place in your SSL Certificate ARN in the designated location. After the Console deploys, set a CNAME record from your SSL Certificate to the Load Balancer's DNS name.

<figure><img src="/files/yxYjw8C374tEUfU41olC" alt=""><figcaption></figcaption></figure>

For further reading, please refer to the [Advanced Deployment Considerations - Optional Load Balancer Configuration](https://help.cloudstoragesec.com/getting-started/how-to-deploy/advanced-deployment-considerations#optional-load-balancer-configuration) page.

**Setting Custom SSL Certs for the API Agent**

The API Agent Configuration allows the setting of a custom SSL Cert for the Load Balancer that will be placed in front of the API Agent service.

Assuming your SSL Certificate is imported into ACM, place the SSL Certificate ARN into the designated location and deploy the API Agent. After the Agent deploys, set a CNAME record from your SSL Certificate to the Load Balancer's DNS name.

<figure><img src="/files/iydsLtjlfUW0TdDegUd9" alt=""><figcaption></figcaption></figure>

For further reading, please refer to the [API Agent Settings - Network Settings](https://help.cloudstoragesec.com/console-overview/configuration/api-agent-settings#network-settings) page.

### Fix 3: Bypass The Error

While not recommended, some of our customers have fully private deployments where they are not concerned about the existence of an SSL Certificate on their Console for access.

Note that some workflows may be interrupted for the API Agent if handling isn't built in to ignore the SSL Certificate error.

We generally recommend fixes 1 and 2, but just note that it's possible to bypass this error, normal Console functioning will not be affected.


# CloudFormation Stack failures

The two most common CloudFormation stack failures customers see are a result of either bad parameters specified within the CloudFormation template or deploying in a non-supported region.

## Bad Parameters

As the [How to Deploy](/getting-started/how-to-deploy) section describes, there are 5 parameters you need to make sure you get right.

* Virtual Private Cloud (VPC) ID
* Subnet A ID
* Subnet B ID
* Console Security Group CIDR Block
* Email

Ensure that the subnets you select for Subnet A and Subnet B are unique (to each other) and both are a part of the VPC you selected.

{% hint style="info" %}
Rules have been added to ensure you select these values correctly.
{% endhint %}

Ensure the CIDR range is a value that you can access. Specify a network range that represents the specific network you will be accessing from (i.e,. your work network) or open it up to everyone with a value of `0.0.0.0/0`.

{% hint style="danger" %}
Using `0.0.0.0/0` will make it accessible to the outside world. SSL based authentication is in place, but you still may want to consider whether "wide open" is the strategy you want to take.
{% endhint %}

## Non-supported Regions for Console Deployment

Antivirus for Amazon S3 uses many native AWS services. Not all AWS services are supported in all AWS regions. Cognito is a service leveraged for authentication and user management, but it is not supported in all regions. Markeplace is not supported in all regions either to use ECS fargate.

Below, you will find a list of supported regions. Please deploy the console to one of these regions.

<details>

<summary>Supported regions for Console deployment</summary>

| Region                        | PAYG Available | BYOL Available |
| ----------------------------- | :------------: | :------------: |
| us-east-1 (N. Virginia)       |       Yes      |       Yes      |
| us-east-2 (Ohio)              |       Yes      |       Yes      |
| us-west-1 (N. California)     |       Yes      |       Yes      |
| us-west-2 (Oregon)            |       Yes      |       Yes      |
| af-south-1 (Cape Town)        |       No       |       Yes      |
| ap-south-1 (Mumbai)           |       Yes      |       Yes      |
| ap-east-1 (Hong Kong)         |       Yes      |       Yes      |
| ap-northeast-1 (Tokyo)        |       Yes      |       Yes      |
| ap-northeast-2 (Seoul)        |       Yes      |       Yes      |
| ap-northeast-3 (Osaka)        |       No       |       Yes      |
| ap-southeast-1 (Singapore)    |       Yes      |       Yes      |
| ap-southeast-2 (Sydney)       |       Yes      |       Yes      |
| ap-southeast-3 (Jakarta)      |       No       |       Yes      |
| ap-southeast-4 (Melbourne)    |       No       |       Yes      |
| ap-southeast-5 (Malaysia)     |       No       |       Yes      |
| ca-central-1 (Canada Central) |       Yes      |       Yes      |
| eu-central-1 (Frankfurt)      |       Yes      |       Yes      |
| eu-south-1 (Milan)            |       No       |       Yes      |
| eu-west-1 (Ireland)           |       Yes      |       Yes      |
| eu-west-2 (London)            |       Yes      |       Yes      |
| eu-west-3 (Paris)             |       Yes      |       Yes      |
| eu-north-1 (Stockholm)        |       Yes      |       Yes      |
| me-central-1 (UAE)            |       No       |       Yes      |
| me-south-1 (Bahrain)          |       No       |       Yes      |
| sa-east-1 (São Paulo)         |       Yes      |       Yes      |
| il-central-1 (Tel Aviv)       |       No       |       Yes      |
| GovCloud (West) AWS regions   |       No       |       Yes      |

Missing regions in this list are due to Amazon Cognito not being supported in those regions.

</details>

{% hint style="info" %}
The scanning agent and console will run in any region that supports Amazon ECS Fargate.
{% endhint %}

If you are still having issues after ensuring these two criteria are met, please [Contact Us](/contact-us).

## v7 Upgrade Failure

We've noticed instances of upgrading from v6 to v7 through the console where the upgrade will fail. This is usually because the console doesn't have the proper permissions. The error should look similar to the below failure:

<figure><img src="/files/fVHGOXH0GlNjIELy09sf" alt=""><figcaption></figcaption></figure>

This will cause the outbound rules of your console/load balancer security group to be removed. You'll need to **add back outbound rules to the security group** and then run the upgrade manually through CloudFormation using the latest v7 CloudFormation template.

If you are upgrading from v6 to v7, make sure you are on the [latest version of v6 before going to v7](/trouble-shooting/error-when-upgrading-to-the-latest-major-version).

## UserPoolUserAdminGroupAttachment Failure

In some instances, we have seen CloudFormation lose the order of the events that need to execute in order to stand the console up successfully. One instance where this happens is with the UserPoolUserAdminGroupAttachment creation.

If you encounter an error similar to the one below you'll want to retry your deployment through a new Stack again.

<figure><img src="/files/UW2Q5KxgsK1CePK6tMKt" alt=""><figcaption></figcaption></figure>

### Update Rollback Failed

There are some cases where, after failing to update, for example, from versions lower than v6.06, the update fails because you are bypassing major versions and skipping some in-between required resources and permissions added on those major versions. What we have usually seen is:

* **Versions lower than 6.06:** Previous Security groups inbound/outbound rules deletion, check your security group for the ConsoleService: **ECS -> Css Cluster, ConsoleService, Configuration and networking, Security group:**
  * **Inbound rules** should be 443 and 80 for 0.0.0.0/0 if it's public and restricted for your VPN/Proxy/IP range if it's private.
  * **Outbound rules** should be all traffic for 0.0.0.0/0.\
    \
    Once this is checked, you can go back to CloudFormation > Stack Actions > Continue Update Rollback. Advanced troubleshooting:
    * If the rollback completes: Good, you can try updating the stack again with [v6.06.000 template](https://css-cft-versions.s3.amazonaws.com/ConsoleCloudFormationTemplate-v6.06.000.yaml).
    * If it fails, click on **View Root Cause.** If that shows you **UserPool failed**, click on **Continue update rollback** again in stack actions and check **only the UserPool checkbox.**

This should be the last step, and everything should go back to normal. You can then update to [v7.11](https://css-cft-versions.s3.amazonaws.com/ConsoleCloudFormationTemplate-v7.11.000.yaml) the same way and then go to the[ latest v8](https://help.cloudstoragesec.com/release-notes/latest) through the CloudStorageSecurity Console or through CloudFormation once again.


# Cross-Region Scanning on with private network

The goal is to avoid going to the internet and fetching everything from the AWS backbone.  This is the AWS recommended solution, keep in mind that it is complex to configure, maintain, and costly

## OVERVIEW

For configuring cross-region access for AWS services without leaving the AWS Backbone first of all we need to follow the steps of leveraging endpoints for the console region mentioned in [our documentation](https://help.cloudstoragesec.com/how-it-works/deployment-details#leveraging-vpc-endpoints). Then we need to execute the same script in the desired region to interact with, allow communication through VPC endpoints and setup DNS resolution so the public url service endpoints get resolved to local ips instead of the public ones.

* Console Region: us-west-2
* Agent Region: us-east-2

## PROCEDURE

AWS lines up what is needed in order to accomplish this task in the following two documents:

* <https://repost.aws/knowledge-center/vpc-endpoints-cross-region-aws-services>: despite it says one or the other both sections are needed.
* <https://repost.aws/knowledge-center/vpc-peering-troubleshoot-dns-resolution>

### <mark style="color:green;">VPC Endpoint Cross-region access</mark>

Above tutorials contain a lot of suppositions and don’t have the level of detail necessary to actually understand the needed changes. The following are some steps done in our development accounts in order to accomplish cross region:

1. Apply CSS[ the CSS provided scripts](https://help.cloudstoragesec.com/how-it-works/deployment-details#leveraging-vpc-endpoints) about leveraging VPC endpoints in the console’s and destination region.
2. Configure VPC Peering Connections between the console and destination region VPCs. Ensure DNS settings are enabled for both:

<figure><img src="https://lh7-us.googleusercontent.com/KXCPrGuhtkVH7NDxqxjo4RHZbq-DHlrIGlN8ZYUJ3jDhCAhyt9xOjFiyP7h5eNj9C9mhCxzSROD_569kwMkuERanM6cG31XTJXfBKOPtlqUgeH2t2eLsgvgm1aOjY2vVupjeQoDb1FA1kfwYTLwrXVs" alt=""><figcaption></figcaption></figure>

3. Configure route tables for both VPCs, in each of them add an entry containing the CIDR of the other region’s VPC and as destination the Peering connection:

<figure><img src="https://lh7-us.googleusercontent.com/dkA89KRVwwg-sFIP0RsD3Vw1cyzzbbAvyczM3jZ2DRUFzlFkZ4e7b-zlwH1R8HQdXqzOseDjacyIHDuWBhtu3m7jorCh5CzHMNGm95SnnJ8033QWajEOD2LGHjAwuauwzo8psZ8Cegswx2yw_s72770" alt=""><figcaption></figcaption></figure>

4. Validate no subnet contains access to a nat or internet gateway, meaning they can’t reach the internet. Create an Ubuntu instance that is in the Console’s region and subnet. Connect to it, probably using a bastion host (public instance within the same VPC but different subnet that can reach the private subnet).

<figure><img src="https://lh7-us.googleusercontent.com/o586dqc6SVq7UBgmeDhWsDYus-_wcszuU7Qt65ZwmeDdyKY7dX8PD7jLasrGYKSFiN3xGEgu-Jn1ephPVChSiETNMApdpSSguK-vBv0-OxpdRJootx1a1H07s_9D4zEdAk65CeAis2wJ1os2vl-D80g" alt=""><figcaption></figcaption></figure>

So right now you are in the console’s subnet, validate you are able to reach the EC2 service belonging to the other destination region (in this case us-east-2) by running the following command with valid AWS Credentials:

{% code overflow="wrap" %}

```
ubuntu@ip-10-0-143-117:~$ aws ec2 describe-volumes --max-items 1 --region us-east-2 --endpoint-url "http://172.31.47.168"
```

{% endcode %}

<figure><img src="https://lh7-us.googleusercontent.com/-nXW2ipHYkfkgbbzbDMH24T_lF4kMR-5-ZqHwuFVISdyAcC_nIYDZFS_IzhLmeD1c_qCKaNKLiYkLHgkW4GsATT7bj8Qxe8RyILKG2LrcR05hpkjM9STS5PKCGt_rwtX2TERxHW30gQtFiCemTtsq0U" alt=""><figcaption></figcaption></figure>

Keep in mind the usage of the destination region and the local private IP of the EC2 VPC Endpoint of the us-east-2 region. This is necessary since there is no DNS resolution configured for the endpoint “ec2.us-east-2.amazonaws.com”.

<figure><img src="https://lh7-us.googleusercontent.com/Kc0gKMOtuhBIe6ttansM0domEe_91iLPX0D5AxDVcQvqLFMQQIoOiZSNo1NyyoSDUelU8f_g6fHH3bC8i9kdtLBrDxc4roJJzXTa5vS65k-YZ698VCIRbjQKl9F-sxvI2X775eyfkCwPLVMIGYyKyI8" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Note also that without the endpoint specification the EC2 instance doesn’t know how to solve the service URL:
{% endhint %}

<figure><img src="https://lh7-us.googleusercontent.com/n6AzOhu59MZsx2SmpWSDnipX0gsvq06ufZoo8Ce06Uy2KyTZQgMczyQTGpqkLPVD64x45w7AnCRtUYhuq3-ppYgdy7iQ88a5EecIx-3MkeQn855UCg0_sc5RNE__Gmr6bT6tn6kfmun8cp9D2iJc3fs" alt=""><figcaption></figcaption></figure>

### <mark style="color:green;">Service Name DNS Resolution</mark>

At this point we are able to reach the VPC Endpoint located in the destination region but without being able to automatically solve the EC2 service. Let’s get into it.

1. Go to route 53 and add a new private hosted zone adding the console’s VPCs.

<figure><img src="https://lh7-us.googleusercontent.com/nl8G5lY4xIv8IdIlt-HGGTrxwtTDVb4kKBTFr4tEf7Ni3GAK6hOHe9_abxezjZ2pRBw2-zFR9RpPuDmpkfmvzQYpStM1TCTm_VHjM-qBMr66p5ipbPpJkC7zu5T1gjR3x756IJWuOvYgqZzeNWWoIVg" alt=""><figcaption></figcaption></figure>

2. Add an A record with Alias selected and the destination region VPC Endpoint as the target:

![](https://lh7-us.googleusercontent.com/DSJLnGxi6F-b0fsXuY6APTe5EPg4ho0LNAPrDBUeSxna-A-lAroWNdzTt4CYqCGq9XLkRmBK43A7vQ6_wZsQo6sj1sihszXjYCQKS5R1pptxTf7Dghq3_5Rhr82U5beLZqoL3YNp6aP7UtnoD-V0L5E)

3. Validate configuration by doing the Ec2 API call without endpoint specification:<br>

   <figure><img src="https://lh7-us.googleusercontent.com/u7U59ptt7FVciAizuBKJyVqihMLHrnIG_oF5-WWQLYGNzgVeHvL8g5Y82u_6phj-4_KXn61mKpGWYuQxno8LJ0g0hDS50Hd0hcjd9QFAUbHpvaOs2VnCCsfX5wmWHmBMSNNp3OFeoXpM9EejFJ6pCnk" alt=""><figcaption></figcaption></figure>

## Services Needed

Services that require this extra configuration since they are instantiated by the console in other regions:

* EC2: For Networking stuff
* ElasticFileSystem: To mount volumes
* CloudWatchLogs: To build statistic results, protecting a bucket (creates CloudStorageSecurity.ECS.{EnvironmentVariables.AppConfigAgentApplicationId}.{serviceDescription} and handles retention policy)
* CloudWatch (called monitoring): To create alarms.
* S3 (interface + gateway): To gather bucket properties. Remember to add a wildcard for the global bucket access:

```
{bucket-name}.s3.{region}.amazonaws.com
```

* SNS: To list topics
* ECS: For ECS related tasks, like creating a cluster or a service
* AppAutoScaling: for autoscaling policies triggered from CW Alarms

**VPC Endpoints in the Agent Region**

<figure><img src="https://lh7-us.googleusercontent.com/8pruHgykt64G9T38AhSZ0hfuLKs79mMLTd9U7SUBxGLlvT2HZZUOGqefVq_z1KGJTZh6_YBQZB4TOhKcymNvemjsBlvh4lA0hmCKY3UFl6Prr3RsKvYqtaBEuiIF_qAUnpG22SA6QzeTvoagwTnWWjg" alt=""><figcaption></figcaption></figure>

**VPC Endpoints in the Console Region**

<figure><img src="https://lh7-us.googleusercontent.com/ITo7ORnqtb78vWzMgEhoGgNpPLU4G3c1kDccEms1nDXeTkYUNEc6piLgOvtAen_vB1V-CNBzfSUtQVmBgoiUFcTKUpATuCqTQk7bt3seTzn7jI4Rq1bKnWu9NLTZqWvNK3hZYJT-GH99qJZhAcONY-c" alt=""><figcaption></figcaption></figure>

**Route53 custom endpoints configuration**

<figure><img src="https://lh7-us.googleusercontent.com/TSD6uvMvYHFMMcwF0zgA87d9xKjm189uP8BxbYI96-kpkwyGP3c4t2jFfohLR0f1uxHw8soCN8pYz5i0dnIJRDjxtdwK4BVGldgdQKuM8AR4YsctmxCrnZDANyCG0BErPellMCY1uzmCD9XnXsgHVgM" alt=""><figcaption></figcaption></figure>

## REMARKS

* The agent task running in the external region needs a proxy defined to reach DynamoDB or internet access to allow its resolution.
* SNS notifications for the Agent will fail since it doesn’t know how to resolve the Console’s region SNS URL endpoint. A route53 entry resolution is needed for the console region associated with the agent region VPC and pointing to resolution for the VPC SNS Endpoint of the console. Also remember to add a rule to the Security Grouping allowing the VPC CIDR of the agent.

## CONCLUSIONS

Using a private subnet allowing only a few services (Marketplace, AppConfig and Cognito) to go through the public internet (maybe behind a proxy) and then all the other services being accessed through VPC Endpoints is definitely doable, even for all the regions.

Pros:

* Great reduction in the amount of traffic over the public internet.

Cons:

* Increased infrastructure costs.
* Increased infrastructure complexity, harder to configure and to maintain.
* New AWS services usage from our part can break console functionality.
* Costs: only the VPC piece cost around $10 daily for the Console region and $7 daily for each extra region.


# API Scanning: Could not connect to SSL/TLS (v7)

As of v7 of our solution, we have implemented TLS 1.3, so if your application is still using TLS 1.2, you will receive an error response.

To solve this, you can still be in the latest version on our product and keep your API Scanning working by changing the TLS version of the API's load balancer:

In AWS, in the API Agent's region, go to **EC2 > LoadBalancers > CloudStorageSecApiLB-{appId} > Listeners and Rules > Https: 443 Listener**

<figure><img src="/files/IDqU0qOBZqT9C3RAUAw6" alt=""><figcaption><p>EC2 > Load Balancers > CloudStorageSecAPILB</p></figcaption></figure>

Once there, go to **Actions > Edit Listener**

<figure><img src="/files/g5EmSCPkUXRp7gBrbkkt" alt=""><figcaption><p>EC2 > Load Balancers > CloudStorageSecAPILB > Https:443 Listener</p></figcaption></figure>

Scroll down to the **Secure listener settings** and change the Security Policy from TLS1.3 to the (recommended) one.

<figure><img src="/files/Ej263LaUyeW2x3spWVFD" alt=""><figcaption><p>EC2 > Load Balancers > CloudStorageSecAPILB > Https:443 Listener > Edit Listener</p></figcaption></figure>

Once this is done, Save the changes, wait a few minutes, and try your API/Token call again.


# Password not received after deployment

Sometimes you may not receive the welcome email which includes your temporary password. If that's the case, here are the steps to logging in for the first time.

## AWS Cognito

1. Go to AWS Cognito and click into the `CloudStorageSecPool`.<br>

   <figure><img src="/files/fkDqFtnYIghi607eGNqr" alt=""><figcaption></figcaption></figure>
2. If you go into the `admin` user, you will see that a password reset is not available. Therefore you will need to create a new user. Once you create a new user, mark the email as verified and set your password from here.

<figure><img src="/files/aLNB5AgCTfO4N3ZPfVYp" alt=""><figcaption></figcaption></figure>

3. Once the user is created, you will need to add it to two Groups, `Admins` and `Primary`.

{% hint style="warning" %}
**Sometimes you may run into an issue where the Groups are not created**

In that case you will have to go to DynamoDB and set both VisibleGroups and Groups table, as the screenshots below show:

<img src="/files/OeredMH8tn0LAYplrYnh" alt="" data-size="original"><img src="/files/ZAugQSS3EuyxPHgTNRYG" alt="" data-size="original">
{% endhint %}

<figure><img src="/files/VbcmT2QKX0Eo8m3AO318" alt=""><figcaption><p>Add user to group in Cognito</p></figcaption></figure>

3. You are now ready to log into our console and start using our solution (please note: a password change will be needed upon first login for this new user)<br>

   <figure><img src="/files/CTgkqixscjyFt4HCQJTw" alt=""><figcaption></figcaption></figure>

If you are still experiencing issues, please [Contact Us](/contact-us).


# Conflicted buckets

Amazon S3 buckets have an event system associated with them. There are 15 possible events that can be triggered on an bucket.

{% hint style="warning" %}
As of v7.00.000 we automatically use EventBridge to resolve any bucket conflicts.

If you are running an older version of our product you will need to use the instructions in this article to troubleshoot the conflicted bucket.

If you have any questions or need assistance please [Contact Us](/contact-us).
{% endhint %}

There is one particular event, `All object create events`, that **Antivirus for Amazon S3** listens for. Because AWS only allows one event listener per event, this is where the conflict can occur. If the bucket has an event listener already assigned to `All object create events` then we *could* have a conflict.

There are 3 types of event listeners than can be assigned to each of the events: SNS Topics, SQS Queues and Lambda Functions. Amazon Simple Notification Service (SNS) is a highly available, durable, secure, fully managed pub/sub messaging service. Amazon Simple Queue Service (SQS) is a fully managed message queuing service that enables you to decouple and scale microservices, distributed systems, and serverless applications. AWS Lambda lets you run code without provisioning or managing servers.

We reflect these conflicts with colored backgrounds to the rows in the bucket management views. A yellow row represents that your bucket has an SNS Topic on it for the event we care about. It is yellow because we can fix this one automatically as you'll learn below. A red row indicates you have either a Queue or a Lambda assigned to the event. We cannot directly fix those and they will require some intervention on your part. Read on to solve these.

<figure><img src="/files/YL20BryekJ0dHNhNc7T3" alt=""><figcaption></figcaption></figure>

## Dealing with Yellows

Because SNS is a pub/sub messaging service, which multiple subscribers can in fact subscribe to, we can simply subscribe the **Antivirus for Amazon S3** queue to the Topic to receive all the events triggered post setup. We will do this automatically when enabling a bucket in the console. So no real conflict when the event listener is an SNS Topic. We just want to make you aware.

{% hint style="warning" %}
There is a chance multiple publishers push messages to this topic. If that is the case, **Antivirus for Amazon S3** will see all messages and attempt to process them. If you have this setup, [Contact Us](/contact-us) to work through one additional option we can explore.
{% endhint %}

## Dealing with Reds

The simple answer here is: turn these to `yellows`. Done. Ok, that is simplistic and there are some steps needed here, but it is true that if these buckets only had SNS Topics on them then `we all (your queue, your lambda and our Antivirus for Amazon S3)` could subscribe to the Topic and each get the event package we needed.

{% hint style="info" %}
You should take a moment to determine what functions you are performing based on that event trigger to ensure there won't be a conflict between what you are doing and what we are doing. For example, you expect the object to be there, but we found an infection and quarantined it to another bucket. Does this break your flow?
{% endhint %}

Now let's walk through how we change from red to yellow.

The short answer is we need to place an SNS Topic on the bucket and assign it to the `All create object events`. Then subscribe your Queue/Lambda that was originally assigned to the event now to the Topic. And then go back to the **Antivirus for Amazon S3** console and enable the bucket for scanning. We will automatically subscribe our queue to the topic you specified.

You have two choices when it comes to the SNS Topic: create one from scratch or leverage the one **Antivirus for Amazon S3** creates. For simplicity we'll walk through leveraging the **Antivirus for Amazon S3** created Topic.

{% hint style="info" %}
If you have not protected any buckets in the given region prior to these steps the SNS Topic we create will not have been created yet. Protect another bucket, even temporarily, in that region to have the SNS Topic created and then you can proceed.
{% endhint %}

We'll walk through how to fix a bucket with lambda configured on it. Fixing a red "queue" bucket will be the same process, but for a queue rather than a lambda function. What it looks like in the **Antivirus for Amazon S3** console:

<figure><img src="/files/X26Wt9jmYxUuZQpUwXTZ" alt=""><figcaption></figcaption></figure>

What it looks like in the Amazon console:

<figure><img src="/files/lCGLwS8v8ZGiDWAsq39I" alt=""><figcaption></figcaption></figure>

As you have it configured here, each time a new object is created/modified the `All object create events` fires and sends the event to a Lambda function. In this case the `helloworld` lambda function.

First, we'll simply delete the event off of the bucket. Now select the event, click `Delete` and then click `Save`.

<figure><img src="/files/2iQIH0oogPGTYPRgXesD" alt=""><figcaption></figcaption></figure>

With this done, if you go back to the **Antivirus for Amazon S3** console the bucket will no longer be conflicted.

<figure><img src="/files/gzJIs3xlvcQasyIGlw9W" alt=""><figcaption></figcaption></figure>

While here, enable the bucket for scanning to apply the SNS Topic to the bucket.

<figure><img src="/files/6v96x4oADWo8QSR5ijO0" alt=""><figcaption></figcaption></figure>

Which gives you this now:

<figure><img src="/files/hT9erdffzWBWuapKEwrv" alt=""><figcaption></figcaption></figure>

You're half way there. Next thing to do is subscribe your lambda to the Topic so it continues to receive the new object bucket events. The easiest way to do this is from the Lambda Management page. Navigate to `AWS Services-->Lambda--><lambda function name>` as seen below.

<figure><img src="/files/REh0cxa8aaKxCAWbP44T" alt=""><figcaption></figcaption></figure>

Delete the `S3 Trigger` seen there and then click the `+ Add trigger` button and populate the following screen as seen below:

<figure><img src="/files/KlBMFBlyeH0Wiaka3UVC" alt=""><figcaption></figcaption></figure>

Click the `Add` button and you will now see the following for your lambda function:

<figure><img src="/files/ZIwwLV2W8LqDikuD3D6r" alt=""><figcaption></figcaption></figure>

Make sure to click `Save` on the Lambda page in the upper right corner. Once you do, you will no longer see the S3 Bucket trigger and will be left with just an SNS Trigger as seen below:

<figure><img src="/files/ASsgYnpH6I1D5kXB3dlP" alt=""><figcaption></figcaption></figure>

You have now made it so your Lambda function will get triggered by the SNS Topic instead of directly from the S3 Bucket.

There is one difference in the JSON the Lambda will receive. The JSON coming directly from the bucket was just that, the package of information related to the object added to the bucket. When coming from the SNS Topic, that same package of information is wrapped in an SNS Topic JSON block as the `Message`. So you will just need to grab that `Message` block and you will be right back where you started. You can see the differences here:

{% tabs %}
{% tab title="JSON from S3 Bucket" %}

<figure><img src="/files/tFzsr8vbKcGvS0VXPQva" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="JSON from SNS Topic" %}

<figure><img src="/files/6vEbi1B778Oe2XUMBGQJ" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

Now you are all set! Your Lambda function gets the event, as seen above, and the **Antivirus for Amazon S3** SNS Topic also receives the event and can now scan the objects.

{% hint style="info" %}
One more reminder, if that Lambda was only tied to a single bucket and you only want it to receive events from that single bucket, you may need to take a slightly different approach. As mentioned earlier, this SNS Topic receives events from all enabled buckets within the region. You will be better off creating a unique SNS Topic that only applies to this bucket. Subscribe your Lambda to it just as we did above and then simply enable this bucket from the console. We'll treat it as a yellow bucket and just subscribe our queue to that Topic as well.
{% endhint %}


# Modifying scaling info post-deployment

Making changes to your configuration after deployment is possible.

As discussed in the [Sizing](/how-it-works/sizing#so-what-does-this-mean) section, there may be times you need or want to change how the product scales. This is simple to do on the [Agent Settings](/console-overview/configuration/agent-settings) page. Please go to this page to make changes to the scaling characteristics for all agents globally or on a per region basis.

{% hint style="info" %}
Changing these values alone may help you meet your requirements. However, there are other values that may need to be tweaked if you aren't seeing the response you were hoping for. Please [Contact Us](/contact-us) for more details if you are still having trouble.
{% endhint %}


# Objects show unscannable with access denied

This issue is seen when the customer is using AWS-KMS with a Custom KMS for encryption on the bucket.

Standard AES-256 and AWS-KMS leveraging `aws/s3` will be read and processed just fine. When using a `Custom KMS ARN` you must give the scanning agent role access to the key in order to process objects within the bucket. This is straight forward to do.

You have two options as seen below to enable this. Global KMS Access is favorable because it is one activity to grant access to all keys. Also, in the event of keys being rotated or as new keys come online for additional buckets the solution will automatically be able to leverage them. The KMS access is granted using the `viaService` option within the permissions. This means that the Agent can only use the keys when dealing with S3 buckets and objects. If you'd prefer to grant access on a per-key basis you can follow the second option.

## Global KMS access by default

Any product update starting with the 4.04.004 release will automatically turn on Global KMS access. This is a result of it being the default option within the CloudFormation template starting with that release. If you do not want this set, follow the steps below, but select No in the option.

{% tabs %}
{% tab title="Global KMS Access (limited scope)" %}
{% hint style="info" %}
In the case of cross-account scanning, in the remote account you would rerun the CloudFormation template and ensure the KMS option is set to Yes much like you'll see below.

The steps below walk you through setting up the `primary` account.
{% endhint %}

1. Login to the AWS Console and navigate to the CloudFormation service (ensure you are in the appropriate region).

   <figure><img src="https://help.cloudstoragesec.com/img/aws-cf-menu.png" alt=""><figcaption></figcaption></figure>
2. Select the stack that represents the initial Console deployment and click the `Update` button (`CloudStorageSec-AV-for-S3` if you kept the default name).

   <figure><img src="https://help.cloudstoragesec.com/img/aws-cf-stack-update1.png" alt=""><figcaption></figcaption></figure>
3. Leave the selection as `Use current template` and click the `Next` button.

   <figure><img src="https://help.cloudstoragesec.com/img/aws-cf-stack-update2.png" alt=""><figcaption></figcaption></figure>
4. Find the `Allow Access to All KMS Keys` option and change this value as desired (Yes to enable, No to disable). **Leave all other parameters as their current values unless you desire them to change as well.**

   ![CF Stack Update 3](https://help.cloudstoragesec.com/img/aws-cf-stack-update3.png)
5. Click the `Next` button and on the following screen.
6. Review the stack changes, tick the `I acknowledge` box and click the `Update Stack` button.

   <figure><img src="https://help.cloudstoragesec.com/img/aws-cf-stack-update4.png" alt=""><figcaption></figcaption></figure>

{% endtab %}

{% tab title="Individual Key Access" %}
{% hint style="info" %}
In the case of cross-account scanning, in the remote account you would assign the `Custom KMS ARN` to the CloudStorageSecRemoteRole.

The steps below walk you through setting up the `primary` account.
{% endhint %}

1. Login to the AWS Console and navigate to your Key Management Service.

   <figure><img src="https://help.cloudstoragesec.com/img/aws-kms-menu.png" alt=""><figcaption></figcaption></figure>
2. Select the key you are using for encryption on that bucket.

   <figure><img src="https://help.cloudstoragesec.com/img/aws-kms-key.png" alt=""><figcaption></figcaption></figure>
3. Scroll down to `Key Users` and click the `Add` button.

   <figure><img src="https://help.cloudstoragesec.com/img/aws-kms-key-user-add.png" alt=""><figcaption></figcaption></figure>
4. Search for the word agent and select the `CloudStorageSecAgentRole-<appID>` role.

   <figure><img src="https://help.cloudstoragesec.com/img/aws-kms-key-search-agent.png" alt=""><figcaption></figcaption></figure>
5. Click the `Add` button and you should now see the following:<br>

   <figure><img src="https://help.cloudstoragesec.com/img/aws-kms-key-user.png" alt=""><figcaption></figcaption></figure>

{% endtab %}
{% endtabs %}

You are now all set in regards to processing the encrypted objects within the bucket. You'll need to reprocess the objects that were scanned prior to enabling the key use.


# Remote account objects not scanning

When you link account you have to deploy a cross-account role in the remote account. You will see a list of the linked accounts and their status on the [Link Accounts](/console-overview/access-management/linked-accounts) page. If a remote account was previously setup with the cross-account role and scanning successfully, then there is an issue with the role in the remote account. It may have been deleted by an account admin by accident or numerous other reasons as to why there may be an issue.

Here is what it will look like if Antivirus for Amazon S3 can no longer utilize the cross-account role to get buckets:

<figure><img src="/files/6a1cOdE2FDAKoifrLZGk" alt=""><figcaption></figcaption></figure>

The first indicator that tipped you off may have been the [Problem Files](/console-overview/see-whats-infected/problem-files) page results or a [Proactive Notification](/console-overview/configuration/proactive-notifications).

<figure><img src="/files/VLNWcsnVdUHr3h9aRnzi" alt=""><figcaption></figcaption></figure>

In order to fix the problem, you have to fix the cross-account role. This may be able to be done in the remote account directly, but you may just need to start over with the role. If the stack still exists in the remote account you could simply rerun the stack there. Alternatively, if you need to run the stack for the first time or again from scratch, you can click the action button on the remote account row and select `Launch Stack` as seen here:

<figure><img src="/files/3u2Qcp9u50NTpBtfp4n2" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
This will launch the `Quick Stack Create` wizard in whichever AWS account you are currently logged into. Ensure you are logged in to the remote account in question.
{% endhint %}


# My scanning agents keep starting up and immediately shutting down

The main reason we see this happening is the agent does not have a route (outbound over internet or through VPC Endpoint) path to Amazon ECR.

This scenario is where the Fargate Service Task cannot reach out to the ECR to get the task image itself to properly load it. What you'll find here is you'll get the following message:

> STOPPED (ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve ecr registry auth: service call has been retried 1 time(s): RequestError: send request failed caused by: Post <https://api.ecr>....)

The agent service just needs to gain access to the ECR. There are two main ways to accomplish this:

* Ensure your VPC is attached to an Internet Gateway with outbound access
* Leverage VPC Endpoints to get you to ECR and API calls internally through AWS' network

<figure><img src="/files/edEwGWJD4WeioekPiu1A" alt=""><figcaption><p><strong>This the Default Public Deployment from AWS VPC</strong><br>You can take an easier a look at the subnets involved and Network connections. Check that the Security Group has outbound access allowed as well</p></figcaption></figure>

{% hint style="warning" %}
Both the console and the scanning agents can run in private subnets and do not require public IPs as long as they can communicate outbound and you can still get to the console.
{% endhint %}

Don't forget about **Security Groups**. We have seen customers be tricked (really just forgotten about the rules they had in place) on gaining access to the console because of the SG that was in place.

{% hint style="danger" %}
Security Groups can also have outbound restrictions. By default they are wide open, but that does not mean yours are. If the steps above do not fix this issue, double check your Security Group settings (outbound rules).
{% endhint %}

If taking these steps does not resolve the problem, please [Contact Us](/contact-us). We are here to help!


# I cannot access the management console

If you are having trouble accessing the management console the below information may be helpful.

## Background

It may occur that you are unable to access the management console UI. This could occur right after installation, after a reboot (from an update or another reason) or after you have changed the subdomain name. The first two scenarios typically turn out to be Subnet issues and the last is typically a DNS issue (if it is temporary).

During deployment you are asked to specify a VPC and 2 Subnets (preferably in different AZs) for the Console to run in. If you want to access the console publicly then the subnets must provide public access. What we have seen with numerous customers is that they will pick 2 subnets, one happens to be public and one happens to be private. Inevitably during the initial boot or after a reboot the console spins up on the private subnet and then can no longer be accessed from the URL or public IP. Ensure the subnets you choose are both public so no matter which the console spins up in, you'll be able to get to it.

{% hint style="info" %}
Neither the console nor the scanning agents require a public IP, however:

* They must have outbound to the internet routes (to pull ECR images).
* They must if you want to access the application from the URL.
* *If you have a VPN or Direct Connect you can access from the private IP and forget the public IP.*
  {% endhint %}

You can leverage an Internet Gateway and/or VPC Endpoints (for those services available) to access what is needed without public outbound access. Checkout the [Deployment Details page](/how-it-works/deployment-details) for more details on public and internal routing.

There are times, typically right after the subdomain changes, that you cannot access the application from the new URL. This is typically a DNS issue and you just have to wait for DNS to catch up in your area. If this issue persists longer than you expect, try to access the console via the public IP assigned to it which can be identified in the AWS Console. If neither work, then explore the subnet issue described above.

## The Fix

There is an easy way to fix this. Run a Stack Update and select two new subnets. Identify before hand which are public or which will provide the access mechanism you'd like to use. For the stack update you will use the existing template and make no other changes but the subnets. When you are able to get back into the console, you can double check your VPC and Subnets on the [Console Settings](/console-overview/configuration/console-settings) page.

* If desired, you could create an entirely new VPC with Subnets designed to work how you expect and run the console off of those.
* Allow DNS enough time to distribute to all locations.
* Check your Security Groups. One user's work/home IP changed and the Security Group was set to only allow the previous IP to access.

The vast majority of the time, it will be a VPC or DNS issue as described above. If you do not believe either of those to be the case, then one other trouble shooting step you could take is go to the ECS service in the AWS Management Console to ensure the console task is running. If it is you can drill down into the task itself to find the public and private IPs and attempt to access the console directly from those. If you can, then you know the console is up and running properly and the issue lies in the registration with Route53. Please [contact us](/contact-us) if this is the issue.

## Possible reasons the URL is not working

We have seen a couple of scenarios where there is a public IP, but DNS fails to come back and allow you to leverage the URL in the CloudFormation outputs.

* VPCs with proxies/firewalls/etc steering traffic and enforcing allowed URLs
  * add cloudstoragesecapp.com to the allowed list
* Blocking outbound HTTPS calls which are used to register with Route53
  * ensure HTTP calls can be made outbound
* No outbound internet access

As suggested above, you can go into the Console Task itself and find the public and private IPs and attempt to access with those. If you can, then one of the items listed above could be in play to affect the URL access. If you choose to access the application privately, work out a method that gives you consistent access to the Console task even after reboot.

## Finding your public IP address:[¶](https://help.cloudstoragesec.com/how-it-works/trouble-shooting/#finding-your-public-ip-address) <a href="#finding-your-public-ip-address" id="finding-your-public-ip-address"></a>

Login to the [AWS Console](https://console.aws.amazon.com/) and navigate to the Elastic Container Service area.<br>

<figure><img src="/files/cI6D96c5qUxMylvmAWLa" alt=""><figcaption></figcaption></figure>

Once in the ECS Management Portal, find the Cloud Storage Security cluster.

<figure><img src="/files/mYr4FXNbdOAs4Eb5bMYh" alt=""><figcaption></figcaption></figure>

Find and click into the Console service.

<figure><img src="/files/E9yria35OPlbFpGdsWfv" alt=""><figcaption></figcaption></figure>

Select the Tasks tab and click into the Task.

<figure><img src="/files/jCmotHsy0bvi5GhxvC7R" alt=""><figcaption></figcaption></figure>

Locate the public IP on the Task details screen.

<figure><img src="/files/Qry8jI5gYeILgW3xt3li" alt=""><figcaption></figcaption></figure>

Now try to access the console with the IP found. If you can access it directly, then you know the application is up and running properly and you are facing a DNS issue.

<figure><img src="/files/7pmCYIAEmF6Q0uWy8XEj" alt=""><figcaption></figcaption></figure>




---

[Next Page](/llms-full.txt/1)

