Skip to content

A seal we can't compute says "try again later", and lets a forgery soften its warning #40

Closed

Description

@threeqube

What

When verifier-core can't compute a credential's seal at all, the verifier-plugin says "We couldn't check this right now… Try again in a little while." (grey, every row "not checked"). That's the catch-all for a passing glitch, but these failures are permanent: trying again always gives the same answer.

Two signature-check problems land there, because src/outcomes.ts has no case for them and they fall through to signature_unchecked (COULD_NOT_CHECK):

  • PARSING_ERROR, "JSON-LD Validation Error: Safe mode validation error": the credential has a field or type that its @context doesn't define.
  • PROOF_UNSUPPORTED, "This verifier does not support this proof's cryptosuite".

Found while testing #39: 299 of 1,711 altered credentials took this path (275 safe mode, 24 unsupported), 98 of them properly re-signed. main behaves the same before and after #39.

Why it matters

It never shows a false "Verified", so it fails safe. But:

  1. A forgery can soften its own warning. The demo's "Changed" credential shows red "This credential has been tampered with". Add one made-up field ("notInAnyContext": "x") and it shows grey "We couldn't check this right now" instead. Someone presenting a forgery can point at the grey box and say the checker is flaky. It takes only a text editor.
  2. A genuine credential can be stuck forever. An issuer who adds a custom field without defining it, or uses a seal type verifier-core doesn't support, gets earners told to try again later, indefinitely. The earner blames their phone or the wallet, and the issuer never hears that the credential is broken.

The wallet's pinned verifier-plugin (release a4ca3e6, built from 37b6fd9) does the same. Run on 3 November 2026 against the site build of the same commit: the demo's "Changed" credential shows red "This credential has been tampered with", and grey "We couldn't check this right now" once "notInAnyContext": "x" is added. It bundles verifier-core 2.0.0, not 1.x as this said before.

Proposed fix

Recognise both problems in the !sealHeld(checks) branch, beside did_web_unresolved and http_error_with_signature_check, and give them a permanent red "can't check" outcome in the spirit of invalid_structure ("We can't check this credential… Ask the issuer for a replacement."). It must not say "tampered": a genuine but carelessly built credential takes the same path, and a "couldn't check" never accuses. Add both to the consistency suite's signature dimension, as #34 does for the unreachable-website outcomes, so the wording rules hold for them.

Earner-facing, so the proposed wording will go to James on the PR before it merges, as usual. Could share a PR with #36, which is also a "couldn't check" reason that doesn't fit.

Not in scope

Changing what verifier-core reports, or the COULD_NOT_CHECK wording for genuinely transient failures.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions