feat(parser_app): verify gateway-signed payment markers - #448
Draft
pepe-anchor wants to merge 1 commit into
Draft
Conversation
Enclave-side half of the x402 trust pair: parser_app checks that a VerifiedPaymentMarker was signed by the pinned gateway key and is bound to this exact request, so a paid parse cannot be replayed against a different transaction. payment_marker takes proto field 5. Field 4 shipped as include_intermediate_output (#414) while this work sat on an unmerged branch; renumbering here is free, renumbering after deploy is not. Policy defaults to Disabled everywhere in this PR, so no caller changes behavior yet. Co-Authored-By: Claude <noreply@anthropic.com>
pepe-anchor
force-pushed
the
pepefigueira/prs-581-04a-payment-verify
branch
from
August 6, 2026 17:08
8bb360c to
320b5ea
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Enclave-side half of the x402 trust pair.
parser_apphas to check that aVerifiedPaymentMarkerwas signed by the pinned gateway key and is bound to this exact request, otherwise a paid parse could be replayed against a different transaction.This is also where a wire collision gets fixed.
ParseRequestfield 4 shipped on main asinclude_intermediate_output(#414) whilepayment_markerwas still sitting on the unmerged x402 branch claiming the same number. Renumbering now is free. Renumbering after the field is deployed is not.What
ParseRequest.payment_markertakes field 5, leavinginclude_intermediate_output = 4untouched.host_primitives::payment_marker: theVerifiedPaymentMarker/SignedVerifiedPaymentMarkertypes,VPM_VERSION, andrequest_hash. Borsh-encoded, because the encoding has to match wire-for-wire between the gateway that signs and the enclave that verifies.parser_app::payment_verify:PaymentPolicy(DisabledorRequired) and the signature plus request-binding check, run as the first thingparse()does.parse()gains a&PaymentPolicyparameter. Every existing caller passesDisabled, so nothing changes behavior in this PR.PaymentPolicy::from_envfrom the branch was dropped on purpose: this repo cannot set env vars in tests (edition 2024 plusforbid(unsafe)bansstd::env::set_var), and the real binaries take config from CLI args.from_hexis the only constructor.Test evidence
Callers updated:
parser_app::service,parser_grpc_server::main(both now pass&PaymentPolicy::Disabled), andparser_gateway::mainpicks up the new struct-literal field.Rollback
Revert the commit and re-run
make -C src generated. The proto field is additive and unused by any deployed caller, so nothing on the wire depends on it yet.Linear
PRS-581
Stack position: based on
main, independent of the pivot PRs. #414.🤖 Generated with Claude Code