@owf/eudi-attestation-schema 0.1.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 +161 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# @owf/eudi-attestation-schema
|
|
2
|
+
|
|
3
|
+
> **⚠️ Experimental:** This package is experimental. The underlying ETSI specification is not yet finalized, and this implementation is used to test the upcoming approach. Breaking changes are possible until the specification is stable.
|
|
4
|
+
|
|
5
|
+
SDK for creating, signing, and validating attestation schema metadata (SchemaMeta) per the **EUDI TS11 Catalogue of Attestations** specification.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This SDK implements the TS11 data model for the EUDI Catalogue of Attestations, enabling:
|
|
10
|
+
|
|
11
|
+
- **Create SchemaMeta objects** using a fluent builder API
|
|
12
|
+
- **Validate SchemaMeta documents** against the TS11 schema
|
|
13
|
+
- **Sign SchemaMeta as JWS** with private keys or custom signers (HSM/KMS)
|
|
14
|
+
|
|
15
|
+
## Specification Reference
|
|
16
|
+
|
|
17
|
+
- [TS11 — Interfaces and formats for catalogue of attributes and catalogue of attestations](https://github.com/eu-digital-identity-wallet/eudi-doc-standards-and-technical-specifications/blob/main/docs/technical-specifications/ts11-interfaces-and-formats-for-catalogue-of-attributes-and-catalogue-of-schemes.md)
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @owf/eudi-attestation-schema
|
|
23
|
+
# or
|
|
24
|
+
pnpm add @owf/eudi-attestation-schema
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Creating a SchemaMeta Object
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import {
|
|
33
|
+
schemaMeta,
|
|
34
|
+
schemaURI,
|
|
35
|
+
trustAuthority,
|
|
36
|
+
} from '@owf/eudi-attestation-schema';
|
|
37
|
+
|
|
38
|
+
const meta = schemaMeta()
|
|
39
|
+
.id('https://gym.example.com/attestations/gym-membership-card')
|
|
40
|
+
.version('1.0.0')
|
|
41
|
+
.rulebookURI('https://example.com/rulebooks/gym-membership/1.0.0.md')
|
|
42
|
+
.rulebookIntegrity('sha256-cJe/IG7DijmXd2FpecyWJVnZ9EuKKprly5auxGm1uIw=')
|
|
43
|
+
.addTrustAuthority(
|
|
44
|
+
trustAuthority()
|
|
45
|
+
.frameworkType('etsi_tl')
|
|
46
|
+
.value('https://example.com/trust-lists/gym-members.jws')
|
|
47
|
+
.isLoTE(true)
|
|
48
|
+
.build()
|
|
49
|
+
)
|
|
50
|
+
.attestationLoS('iso_18045_basic')
|
|
51
|
+
.bindingType('key')
|
|
52
|
+
.addFormat('dc+sd-jwt')
|
|
53
|
+
.addSchemaURI(
|
|
54
|
+
schemaURI()
|
|
55
|
+
.format('dc+sd-jwt')
|
|
56
|
+
.uri('https://example.com/schemas/gym-membership.dc+sd-jwt.json')
|
|
57
|
+
.integrity('sha256-M8H+reBt9Nr/s8CRicJrthAnk7UdWyTyONW0N8Z/Axw=')
|
|
58
|
+
.build()
|
|
59
|
+
)
|
|
60
|
+
.build();
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Validating a SchemaMeta Document
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import {
|
|
67
|
+
validateSchemaMeta,
|
|
68
|
+
assertValidSchemaMeta,
|
|
69
|
+
} from '@owf/eudi-attestation-schema';
|
|
70
|
+
|
|
71
|
+
// Returns { valid: boolean, errors: ValidationError[] }
|
|
72
|
+
const result = validateSchemaMeta(untrustedData);
|
|
73
|
+
if (!result.valid) {
|
|
74
|
+
console.error('Validation errors:', result.errors);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Or use the assertion form (throws SchemaMetaException on invalid input)
|
|
78
|
+
assertValidSchemaMeta(untrustedData);
|
|
79
|
+
// untrustedData is now typed as SchemaMeta
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Signing a SchemaMeta as JWS
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { ES256 } from '@owf/crypto';
|
|
86
|
+
import { signSchemaMeta, schemaMeta, schemaURI } from '@owf/eudi-attestation-schema';
|
|
87
|
+
|
|
88
|
+
const { privateKey } = await ES256.generateKeyPair();
|
|
89
|
+
const signer = await ES256.getSigner(privateKey);
|
|
90
|
+
|
|
91
|
+
const meta = schemaMeta()
|
|
92
|
+
.version('1.0.0')
|
|
93
|
+
.rulebookURI('https://example.com/rulebook.md')
|
|
94
|
+
.attestationLoS('iso_18045_basic')
|
|
95
|
+
.bindingType('key')
|
|
96
|
+
.addFormat('dc+sd-jwt')
|
|
97
|
+
.addSchemaURI(
|
|
98
|
+
schemaURI()
|
|
99
|
+
.format('dc+sd-jwt')
|
|
100
|
+
.uri('https://example.com/schema.json')
|
|
101
|
+
.build()
|
|
102
|
+
)
|
|
103
|
+
.build();
|
|
104
|
+
|
|
105
|
+
const signed = await signSchemaMeta({
|
|
106
|
+
schemaMeta: meta,
|
|
107
|
+
keyId: 'catalog-signer-2025',
|
|
108
|
+
certificates: [pemCertificate],
|
|
109
|
+
signer,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
console.log(signed.jws); // Compact JWS string
|
|
113
|
+
console.log(signed.iat); // Issued-at timestamp (epoch seconds)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Verifying a Signed SchemaMeta
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { ES256 } from '@owf/crypto';
|
|
120
|
+
import { verifySchemaMeta } from '@owf/eudi-attestation-schema';
|
|
121
|
+
|
|
122
|
+
const verifier = await ES256.getVerifier(publicKey);
|
|
123
|
+
|
|
124
|
+
const { header, payload, iat } = await verifySchemaMeta({
|
|
125
|
+
jws: signed.jws,
|
|
126
|
+
verifier,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
console.log(payload.version); // '1.0.0'
|
|
130
|
+
console.log(header.kid); // 'catalog-signer-2025'
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Data Model
|
|
134
|
+
|
|
135
|
+
### SchemaMeta (Main Class)
|
|
136
|
+
|
|
137
|
+
| Field | Required | Type | Description |
|
|
138
|
+
|---|---|---|---|
|
|
139
|
+
| `id` | No | `string` | Unique identifier for the attestation schema |
|
|
140
|
+
| `version` | Yes | `string` | Schema version (SemVer) |
|
|
141
|
+
| `rulebookURI` | Yes | `string` (URL) | URI of the Attestation Rulebook |
|
|
142
|
+
| `rulebookIntegrity` | No | `string` | W3C SRI integrity metadata for the rulebook |
|
|
143
|
+
| `trustedAuthorities` | No | `TrustAuthority[]` | Trust anchors for attestation issuers |
|
|
144
|
+
| `attestationLoS` | Yes | `AttestationLoS` | Level of security |
|
|
145
|
+
| `bindingType` | Yes | `BindingType` | Cryptographic binding type |
|
|
146
|
+
| `supportedFormats` | Yes | `AttestationFormat[]` | Supported attestation formats |
|
|
147
|
+
| `schemaURIs` | Yes | `SchemaURI[]` | Schema URIs per format |
|
|
148
|
+
|
|
149
|
+
### Enumerations
|
|
150
|
+
|
|
151
|
+
**AttestationFormat**: `dc+sd-jwt`, `mso_mdoc`, `jwt_vc_json`, `jwt_vc_json-ld`, `ldp_vc`
|
|
152
|
+
|
|
153
|
+
**AttestationLoS**: `iso_18045_high`, `iso_18045_moderate`, `iso_18045_enhanced-basic`, `iso_18045_basic`
|
|
154
|
+
|
|
155
|
+
**BindingType**: `claim`, `key`, `biometric`, `none`
|
|
156
|
+
|
|
157
|
+
**FrameworkType**: `aki`, `etsi_tl`, `openid_federation`
|
|
158
|
+
|
|
159
|
+
## License
|
|
160
|
+
|
|
161
|
+
Apache-2.0
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@owf/eudi-attestation-schema",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SDK for creating, signing, and validating attestation schema metadata (SchemaMeta) per EUDI TS11 Catalogue of Attestations",
|
|
5
|
+
"experimental": true,
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"exports": "./src/index.ts",
|
|
11
|
+
"homepage": "https://github.com/openwallet-foundation-labs/identity-common-ts/tree/main/packages/eudi-attestation-schema",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/openwallet-foundation-labs/identity-common-ts",
|
|
15
|
+
"directory": "packages/eudi-attestation-schema"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"module": "./dist/index.mjs",
|
|
19
|
+
"types": "./dist/index.d.mts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": "./dist/index.mjs",
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"eudi",
|
|
27
|
+
"attestation",
|
|
28
|
+
"schema",
|
|
29
|
+
"catalog",
|
|
30
|
+
"wallet",
|
|
31
|
+
"jwt",
|
|
32
|
+
"schema-meta",
|
|
33
|
+
"ts11"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsdown src/index.ts --format esm --dts --sourcemap"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@owf/crypto": "workspace:*",
|
|
40
|
+
"@owf/identity-common": "workspace:*",
|
|
41
|
+
"zod": "^4.3.6"
|
|
42
|
+
}
|
|
43
|
+
}
|