@openeudi/openid4vp 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -33
- package/dist/index.cjs +458 -264
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -21
- package/dist/index.d.ts +73 -21
- package/dist/index.js +446 -265
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @openeudi/openid4vp
|
|
2
2
|
|
|
3
|
-
OpenID4VP credential parsing and validation for EUDI Wallets. Supports SD-JWT VC and mDOC credential formats with issuer trust verification, expiry checking,
|
|
3
|
+
OpenID4VP credential parsing and validation for EUDI Wallets. Supports SD-JWT VC and mDOC credential formats with issuer trust verification, expiry checking, selective disclosure claim extraction, and DCQL-based credential matching.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -33,39 +33,105 @@ if (result.valid) {
|
|
|
33
33
|
|
|
34
34
|
## Authorization requests
|
|
35
35
|
|
|
36
|
-
Build an OpenID4VP authorization request URI to send to an EUDI Wallet:
|
|
36
|
+
Build an OpenID4VP authorization request URI to send to an EUDI Wallet. The request carries a DCQL query ([Digital Credentials Query Language](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-digital-credentials-query-l)) describing the credentials you want:
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
|
-
import { createAuthorizationRequest } from "@openeudi/openid4vp";
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
nonce: crypto.randomUUID(),
|
|
39
|
+
import { buildHaipQuery, createAuthorizationRequest } from "@openeudi/openid4vp";
|
|
40
|
+
|
|
41
|
+
const query = buildHaipQuery({
|
|
42
|
+
credentialId: "pid",
|
|
43
|
+
format: "dc+sd-jwt",
|
|
44
|
+
vctValues: ["https://pid.eu/v1"],
|
|
45
|
+
claims: ["age_over_18"],
|
|
47
46
|
});
|
|
48
47
|
|
|
48
|
+
const request = createAuthorizationRequest(
|
|
49
|
+
{
|
|
50
|
+
clientId: "x509_san_dns:verifier.example.com",
|
|
51
|
+
responseUri: "https://verifier.example.com/cb",
|
|
52
|
+
nonce: crypto.randomUUID(),
|
|
53
|
+
},
|
|
54
|
+
query,
|
|
55
|
+
);
|
|
56
|
+
|
|
49
57
|
console.log(request.uri);
|
|
50
58
|
// openid4vp://authorize?response_type=vp_token&response_mode=direct_post&...
|
|
51
59
|
|
|
52
60
|
console.log(request.state);
|
|
53
61
|
// auto-generated UUID unless you provide one
|
|
54
62
|
|
|
55
|
-
console.log(request.
|
|
56
|
-
//
|
|
63
|
+
console.log(request.dcqlQuery);
|
|
64
|
+
// the DCQL query embedded in the request
|
|
57
65
|
```
|
|
58
66
|
|
|
59
67
|
### AuthorizationRequestInput
|
|
60
68
|
|
|
61
|
-
| Field
|
|
62
|
-
|
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
| Field | Type | Required | Description |
|
|
70
|
+
| -------------- | -------- | -------- | ---------------------------------------------- |
|
|
71
|
+
| `clientId` | `string` | Yes | Your verifier client identifier |
|
|
72
|
+
| `responseUri` | `string` | Yes | Callback URL for the wallet response |
|
|
73
|
+
| `nonce` | `string` | Yes | Challenge nonce for replay protection |
|
|
74
|
+
| `state` | `string` | No | Session state (auto-generated UUID if omitted) |
|
|
75
|
+
|
|
76
|
+
The second argument is a DCQL `Query` object. Use `buildHaipQuery` (below) or hand-construct one and validate it via `validateHaipQuery`.
|
|
77
|
+
|
|
78
|
+
## HAIP helpers
|
|
79
|
+
|
|
80
|
+
For the High Assurance Interoperability Profile (HAIP) commonly used by EUDI Wallets:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { buildHaipQuery, validateHaipQuery } from "@openeudi/openid4vp";
|
|
84
|
+
|
|
85
|
+
// Build a HAIP-compliant DCQL query:
|
|
86
|
+
const query = buildHaipQuery({
|
|
87
|
+
credentialId: "pid",
|
|
88
|
+
format: "dc+sd-jwt",
|
|
89
|
+
vctValues: ["https://pid.eu/v1"],
|
|
90
|
+
claims: ["age_over_18", "given_name"],
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Or validate a hand-built DCQL query:
|
|
94
|
+
validateHaipQuery(query); // throws HaipValidationError on violation
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Supported formats: `dc+sd-jwt` and `mso_mdoc`. Other formats (e.g., `jwt_vc_json`) will be rejected by the validator.
|
|
98
|
+
|
|
99
|
+
Known EUDI doctypes auto-namespace their claim paths (e.g., `org.iso.18013.5.1.mDL` → claims under `org.iso.18013.5.1`). Unknown doctypes use the full doctype string as the namespace.
|
|
100
|
+
|
|
101
|
+
## Verifying presentations against a query
|
|
102
|
+
|
|
103
|
+
Use `verifyPresentation` to combine crypto/structural verification with DCQL matching in a single call:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { verifyPresentation } from "@openeudi/openid4vp";
|
|
107
|
+
|
|
108
|
+
const result = await verifyPresentation(vpToken, query, {
|
|
109
|
+
nonce,
|
|
110
|
+
trustedCertificates,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (result.valid) {
|
|
114
|
+
console.log("matched claims:", result.match.matches[0].extractedClaims);
|
|
115
|
+
console.log("submission:", result.submission);
|
|
116
|
+
} else {
|
|
117
|
+
console.warn("mismatch reasons:", result.match.unmatched);
|
|
118
|
+
// each entry: { queryId, reason, detail? }
|
|
119
|
+
// reason ∈ { format_mismatch, vct_mismatch, doctype_mismatch, missing_claims, trusted_authority_mismatch, no_credential_found }
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Mismatches return `valid: false` — they do not throw. Only crypto/structural failures (malformed VP tokens, invalid signatures, expired credentials) and malformed DCQL queries throw exceptions.
|
|
124
|
+
|
|
125
|
+
### ParseOptions / VerifyOptions
|
|
126
|
+
|
|
127
|
+
Both `parsePresentation` and `verifyPresentation` accept:
|
|
128
|
+
|
|
129
|
+
- `nonce` (required) — the nonce bound into the VP token at creation time.
|
|
130
|
+
- `trustedCertificates` (required) — the set of trusted issuer certificates for crypto verification.
|
|
131
|
+
- `audience?` — expected audience.
|
|
132
|
+
- `allowedAlgorithms?` — restrict signature algorithms.
|
|
133
|
+
- `skipTrustCheck?` — skip trust-list checks (dev/test only).
|
|
134
|
+
- `expectedDocType?` — for mDOC verification.
|
|
69
135
|
|
|
70
136
|
## Supported formats
|
|
71
137
|
|
|
@@ -118,14 +184,6 @@ class MyCustomParser implements ICredentialParser {
|
|
|
118
184
|
}
|
|
119
185
|
```
|
|
120
186
|
|
|
121
|
-
### ParseOptions
|
|
122
|
-
|
|
123
|
-
| Field | Type | Description |
|
|
124
|
-
| --------------------- | -------------- | ------------------------------------ |
|
|
125
|
-
| `trustedCertificates` | `Uint8Array[]` | Issuer certificates to trust |
|
|
126
|
-
| `nonce` | `string` | Expected nonce for replay protection |
|
|
127
|
-
| `skipTrustCheck` | `boolean?` | Explicit opt-in to skip the trust check. When omitted or `false`, `trustedCertificates` must be non-empty — otherwise parsing throws `MalformedCredentialError`. Use `true` for demo/mock environments. |
|
|
128
|
-
|
|
129
187
|
### PresentationResult
|
|
130
188
|
|
|
131
189
|
| Field | Type | Description |
|
|
@@ -145,6 +203,7 @@ class MyCustomParser implements ICredentialParser {
|
|
|
145
203
|
| `UnsupportedFormatError` | Unsupported credential format: `{format}` | Token format is not SD-JWT VC or mDOC |
|
|
146
204
|
| `MalformedCredentialError` | Credential structure is malformed | Token cannot be decoded or is structurally invalid |
|
|
147
205
|
| `NonceValidationError` | Nonce does not match expected value | Key binding JWT nonce does not match |
|
|
206
|
+
| `HaipValidationError` | HAIP query constraint violated | DCQL query fails `validateHaipQuery` |
|
|
148
207
|
|
|
149
208
|
```ts
|
|
150
209
|
import { MalformedCredentialError, ExpiredCredentialError } from "@openeudi/openid4vp";
|
|
@@ -162,7 +221,7 @@ try {
|
|
|
162
221
|
|
|
163
222
|
This library implements the **verifier side** of OpenID4VP for SD-JWT VC and mDOC credentials.
|
|
164
223
|
|
|
165
|
-
**What is implemented (v0.
|
|
224
|
+
**What is implemented (v0.4.x):**
|
|
166
225
|
|
|
167
226
|
- SD-JWT VC: full cryptographic verification (issuer JWT signature via x5c, disclosure hashes, key binding JWT signature + sd_hash, nonce check)
|
|
168
227
|
- mDOC / ISO 18013-5 *mso_mdoc* format: CBOR decoding and claim extraction
|
|
@@ -171,7 +230,10 @@ This library implements the **verifier side** of OpenID4VP for SD-JWT VC and mDO
|
|
|
171
230
|
- mDOC IssuerSignedItem digest verification
|
|
172
231
|
- `expectedDocType` ParseOptions to lock the credential type
|
|
173
232
|
- Algorithm allowlist (ES256/384/512 — ECDSA only per EUDI policy)
|
|
174
|
-
- Authorization request builder
|
|
233
|
+
- Authorization request builder with DCQL query
|
|
234
|
+
- DCQL query matching via [@openeudi/dcql](https://www.npmjs.com/package/@openeudi/dcql)
|
|
235
|
+
- HAIP query build/validate helpers
|
|
236
|
+
- `verifyPresentation` — combined crypto + DCQL match in one call
|
|
175
237
|
- Certificate trust check via byte-equality against a caller-supplied trusted set
|
|
176
238
|
|
|
177
239
|
**What is NOT yet implemented** (planned for follow-up releases — do not assume compliance in production until present):
|
|
@@ -179,18 +241,21 @@ This library implements the **verifier side** of OpenID4VP for SD-JWT VC and mDO
|
|
|
179
241
|
- X.509 certificate chain building and validation beyond leaf-byte-equality
|
|
180
242
|
- EU List of Trusted Lists (LOTL) / ETSI TL resolution
|
|
181
243
|
- Certificate revocation (CRL, OCSP)
|
|
182
|
-
- DCQL query / credential matching — see [@openeudi/dcql](https://www.npmjs.com/package/@openeudi/dcql)
|
|
183
|
-
- OpenID4VP HAIP (High Assurance Interoperability Profile) constraint validation
|
|
184
244
|
- OpenID Foundation conformance test suite integration
|
|
185
245
|
- SIOPv2 (Self-Issued OpenID Provider) identity flows
|
|
186
246
|
|
|
187
|
-
EUDI Architecture Reference Framework (ARF) alignment: tracks OpenID4VP 1.0 final.
|
|
247
|
+
EUDI Architecture Reference Framework (ARF) alignment: tracks OpenID4VP 1.0 final. Full ARF 1.4+ profile compliance will be added before a stable 1.0.
|
|
188
248
|
|
|
189
249
|
## Related packages
|
|
190
250
|
|
|
191
251
|
- **[@openeudi/core](https://www.npmjs.com/package/@openeudi/core)** -- Framework-agnostic EUDI Wallet verification protocol engine with session management and QR code generation.
|
|
252
|
+
- **[@openeudi/dcql](https://www.npmjs.com/package/@openeudi/dcql)** -- DCQL query matching engine used internally by `verifyPresentation`.
|
|
192
253
|
- **[eIDAS Pro](https://eidas-pro.eu)** -- Managed verification service with admin dashboard, webhook integrations, and plugin support for WooCommerce and Shopify.
|
|
193
254
|
|
|
255
|
+
## Migration from 0.3.x
|
|
256
|
+
|
|
257
|
+
See [CHANGELOG.md](./CHANGELOG.md) for the full 0.4.0 migration guide (breaking changes and new APIs).
|
|
258
|
+
|
|
194
259
|
## License
|
|
195
260
|
|
|
196
261
|
[Apache 2.0](./LICENSE)
|