File upload virus scanning backed by ClamAV. Intercepts file uploads before they reach MinIO, scans them synchronously or asynchronously, and blocks infected files with a clear error response. Signature definitions update automatically on a configurable schedule. A Hasura Remote Schema mutation lets frontend apps trigger on-demand scans of files already in storage.
Security features are never paywalled in nSelf. This plugin requires no membership and is available on every install.
nself plugin install nself-scan
nself build
nself start| Variable | Required | Default | Description |
|---|---|---|---|
SCAN_MODE | No | sync | Scan mode: sync (blocks upload) or async (upload proceeds, scan in background) |
SCAN_MAX_FILE_MB | No | 100 | Maximum file size in MB to scan (larger files pass through with a warning) |
SCAN_QUARANTINE_BUCKET | No | nself-quarantine | MinIO bucket where infected files are moved instead of deleted |
SCAN_DELETE_INFECTED | No | false | Permanently delete infected files rather than quarantining them |
SCAN_SIGNATURE_UPDATE_CRON | No | 0 */6 * * * | ClamAV signature update schedule (cron expression) |
SCAN_NOTIFY_WEBHOOK | No | — | Webhook URL to notify when an infected file is detected |
SCAN_ALLOW_EXTENSIONS | No | — | Comma-separated list of file extensions to skip scanning (e.g. .pdf,.png) |
In sync mode, upload requests pass through an nself-scan middleware layer before reaching the storage handler. Infected files receive a 422 Unprocessable Entity response with the virus name. In async mode, uploads complete normally and a background worker scans the file in MinIO — infected files are quarantined or deleted and a webhook is fired if configured.
# Scan a file already in MinIO
curl -X POST https://api.yoursite.com/scan/file \
-H "Authorization: Bearer $TOKEN" \
-d '{"bucket": "uploads", "key": "documents/contract.pdf"}'
# Returns: {"clean": true, "scanned_at": "2026-05-01T10:00:00Z"}
# Or via Hasura GraphQL mutation
# mutation {
# scanFile(bucket: "uploads", key: "documents/contract.pdf") {
# clean
# scanned_at
# threat_name
# }
# }| Endpoint | Method | Description |
|---|---|---|
/scan/file | POST | Scan a file in MinIO by bucket + key |
/scan/upload | POST | Upload and scan in one request (sync mode) |
/scan/quarantine | GET | List files in the quarantine bucket |
/scan/quarantine/:key | DELETE | Permanently delete a quarantined file |
/scan/signatures | GET | Current ClamAV signature version and last update time |
/scan/health | GET | ClamAV daemon status and signature freshness |
np_scan_results — per-file scan records with result, threat name, and scan timenp_scan_signatures — ClamAV signature version historyClamAV daemon not starting. Check that the container has at least 512 MB of RAM available — ClamAV loads its signature database into memory on startup. Run nself logs nself-scan to see startup errors.
Signature updates failing. The update cron requires outbound internet access to database.clamav.net. Verify your server can reach it: curl -I https://database.clamav.net.
Free Plugin — Security Always Free | Port: 3829 | v0.1.0