Serving Private Files
A private file is not served by the web server. It is fetched by the platform, which checks whether the requester may have it.
Where to find it
Architect Panel → Data:
- File Stores — the stores themselves, and View File Store on a row
- Large Uploads — in-progress and stalled upload sessions
- File Import Routines — watched sources and their mappings
Architect Panel → Security:
- Permissions — what the check consults
Architect Panel → Activity:
- Error Log — refused requests
What the serving layer does
- Establishes who is asking.
- Establishes which file, and which record it belongs to.
- Checks whether that person may see that record.
- Serves the file, or refuses.
That third step is the whole feature. Without it you have a private directory served publicly by a different route.
Permission on the record, not the file
The right question is whether the person may see the thing the file is attached to. A file is not usually a separate object with its own audience; it belongs to a case, an order, a person.
Checking only that somebody is signed in is the commonest weakness — it turns "private" into "private from the public internet", which is a much weaker claim.
Refuse the same way every time
A refusal that differs depending on whether the file exists tells an attacker which record identifiers are real. The same response for "no such file" and "not allowed" gives nothing away.
Never accept a path from the request
A file should be identified by its record, not by a location the requester supplies. Accepting a path is how a request for something outside the intended directory succeeds.
Set the response headers deliberately
The content type and whether the file displays or downloads. Serving user-uploaded content in a way a browser will render is a way to make an upload behave like part of your site.
For anything user-supplied, prefer download over display.
Consider logging access
For sensitive documents, who fetched what and when is worth having. It is the same reasoning as a read log on a record, and files are frequently the most sensitive part of one.
Watch for enumeration
A single user requesting many files in sequence is either a legitimate bulk export or somebody working through identifiers. Either way it is worth noticing.
Test it properly
Take a real file address, and try it: signed out, signed in as somebody without access, and signed in as somebody with it. Only the third should succeed.
Do this after any permission change, because file access follows record access and record access changes.
Worked example
An organisation tests private file access with three accounts after every permission change. One test found a file reachable by any signed-in user because the check confirmed authentication rather than record access — a distinction that only appears when you test with the second account.
Recommendations
- Check record access, not merely that somebody is signed in.
- Identify files by record, never by a supplied path.
- Refuse identically whether or not the file exists.
- Test with three accounts after permission changes.