Secure Uploads - v1.0.0
Getting Started
A five-minute path from install to serving an uploaded file behind a signed URL.
1. Install
composer require artisanpack-ui/secure-uploads
php artisan migrate
The migration adds the secure_files table.
2. Add the trait to a model
use ArtisanPackUI\SecureUploads\Concerns\HasSecureFiles;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasSecureFiles;
}
The trait gives the model a morphMany relationship to SecureUploadedFile plus a set of attach / detach / query helpers.
3. Attach a file from a request
public function store(Request $request, Post $post)
{
$request->validate([
'attachment' => ['required', 'file', new \ArtisanPackUI\SecureUploads\Rules\SecureFile],
]);
$stored = $post->attachSecureFile($request->file('attachment'));
return redirect()->route('secure-file.show', ['identifier' => $stored->identifier]);
}
attachSecureFile() runs the full pipeline: validates MIME against the file's actual contents, sanitizes the filename, optionally runs malware scanning, stores the file outside the public root, and creates a SecureUploadedFile model linked to the post.
4. Serve the file via signed URL
The package ships routes for serving and downloading. Get a fresh signed URL whenever you need to render or hand out the file:
$url = secure_uploads()
->generateSecureUrl($stored->identifier, expirationMinutes: 15);
Or use Laravel's route helpers directly — both routes are signed-only and protected by the bundled SecureFileController:
URL::signedRoute('secure-file.show', ['identifier' => $stored->identifier]);
URL::signedRoute('secure-file.download', ['identifier' => $stored->identifier]);
5. (Optional) Enable malware scanning
Out of the box the package uses the NullScanner — useful for dev / CI. Switch to a real scanner by setting an env var:
SECURE_UPLOADS_MALWARE_SCANNING_ENABLED=true
SECURE_UPLOADS_MALWARE_DRIVER=clamav
CLAMAV_SOCKET_PATH=/var/run/clamav/clamd.sock
Or use VirusTotal:
SECURE_UPLOADS_MALWARE_DRIVER=virustotal
VIRUSTOTAL_API_KEY=...
The attachSecureFile() pipeline calls the configured scanner automatically. See Malware scanning for the full flow.
Next steps
- Usage — full reference for the validation pipeline, scanner contract, storage service, events, middleware, and Artisan commands.
- Advanced — building a custom scanner, customizing the validation pipeline, processing the quarantine queue.
- Installation — requirements and the full config reference.