Independent verification
Re-verify a device-signed payment yourself. No account required.
Yebo's core claim is that approval evidence outlives the vendor, including us. Below is a payment approval signed by the approver's own passkey, Yebo's gateway key, the approver's public key, an evidence bundle, and the verifier. Prove the claim without trusting us.
Sample: a test approval made by a software passkey in a local Yebo gateway, with a test identity and a test gateway key. Production artifacts have the same format; verify them with the gateway's published key. The payment is 150 USD to sample-vendor and ran as a dry run: no money moved. Per-payment device signing is live and has been exercised in production with a real device; these files are a test so that no real person's identifiers are published. Everything on this page works offline. The verifier makes no network calls, needs no API key, and never contacts Yebo. If Yebo disappeared tomorrow, this procedure would still work.
Step by step
Verify a device-signed payment approval
Three steps, one command. You need Node.js 18 or newer, nothing else: the commands run the open-source npm package yebo-verify, pinned to 0.2.0 as shown. Versions before 0.2.0 cannot read device-signed artifacts, so the commands pin 0.2.0.
- 1
Download the artifact and the two public keys
sample-mandate.json: the mandate artifact for a 150 USD payment to sample-vendor, approved by the test identity user:sample-approver with its passkey. sample-gateway-key.pem: the public key of the (test) Yebo gateway that countersigned the record. sample-approver-key.jwk: the approver's registered passkey public key (P-256 JWK). - 2
Run the verifier
In a terminal, in the folder where you downloaded the three files:npx yebo-verify@0.2.0 sample-mandate.json --gateway-key sample-gateway-key.pem --require-hardware --approver-key sample-approver-key.jwk
--require-hardwarefails the check unless the approver's own device signed the payment.--approver-keypins the key that must have made that signature. Add--explainfor a plain-language explanation of every field. - 3
Read the output
This is the verifier's actual output on the sample files:
YEBO MANDATE VERIFICATION artifact sample-mandate.json key sample-gateway-key.pem (Yebo gateway key) approver sample-approver-key.jwk (pinned approver key) RESULT: PASS - the approver's own device signed exactly this payment, and Yebo's gateway countersigned the record. Field breakdown action payment amount 150 USD payee sample-vendor requested by user:sample-approver approver passkey:user:sample-approver approval type human_device policy version sha256:d01a6c9d2614f735dc65… approved at 2026-10-09T03:18:10.059Z valid window 2026-10-09T03:18:10.050Z → 2026-10-09T03:33:10.050Z mandate id 1e999a0f-2bd8-42f8-8aa8-fe16e803017c approver device SIGNED (WebAuthn assertion over this payment) Yebo gateway sigVALID (ECDSA P-256 / SHA-256) Checks [PASS] Artifact structure All required mandate and approval fields are present. [PASS] Public key Key fingerprint c0fab81305d6e928… accepted for verification. [PASS] Mandate integrity Recomputed mandate hash 3456d13ddf4e0339… matches the hash signed at approval. [PASS] Policy binding The policy hash in the mandate matches the policy hash the approver signed. [PASS] Signed approval fields artifact_version 2.0: the approver signature covers approved_by, mandate_hash, policy_hash, timestamp, algorithm, key_fingerprint. Editing the approver name or any of these fields fails the signature check. [PASS] Yebo gateway signature Yebo's gateway signed the approval record (approver, approval type, mandate hash, policy hash, timestamp, algorithm, key fingerprint, device key fingerprint) with its published key. This is Yebo's counter-signature, not the approver's. [PASS] Approver device signature (WebAuthn) The approver's own device (passkey:user:sample-approver) signed SHA-256 of exactly this payment and approver (WebAuthn, user verified) under the credential key 3ed058baf3db478b…. [PASS] Pinned approver key The device signature was made with the pinned approver key (fingerprint 3ed058baf3db478b…). [PASS] Approval inside validity window Approved at 2026-10-09T03:18:10.059Z, inside the mandate's validity window (2026-10-09T03:18:10.050Z to 2026-10-09T03:33:10.050Z).
In plain words
What each check proves
Each line of the output answers one question an auditor would ask about this payment.
The approver's own passkey signed a hash of this exact payment (amount, payee, requesting agent, validity window) and of the approver's identity, with user verification. Change one cent, the payee or the approver and this check fails.
Yebo's gateway signed the approval record with its published key. This is Yebo's counter-signature, never the approver's: it shows the record is the one the gateway issued, unaltered.
The device signature was made with the key you supplied, not just any key carried inside the artifact. For a real payment, take the approver's registered passkey public key from your organisation's own records, not from the artifact.
The approval was recorded between the mandate's issued_at and expires_at. An approval outside the window fails.
The verifier recomputes the mandate's content hash and checks it against the hash that was signed, and checks the policy hash in force at approval. The tampered sample below fails here.
In the evidence bundle, the gateway-signed execution receipt carries the mandate hash and a reference to this approval's signature, so it points back to exactly this device-signed approval. The bundle's signed manifest covers every file in it.
The part that matters
Now try to break it
Verification you cannot break is verification you cannot trust. This artifact is the same mandate, with the amount changed from 150 to 1500 after approval. Run the same command and watch it fail.
sample-mandate-tampered.json: download it into the same folder and run:
npx yebo-verify@0.2.0 sample-mandate-tampered.json --gateway-key sample-gateway-key.pem --require-hardware --approver-key sample-approver-key.jwk
YEBO MANDATE VERIFICATION artifact sample-mandate-tampered.json key sample-gateway-key.pem (Yebo gateway key) approver sample-approver-key.jwk (pinned approver key) RESULT: FAIL - this artifact does not verify. Field breakdown action payment amount 1500 USD payee sample-vendor requested by user:sample-approver approver passkey:user:sample-approver approval type human_device policy version sha256:d01a6c9d2614f735dc65… approved at 2026-10-09T03:18:10.059Z valid window 2026-10-09T03:18:10.050Z → 2026-10-09T03:33:10.050Z mandate id 1e999a0f-2bd8-42f8-8aa8-fe16e803017c approver device INVALID Yebo gateway sigVALID (ECDSA P-256 / SHA-256) Checks [PASS] Artifact structure All required mandate and approval fields are present. [PASS] Public key Key fingerprint c0fab81305d6e928… accepted for verification. [FAIL] Mandate integrity The mandate contents do NOT match what was approved. Recomputed hash 2d0a8546c2aed61f… differs from the signed hash 3456d13ddf4e0339…. One or more of these fields has been altered since approval: mandate_id, subject_identity, counterparty_identity, capability, policy_hash, nonce, issued_at, expires_at, amount, currency. [PASS] Policy binding The policy hash in the mandate matches the policy hash the approver signed. [PASS] Signed approval fields artifact_version 2.0: the approver signature covers approved_by, mandate_hash, policy_hash, timestamp, algorithm, key_fingerprint. Editing the approver name or any of these fields fails the signature check. [PASS] Yebo gateway signature Yebo's gateway signed the approval record (approver, approval type, mandate hash, policy hash, timestamp, algorithm, key fingerprint, device key fingerprint) with its published key. This is Yebo's counter-signature, not the approver's. [FAIL] Approver device signature (WebAuthn) WebAuthn assertion does NOT verify for this mandate and approver: the authenticator signed a different challenge: clientDataJSON.challenge does not equal SHA-256 of what this evidence says was approved. [PASS] Pinned approver key The device signature was made with the pinned approver key (fingerprint 3ed058baf3db478b…). [PASS] Approval inside validity window Approved at 2026-10-09T03:18:10.059Z, inside the mandate's validity window (2026-10-09T03:18:10.050Z to 2026-10-09T03:33:10.050Z). What did not verify: - tampered mandate - the contents differ from what the approver signed - bad hardware approval - the WebAuthn assertion does not verify over what this evidence says was approved
Both signatures on the record are still authentic, but the mandate no longer matches what was signed: the content hash differs, and the approver's device signature no longer covers this payment. Verification fails and says exactly why. Try it yourself: change the payee, the approver, or one cent of the amount and re-run. Every edit fails.
Also try a different approver key: generate any other P-256 key and pass it as --approver-key. The verifier fails with an approver key mismatch.
Evidence bundle
Verify the whole record: approval, receipt and audit trail
The evidence bundle is what the gateway exports for a payment: the execution receipt (a dry run, so no money moved), the mandate record, the device-signed mandate artifact and the audit events, sealed by one gateway-signed manifest.
- 1
Download the bundle
sample-evidence-bundle.json, into the same folder as the two keys. - 2
Run the verifier in bundle mode
npx yebo-verify@0.2.0 bundle sample-evidence-bundle.json --gateway-key sample-gateway-key.pem --require-hardware --approver-key sample-approver-key.jwk
YEBO EVIDENCE BUNDLE VERIFICATION bundle sample-evidence-bundle.json gateway key sample-gateway-key.pem approver key sample-approver-key.jwk RESULT: PASS - every check verified. Checks [PASS] Bundle structure Bundle contains 4 artifact(s) and a signed manifest. [PASS] Gateway public key Gateway key fingerprint c0fab81305d6e928… accepted for verification. [PASS] Per-artifact digests All 4 artifact content digest(s) recompute to their manifest values. [PASS] Manifest root hash Root hash cda6e4329747e18d… recomputes from the per-artifact digests. [PASS] Manifest signature ECDSA P-256 signature over the root hash is valid under the supplied gateway key. [PASS] Contained execution receipts All 1 execution receipt(s) verify under the gateway key; 1 of them chain-verified against mandate artifacts in this bundle. [PASS] Artifact structure (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) All required mandate and approval fields are present. [PASS] Public key (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) Key fingerprint c0fab81305d6e928… accepted for verification. [PASS] Mandate integrity (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) Recomputed mandate hash 3456d13ddf4e0339… matches the hash signed at approval. [PASS] Policy binding (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) The policy hash in the mandate matches the policy hash the approver signed. [PASS] Signed approval fields (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) artifact_version 2.0: the approver signature covers approved_by, mandate_hash, policy_hash, timestamp, algorithm, key_fingerprint. Editing the approver name or any of these fields fails the signature check. [PASS] Yebo gateway signature (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) Yebo's gateway signed the approval record (approver, approval type, mandate hash, policy hash, timestamp, algorithm, key fingerprint, device key fingerprint) with its published key. This is Yebo's counter-signature, not the approver's. [PASS] Approver device signature (WebAuthn) (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) The approver's own device (passkey:user:sample-approver) signed SHA-256 of exactly this payment and approver (WebAuthn, user verified) under the credential key 3ed058baf3db478b…. [PASS] Pinned approver key (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) The device signature was made with the pinned approver key (fingerprint 3ed058baf3db478b…). [PASS] Approval inside validity window (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) Approved at 2026-10-09T03:18:10.059Z, inside the mandate's validity window (2026-10-09T03:18:10.050Z to 2026-10-09T03:33:10.050Z).
sample-evidence-bundle-tampered.json: the same bundle with the execution receipt's amount changed from 150 to 1500.
npx yebo-verify@0.2.0 bundle sample-evidence-bundle-tampered.json --gateway-key sample-gateway-key.pem --require-hardware --approver-key sample-approver-key.jwk
YEBO EVIDENCE BUNDLE VERIFICATION bundle sample-evidence-bundle-tampered.json gateway key sample-gateway-key.pem approver key sample-approver-key.jwk RESULT: FAIL - this does not verify. Checks [PASS] Bundle structure Bundle contains 4 artifact(s) and a signed manifest. [PASS] Gateway public key Gateway key fingerprint c0fab81305d6e928… accepted for verification. [FAIL] Per-artifact digests Artifact content does NOT match its manifest digest - the content was altered after the bundle was sealed: execution-receipt-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json (manifest b9fc969dc3e9816f…, recomputed 290c067d23144988…). [PASS] Manifest root hash Root hash cda6e4329747e18d… recomputes from the per-artifact digests. [PASS] Manifest signature ECDSA P-256 signature over the root hash is valid under the supplied gateway key. [PASS] Contained execution receipts All 1 execution receipt(s) verify under the gateway key; 1 of them chain-verified against mandate artifacts in this bundle. [PASS] Artifact structure (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) All required mandate and approval fields are present. [PASS] Public key (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) Key fingerprint c0fab81305d6e928… accepted for verification. [PASS] Mandate integrity (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) Recomputed mandate hash 3456d13ddf4e0339… matches the hash signed at approval. [PASS] Policy binding (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) The policy hash in the mandate matches the policy hash the approver signed. [PASS] Signed approval fields (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) artifact_version 2.0: the approver signature covers approved_by, mandate_hash, policy_hash, timestamp, algorithm, key_fingerprint. Editing the approver name or any of these fields fails the signature check. [PASS] Yebo gateway signature (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) Yebo's gateway signed the approval record (approver, approval type, mandate hash, policy hash, timestamp, algorithm, key fingerprint, device key fingerprint) with its published key. This is Yebo's counter-signature, not the approver's. [PASS] Approver device signature (WebAuthn) (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) The approver's own device (passkey:user:sample-approver) signed SHA-256 of exactly this payment and approver (WebAuthn, user verified) under the credential key 3ed058baf3db478b…. [PASS] Pinned approver key (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) The device signature was made with the pinned approver key (fingerprint 3ed058baf3db478b…). [PASS] Approval inside validity window (mandate-artifact-1e999a0f-2bd8-42f8-8aa8-fe16e803017c.json) Approved at 2026-10-09T03:18:10.059Z, inside the mandate's validity window (2026-10-09T03:18:10.050Z to 2026-10-09T03:33:10.050Z). What did not verify: - tampered bundle - artifact content does not match its manifest digest
The receipt's amount is not one of the receipt's own signed fields; the receipt is bound to the amount through its mandate hash, which points to the device-signed mandate. Inside a bundle, the edit is caught by the signed manifest, which no longer matches the altered file.
Field reference
What each field is, and why an auditor cares
The artifact (version 2.0) has three parts: the mandate (what was asked), the approval (who approved it, signed by their device and countersigned by Yebo), and the gateway key reference. In this sample the identity is a test identity.
The action that was authorized, here payment. An approval for one action cannot be reused for another.
The exact amount approved. Covered by the mandate hash that the approver's device signed: altering it after approval fails verification. This is the field the tampered sample changes.
Who the payment is to. Also covered by the signed hash: the payee cannot be swapped after approval.
The identity the payment was requested under. The approval below records who authorized it.
The approver's identity. In artifact version 2.0 it is signed, by Yebo's gateway and inside the approver's own device signature, so an edited approver fails. Match it to your delegation of authority.
The WebAuthn assertion from the approver's passkey over SHA-256 of { payload, mandate_hash, approver }, with the credential's public key. This is the approver's own signature.
ECDSA P-256 signature by Yebo's gateway over the approval record. Checked with the gateway key named in gateway_key.key_id, which the gateway publishes.
A digest of the exact policy configuration in force at approval time. Lets you confirm which control governed the item.
A random value consumed at execution. Prevents the same approval from being replayed for a second payment.
Mandates are short-lived: a per-payment approval is bound to one request and must happen inside this window.
Testing procedure
How to test this as an approval control
The same four steps you would apply to any approval control, except that step 3 requires no vendor cooperation.
- 1
Sample
Select a sample of disbursements over threshold from the payment population, exactly as with any approval control. - 2
Obtain
For each sampled item, obtain its mandate artifact (the gateway serves it at /mandate-artifact/<mandate id>) and its evidence bundle (/evidence/export). Execution runs in dry-run mode today, so these are dry-run receipts and no money moves. - 3
Re-verify
Run npx yebo-verify@0.2.0 against each artifact or bundle with the gateway's published key (listed at the gateway's /authorization-receipt/keys endpoint) and, with --approver-key, the approver's registered passkey public key from your organisation's own records. No access to the AP platform, the payment rail, or Yebo is required. The exit code is machine-readable (0 = pass), so a full sample can be verified in one scripted pass. - 4
Match authority
Match approval.approved_by against the delegation of authority in effect at the payment date, and match mandate_id against the system of record for the item.
The verifier is the open-source npm package yebo-verify (MIT license): view the package on npm. It uses only Node's built-in crypto, and every check can be re-implemented in any language, so you do not have to trust our binary either.
Practitioner validation
Did this hold up?
If you test approval controls for a living, your answer to these two questions is the test we care about.