Document security / Who can reach the document
Marking a document so a leaked copy can be traced back
Putting a per-recipient mark on a document so a copy found elsewhere can be attributed, which is a deterrent and an investigation aid rather than a control.
The exposure
For documents that will be distributed to many people and must not be redistributed, no access control helps after delivery: the recipient is authorised and a copy is a copy. What is left is attribution. A per-recipient mark makes a leaked copy traceable, which deters the casual sharing that accounts for most leaks and gives an investigation somewhere to start. It is worth being clear that it is not protection, and that a recipient who cares can remove a visible mark.
The decisions
Reasons rather than a description of the code. Each one has a default that is fine for a page and wrong for a file somebody keeps.
- Mark per recipient rather than per document, or the mark identifies nothing.
- Make it visible if deterrence is the goal, since an invisible mark deters nobody. A visible name and timestamp is what stops casual forwarding.
- Record which recipient received which marked copy at generation time, or the mark cannot be resolved later.
- Keep the mark from obscuring content, so it does not make the document harder to use for the people who received it legitimately.
- Do not claim it prevents anything. It attributes; it does not restrict, and a determined recipient can remove a visible mark.
- Consider whether the mark itself discloses something. A watermark naming a person is visible to anybody they legitimately show the document to.
In practice
A fragment, with the thing that goes wrong kept in a comment where it is the more instructive half.
// Per recipient, or it identifies nothing.
function watermarkFor(recipient, issuedAt) {
return `${recipient.name} · ${recipient.id} · ${format(issuedAt, "yyyy-MM-dd HH:mm")}`;
}
const html = template({
content,
watermark: watermarkFor(recipient, now),
});
// Record it, or the mark cannot be resolved when a copy turns up.
await audit.record({
action: "document.watermarked",
documentId,
recipientId: recipient.id,
mark: watermarkFor(recipient, now),
at: now,
});
/* Visible, because deterrence is the point and an invisible mark
deters nobody:
.watermark {
position: fixed;
top: 50%; left: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
z-index: -1;
font-size: 28pt;
color: #e0ded8;
print-color-adjust: exact;
}
What it is: attribution, and a deterrent against casual forwarding.
What it is not: a restriction. A recipient who cares can remove it.
And consider the mark itself: a watermark naming a person is visible
to everyone they legitimately show the document to. */What people do instead
Watermarking every copy identically. It looks like a control, it satisfies a requirement on paper, and when a copy turns up somewhere it should not, the mark narrows the source to everybody who received one.
How this is found out
The gap is discovered at the only moment it matters, when a leaked copy is in hand and the question is who had it. If the mark is not per recipient and not recorded, the answer is unavailable.
Frequently asked
Does this page tell me what the law requires?
No, and deliberately not. Retention periods, erasure obligations and residency rules vary by jurisdiction, by industry and by the kind of document, and they change. What these pages describe is the shape of the problem and the mechanisms a system needs in order to implement whatever answer your own advisers give you. Where a genuine tension exists, such as an immutable record against a right to erasure, it is named as a tension rather than resolved.
Why is so much of this about the contents rather than access control?
Because access control decides who can obtain a copy and has no opinion at all about what happens to the copy. Once a document is on somebody's laptop, forwarded to a colleague or printed, every control listed here has already stopped applying to it. What is inside the file is therefore the part that keeps mattering, which is the opposite of the balance you would strike for a page.
How much of this applies at a small volume?
Most of it, because these are decisions rather than infrastructure. Redacting by omitting rather than covering costs nothing. Deciding what goes on a template costs one review. Classification is one object in code. Legal hold and an audit trail are the two that take real work, and both are far cheaper to build before they are requested than under the deadline that comes with the request.
Related security topics
The decisions that depend on each other, then the rest of the same group.
What a PDF password actually protects, and what it does not
Password protection on a document, which is genuinely useful for one purpose and routinely presented as something much stronger.
Recording who generated, accessed and shared each document
The record of what happened to a document and who did it, which is asked for after an incident and cannot be reconstructed then.
Sending a document as a link or as an attachment, and the tradeoff
Two delivery models with different security properties, where the convenient one is usually the less controlled one.
Serving a generated document behind proper access control
Making sure the person downloading a document is entitled to it, which fails most often because the document lives somewhere the check does not.
Signed URLs for documents, and choosing an expiry that fits
Giving out a URL that carries its own authorisation for a limited time, which moves the access check to the moment the link is minted rather than the moment it is used.
Every document security topic
The full list, grouped by access, contents and what happens afterwards.
What this API actually does
The options and endpoints these decisions are built on, one page each.
Most of these are decisions rather than features, and the cheapest time to make them is before the first document is delivered rather than after one reaches the wrong person.