Release note · August 4, 2026

A selector needs its canonicalization

By SybilGambleyyu · DocFence 0.42.0

A relationship selector is meaningful only as part of the OPC transform sequence that processes it. The prior DocFence release corrected the selector element itself; 0.42 closes the adjacent sequencing gap. A static coverage audit now credits a relationship declaration only when its relationship transform is immediately followed by a supported XML Canonicalization transform.

Correction, August 4, 2026: 0.42 required a valid transform sequence for each reference, but did not count duplicate relationship transforms for the same relationships part across bound Manifests in one XML signature. DocFence 0.43 now rejects those duplicate declarations as unsupported. The 0.42 parser did not claim XMLDSIG validity, but its static audit did not yet enforce this separate OPC cardinality rule.

The sequence is part of the declaration

The OPC digital-signature requirements require a producer to follow a relationships transform with canonicalization, and require a consumer to treat a missing successor as an error. They permit XML Canonicalization and XML Canonicalization with Comments alongside the package-specific relationship transform. The transform filters and orders relationship XML; canonicalization gives the resulting XML the byte representation a digest can consume.

<ds:Transforms>
  <ds:Transform Algorithm="…/RelationshipTransform">
    <opc:RelationshipReference SourceId="…"/>
  </ds:Transform>
  <ds:Transform Algorithm="…/REC-xml-c14n-20010315"/>
</ds:Transforms>

That does not make DocFence an XMLDSIG validator. It is a narrow condition on when the tool will treat a stored selector as a static coverage declaration. Without it, a malformed transform chain could look like coverage even though an OPC signature consumer must reject the sequence.

What 0.42 accepts

For a manifest reference to a relationships part, DocFence now requires one direct ds:Transforms list whose direct children are XMLDSIG Transform elements using only the OPC relationship algorithm or either OPC-supported C14N algorithm. It requires exactly one relationship transform and checks that its next sibling is C14N. The standard RelationshipReference/@SourceId and RelationshipsGroupReference/@SourceType selectors are then resolved case-sensitively.

A missing successor, reversed order, duplicate ds:Transforms list, or unsupported trailing transform is kept as one aggregate unsupported manifest reference. No selector, relationship ID or type, URI, part path, digest material, certificate data, or private semantic fingerprint enters the public report.

Useful static evidence has a boundary

The two policy controls remain unchanged:

version: 1
rules:
  require_complete_package_signature_coverage: true
  no_package_signature_coverage_changes: true

DFP092 can require complete coverage in DocFence’s bounded Word scope, while DFP093 preserves an approved static-declaration baseline. Neither recomputes transformations or digests, verifies an XML signature, validates a certificate or trust chain, checks revocation, establishes signer identity, or predicts an Office client’s decision.

An existing independent fixture already uses the sequence

DCAB 0.31’s relationship-type reassignment case already writes the required relationship-transform-then-C14N sequence and independently validates that exact order. A fresh DocFence 0.42 installation still recognizes its same-count package_signature_coverage_changed boundary across the 42-case corpus. The fixture remains deliberately non-cryptographic: it tests static declaration handling, not signature validity.

Released and checked

The tagged source passed hosted CI on Python 3.11 and 3.13, including build and distribution metadata checks. Fresh wheel installation exercised the DCAB relationship-type fixture, and the public GitHub wheel and source distribution were downloaded and byte-compared against the verified local builds.

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

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

The tagged policy reference, threat model, and validation notes define the exact boundary. A static signal gains trust by narrowing what it credits—not by silently implying the rest of signature validation.