OID4VP protocol
When a bank needs to verify a customer's identity using their EUDI Wallet, both systems need to speak the same language. OpenID for Verifiable Presentations (OID4VP) is that language. It defines how Relying Parties request credentials from wallets and how wallets deliver verified responses back.
The Truvity EUDIW Connector implements OID4VP as the core protocol for all credential verification flows.
Why OID4VP matters
Before OID4VP, there was no standard way for digital wallets and verification systems to exchange credentials. Each implementation used proprietary protocols, making cross-border and cross-vendor interoperability impossible.
OID4VP defines message structures, transaction flows, and an interface specification for credential presentation, building on concepts from OAuth 2.0. Because every EUDI Wallet and every Relying Party implements the same protocol, a wallet issued in one member state works with a Relying Party in any other member state.
The EUDI ecosystem also supports proximity presentation flows using ISO/IEC 18013-5 for scenarios where the user and the Relying Party are physically co-located. OID4VP covers remote flows only.
Request delivery through the Digital Credentials API
In the EUDI ecosystem, OID4VP presentation requests don't travel directly from the Relying Party to the wallet. Instead, the W3C Digital Credentials API (for browser-based flows) or the platform API (for app-based flows) mediates the interaction. The browser and operating system handle wallet selection, origin verification, and session binding on behalf of the user.
This architecture means the Relying Party never needs to know which wallet the user has installed. The browser and OS route the request to the appropriate wallet and ensure the response comes back through a secure, authenticated channel.
Protocol flow
The OID4VP flow is asynchronous. Your app starts a verification session, the user responds through their wallet, and the connector delivers the result to your system through a callback.
Request creation
When your app creates a presentation request, the connector builds a signed authorization request. This request specifies:
- The credentials and attributes you need, expressed as a DCQL query
- A cryptographic nonce that uniquely identifies this session
- Optional transactional data that binds the presentation to a specific action (for example, a payment authorization)
The connector signs the request using your X.509 certificate, which allows the wallet to verify your identity as a registered Relying Party.
Request delivery
How the request reaches the user's wallet depends on the scenario:
- Same-device flow: The connector provides an
openid4vp://deep link URI. The browser or platform API (such as the W3C Digital Credentials API) forwards the request to the wallet. The operating system handles wallet selection if the device hosts multiple wallets. This applies when both your app and the wallet run on the same device. - Cross-device flow: The connector provides an
openid4vp://URI that your app renders as a QR code. The user scans the QR code with their phone. In the EUDI ecosystem, the browser may initiate a secure tunnel using the FIDO CTAP 2.2 hybrid flow, where the device emits a BLE advertisement as a proximity check to mitigate relay attacks. After the tunnel is established, the OID4VP request is sent through it. This is the typical scenario when the user is on a desktop and their wallet is on their phone.
In both cases, the wallet validates the signed request before proceeding.
Trust verification
Before showing the request to the user, the wallet authenticates your Relying Party. It validates your X.509 certificate chain against the trusted list of the relevant jurisdiction.
If the certificate is invalid or revoked, the wallet blocks the request. This mechanism protects users from presenting credentials to unauthorized parties.
User consent and selective disclosure
The wallet displays who is requesting data and what data is requested. The user must explicitly consent before any data leaves the wallet.
Wallets enforce selective disclosure. If you only need to verify a user's age, you can request just the age_over_18 attribute (if defined in the attestation scheme) rather than the full date of birth. The wallet shares only the specific attributes you request and withholds everything else.
Response submission
After the user consents, the wallet constructs a verifiable presentation containing:
- The disclosed attributes approved by the user
- A key binding proof that demonstrates legitimate possession of the credential
- The original issuer signatures on the credential
The wallet encrypts this response using an ephemeral public key from the authorization request and submits it to the connector. Response encryption is mandated by the HAIP profile, which constrains OID4VP for the EUDI ecosystem.
Verification
The connector decrypts the response and validates it:
- Checks the credential structure and format
- Verifies the issuer's signature and trust chain
- Confirms key binding (proof of possession)
- Checks revocation status
- Validates that any transactional data was correctly signed
Result delivery
After verification, the connector delivers the result to your app through a callback. The connector uses an ephemeral data model—it processes credentials in memory and does not persist user data. You receive the verified attributes in a Presented Credentials Event and must capture them immediately.
For details on the event statuses your callback can receive, see the callback events reference.
Security mechanisms
Nonce
Every presentation request includes a unique nonce. The wallet signs this nonce as part of its response, which serves two purposes:
- Replay prevention: A captured response can't be reused because the nonce is single-use
- Session binding: The nonce ties the wallet's response to the specific request that initiated it
Ephemeral encryption
Each session uses a unique encryption key pair. The connector includes the public key in the authorization request, and the wallet encrypts its response with it. This ensures that even if an attacker intercepts network traffic, the credential data remains confidential. The connector deletes the encryption keys after the session completes.
Transactional data
For high-value operations, you can include transactional data in the presentation request. The wallet displays this data to the user and signs over it, creating a cryptographic binding between the user's consent and the specific action. This prevents a presentation intended for one transaction from being replayed in a different context.
Specification version
The EUDI ecosystem references OpenID for Verifiable Presentations 1.0 as identified in the ARF's Set of Technical Specifications.
Further reading
- HAIP profile—the security profile that constrains OID4VP for the EUDI ecosystem
- DCQL query language—how to specify which credentials and attributes to request
- Connector architecture—how the connector implements the protocol