For the complete documentation index, see llms.txt. This page is also available as Markdown.

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, 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) 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.

Prerequisites

Before deploying, make sure you have:

  1. A Cloud Storage Security Console deployed and active in your environment.

  2. An API Agent 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 — 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 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:

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.

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.

Pointing Your ICAP Client at the Server

The stack output IcapEndpoint is your target:

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:

2. Clean file — expect "No modification needed (Allow 204 response)":

3. EICAR test file — the industry-standard, harmless antivirus test file; expect an HTTP 403 block page:

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 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

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.

Last updated