Document security / What is inside it
Internal information that ends up printed on a customer document
The values that reach a customer-facing document because they were available, which are usually internal identifiers, judgements and debugging aids.
The exposure
Documents accumulate helpful additions. A support reference in the footer, a batch identifier for tracing, an internal status, a template version. Each is added for a good internal reason and each is visible to the recipient forever. Some of them are merely untidy. Others disclose an internal judgement about the customer, reveal system topology, or contradict something the document says. The pattern is the same in every case: nobody decided to show it to the customer, it was just easier to include than to exclude.
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.
- Decide per field whether the recipient should see it, and treat the default as no. Internal information belongs in your logs and your audit record, which is where it is useful.
- Never print an internal classification, score or flag. A customer segment or a risk indicator on a customer document is a disclosure of an opinion about them.
- Keep internal identifiers off unless the recipient needs to quote them. Where they do, use a reference designed for that purpose rather than a primary key.
- Keep system information off entirely: hostnames, environment names, queue identifiers, template versions. They tell a recipient about your infrastructure and mean nothing to them.
- Watch the footer particularly, because it is where debugging aids are added and it is the part of a template nobody reviews after the first time.
- Assert the absence of internal patterns in the rendered text, so an addition made for a good reason is caught before it ships.
In practice
A fragment, with the thing that goes wrong kept in a comment where it is the more instructive half.
/* Everything on this list was added for a good internal reason and
is visible to the recipient forever.
internal customer segment an opinion about them
risk or credit score an opinion about them
account notes written by staff about them, in their words
database primary keys not a reference they can quote
environment or hostname your topology
queue or batch identifiers meaningless to them
template version meaningless to them
"generated by ... at ..." usually meaningless, sometimes
contradicts the document's date */
// The footer is where these appear, because it is the part nobody
// re-reads after the first review.
const footer = `<div style="font-size:7pt">
${company.registeredDetails}
</div>`;
// Not: `ref ${invoice.id} · ${process.env.NODE_ENV} · tpl ${TEMPLATE_VERSION}`
// A guard, so a helpful addition is caught rather than shipped.
test("no internal information reaches the document", async () => {
const text = await extractText(await renderFixture("invoice", "typical"));
expect(text).not.toMatch(/\b(staging|production|prod-\w+)\b/i);
expect(text).not.toMatch(/\btpl[- ]?v?\d+\b/i);
expect(text).not.toContain(invoice.id); // internal key
expect(text).not.toContain(customer.segment);
expect(text).not.toContain(customer.riskBand);
});What people do instead
Adding a trace identifier to the footer during an incident so support can correlate a document with a log. It solves that day's problem, it is never removed, and every document from then on carries an internal identifier and, often, an environment name.
How this is found out
Occasionally by a customer asking what a code on their invoice means. More often never, because it is small text in a footer that nobody reads including the people who put it there.
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.
Personal data in a document that will be emailed
What a document discloses once it is attached to a message, which is more than the recipient asked for and travels further than the message.
What metadata a generated PDF carries, and how to check
The fields a document format carries alongside its visible content, which are invisible on the page and present in the file.
Classifying generated documents so handling rules can apply
Attaching a sensitivity level to each kind of document, which is what makes every other rule in this cluster applicable rather than aspirational.
Why a black rectangle over text does not redact it
The most consequential misunderstanding in document handling: covering text with a shape hides it visually and leaves it entirely intact in the file.
Files embedded inside a PDF, and what they can carry
A PDF can contain other files inside it, which is useful for machine-readable payloads and is a way for content to travel without being visible.
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.