Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Virus Scan Sdk Laravel Package

attachmentav/virus-scan-sdk

AttachmentAV Virus Scan SDK for Laravel and PHP makes it easy to scan file uploads and email attachments for viruses and malware. Integrate the AttachmentAV API with a simple, framework-friendly client to check files before storing or forwarding them.

View on GitHub
Deep Wiki
Context7

Getting Started

widdix/attachmentav-sdk-php is the vendor's official PHP client for the attachmentAV malware/virus scanning API. v1.0.0 is the first stable tag, so pin it (composer require widdix/attachmentav-sdk-php:^1.0) and treat the public API as semver-stable from here. The release notes are only a link to the full changelog — if you were on a 0.x/dev constraint, diff the commits for namespace/method renames before upgrading.

Look at these first, in order:

  1. README.md usage examples — this is a framework-agnostic SDK. There is no Laravel service provider, facade, publishable config, or queue integration. Wiring is your job, which is the main "getting started" cost.
  2. src/ — confirm the client class namespace and the exact method names for sync scan, async scan, async result lookup, and S3/URL scanning.
  3. composer.json — check the PHP constraint and whether HTTP goes through Guzzle/PSR-18 (matters for Http::fake()-style testing).

Minimal bootstrap: get an API key from the attachmentAV dashboard and note your region host (EU vs US) — keys are region-scoped. Then:

// config/services.php
'attachmentav' => [
    'key'    => env('ATTACHMENTAV_API_KEY'),
    'region' => env('ATTACHMENTAV_REGION', 'eu'), // eu|us
],

// AppServiceProvider::register()
$this->app->singleton(AttachmentScanner::class, fn () => new SdkScanner(
    client: new \Widdix\AttachmentAV\Client(/* key + base URL from config/services */),
));

Wrap the SDK behind your own AttachmentScanner interface immediately — you will want to fake it in tests and you may want to swap vendors later.

First use case: scan a file synchronously on upload in a low-traffic path (admin imports, back-office uploads) so you can see the real response shape (clean / infected / not_found / failed plus a trace ID) before building the async pipeline.

Implementation Patterns

Quarantine-then-promote. Never write user uploads to a public disk first. Store to a private quarantine disk, record the pending scan on your model, scan, then move to the permanent disk on clean and delete plus emit an event on infected. Keep the original filename in the database, not in the storage path.

Always queue user-facing scans. The sync endpoint blocks for as long as the scan takes; doing it inside the request cycle will blow through PHP max_execution_time, nginx/ALB timeouts, and your users' patience. One job for small files (ShouldQueue, tries = 3, backoff = [5, 30, 120]), and for large files the async endpoints: submit → persist the trace ID → a second job polls the result with increasing delay (retryUntil or a scheduled re-check), then dispatches the same promote/quarantine logic.

Stream, don't slurp. Storage::get() loads the whole file into memory. Use readStream() / fopen() and pass the stream (or a temporary path) to the SDK so a 100 MB attachment doesn't OOM a queue worker.

Offload to S3 scanning when the file already lives in object storage. The S3 endpoints let the service fetch the object itself, avoiding a round-trip of the bytes through your app. You need the key/bucket/region plus whatever access arrangement your plan requires — verify that in the README before designing around it, and remember presigned URLs expire.

Validation-rule integration. A SafeAttachment rule that runs the sync scan is tempting but only appropriate for small files and low volume; otherwise have the rule assert "scan pending/clean" against your own DB state and let the queue do the work.

Fake it in tests. Bind a stub AttachmentScanner in the container that returns canned clean/infected/failed results. Assert the quarantine→promote transition, not the SDK. Keep one integration test marked @group external that hits the real API with a tiny fixture file.

Observability. Log the trace ID (never the API key) on every scan, emit AttachmentScanned/AttachmentInfected events, and put the trace ID in your infected-file audit record — it's the identifier vendor support will ask for.

Gotchas and Tips

  • Region mismatch is the #1 confusing failure. An EU key against the US host returns 401/403 that looks like a bad key. Put the base URL in config, not in code, and assert it at boot in a test.
  • Content type matters. Scans are sent with the file's content type/binary body; sending multipart/form-data or a wrong MIME type can yield parse errors or bogus verdicts. Set it from the detected MIME, not from the client-supplied filename.
  • not_found on an async result is usually "not done yet", not an error. Poll with backoff; only treat repeated failed as terminal. Don't mark a file clean by default on timeout — fail closed.
  • Rate limits and 413s. Plans cap request rate and file size; you'll see 429 and 413. Catch them explicitly, back off with jitter, and surface a "scan pending" state rather than a 500. Scans are safe to retry — make the job idempotent by keying on your own scan record.
  • Don't cache per-scan state in a singleton. Under Octane the bound client survives requests; keep the client stateless or use scoped() and never stash a trace ID on it.
  • Secrets hygiene. env() only in config files, never in the client call site; keep the key out of any MIX_/VITE_-prefixed variable and out of exception messages you might flash to users.
  • No framework glue means no config caching surprises — but also no vendor:publish. If you add your own config/attachmentav.php, remember config:cache in deploy, and pass config values into the client at binding time rather than reading env() later.
  • Extension point to plan for: the SDK is thin, so put retry/backoff, logging, metrics, and the clean/infected decision in your wrapper — not scattered across jobs and controllers. That's also where you'll add a second scanner vendor or a local ClamAV fallback if you ever need one.
  • Cost/abuse: every scan is billed and every upload triggers one. Validate size and type before scanning, dedupe by file hash where possible, and rate-limit upload endpoints per user.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource