A Buyer and an Attacker, each holding their own Ed25519 keypair, negotiate with a Supplier that holds a policy and a set of trust anchors. Every decision below comes from actually running that protocol on this request — nothing here is a recorded transcript.
PERMITTEDBeat 1 — accepted (within granted authority)
- asker
- Buyer did:key:z6MkmJS9DAtktY2imSHAvdLxP75GUCy21mY5JNg7u14MgAif
- asked for
- purchase-office-supplies, amount=150
policy — identity proven; credential, issuer trust, revocation, and scope all evaluated
R-purchase-office-suppliesoffice-supply purchases are permitted up to a ceiling of 500 (the credential's own granted scope already matches this ceiling)
credentialSubject.actionrequested purchase-office-suppliespermitted purchase-office-supplies
action "purchase-office-supplies" permitted under rule "R-purchase-office-supplies"; issuer did:key:z6MkoBFJK1xtv4CJUw15wDQyiERuYtdgqegYktLqAugBof4z; revocation checked and clean
REFUSED · over-scopeBeat 2 — refused (over scope)
- asker
- Buyer did:key:z6MkmJS9DAtktY2imSHAvdLxP75GUCy21mY5JNg7u14MgAif
- asked for
- purchase-office-supplies, amount=5000
policy — identity proven; credential, issuer trust, revocation, and scope all evaluated
credential:own-scopethe presented authority credential's own granted scope
scope.amountrequested 5000permitted 500
requested "amount" = 5000 exceeds the permitted maximum of 500 (source: the credential's own scope)
REFUSEDBeat 3 — refused (spoofed identity)
- asker
- Impostor claiming did:key:z6MkmJS9DAtktY2imSHAvdLxP75GUCy21mY5JNg7u14MgAif (Attacker's real DID is did:key:z6MkotzqXDYzaTDheYWH8WxdV6CqrNAcCHkdQisoz4NNrrpq)
- asked for
- purchase-office-supplies, amount=100, presenting the Buyer's real credential
claimed identitydid:key:z6MkmJS9DAtktY…u14MgAif
buyer's real DIDdid:key:z6MkmJS9DAtktY…u14MgAif
Character-for-character identical. Copying a public DID string is free — proving possession of the private key behind it is not, which is exactly what failed here, before the presented credential was ever examined.
proof of possession — refused before any credential was examined
gate:proof-of-possessionthe presenter must prove possession of the private key behind its claimed DID by signing this session's fresh challenge (M1); possessing or copying the DID string alone proves nothing
proof.signatureactual Signature verification failed for proof of possession of did:key:z6MkmJS9DAtktY2imSHAvdLxP75GUCy21mY5JNg7u14MgAif
did:key:z6MkmJS9DAtktY2imSHAvdLxP75GUCy21mY5JNg7u14MgAif did not prove possession of the private key behind that DID over this session's fresh challenge (Signature verification failed for proof of possession of did:key:z6MkmJS9DAtktY2imSHAvdLxP75GUCy21mY5JNg7u14MgAif) — a copied DID string proves nothing; only a signature nobody without the true private key could produce does, and this one does not verify against that DID's public key
REFUSED · untrusted-issuerBeat 4 — refused (forged credential)
- asker
- Attacker did:key:z6MkotzqXDYzaTDheYWH8WxdV6CqrNAcCHkdQisoz4NNrrpq
- asked for
- purchase-office-supplies, amount=1000, presenting a credential it minted for itself
policy — identity proven; credential, issuer trust, revocation, and scope all evaluated
gate:issuer-trustthe credential's issuer must be a configured trust anchor, or vouched for by one (M4)
issuerTrust.reason.kindactual self-issued
issuer did:key:z6MkotzqXDYzaTDheYWH8WxdV6CqrNAcCHkdQisoz4NNrrpq is the credential's own subject — self-issued authority is always refused
Honestly labelled: the attacker's own signature on this credential is genuinely valid. It is refused because the attacker is not a trust anchor this Supplier configured — a valid signature and a trusted issuer are different questions.