[SCITT] Re: Review of draft-hawkins-scitt-attested-agent-payment-00 (re-verification against -01)

Tiago Pinto <tiago@donttrustverify.pt> Tue, 18 August 2026 13:10 UTC

Return-Path: <tiago@donttrustverify.pt>
X-Original-To: scitt@mail2.ietf.org
Delivered-To: scitt@mail2.ietf.org
Received: from localhost (localhost [127.0.0.1]) by mail2.ietf.org (Postfix) with ESMTP id 1D0DF12BA1FD3 for <scitt@mail2.ietf.org>; Tue, 18 Aug 2026 06:10:22 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ietf.org; s=ietf1; t=1787058622; bh=zLIHCgsw+hMDWEqr2Mq9AFS3MuL3XFNZuri6qVMvAQM=; h=Date:To:From:Cc:Subject; b=XQ9n09Y6fAOcIzipShGWVNHvR3fy0DwHvKsiPNoo87Sea2B01bz3SvqrA23JbdUXK wodoemiOEqvEUS+Uc61X7PbcvAi7TcsiEkZ/k62IQoJJ/M2Bh30oya/PVHof6lKpM2 IP/dOQtL2ig2iCdRyZqXk9EAweliL4OEBDvW3vOU=
X-Quarantine-ID: <z3Gm1XOfBZn3>
X-Virus-Scanned: amavisd-new at ietf.org
X-Amavis-Alert: BANNED, message contains .asc,check_cddl_v3.out
X-Spam-Flag: NO
X-Spam-Score: -2.799
X-Spam-Level:
X-Spam-Status: No, score=-2.799 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: mail2.ietf.org (amavisd-new); dkim=pass (2048-bit key) header.d=donttrustverify.pt
Received: from mail2.ietf.org ([166.84.6.31]) by localhost (mail2.ietf.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id z3Gm1XOfBZn3 for <scitt@mail2.ietf.org>; Tue, 18 Aug 2026 06:10:18 -0700 (PDT)
Received: from mail-4396.protonmail.ch (mail-4396.protonmail.ch [185.70.43.96]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mail2.ietf.org (Postfix) with ESMTPS id 6372D12BA1FBD for <scitt@ietf.org>; Tue, 18 Aug 2026 06:10:17 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=donttrustverify.pt; s=protonmail; t=1787058606; x=1787317806; bh=zLIHCgsw+hMDWEqr2Mq9AFS3MuL3XFNZuri6qVMvAQM=; h=Date:To:From:Cc:Subject:Message-ID:Feedback-ID:From:To:Cc:Date: Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector; b=ee7No4MxaziWYx9wfkRySPez9BiFXeqwELIzu4HXRgm/np8TrdgFV1FtntdnM6Ln2 t0Wfo56px969P7aXe4uUO0fDcScP+aFCywBBs/Q3xD0WYhwlBLA93tc5Py+NRwfMc7 2QNnPj8YrnpZbSlnquuXkX5fhUXcbr6v70YBZHBw0ZulcYl8z2bLPlU/Ikqh/AnZHi rBHkYI3a0rbyui7DL7tmsG+YQxEB8NvUf7Y1hY9XBcaEJOiEZ0PYgSVfNwx9qWlJ29 oJUruH1gACw8VFw00jHEUlwL3OEmPxtX4AU6gELEtsUaKjKAqK6uNhWSLV0N7heG0u Q0/DvRNstBDrg==
Date: Tue, 18 Aug 2026 13:10:01 +0000
To: Walter Hawkins <wdhawkins46@gmail.com>
From: Tiago Pinto <tiago@donttrustverify.pt>
Message-ID: <EGUVAQcIElPln7J73y5BJQcvt-N2YNCggYVQv5k4FFHqH7AceiVa3aj5FE0BDcDcZba_JIKR6qF8tbSP4mCEKW5uE44_PRL8P-3y2Tb9e9E=@donttrustverify.pt>
Feedback-ID: 206570780:user:proton
X-Pm-Message-ID: 7c99d76f0daf9a8ba36acf0c71d65bc4a3744949
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="b1=_rd3rHoot0Skg5ajPGIBgfPMFQW1zLwAgC0rJb5DxkoQ"
Message-ID-Hash: PDDENHRM6E7EQ4DQWCOFP4R2SDSTR26B
X-Message-ID-Hash: PDDENHRM6E7EQ4DQWCOFP4R2SDSTR26B
X-MailFrom: tiago@donttrustverify.pt
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
CC: "scitt@ietf.org" <scitt@ietf.org>
X-Mailman-Version: 3.3.9rc6
Precedence: list
Subject: [SCITT] Re: Review of draft-hawkins-scitt-attested-agent-payment-00 (re-verification against -01)
List-Id: "Supply Chain Integrity, Transparency, and Trust" <scitt.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/scitt/D586L838b8ZWPXukCLQqA1ZqNuU>
List-Archive: <https://mailarchive.ietf.org/arch/browse/scitt>
List-Help: <mailto:scitt-request@ietf.org?subject=help>
List-Owner: <mailto:scitt-owner@ietf.org>
List-Post: <mailto:scitt@ietf.org>
List-Subscribe: <mailto:scitt-join@ietf.org>
List-Unsubscribe: <mailto:scitt-leave@ietf.org>

Walter, all,

Bytes confirmed first. The -01 text I read hashes to
9e6deb7c735a5f776809e3e1431c7e67e1ecc664ab2c0a94895d51778f4080a7,
matching the rendered text of the posted revision. Everything below is
against those bytes. The executable checks referenced here are attached
and hash-pinned; the SHA256SUMS file lists them.

Overall: the eight blocking items are substantially adopted, and I say
so item by item. The re-verification found one new blocking finding
that lives between two of the adopted corrections, exactly the class I
said this reading would target; one normative-consistency
contradiction; two repairable grammar gaps; and a family of four
interoperability and wire-definition gaps in values the text itself
makes load-bearing.
The two pre-declared targets come back clean at the semantic level,
with qualifications stated below. Where an area is clean, I name it.

1. The eight blocking items.

Item 1 (apk versus cnf): adopted. Check 2 constructs the
required-parameter COSE_Key, hashes with SHA-256, and compares byte for
byte. Closed.

Item 2 (key attributes, trust model, freshness): adopted. The three
attributes are named, the combined model is chosen explicitly, and
Check 1 enforces iat, nbf, exp and the nonce. Closed.

Item 3 (code identity and mediation): adopted. The code member is now
(alg, artifact, digest), and the mediation requirement is a MUST. One
residual note under the interactions below.

Item 4 (issuance-time versus transaction-time evidence): adopted. The
two classes are defined and Check 1 refuses conflation. Closed.

Item 5 (aggregate bound): adopted in the normative prose and in the
settlement procedure. Executor binding, evaluation-and-settlement
atomicity, and the execution-record enumeration close what I raised
within a single scope. The CDDL does not enforce the executor
condition, reported separately below; and the new finding below
reopens the bound across reissuance, not within a scope.

Item 6 (instruction identity and replay): adopted within the normal
model. A conditional case across executors is described under the
scope-validity contradiction below.

Item 7 (constraints consumed): adopted. Check 6 consumes limits, rails
and payees. Closed.

Item 8 (supersession and issuer verification): the semantics are
adopted. The (iss, sub) sequencing rule, the monotonic precedence
rule, the discovery rule and the funds-authority check are all
specified at the semantic level, and the sequencing logic holds under
every conformant scenario I ran. The wire
profile is incomplete: neither sub nor the sequence number is yet
interoperably encodable, detailed in the wire section below.

2. New blocking finding: reissuance can restart the aggregate
allowance.

Two adopted rules compose badly. The aggregate is evaluated against
the enumeration of execution digests kept per scope, and the execution
digest includes the scope digest under which settlement was authorized.
Separately, sub is the scope digest of the initial scope and remains
constant across reissuance, so a reissued scope belongs to the same
authorization sequence, while a reissuance that changes any scope
member, including a refreshed expiry, changes the scope digest. The
consequence: the sequence continues, the aggregate accounting starts
over.

This is not a pathological sequence. The text itself says issuers
SHOULD prefer reissuance to long lifetimes. Exercising exactly that
recommendation, the attached sequencing model exercises 24 hourly
reissues in one sequence, sub constant and sequence number rising, and
under each scope the executor makes five payments of 10000, each
within the per-payment bound; 1200000 settles inside the 24h window of
a 50000 aggregate, and the per-payment bound and the aggregate
predicate of Check 6 pass for every settlement. That is the
adversarial ceiling, not the typical case. It is the same shape as the multi-executor
multiplication the executor member was introduced to close, with N now
counted in reissuances rather than executors.

The question the text has to answer: does an aggregate bound belong to
the individual scope or to the authorization sequence identified by
(iss, sub)? If it belongs to the scope, the text should say plainly
that reissuance resets the aggregate allowance, because that is a
large consequence to leave implicit. If it belongs to the sequence,
the accounting cannot stay keyed by scope digest alone; and rekeying
by (iss, sub) raises a second question the text must then answer:
which limit governs history already accumulated when a reissuance
narrows the bound mid-sequence.

The same ownership question shows from the other side. Nothing binds
identical scope bytes to a single sequence: the same scope bytes can
appear as a reissuance in one sequence and as the initial scope of
another, both registrations conformant. Section 5.1 requires the
executor to maintain the execution-digest enumeration per scope, while
each execution digest carries the scope digest; it does not say
whether identical scope bytes used under two distinct (iss, sub)
sequences share one accounting state or have one per sequence.
Supersession, by contrast, is explicitly pair-keyed, so the two
statements have independent revocation state. I raise this here rather
than as a separate finding because it is the same ownership question:
the text needs to say whether aggregate accounting belongs to the
scope or to the authorization sequence.

3. Scope-validity contradiction in limits.

The limits member says the minimum is a per-payment amount and an
aggregate over a stated window. The executor member says scopes whose
limits contain only a per-payment bound MAY omit it. The CDDL follows
the second reading, aggregate and window are optional. The
minimum-limits prose conflicts with the per-payment-only allowance;
the grammar follows the latter. Two independent implementations of
the same bytes can disagree on whether a scope is valid at all, which
is the same ruler the -00 review applied.

A consequence worth deciding at the same time: if per-payment-only
scopes are permitted, they carry no executor member, and the replay
rule in Check 5 binds one executor. Nothing then binds the instruction
to one executor, so the same signed instruction handed to two
executors settles twice, each executor conformant. This exists only if
per-payment-only scopes exist; it resolves with the contradiction
above.

4. The grammar does not enforce two of its own stated requirements.

Both are expressible in CDDL by group choice, so both are repairable,
not language limits. The prose defines the aggregate as a maximum over
a stated window and defines that window as rolling seconds; the CDDL
comment repeats that window is REQUIRED with aggregate; the executable
grammar accepts aggregate without it. And the grammar accepts a scope
carrying an aggregate bound without the executor member, against the
prose that makes executor REQUIRED in that case. Cross-field
constraints such as the deadline never exceeding expiry are outside
what CDDL can express; those belong to conformance tests, and I do not
report them against the grammar.

5. Four load-bearing values lack a wire representation.

The -00 review's test was whether two independent implementations,
given the same artifacts and inputs, evaluate the same predicates the
same way. Four values this revision makes load-bearing do not yet pass
it, and the first three are demonstrated by execution in the attached
wire checks.

The scope digest has no hash function. The text mandates the
deterministic CBOR encoding and says the digest is computed over
exactly those bytes, and its own words make the digest load-bearing,
it is how a scope is referenced in Receipts, in reports, in holds, and
in Check 5 selection. The document normatively fixes SHA-256 for the
APK thumbprint; its sha-256 and sha-384 mention under the software
identity alg member is an example for the measured-software digest,
not a rule for the scope digest. Two implementations hashing the same prescribed
bytes with SHA-256 and SHA-384 are both conformant and
independently compute different scope identifiers; references whose
construction or validation depends on recomputing that digest
therefore diverge. The repair is one sentence naming the function.

The sub claim has no byte-to-claim representation. RFC 9943's normative
CDDL defines sub as a tstr; this profile equates sub with the scope
digest but specifies no textual representation for that digest. Lowercase hex and base64url are both plausible textual
representations that satisfy the tstr type, but they produce different
sub values; two independent implementations constructing or validating the
required sub equals scope-digest binding have no specified common
representation.

The sequence number has no wire definition. It is required to exist
and be monotonic; no claim or member label, type, or encoding is
given, nor is the result defined if two statements in one sequence
carry the same sequence number. My sequencing checks exercise the
stated semantics and they hold; but the harness invents the carrier,
because the text has not said where the number lives or how two
implementations read the same value from the same Signed Statement.

The execution digest is underspecified. The fields are named, amount,
payee, settlement timestamp, scope digest, but no hash function, no
serialization, and no timestamp precision is stated, so the promised
recomputation by any party holding the payment's terms is not yet
defined. The payment intent identifier, which Check 5 introduces to
distinguish payment instructions for replay purposes, is also absent
from the digest input. Two distinct payments differing only in intent
identifier therefore have identical named digest inputs. Whether an
enumeration preserves repeated identical digests is not specified, so
I treat that second point as an ambiguity rather than as a
demonstrated undercount.

These four together qualify the closure of the sequencing item above
and reopen, in part, two of the -00 review's non-blocking requests:
the definition-not-description request, since the definition now
exists but its identifying digest does not name an algorithm, and the
registration-auditability request, since the enumeration exists but
its verifying artifact is not yet byte-for-byte recomputable.

6. The two pre-declared targets.

Target one, whether sub genuinely stays constant across reissuance and
revocation: clean at the semantic level. I found no path to a
different pair. Revocation under a different pair supersedes nothing,
by the text's own rule, and precedence by explicit sequence number
holds even when registration order is inverted. The qualification is
the wire section above: the semantics hold, but sub and the sequence
number are not yet interoperably encodable. The two-sequence
construction discussed under the new finding does not break this
target: sub stays constant within each sequence; what it raises is
accounting ownership, and it is treated there.

Target two, whether a signed but position-less answer can be treated
as determinate: clean. Where the service advertises supersession
queries, an unsigned or position-less answer is indeterminate by the
explicit route. Where the service does not advertise them, the outcome
is obtained compositionally: the text says such services are out of
scope by construction, while Check 9 defines inability to determine
supersession status as indeterminate, and the determinate answer is
defined as signed and position-carrying. There is no explicit
normative branch stating that a non-advertising service yields an
indeterminate result. The semantics converge, so this is editorial,
not a finding: a single sentence, if the Transparency Service does not
advertise supersession queries the executor MUST treat the
supersession status as indeterminate, would make the derived outcome
explicit.

7. The other pre-declared interactions.

crit against the CDDL: clean. The open map plus the crit semantics
compose exactly as intended; unknown members not named in crit pass
and must be ignored, members named in crit and not understood force
refusal. One undefined case noted, a crit naming a member absent from
the map has no stated semantics; I do not report it as a finding.

Mediation against instruction identity: clean, with one residual
ambiguity I flag without elevating. The verification checks are
attributed to the Payment Executor, while the mediation paragraph has
them executed by the measured component; the text does not say which
fields that component must itself observe before releasing a
signature. There is an implementation that satisfies both texts, so
this is an unspecified interface, not a contradiction.

8. Method note: the document ships no test vectors.

The word example occurs twice in the text, both times in prose. The
CDDL is introduced as the algorithm's input contract, and there is
nothing in the document to exercise it against. Every vector behind
the grammar findings above was therefore written by me from the prose
of the authorization-scope definition, and each states its expected
outcome and its basis before the grammar's answer. The vectors and
their run output are attached and pinned. This is a recommendation
rather than a finding: I recommend including normative or clearly
identified conformance vectors in a future revision, especially
because the CDDL is described as the algorithm's input contract, and
because the grammar gaps above were one execution away from the text.

9. Editorial.

In the rendered text, the [MEASURE] and [ERC8004-STUDY] references
carry empty author lists, commas with no names. In the XML source the
author elements carry surnames only. Supplying initials alongside
surname, or a fullname, and re-rendering should repair the references.
Worth fixing before the next posting, since
the -00 thread turned on getting exactly that reference right.

The attached artifacts are the extracted grammar, three check scripts
(grammar vectors, sequencing scenarios, wire representations), their
outputs, and the reproduction record. I re-ran the checks on a
separate Linux x86_64 machine under Python 3.14.4; the outputs are
byte-identical to the packaged run under 3.12.3, compared with cmp.
SHA256SUMS covers the evidence set. As before, if I found nothing worth
objecting to in an area, I said so and named the area.

Regards,
Tiago Pinto
Independent author and researcher, verifiable trust and AI governance
https://donttrustverify.pt


Em sábado, 15 de agosto de 2026 às 13:38, Tiago Pinto <tiago@donttrustverify.pt> escreveu:

> Walter,
>
> Bytes confirmed first. The XML in the archive hashes to 75e899657943852297878e2e3ab21dba437ca848c46780a2b739111fb1f721d7, matching what you sent; the rendered text is 9e6deb7c735a5f776809e3e1431c7e67e1ecc664ab2c0a94895d51778f4080a7. Whatever I report will be against those bytes and will name them.
>
> On scope, I will take more than one of the eight, and for a reason worth stating. Eight normative changes in a document this size interact, and the failures that matter in a revision like this one are usually not inside a single adopted item but across two: the atomicity requirement of the aggregate bound against the sequencing rules, the crit member against the CDDL, the mediation requirement against instruction identity. Reading item by item would miss exactly that class. So the reading will cover all eight and their interactions; the executable checks will go where there is something to execute, which is the CDDL against the document's own examples, and the sequencing predicates.
>
> Two things I will be looking at specifically, so they are on the record before I look. Whether sub as the initial scope digest genuinely stays constant across both reissuance and revocation, since that is the load-bearing claim of the sequence identifier. And whether the determinate none-present answer requires a signed response carrying a position in every path through Section 6, or whether the redrafting left a route where a signed but position-less answer is treated as determinate. That second one is the narrowing you credited to me; it is the one I should be hardest on.
>
> No date promised. It goes out when it is finished, with the checks attached and hash-pinned before sending, as before. If I find nothing worth objecting to in an area, I will say that too, and name the area.
>
> Best regards,
> Tiago Pinto
>
>
>
> Em sábado, 15 de agosto de 2026 às 06:28, Walter Hawkins <wdhawkins46@gmail.com> escreveu:
>
> > Tiago,
> >
> > -01 is posted, and it is mostly your review. Point by point, in your numbering.
> >
> > 1. Adopted. The scope's apk is now defined as the RFC 9679 thumbprint computed with SHA-256 over the required-parameter COSE_Key construction, and Check 2 states the procedure: extract the Subject Public Key from cnf, construct, hash, compare byte for byte. The comparison is over the computed thumbprint, never serialized encodings, matching the dependency's own comparison rule.
> >
> > 2. All three parts adopted. (a) Check 3 now names the members: never_extractable true, extractable false, local true — and your distinction drove the choice; the property the profile needs is never-extractability, since a once-extractable key may already have copies. Because every member is optional in the dependency, absence of any of the three is failure of the check, not silence. (b) The combined model is in scope; the split model is explicitly out of scope at this revision. (c) iat, nbf and exp enforcement is now part of Check 1.
> >
> > 3. Adopted, both halves. The code member is now a structure — alg, artifact class, digest — so the Check 4 comparison is defined across attesters. And the aside you flagged is promoted to a normative paragraph after the checklist: all APK payment signing MUST be mediated by the component covered by the code measurement, with the signing-service failure you described spelled out as the thing this requirement exists to prevent. You were right that without it the draft's thesis was not established.
> >
> > 4. Adopted in the shape you suggested. Authorization-time and transaction-time evidence are now defined terms; Check 1 consumes the latter, Check 8's Receipt refers to the former, and the text says plainly that the two are distinct artifacts that must not be conflated. Your aside about per-transaction freshness being the right call is now the design rationale in the definitions.
> >
> > 5. Adopted via executor binding plus atomicity. A scope carrying an aggregate bound MUST name its executor, who is the serialization point; an executor named by no scope it is shown refuses. The evaluation-and-settlement sequence MUST be atomic with respect to the scope's spend accounting, which closes the read-check-settle race. Separately — from Pablo Etcheverry's finding in the other thread — the accounting itself is now checkable: each settled payment gets an execution digest and the executor MUST enumerate them on challenge, so the aggregate is auditable rather than asserted. The two changes compose: yours makes the aggregate an aggregate, his makes it checkable.
> >
> > 6. Adopted with exactly your field list. The instruction must bind, under the APK signature: one scope by digest, a payment intent identifier, payee, amount with unit, and rail — and an executor MUST NOT settle the same intent twice under a scope. Encodings are left to rail profiles; presence and signature coverage are not.
> >
> > 7. Adopted, nearly verbatim — "constraint members that the normative procedure did not evaluate would not be constraints" is now in Check 6, which enforces rails and payees alongside limits. The rails-absence ambiguity you flagged is resolved the way you suggested: absence means the scope imposes no rail restriction, and this does not override relying-party policy.
> >
> > 8. Adopted, and this one forced the most new text. Section 6 now defines the sequencing: sub is the scope sequence identifier (the initial scope's digest, constant across reissuance and revocation), superseding statements MUST reuse the (iss, sub) pair, precedence is an explicit monotonic sequence number rather than ledger order — your citation of the 9943 ordering warning is why — and a determinate "none present" means a signed, position-carrying answer showing the scope's own statement as the sequence's highest. Issuer is now a defined term, and Check 8 requires the executor to have a rail- or deployment-defined funds-authority procedure, with its absence being failure of the check rather than permission.
> >
> > 9. Adopted. A crit member: members named in it that an executor does not understand force refusal; unknown members not named in it are ignored. Your framing — the extension rule itself producing the widening Section 7 warns against — is in the member's definition.
> >
> > 10. Adopted. There is now CDDL, and the choices it forced are made: integer minor units with declared scale, aggregate window as rolling seconds ending at evaluation time (calendar readings declared non-conforming), expiry as epoch seconds, rail and payee namespaces delegated to rail profiles explicitly.
> >
> > 11. Adopted. The third bullet no longer asserts disinterest; it states neutrality as a deployment goal made checkable by witnessing, and Security Considerations now carries the countersigned-checkpoint requirement with quorum witnessing as the mechanism that makes divergent views detectable. Registration Policy is likewise rewritten: the log records, it does not adjudicate, and it MUST NOT label registrations as attested.
> >
> > 12. Adopted by narrowing plus one addition. The Abstract now claims auditability of the authorization artifact and its registration, says outright that registration does not evidence that the verification procedure ran for any settlement, and points at the execution-record mechanism as what makes the executor's aggregate accounting auditable on challenge — your "define a per-payment record" alternative, arrived at through Pablo's finding.
> >
> > 13. All three corrections taken. The title is fixed, your exact figures (21.20 / 63.78 / 84.98 over the 280-day window) replaced the vague sentence, and the registry claim is re-attributed to the ERC-8004 study the paper cites as related work — arXiv:2606.26028 — whose tier-5 liveness numbers actually support it.
> >
> > Your supersession follow-up from the other mail is also in: the signed-answer requirement is a MUST on services that advertise supersession queries, an unsigned or position-less answer stays indeterminate, and services that never advertise the query are out of scope by construction. The requirement sits on the party making the claim; that shape is yours and the text says so.
> >
> > And yes — I would like to take you up on the re-verification you offered. The submitted XML's sha256 is 75e899657943852297878e2e3ab21dba437ca848c46780a2b739111fb1f721d7, and the rendered text is on the datatracker as draft-hawkins-scitt-attested-agent-payment-01. Any of the eight, against those bytes, on your schedule.
> >
> > Thank you for the most rigorous reading this document has had.
> >
> > Walter
> >
> > On Fri, Aug 7, 2026 at 10:13 AM Tiago Pinto <tiago=40donttrustverify.pt@dmarc.ietf.org> wrote:
> >
> > > Hello Walter, all,
> > >
> > > I read the -00 in full, together with its normative dependencies, in
> > > particular draft-reddy-rats-key-binding-01, RFC 9711, RFC 9334 and
> > > RFC 9943, and the [MEASURE] reference. Artifacts were pinned before
> > > reading:
> > >
> > > draft-hawkins-scitt-attested-agent-payment-00.txt
> > > sha256 ef2cb984f9fb671ca330d2ea6a61631a5629e003bb3c48b07c1fa8509a302bd7
> > >
> > > draft-reddy-rats-key-binding-01.txt
> > > sha256 bce9463956cc6ca0f08e87bc14a7839725cc9431ee7e1de75b5daefecd14481d
> > >
> > > [MEASURE]: arXiv:2607.12575v1, read in full.
> > >
> > > Overall: the contribution is identifiable and the join is the right
> > > one. The document also gets right several things that are usually
> > > confused. Consent is not attestation, attestation is not correctness,
> > > an extractable key voids the property, executors fail closed, and the
> > > distinction between "authorization refused" and "authorization could
> > > not be evaluated", with its fail-open rationale, is the best single
> > > paragraph in the draft.
> > >
> > > My concern is interoperability. The test I applied throughout: are
> > > the protocol-defined predicates sufficiently specified that two
> > > independent implementations, given the same artifacts and the same
> > > applicable trust and policy inputs, evaluate them consistently? At
> > > -00 they are not. I found eight issues I would treat as blocking,
> > > plus three important ones and two claim calibrations. The
> > > Registration Policy change and the countersigned-checkpoint text
> > > already committed earlier in this thread are taken as settled and are
> > > not relitigated here.
> > >
> > > 1. Blocking: "apk" and "cnf" are different types.
> > >
> > > Section 3 defines apk as the RFC 9679 thumbprint of the key. Section 4
> > > step 2 requires that "the cnf key in the evidence equals the apk named
> > > in the scope". A COSE_Key and a COSE Key Thumbprint are not comparable
> > > as written. RFC 9679 defines the deterministic COSE_Key construction
> > > that is the thumbprint input, but it leaves the hash function to the
> > > application and requires that all parties reproducing a thumbprint
> > > use the same algorithm. So the step needs to state how the Subject
> > > Public Key extracted from cnf is used to construct the RFC 9679
> > > required-parameter COSE_Key, which hash algorithm is used, and that the resulting
> > > thumbprint is compared byte for byte with apk. Note that the
> > > dependency is explicit that key comparison for proof of possession is
> > > performed over key parameters rather than serialized encodings
> > > (reddy-01, Section 7.2); the thumbprint path needs the same level of
> > > care.
> > >
> > > 2. Blocking: the use of the key-binding profile is incomplete.
> > >
> > > Three sub-issues.
> > >
> > > (a) The required key-attributes members are not named. In reddy-01
> > > Section 7.1 every attribute is optional and the only requirement is
> > > that at least one member is present. An EAT carrying only
> > > sensitive=true conforms to the dependency and gives Section 4 step 3
> > > nothing to evaluate. The profile must name the members and values it
> > > requires, for example, if these are indeed the intended properties:
> > > extractable equal to false, never-extractable equal to true, and
> > > local equal to true. "Non-extractable" is ambiguous between
> > > extractable=false and never-extractable=true, and the difference
> > > matters: a key that was extractable in the past may already have
> > > copies outside the environment, so the property this draft needs is
> > > never-extractable. "Generated within the attested environment"
> > > corresponds to local=true, a member this draft never names.
> > >
> > > (b) Combined versus split model. reddy-01 defines both, and in the
> > > split model there are two cnf claims (the PAT carries the KAK, the
> > > KAT carries the Subject Key) with a distinct eight-step verification.
> > > "The cnf key in the evidence" is ambiguous there. Please state which
> > > model or models are in scope, or profile both paths.
> > >
> > > (c) The dependency requires verifiers to enforce iat, nbf and exp in
> > > addition to the nonce (reddy-01, Section 5). If Section 4 is the
> > > exhaustive pre-settlement checklist, these checks are missing from it.
> > >
> > > 3. Blocking: "code" has no interoperable semantics, and the claim
> > > built on it is stronger than attestation provides.
> > >
> > > First, the mechanics: which EAT claim carries the software identity,
> > > which digest algorithm, which artifact is digested (binary, VM image,
> > > container, configuration, model weights), and how reference values
> > > enter appraisal. RFC 9711 deliberately leaves measurement semantics
> > > to profiles; this profile has to choose, or two attesters will
> > > represent the same software differently and the step 4 comparison
> > > becomes undefined.
> > >
> > > Second, the deeper point: a key held in an attested environment does
> > > not by itself establish that only the measured program can cause
> > > signatures with that key. If a signing service inside the environment
> > > accepts requests from software outside the measured component, the
> > > signature is valid, the key is non-extractable, the attestation
> > > verifies, and the payment decision was still not made by the reviewed
> > > program. Section 7 already contains the seed of the fix, in the
> > > sentence beginning "Where the endorsed code is itself the
> > > authorization logic". I would promote that aside to a normative
> > > requirement, along these lines: all use of the APK for payment
> > > signing MUST be mediated by the component covered by the code
> > > measurement, such that unmeasured software cannot cause an APK
> > > payment signature except through the authorization checks performed
> > > by that measured component. Without some such property, the step from
> > > key-bound-to-environment to payment-decision-bound-to-reviewed-agent
> > > is not established, and that step is the draft's thesis.
> > >
> > > 4. Blocking: registration-time and transaction-time evidence cannot
> > > be the same artifact.
> > >
> > > Section 2 says the scope, the attestation evidence and the endorsed
> > > software identity are "registered together"; Section 5 says the scope
> > > is registered together with "a reference to the attestation
> > > evidence". Those two descriptions already differ, and neither
> > > composes with Section 4 step 1, which requires an eat_nonce supplied
> > > by the verifying party for this transaction. Under the Section 2 flow, the registered EAT cannot contain a nonce
> > > that an executor generates later for the transaction. As written,
> > > two conforming implementations diverge: one reuses the registered
> > > evidence and violates freshness, the other obtains fresh evidence
> > > that is not the evidence the Receipt refers to. Both can defend their
> > > reading from the current text.
> > >
> > > One clean fix is to distinguish two evidence classes explicitly:
> > > authorization-time evidence, registered with the scope, establishing
> > > the APK-to-code binding at issuance, and transaction-time evidence,
> > > freshly generated under the executor's nonce, establishing that the
> > > binding still holds at the moment of payment. Step 8's Receipt check
> > > would then refer to the former and step 1 to the latter. Other
> > > resolutions are possible; what the text cannot keep doing is calling
> > > both "the attestation evidence". As an aside, requiring fresh
> > > evidence per transaction is the right call: the dependency itself
> > > warns that nothing guarantees the platform state after evidence
> > > generation (reddy-01, Section 8.8).
> > >
> > > 5. Blocking: the aggregate limit is not an aggregate.
> > >
> > > Step 6 checks "the executor's own record of prior spending under this
> > > scope". The scope has no member binding it to an executor, so N
> > > executors each enforce the aggregate independently and the principal's
> > > bound multiplies by N while every party remains fully conformant.
> > > Even with a single executor the check has a read-check-settle race
> > > under concurrent instructions, since no reservation or atomic-update
> > > behaviour is required. Either bind a scope to a named executor,
> > > making that executor the serialization point, or define shared
> > > accounting, or state plainly that limits are per-executor, which is a
> > > different promise than the one Section 3 makes.
> > >
> > > 6. Blocking: a valid instruction can be replayed, and does not name
> > > its scope.
> > >
> > > Step 5 requires the instruction to be signed by the APK and its terms
> > > to be covered by the signature. Nothing binds the instruction to a
> > > specific scope (an APK can hold two overlapping scopes, for example
> > > across renewal; which limits apply?), to an executor, or to a
> > > one-time identifier. The eat_nonce freshens the attestation, not the
> > > instruction, so fresh evidence plus a replayed instruction composes.
> > > A repeated small instruction consumes the aggregate ceiling in fully
> > > conforming steps, and nothing lets an executor say "this payment
> > > intent has already been consumed". The minimum semantic fields that
> > > need to be cryptographically bound: a scope identifier, a payment
> > > intent identifier, payee, amount with an explicit unit, rail, and a
> > > rule that an executor MUST NOT settle the same intent more than once.
> > > If the draft wants to remain payment-protocol agnostic, it can define
> > > the required semantic fields and leave encodings to rail profiles.
> > >
> > > 7. Blocking: not all Authorization Scope constraints are enforced by
> > > the verification procedure.
> > >
> > > Section 3 defines rails and payees as constraints of the scope.
> > > Section 4 never consumes them: step 5 verifies the signature, step 6
> > > verifies limits only, step 7 expiry, step 8 the Receipt. There is no
> > > MUST that the payment's rail is among rails or that the counterparty
> > > satisfies payees. A scope stating payees equal to Merchant A can be
> > > settled toward Merchant B by an executor that literally performs all
> > > eight steps. Constraint members that the normative algorithm does not
> > > evaluate are not constraints; either add the checks to Section 4 or
> > > remove the members.
> > >
> > > Within rails there is a second, smaller point: the text says absence
> > > means the scope is rail-agnostic, and in the same sentence recommends
> > > treating absence "as broader than intended rather than as
> > > permission". The interaction between those two statements is unclear.
> > > If absence means the scope itself imposes no rail restriction, say so
> > > explicitly and clarify that this does not override relying-party
> > > policy. As written, "rail-agnostic" and "rather than as permission"
> > > leave the authorization semantics unnecessarily ambiguous.
> > >
> > > 8. Blocking: supersession and issuer verification are relied on but
> > > not defined.
> > >
> > > Step 8 requires that "the scope has not been superseded", and
> > > Section 6 allows revocation "registered as a superseding statement".
> > > RFC 9943 makes iss and sub mandatory in a Signed Statement and
> > > provides the sequencing primitives: iss and sub identify and group
> > > Statements about the same subject, and a changed state can be
> > > registered under the same pair. What RFC 9943 does not supply for
> > > this application, and what this profile therefore has to define, is
> > > the supersession semantics required by step 8: what iss and sub
> > > mean for an Authorization Scope, the requirement that a superseding
> > > or revocation statement reuse the same (iss, sub) as the scope
> > > sequence, what establishes precedence between statements (noting that
> > > 9943 warns registration order on a ledger cannot be assumed to match
> > > issuance order absent policy), and how an executor discovers the
> > > latest statement of a sequence and establishes that no later one
> > > exists. Without that, "has not been superseded" is not evaluable.
> > >
> > > Related: "issuer" appears in Sections 3 and 6 but is never defined,
> > > and no verification step establishes that the Signed Statement's iss
> > > may authorize spending from the relevant principal's account.
> > > Registration authenticates the party that made the statement; it does
> > > not establish that this party may bind those funds. The check may
> > > well be rail-specific or deployment-specific, and that is fine, but a
> > > conforming executor needs a defined step for it. It cannot simply be
> > > absent from the algorithm.
> > >
> > > Important, not blocking:
> > >
> > > 9. "Unknown members MUST be ignored" conflicts with "MUST NOT be
> > > widened". A future restrictive member added by an issuer, for
> > > example a payee category or a jurisdiction constraint, is ignored by
> > > an older executor, which silently widens the effective scope. That is
> > > the inflation Section 7 warns against, produced by the extension rule
> > > itself. A criticality mechanism is the usual answer: members marked
> > > critical MUST cause refusal when not understood. Blanket rejection of
> > > unknown members would kill extensibility; blanket ignoring is too
> > > permissive for authorization constraints.
> > >
> > > 10. The Authorization Scope needs a definition, not a description.
> > > There is no CDDL. For limits, the text fixes neither integer versus
> > > decimal, nor minor units, nor the asset identifier, nor the window
> > > semantics: "maximum aggregate amount over a stated interval" admits
> > > rolling-24-hours, UTC calendar day and local calendar day readings,
> > > and those produce different authorization decisions on identical
> > > inputs. expiry has no stated encoding, rails and payees no namespace,
> > > code no digest algorithm. In a specification this is the algorithm,
> > > not editorial polish.
> > >
> > > 11. Section 5, third bullet, claims more than SCITT provides. "Held
> > > by a party with no interest in how the transaction is later
> > > characterized" is a deployment outcome, not a property a Receipt
> > > carries. RFC 9943 permits a Transparency Service operated by an
> > > interested party and leaves the choice of which services to trust to
> > > relying parties. The countersigned-checkpoint text already committed
> > > for -01 in this thread is the honest version of this property: state
> > > neutrality as the goal, and witnessing as the mechanism that makes
> > > divergence detectable, rather than asserting disinterest as given.
> > >
> > > Claim calibrations:
> > >
> > > 12. The Abstract promises that the registration "makes the
> > > authorization auditable independently of the agent and of the
> > > executor". What is registered supports auditing the authorization
> > > artifact and its prior registration. It does not evidence that the
> > > executor performed the Section 4 checks before a given settlement:
> > > the instruction, the transaction-time evidence, the verification
> > > result and the spend state are not registered anywhere. Either narrow
> > > the claim to what the registered artifact carries, or define a
> > > per-payment record that carries the rest, which would also provide
> > > evidence relevant to aggregate-spend auditing.
> > >
> > > 13. [MEASURE]: three corrections, one of them in the draft's favour.
> > >
> > > (a) The title cited is not the paper's title. The reference resolves
> > > to arXiv:2607.12575, "How Agentic Is Agentic Commerce? A
> > > Population-Scale Measurement of x402 Adoption and Authenticity", by
> > > Ling, Zhou, Wu and Wang, submitted 14 July 2026.
> > >
> > > (b) The draft's first claim is fully supported, and in the paper's
> > > own vocabulary: over a 280-day window, 21.20 percent of settlements
> > > are classified fictitious and 63.78 percent internal settlement
> > > within a linked cluster, 84.98 percent operator-internal in total.
> > >
> > > (c) The second claim is not supported by this source. The paper
> > > measures the CDP Bazaar, which it describes as the x402 protocol's
> > > resource-discovery catalog, not an agent identity registry, and its
> > > liveness numbers run the other way: 52.09 percent of probed hosts
> > > still return a live 402 challenge, and only 11.54 percent return no
> > > response at all. "A majority of entries in at least one agent
> > > identity registry could not be reached" matches neither the object
> > > measured nor the numbers. The sentence may belong to the ERC-8004
> > > registry study the paper cites as related work; please cite the
> > > correct source for it, or drop it.
> > >
> > > Scope of this review: I read the -00, reddy-01 and the [MEASURE]
> > > paper in full, checked every normative statement quoted above against
> > > the pinned bytes, and verified the reference against the published
> > > arXiv record. I did not implement the profile, and my prior-art
> > > search was limited to the documents named here; if any of this has
> > > been raised elsewhere, I would be glad to be pointed at it. Happy to
> > > re-verify any of the eight blocking items against a revised text.
> > >
> > > Regards,
> > > Tiago Pinto
> > >
> > > --
> > > SCITT mailing list -- scitt@ietf.org
> > > To unsubscribe send an email to scitt-leave@ietf.org