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:
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:
A Cloud Storage Security Console deployed and active in your environment.
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.
A console user with API Access enabled — the ICAP server uses this username and password to authenticate to the Scanning API.
An AWS account and the VPC where your ICAP client runs, with two or more subnets for the load balancer and the Fargate task.
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.
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:
Go to CloudFormation > Create stack > With new resources (standard), choose Amazon S3 URL, and paste the template URL above.
Name the stack (e.g.
css-icap-server) and fill in the parameters (see the table below).Acknowledge the IAM capabilities notice and click Submit. The stack reaches
CREATE_COMPLETEin about 5 minutes.Open the Outputs tab —
IcapEndpointis 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 theScanApiSecretArnparameter.Stack parameters: enter the username and password directly in the
ApiUserandApiPassfields. 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
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(orRESPMOD) with the encapsulated HTTP messageSend
Allow: 204(recommended — the cheaper clean-file path)Reuse connections (persistent connections are supported and recommended)
Optionally use Preview — the server advertises
Preview: 4096in itsOPTIONSresponse
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).
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
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.
Operations
Logs: the CloudWatch log group
/css-icap-server/icaprecords one line per request with the verdict (CLEAN/INFECTED/ scan-API errors).Health: every task runs a real health probe every 30 seconds (ICAP
OPTIONSanswered 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 tofalsewhen done.
Troubleshooting
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