How to Scan File Uploads for Malware on Fly.io
If your Fly.io app accepts file uploads, those files aren't scanned for malware. Fly handles global deployment and edge networking — but a user can upload a malicious file and it'll be stored and served like any other attachment.
AttachmentScanner adds malware scanning with a single API call. Files are checked against multiple antivirus engines and you get back a clear result: clean, malicious, or suspicious.
This guide covers adding scanning to a Fly app. For the full picture on scanning strategies, see the complete guide to scanning user uploads.
Set Your Secrets
Sign up for an account to get your API token and scanner URL. Add them as secrets in your Fly app:
fly secrets set ATTACHMENT_SCANNER_URL=https://scans.attachmentscanner.com
fly secrets set ATTACHMENT_SCANNER_API_TOKEN=your_token_here
Fly injects secrets as environment variables at runtime. That's all the configuration you need.
Your First Scan
Test the connection with the EICAR test file — a standardised test file that every antivirus engine detects:
curl -H "Authorization: Bearer $ATTACHMENT_SCANNER_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.attachmentscanner.com/eicar.com"}' \
-XPOST $ATTACHMENT_SCANNER_URL/v1.0/scans
{
"status": "found",
"filename": "eicar.com",
"matches": ["Eicar-Test-Signature"]
}
That's it — scanning is working. Now let's integrate it into your app.
Scanning from Your App
The examples below use TypeScript, but AttachmentScanner works with any language. See the documentation for examples in Ruby, Python, Go, and more.
Scan by URL
If your files are in cloud storage, pass a URL and AttachmentScanner fetches the file directly:
const response = await fetch(
`${process.env.ATTACHMENT_SCANNER_URL}/v1.0/scans`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ATTACHMENT_SCANNER_API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ url: fileUrl }),
}
);
const result = await response.json();
if (result.status === "found") {
// Reject the upload
}
Scan a File Upload Directly
To scan a file from a multipart upload, send it as multipart/form-data:
const formData = new FormData();
formData.append("file", fileBuffer, filename);
const response = await fetch(
`${process.env.ATTACHMENT_SCANNER_URL}/v1.0/scans`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ATTACHMENT_SCANNER_API_TOKEN}`,
},
body: formData,
}
);
Going Async: The Recommended Approach
The examples above are synchronous — your server blocks while the scan runs. For production, use async scanning with callbacks. Your upload handler returns immediately, and AttachmentScanner POSTs the result to your callback URL when the scan finishes.
// Upload handler — returns immediately
await fetch(`${process.env.ATTACHMENT_SCANNER_URL}/v1.0/scans`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ATTACHMENT_SCANNER_API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: presignedUrlFor(stagedPath),
async: true,
callback: "https://your-app.fly.dev/webhooks/scan-complete",
}),
});
return res.status(202).json({ status: "processing" });
The uploads guide covers the full async pattern
including callback handling, staging areas, and the warning status.
Multi-Region Scanning
One of Fly's strengths is running your app close to users. If your app runs in multiple regions, your scanning API calls still go to a single AttachmentScanner endpoint — but because we scan via URL (not file upload), latency stays low. The scan engines fetch the file directly from your storage, not through your app.
Works Everywhere
AttachmentScanner is cloud-agnostic — the same API works whether you're on Fly.io, Heroku, Railway, Vercel, or your own infrastructure. If you move between platforms, the integration stays the same.
Getting Started
- Sign up and grab your API token
- Set
ATTACHMENT_SCANNER_URLandATTACHMENT_SCANNER_API_TOKENwithfly secrets set - Test with EICAR to confirm scanning works
- Set up async scanning with callbacks for production
If you need help with your integration, get in touch — we're always happy to help.
AttachmentScanner Team
Other Articles
Scan File Uploads on Railway
AttachmentScanner Team
Scan File Uploads on Heroku
AttachmentScanner Team
Scanning User Uploads for Malware
AttachmentScanner Team