Summary

  • On 27 September, an individual wallet-state attestation Internet-Draft reached revision -01. It remains an unendorsed I-D, not an RFC or evidence of deployment.
  • The proposed JSON signature covers a result, conditions and signed observation anchors, but the top-level signed object does not generally name the wallet. A second-hand verifier cannot infer that subject from the signature alone.
  • The JSON expiresAt is also unsigned. The optional JWT form signs a wallet sub and an exp, but a recipient must verify that token separately and check its relationship to any sibling JSON attestation.

The handoff that exposes the missing name

The primitive in Douglas Cameron Borthwick's revision -01 is straightforward at the front door. An issuer observes public on-chain state for a wallet, evaluates operator-defined conditions and returns a signed boolean or structured fact. A verifier can check the signature offline against the issuer's published key set. The wallet holder need not present a credential. That architecture has a plausible attraction for access decisions: the recipient might learn that a threshold is met without receiving the underlying balance.

But the issuer's answer may travel. Imagine one service requests the check and a second service makes the access decision. The requester knows the wallet address it supplied. The recipient sees only the response. Section 5 of the revision now states the exact signed top-level JSON members: id, pass, results and attestedAt. The wallet address is not a general member of that signed set. A particular condition may include an address in evaluatedCondition, so it would be wrong to say the wallet is always absent. The format simply does not guarantee that a second-hand recipient can identify the subject from the signed bytes.

That is a custody problem for the request context, not proof of a broken signature. A valid signature can establish what the issuer signed. It cannot make an omitted wallet address appear in the message. If the access desk joins a verified pass to the wrong account record, the cryptography may be working exactly as designed while the decision is wrong. The issuer's condition evaluation, the transport of the response and the relying party's subject binding are separate control points.

The clock beside the signature

The same boundary governs time. Each result carries a chain-specific observation reference, and the signed object carries attestedAt. By contrast, the JSON response sends expiresAt beside the signed bytes. Revision -01 describes that field as an issuer-provided time-to-live hint. A recipient concerned about tampering can compare it with signed attestedAt and the issuer's documented validity window. A recipient needing a strict age limit can impose one on the signed observation anchors. Neither operation follows from signature verification alone.

This is not a newly introduced defect in September. The draft's own change log says existing signatures from revision -00 continue to verify. The newer text makes the envelope, reconstruction and verification steps explicit; it also loosens the status of freshness and expiry checks to recommendations. In the new seven-step procedure, key selection, byte reconstruction, signature verification and condition-hash recomputation are required by the draft. The freshness and expiry steps are recommended. That difference matters to a relying party that wishes to treat a boolean as current authority. It must state its own maximum age rather than assume that every implementation will enforce one.

The key has a similar distinction. The adjacent JSON kid is used to select a key and, in this revision, the signing scheme. A missing or unknown kid is unverifiable, not evidence of a bad signature under some guessed key. The draft forbids trying another key by default. A verifier may refresh a stale key set and try again, but it cannot turn uncertainty into acceptance. The proposed conditionHash check protects the evaluated condition's integrity; it does not, by itself, fill the wallet gap when the address was not part of that condition.

A second envelope is not a repair by association

The optional JWT format changes the coverage. Its signed claims include sub for the wallet actually evaluated and exp for expiry; its protected header carries kid. The revision sends this token beside the JSON response when requested. It says a relying party reading JWT claims must verify the JWT itself. Verifying the JSON sibling is not a substitute. If both are present, the specified correspondence check compares their related fields, and a transmitted JWT that fails verification or does not correspond must cause rejection. The JSON signature still has its own scope; a valid JWT does not magically insert sub into the JSON signed bytes.

There is an alternate route to more independent observation: an optional Merkle proof where the condition and chain support it. The draft expressly allows proof unavailability, and proof mode may expose a raw value such as a balance that boolean mode would withhold. This is a genuine verification-versus-disclosure trade-off, not a universal answer to the subject-binding question. Even a correct storage proof needs a decision about which wallet and condition the recipient meant to check.

Revision -01 also adds a domain-separated JSON signing option and a companion-signature option. Those may matter for interoperability and algorithm migration, but neither is a substitute for preserving the subject and expiry policy across an organisational handoff. The Datatracker record labels the document an active individual Internet-Draft with no RFC stream and IESG state I-D Exists; it explicitly warns that I-D hosting is not IETF endorsement. The author's references to adjacent projects and production issuers are not independent evidence here of deployed interoperability or an incident.

Sources