Release note · August 1, 2026

A Word restriction is not encryption

By SybilGambleyyu · DocFence 0.13.0

A Word template can open as read-only, permit only comments or form fields, recommend read-only mode, or ask before leaving a restriction. Those controls can matter enormously to a publishing, review, or handoff workflow. But they are not the same as encrypting a file, and a package that stores them should not be described as cryptographically secure merely because a password-looking value appears in its settings.

Microsoft’s WordprocessingML document-protection contract is unusually clear about this boundary: editing restrictions are for preventing unintentional changes, do not encrypt the document, and are not intended as a security feature. Its independent write-protection setting carries the same caveat. Yet both remain meaningful stored state—and protection elements can retain password-verifier fields such as hashes and salts.

DocFence 0.13 makes that boundary review-visible without exposing the underlying protection material or overstating what it means.

What the package can retain

Word stores direct w:documentProtection and w:writeProtection elements in a document Settings part. The first can specify an editing mode such as read-only, comments, tracked changes, or forms, plus formatting and an enforcement attribute. The second can recommend read-only mode or retain write-protection material. The exact client behavior matters, especially when an enforcement attribute is absent, so DocFence reports stored evidence rather than predicting what an editor will do.

DocFence discovers Settings through Word’s conventional word/settings.xml path and recognized Transitional or Strict settings relationships from the main or glossary document. It checks direct protection leaves, permits at most one of each per Settings part, and rejects malformed recognized shape, attributes, edit modes, or boolean values.

Counts in reports; verifier material stays private

Profile JSON, Markdown, and SARIF expose only aggregate document-protection element, explicitly-enabled enforcement, formatting-restriction, edit-mode, write-protection, read-only-recommendation, and password-material counts. A password-material count means the element stores at least one hash or salt attribute; it does not say the verifier is complete, valid, or strong.

DocFence never prints hashes, salts, verifier values, provider or algorithm fields, other protection attributes, Settings-part paths, or fingerprints. The full direct elements are privately fingerprinted, so a same-count verifier rewrite remains review-visible without putting password-verifier material in CI output.

Choose a clean handoff or freeze an approved restriction

For an external handoff that must carry no stored Word editing or write-protection state:

rules:
  require_no_word_protection: true

This produces DFP039. It fails whenever a recognized protection element is present, including an otherwise empty one. For an approved template that intentionally retains a known restriction:

rules:
  no_word_protection_changes: true

DFP040 detects a private-inventory change from that baseline. These rules protect package state; they do not turn an editing restriction into an encryption or security claim.

What this deliberately does not do

DocFence does not validate password construction or strength, derive, test, or recover a password, assess an algorithm, bypass a restriction, decrypt a document, determine effective Office enforcement, or decide whether a document is secure. It also does not expose a protected value in the name of explaining it. A counts-and-private-digest boundary is intentionally much narrower—and much safer for CI artifacts—than a password or cryptographic analysis tool.

Release evidence

The 0.13 suite has 35 tests. It covers same-count hash/verifier rewrites; JSON, Markdown, and SARIF redaction; policy findings; conventional, Transitional, Strict, and glossary-linked Settings discovery; duplicate protection leaves; malformed roots/leaves; unsupported attributes; invalid edit and boolean values; and external Settings relationships. It passed Python 3.11 and 3.13 CI, Ruff, and compilation checks. The wheel and source archive were independently rebuilt from the release commit and matched byte-for-byte.

An installed wheel profiled two independent Open XML SDK protection assets: one reported a stored write-protection element and read-only recommendation; another reported a document-protection element with explicit enforcement and a formatting restriction. Neither reported password-material attributes. The release smoke also preserved DocFence’s existing public signed-package and ordinary Word-package checks.

python -m pip install https://github.com/SybilGambleyyu/docfence/releases/download/v0.13.0/docfence-0.13.0-py3-none-any.whl

docfence profile candidate.docx --format markdown
docfence check approved.docx candidate.docx --policy docfence.yml --format sarif --output docfence.sarif

The public release includes the wheel, source archive, and SHA-256 manifest. The precise semantics and limits are in the policy reference and threat model. For the preceding package-trust boundary, read A Word file can carry a signature without proving trust.