Agent-Passport,
Agent-Grant, tag="agent-payer-auth"); card-network merchant edges read
the Visa Trusted Agent Protocol (TAP) profile; bot-management edges read
Web Bot Auth. One library signs and verifies all three:
@grantex/agent-httpsig (TypeScript) and grantex-agent-httpsig (Python),
both unpublished and in this repository.
Signature profiles
The relying party chooses the profile it enforces; a request is never read
under another one. The grantex profile and the TAP payer profile share the
tag
agent-payer-auth, so a verifier configured for one refuses the other’s
covered-component set.
TAP body objects
TAP also carriesagenticConsumer (consumer recognition) and
agenticPaymentContainer objects in the request body, each signed and bound
to the message signature’s nonce and keyid. The library builds and checks
them. A failed consumer object is reported for the merchant to weigh; a
failed payment container is never usable for payment.
What the published TAP specification does not settle is configurable, with
documented defaults:
- where the objects sit in the body (default: top-level
agenticConsumerandagenticPaymentContainermembers); - what the object signature covers (default: RFC 8785 JCS of the object
without
signature, signature base64url).
rsa-pss-sha512 (RFC 9421 section 3.3.1, RSA keys of at least 2048
bits) under the TAP and Web Bot Auth profiles; TAP’s sample code names an
rsa-pss-sha256 algorithm that is not in the RFC 9421 registry and is not
accepted.
The Grantex consent record object
grantexConsentRecord is a Grantex extension carried beside the TAP objects:
the granted Grantex commerce consent the agent acts under (consent id,
merchant, agent, approved scopes, amount cap, consent text version, approval
and expiry), bound to the message nonce. It carries no principal identifier.
The relying party checks the consent with Grantex by its id.
The registry key directory
WithHTTP_SIGNATURE_DIRECTORY_ENABLED=true (default off) the auth service
serves GET /.well-known/http-message-signatures-directory
(draft-meunier-webbotauth-httpsig-directory-00) with media type
application/http-message-signatures-directory+json: a JWK Set of the usable
keys of agents whose developers opted in.
- Only keys that are usable now are listed: active, or rotated and inside their overlap; never pending, unproven or compromised; the agent must be active. Removing a key from the directory is how it is deactivated.
- Only P-256 (
ecdsa-p256-sha256) and Ed25519 (ed25519) keys are listed. - Each entry has
kid= its RFC 7638 thumbprint,use: "sig",nbfand, for a rotated key,exp. - The response carries
Content-DigestandCache-Control: public, max-age=300.
"@authority";req and content-digest, with
tag="grantex-registry-directory" and the platform kid from
/.well-known/jwks.json. A relying party that trusts the registry can check
that signature. A client that strictly applies the draft ignores keys
without their own signature; it should resolve these agents through the
registry lookup instead. An operator that hosts its own directory signs it
per key with signDirectoryResponse / sign_directory_response.
Signature-Agent on Grantex agent requests
An agent that wants Web Bot Auth relying parties to find its key adds aweb-bot-auth signature beside the Grantex one and names the registry as its
Signature-Agent:
sig1; Web Bot Auth verifiers read sig2 and fetch
the directory from the Signature-Agent origin.
Scheme agent ids
Card networks identify registered agents with their own identifiers. WithREGISTRY_SCHEME_AGENT_IDS_ENABLED=true (default off), an accredited
issuer’s agent attestation may carry them:
- The schemes are
visa_tapandmastercard_agent_pay. The identifiers are opaque, scheme-scoped strings of 1 to 256 characters. Neither scheme publishes an identifier format (TAP keys an agent by thekeyidof its key store; Mastercard Agent Pay’s wire details are not public), so the registry never parses or validates them beyond length. - A relying party finds the agent with
GET /v1/registry/agents?scheme=visa_tap&scheme_agent_id=tap-agent-0001. The answer is the usual minimised lookup, and each counted attestation shows thescheme_agent_idsit carries. /.well-known/agent-registry.jsonnames the schemes, each withid_format: "opaque", and theagent_by_scheme_agent_idlookup template.
Scheme token binding on the payment capability
A buyer agent’s payment can be bound to a token a scheme or provider holds: a network token (visa, mastercard), a UPI AutoPay mandate
(upi_autopay) or a payment provider’s tokenised instrument
(provider_token, for example on the Plural rail). The
mandate_capability artifact, which already says a provider-owned payment
capability exists, may carry that binding as token_binding:
token_refis an opaque reference to the token the scheme or provider holds, never the token and never an account number: a run of 13 to 19 digits is refused.- The binding must sit inside the capability: the same buyer agent,
merchants within its
merchant_scope, the same currency, a limit no higher than itsmax_amount, and no expiry after the artifact’s. Anything else is refused withtoken_binding_invalid. - Grantex describes and checks the binding; it never executes it. The relying party’s executor (AgenticOrg’s Plural executor, for example) calls the scheme or provider.
parseSchemeTokenBinding and
checkTokenBindingWithinCapability in @grantex/sdk, and the same module in
the auth service.
KYA tier on the Agent Passport
The Agent Passport can carry a KYA tier mapped from the agent’s registry trust marks through an operator-configured table, pending the scheme specifications. See MPP Agent Passport.HTTP 402 payments: challenges, receipts and commitment evidence
- MPP uses the “Payment” HTTP authentication scheme
(draft-ryan-httpauth-payment-01):
WWW-Authenticate: Payment …on the 402,Authorization: Payment <base64url JSON>on the retry,Payment-Receipton success.@grantex/mppimplements the challenge binding, the credential checks, the receipt, the problem details and an Express middleware. - x402 v2 uses
PAYMENT-REQUIRED,PAYMENT-SIGNATUREandPAYMENT-RESPONSE.@grantex/x402pays through them and reads the settlement receipt. - Commitment evidence.
POST /v1/commerce/oacp/commitment-evidence/settlement-receipts(AgenticOrg service token, scopecommerce.oacp.commitment_evidence.write, allow-listed tenants) binds a successful x402 settlement or MPP receipt to a commitment as a signedcommitment_evidenceartifact on the OACP status list:commitment_type: "settlement_receipt_reference", the artifacts the commitment relied on (issued, unrevoked, same tenant and merchant), and the receipt’ssha-256over its RFC 8785 form with the network or method and the transaction or reference. The payer is never copied. Neither receipt form is signed, so the artifact recordsreceipt_verification: "reported_not_verified_by_grantex". It is idempotent per commitment: the same receipt returns the same artifact, another receipt is409 commitment_receipt_conflict; a failed settlement is422 settlement_not_successful.