Skip to content

A new issuer against an old verifier reports a broken chain, not a version skew #22

Description

@stormer78

0.7.0 and 0.8.0 are both breaking on the wire, and the CHANGELOGs cover them well in one
direction: an old credential reaching a new verifier fails loudly and on purpose —
"an old digest reaching a new verifier fails with InvalidDigest rather than as a silent
mismatch, which is the intended outcome."

The other direction is not covered, and it is the one a mixed deployment actually hits
first.

What it looks like

A 0.7+ attenuate writes authority.parent as a multibase multihash. A 0.6
verify_chain compares that field against the parent's id:

// 0.6
match (&grant.parent, parent.id()) {
    (Some(named), Some(presented)) if named == presented => {}

so it refuses with:

chain link 0 names parent `zQmPvoSXm7pYriaeeE3DRWVybmhYDkMt1UtNrxiRdFfRcrT`,
but was presented after `urn:uuid:064710ef-90ab-4013-9f95-f224af758754`

Both values are printed, and nothing says they are different kinds of identifier. It
reads as a tampered or interleaved chain — which is exactly what BrokenLink means the
rest of the time — so the first hour goes into the chain and none of it into the
dependency graph. That is where it cost me an hour; I only found it by diffing 0.6 and 0.7
side by side.

Why this direction rather than the documented one

Clients upgrade before servers. A browser member picking up the newest crate and talking to
a host built from a workspace that pins an older one is not an unusual deployment, it is
the normal one — and it is how I hit this, building a wasm room member against room-host.

What would have saved it

Either would have:

  1. A line in the migration notes saying which end moves first — verifiers before
    issuers, or both together — for 0.7's parent digest and 0.8's presenter rule alike.
  2. A hint in BrokenLink when named decodes as a multibase digest and presented
    does not (or vice versa): "these are different kinds of identifier — the credential was
    issued by a newer dtg-credentials than this verifier". Cheap, and it only fires in the
    case that is already an error.

(1) alone is probably enough. (2) helps whoever skips the notes, which is most people
debugging at the point they see this.

The consumer this is about

verifiable-trust-infrastructure pins dtg-credentials = "0.6", so it is now two breaking
releases behind on the library its room authorization rests on. Worth saying because the
upgrade has a correctness payoff rather than just currency: per the 0.8 notes, both
hand-written presenter re-checks go away. vti-rooms-dtg::nomination currently carries

// `verify_chain` uses `claimant` only for the audience check; it does not require the
// grant to name them. Without this a nomination would be a bearer token, and anyone who
// ever observed one could take the room the moment it went dormant.

which is precisely the gap 0.8 closes in the library. Two copies of a check is one place
for it to be forgotten — the changelog says so, and this is the code it is talking about.

Happy to do the VTI-side bump if the ordering guidance lands here first.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions