Document upload quarantine: release the bytes you actually scanned
Structure uploads so validation, scanning, and release happen before untrusted files reach shared document workflows.

Keep new uploads outside normal preview, download, and editing routes until validation releases them. Bind the release decision to an immutable object or verified digest. Otherwise, a scanner can approve one file while downstream workers process different bytes under the same storage key.
Receipt is not release
Store newly received bytes in a location that ordinary preview, editing, and download paths cannot access. Give the upload a business state such as awaiting validation, with ownership and a traceable identifier. The application can acknowledge receipt without claiming that the file is ready to open. Avoid publishing the final document record first and relying on a later scanner to remove unsafe content. That design leaves a period during which another worker or user can retrieve the unreviewed object through a normal application route.

Validation has more than one possible result
Apply an allowlist appropriate to the business workflow, check size limits, and inspect file signatures or structure with maintained tooling. A filename extension and browser supplied content type are both useful hints, but neither proves the content type. Decide how encrypted documents, nested archives, macros, and embedded objects are handled by policy and by the actual scanning tools. State limitations explicitly. A successful malware scan is one control, not a guarantee that a complex parser can safely process every possible document structure.
Bind approval to immutable bytes
Compute an integrity digest for the object that is validated and associate the release decision with those exact bytes. If the object can change under the same storage key after scanning, the decision may no longer apply. Use immutable objects or guarded updates, and only promote the validated version into the normal workflow. Keep scanner version, policy version, result, and processing timestamps for diagnosis according to retention rules. Avoid exposing detailed detection internals to ordinary users when a simpler rejected or review required status is sufficient.
The release record should answer four questions: which object was examined, which policy was applied, what result was returned, and which component authorized promotion. An illustrative record might contain object_version, sha256, policy_revision, scanner_revision, and release_state. Do not use an editable filename as the only link between the scan and the document.
| Result | Normal next action |
|---|---|
| Validation passed | Release the verified object through a guarded transition |
| Unsupported or encrypted input | Apply the documented review or rejection policy |
| Scanner unavailable | Keep pending and retry within a bounded policy |
| Object changed during processing | Reject the stale result and validate the new bytes |
Keep quarantine credentials narrower than general storage administration. The upload path should be able to create an untrusted object without granting users the ability to mark it released. Likewise, a preview worker should consume released references rather than reading arbitrary quarantine keys. Test both boundaries directly; a disabled Open button does not protect an alternate download route.

Operate the pending queue
- Show upload owners whether validation is pending, failed, or rejected.
- Alert on the age of pending objects and scanner health.
- Restrict manual release to an audited administrative process.
- Remove abandoned or rejected objects according to a defined retention policy.
- Verify that every processing path consumes only released immutable versions.


