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.

3 minread 681words last updated

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

PieceWhat it doesDecision to make early
StorageObject storage, private, versioned, in the right regionRegion and residency; a separate bucket per environment
MetadataA database record per file: owner, record, type, size, key, timestampsWhat to record; how files relate to business records
Upload pathValidation by content, size limits, renaming, direct-to-storage uploads for large filesAccepted types per document category
SecurityScanning, signed links, permission checks on every download, no public bucketWho may see, download, replace and delete per record
VersionsKeep history or overwritePer document type
RetentionHow long each type is kept; automated deletionLegal and business requirements per type
UsefulnessPreviews, thumbnails, text extraction, searchWhich types need which

The upload path, done properly

  1. The browser uploads directly to storage through a signed upload address, so large files never pass through the application server.
  2. The application validates the file’s actual content type and size, rejects what is not allowed, and records the metadata.
  3. The file is stored under a generated key, never its original name, in a private bucket.
  4. A scan runs for types people will open; infected files are quarantined and the uploader told.
  5. Previews and text extraction run asynchronously where useful.
  6. Downloads go through a permission check and a short-lived signed link.
  7. 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.

Written by the CivSec S.M.A.R.T team

We build and run websites, software and AI systems for businesses. We write about what we see in that work, in plain language, and we update articles when things change.

Last checked . Spotted something outdated? Tell us.

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

  1. OWASP Cheat Sheet Series: File Upload (accessed 2026-09-12)