File uploads and document management in custom software
Documents in business software need storage, security, versions, search and retention. What to decide before building it.
The short answer
Almost every business application ends up holding documents: contracts, photos, invoices, specifications, scans. Handling them well means more than an upload button. Files belong in object storage with a database record for their metadata, never in the database itself and never on the web server’s disk. Every upload is validated by content, limited in size, renamed, scanned if a person will open it, and served through short-lived signed links only to users entitled to see it. And several decisions are far easier before the first file arrives than after the ten-thousandth: versioning, retention, permissions, and whether documents should be searchable by their content.
The pieces
| Piece | What it does | Decision to make early |
|---|---|---|
| Storage | Object storage, private, versioned, in the right region | Region and residency; a separate bucket per environment |
| Metadata | A database record per file: owner, record, type, size, key, timestamps | What to record; how files relate to business records |
| Upload path | Validation by content, size limits, renaming, direct-to-storage uploads for large files | Accepted types per document category |
| Security | Scanning, signed links, permission checks on every download, no public bucket | Who may see, download, replace and delete per record |
| Versions | Keep history or overwrite | Per document type |
| Retention | How long each type is kept; automated deletion | Legal and business requirements per type |
| Usefulness | Previews, thumbnails, text extraction, search | Which types need which |
The upload path, done properly
- The browser uploads directly to storage through a signed upload address, so large files never pass through the application server.
- The application validates the file’s actual content type and size, rejects what is not allowed, and records the metadata.
- The file is stored under a generated key, never its original name, in a private bucket.
- A scan runs for types people will open; infected files are quarantined and the uploader told.
- Previews and text extraction run asynchronously where useful.
- Downloads go through a permission check and a short-lived signed link.
- Every upload, download, replacement and deletion is logged.
Making documents useful
A list of filenames is where most document features stop. Previews and thumbnails let people find a file by looking. Text extraction from PDFs and scans makes documents searchable by content, which is often the feature users wanted all along. Linking every document to the business record it belongs to, the client, the project, the order, means it is found from the place people already are. These are modest additions when planned and expensive when retrofitted.
What this means for you
Document handling is a small system inside your application: object storage with metadata records, a safe upload path, signed downloads with permission checks, versions and retention decided per type, and enough preview and search to make documents findable. Decide the per-type rules before the first upload and build the safe path from the start. It costs little then and a great deal later.
Frequently asked questions
Should we store files in the database?
No. Databases are for structured data and are expensive to back up and scale when filled with files. Store the file in object storage, which is built for it, and keep a database record with the metadata: who uploaded it, when, which record it belongs to, its type, size and storage key. That pattern is standard and it keeps both systems doing what they are good at.
How do we control who can see a document?
Never by a public link. The application checks the user's permission for the record the document belongs to, then issues a short-lived signed link to the storage service for that one download. The storage bucket itself is private. That way a link cannot be shared beyond its lifetime and permissions are enforced by the same rules as the rest of the application.
Do we need versioning?
For anything that gets revised and matters later, contracts, specifications, reports, yes: keep every version with who changed it and when, and show the history. For disposable files, photos of a delivery, a scanned receipt, overwrite or single version is fine. Decide per document type; retrofitting versioning is painful.
Sources
- OWASP Cheat Sheet Series: File Upload (accessed 2026-09-12)