Discuss a project
menu

Verifiable credentials: from issuer to holder to verifier

Follow a credential through an illustrative contractor-access system, with trust decisions, replay protection and a practical test plan.

A verifiable credential lets one party make a claim that another party can check. The interesting engineering question is what your application should do after that check succeeds.

The W3C model separates three roles: an issuer creates credentials, a holder manages and presents them, and a verifier evaluates them. The holder and the person or entity described by a credential need not be the same. Cryptographic verification does not establish that every claim is true or that an issuer is suitable for your use case. Those decisions belong to your trust model. W3C Verifiable Credentials Data Model 2.0

Start with a decision your service needs to make

Consider an illustrative contractor portal. A training provider issues evidence that a contractor completed a safety course. The contractor presents that evidence when requesting access to a worksite. This is a design example, not a su.engineering client case study.

The portal needs to answer a narrow question: does this person satisfy this site's training requirement today? It does not need the contractor's home address or complete employment history.

Write that decision down before choosing a wallet or credential format. For this example, the acceptance policy might require an approved training provider, a particular course, a current validity period and a presentation tied to the person requesting access. A valid credential from an unrelated provider should still fail that policy.

Follow the credential through the system

Training provider       Contractor wallet       Worksite portal
      |                        |                       |
      |--- issue credential -->|                       |
      |                        |<-- request evidence --|
      |                        |--- presentation ----->|
      |                        |                       |-- check proof
      |                        |                       |-- apply policy
      |                        |<-- access decision ---|

At issuance, the provider needs a reliable process for connecting course completion to the intended recipient. At presentation, the portal needs a reliable process for connecting the response to its pending access request. Treat these as separate boundaries in the implementation and in the test plan.

A useful application interface returns a structured result rather than a single verified: true flag. For example, separate a failed proof check, an unaccepted provider, a missing course and unavailable status information. This lets the UI tell a contractor what to do next without exposing raw credential contents in an error log.

Bind the response to the request

OpenID4VP defines a protocol for requesting and presenting credentials. Its security requirements include replay protections and checks on the returned credentials and presentations. Implement the requirements of the selected credential format and profile, including nonce and intended-verifier binding where required; a successful signature check by itself is insufficient. OpenID4VP 1.0, security considerations

For the portal example, make request state short-lived and consume it atomically when accepting a response. A browser refresh or two simultaneous submissions should not produce two independent admissions from one pending request. Keep the application session associated with that request explicit rather than inferring it from whichever user happens to be logged in when a callback arrives.

Make privacy part of the acceptance policy

Selective disclosure depends on the credential format and securing mechanism; it is not an automatic property of every credential. The W3C model also identifies correlation risks from identifiers, signatures and status checks. Requesting fewer fields is useful, but does not by itself make presentations unlinkable. W3C privacy considerations

For this portal, review the database schema alongside the credential request. If the request asks only for course eligibility but the backend stores the entire presentation, the storage design defeats the narrower request. Consider recording the decision, policy version and minimal audit evidence appropriate to the deployment. Document the reason for each retained field and who can read it.

Test rejection paths before connecting more wallets

Use synthetic credentials and identities in a test environment. For our example, the minimum useful test set includes:

  • A correct course from an unaccepted provider: reject under the trust policy.
  • An accepted provider with the wrong course: reject under the access policy.
  • A presentation for a previous request: reject rather than starting a new session.
  • Two concurrent submissions of one response: accept at most once.
  • An unavailable status dependency: follow a documented failure policy instead of silently treating the credential as current.
  • A wallet sending additional attributes: prevent those fields from entering routine logs or analytics.

Record which wallet, credential format, library version and policy version produced each result. A green test against one combination is evidence about that combination; it is not proof of ecosystem-wide interoperability.

Bring the trust model into the project brief

Before building, agree who may issue accepted credentials, which decision the verifier makes, how wallet loss is handled, and what happens when dependencies are unavailable. These questions make a project brief more useful than a requirement to “support SSI.”

We work with teams on identity and EUDI engineering. If your next system needs credentials, wallets or verification, what shall we build together?

Working on something similar? Talk to us

← all writing