Developers · Approval requests
Verify a decision's signed receipt
Every decision on a request comes with a signed receipt that your system can verify without depending on the service.
Step 1: the request digest
Recompute SHA-256("AUTHGUARD\0INTENT\0V1\0" ‖ intentJson) over the UTF-8 bytes of intentJson exactly as received (the prefix holds three NUL bytes). It must equal intentDigest.
Step 2: the receipt digest
Check receipt.payloadDigestSha256 == SHA-256(receipt.payload).
Step 3: the receipt content
Parse receipt.payload (schema authguard.intent.decision-receipt, version 1) and check:
- the expected
intentId,tenantId,clientIdandsubjectUserId; intentDigestSha256equals step 1;decisionisapprovedordenied;factorispasskeyordevice(a phone decision);decidedAtEpochSecondslies between the request's issue and expiry.
The SDKs do steps 1 to 3 with verifyIntentDigest and checkReceipt (TypeScript) or verify_intent_digest and check_receipt (Python).
Step 4: the signatures
receipt.signatureEnvelope holds two signatures, ML-DSA-65 and Ed25519, over the intent_decision_receipt domain, with the request identifier as object and receipt.payload as canonical bytes. Verify both with the installation's public keys. At this stage the operator delivers those public keys on request, through a separate channel; compare the SHA-256 fingerprints you are given.
When to verify
Before running an approved operation, and whenever you must prove to an auditor that the operation was approved by that person, with that factor, at that time.
Error codes in this article
Was this page helpful?
Thank you. Your answer stays in this browser; nothing is sent.
Sorry about that. Try:
- searching for the exact text of the message or the error code
- the error code index
- asking your organization's administrator