@verana-labs/vs-agent-plugin-openid4vc 1.12.0-oidc4vc.7 → 2.0.0-dev.66
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 +127 -157
- package/build/config.d.ts +12 -3
- package/build/config.js +115 -237
- package/build/config.js.map +1 -1
- package/build/index.d.ts +19 -12
- package/build/index.js +36 -16
- package/build/index.js.map +1 -1
- package/build/nestjs/OpenId4VcPlugin.js +18 -43
- package/build/nestjs/OpenId4VcPlugin.js.map +1 -1
- package/build/nestjs/V2OpenId4VcCredentialExchangesController.d.ts +19 -0
- package/build/nestjs/V2OpenId4VcCredentialExchangesController.js +161 -0
- package/build/nestjs/V2OpenId4VcCredentialExchangesController.js.map +1 -0
- package/build/nestjs/V2OpenId4VcPresentationsController.d.ts +19 -0
- package/build/nestjs/V2OpenId4VcPresentationsController.js +147 -0
- package/build/nestjs/V2OpenId4VcPresentationsController.js.map +1 -0
- package/build/nestjs/V2OpenId4VcSigningCertificatesController.d.ts +17 -0
- package/build/nestjs/V2OpenId4VcSigningCertificatesController.js +58 -0
- package/build/nestjs/V2OpenId4VcSigningCertificatesController.js.map +1 -0
- package/build/nestjs/dto/credential-exchange.dto.d.ts +31 -0
- package/build/nestjs/dto/credential-exchange.dto.js +150 -0
- package/build/nestjs/dto/credential-exchange.dto.js.map +1 -0
- package/build/nestjs/dto/index.d.ts +3 -0
- package/build/nestjs/dto/index.js +20 -0
- package/build/nestjs/dto/index.js.map +1 -0
- package/build/nestjs/dto/presentation.dto.d.ts +56 -0
- package/build/nestjs/dto/presentation.dto.js +234 -0
- package/build/nestjs/dto/presentation.dto.js.map +1 -0
- package/build/nestjs/dto/signing-certificate.dto.d.ts +8 -0
- package/build/nestjs/dto/signing-certificate.dto.js +40 -0
- package/build/nestjs/dto/signing-certificate.dto.js.map +1 -0
- package/build/nestjs/mappers.d.ts +5 -0
- package/build/nestjs/mappers.js +31 -0
- package/build/nestjs/mappers.js.map +1 -0
- package/build/sdk/setupOpenId4Vc.d.ts +8 -12
- package/build/sdk/setupOpenId4Vc.js +94 -80
- package/build/sdk/setupOpenId4Vc.js.map +1 -1
- package/build/services/CertificateService.d.ts +5 -22
- package/build/services/CertificateService.js +90 -84
- package/build/services/CertificateService.js.map +1 -1
- package/build/services/IssuerService.d.ts +31 -44
- package/build/services/IssuerService.js +133 -107
- package/build/services/IssuerService.js.map +1 -1
- package/build/services/VerifierService.d.ts +37 -44
- package/build/services/VerifierService.js +150 -226
- package/build/services/VerifierService.js.map +1 -1
- package/build/services/presentationRequest.d.ts +51 -0
- package/build/services/presentationRequest.js +67 -0
- package/build/services/presentationRequest.js.map +1 -0
- package/build/services/presentationVerification.d.ts +12 -0
- package/build/services/presentationVerification.js +13 -0
- package/build/services/presentationVerification.js.map +1 -0
- package/build/trust/CertificateTrust.d.ts +1 -4
- package/build/trust/CertificateTrust.js +10 -15
- package/build/trust/CertificateTrust.js.map +1 -1
- package/build/trust/keyBinding.d.ts +4 -17
- package/build/trust/keyBinding.js +34 -144
- package/build/trust/keyBinding.js.map +1 -1
- package/build/trust/types.d.ts +5 -16
- package/build/trust/types.js +8 -0
- package/build/trust/types.js.map +1 -1
- package/build/types.d.ts +21 -51
- package/build/types.js +3 -0
- package/build/types.js.map +1 -1
- package/build/utils/isRecord.d.ts +1 -0
- package/build/utils/isRecord.js +7 -0
- package/build/utils/isRecord.js.map +1 -0
- package/build/utils/serviceDisplay.d.ts +8 -0
- package/build/utils/serviceDisplay.js +11 -0
- package/build/utils/serviceDisplay.js.map +1 -0
- package/package.json +10 -8
- package/build/nestjs/CertificatesController.d.ts +0 -11
- package/build/nestjs/CertificatesController.js +0 -58
- package/build/nestjs/CertificatesController.js.map +0 -1
- package/build/nestjs/IssuerController.d.ts +0 -8
- package/build/nestjs/IssuerController.js +0 -66
- package/build/nestjs/IssuerController.js.map +0 -1
- package/build/nestjs/VerifierController.d.ts +0 -8
- package/build/nestjs/VerifierController.js +0 -66
- package/build/nestjs/VerifierController.js.map +0 -1
- package/build/nestjs/dto.d.ts +0 -7
- package/build/nestjs/dto.js +0 -34
- package/build/nestjs/dto.js.map +0 -1
- package/build/services/StatusListService.d.ts +0 -42
- package/build/services/StatusListService.js +0 -132
- package/build/services/StatusListService.js.map +0 -1
- package/build/trust/TrustClient.d.ts +0 -12
- package/build/trust/TrustClient.js +0 -120
- package/build/trust/TrustClient.js.map +0 -1
- package/build/trust/verdict.d.ts +0 -2
- package/build/trust/verdict.js +0 -13
- package/build/trust/verdict.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,194 +1,164 @@
|
|
|
1
|
-
# OpenID4VC
|
|
1
|
+
# OpenID4VC
|
|
2
2
|
|
|
3
|
-
`@verana-labs/vs-agent-plugin-openid4vc`
|
|
3
|
+
`@verana-labs/vs-agent-plugin-openid4vc` gives VS Agent an OpenID4VCI issuer and an OpenID4VP
|
|
4
|
+
verifier for `dc+sd-jwt` credentials. It ships in every `vs-agent` image and turns on when the
|
|
5
|
+
operator sets `OID4VC_CONFIG_FILE_LOCATION`. Nothing else enables it.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
What it does:
|
|
6
8
|
|
|
7
|
-
- pre-authorized OpenID4VCI issuance of `dc+sd-jwt` credentials
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
9
|
+
- pre-authorized OpenID4VCI issuance of `dc+sd-jwt` credentials, valid until they expire: the
|
|
10
|
+
agent hosts no status list yet, so a credential carries no `status` claim and the `ttlSeconds`
|
|
11
|
+
of its offer is its only bound;
|
|
12
|
+
- OpenID4VP requests in DCQL (`direct_post.jwt`, `x509_hash` or DID client identifier) or, for a
|
|
13
|
+
wallet that predates DCQL, Presentation Exchange (`direct_post`);
|
|
14
|
+
- the `/v2/openid4vc` Administration API scope: create an offer or a request, then list, read
|
|
15
|
+
and delete.
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
Out of scope, and not implied: W3C VCDM credentials, ISO mdoc, authorization-code issuance,
|
|
18
|
+
wallet-attestation trust-list distribution, production PKI onboarding, formal conformance.
|
|
14
19
|
|
|
15
|
-
##
|
|
20
|
+
## Not wired up yet
|
|
16
21
|
|
|
17
|
-
|
|
22
|
+
The configuration file the spec defines carries no credential type and no trust setting, and the
|
|
23
|
+
agent derives none of them yet. So `createCredentialOffer` and `createPresentationRequest` answer
|
|
24
|
+
`404 UNKNOWN_ID` for every `jsonSchemaCredentialId`, `createCredentialOffer` answers it for every
|
|
25
|
+
`statusListId`, and reading a verified presentation answers the `RESOLVER_UNAVAILABLE` verdict.
|
|
26
|
+
Four issues carry the rest:
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
- [#710](https://github.com/verana-labs/vs-agent/issues/710): SD-JWT VC Type Metadata, served at
|
|
29
|
+
the spec path `/vt/vct/{credentialSchemaId}`;
|
|
30
|
+
- [#711](https://github.com/verana-labs/vs-agent/issues/711): credential types read from the VPR,
|
|
31
|
+
one per active issuer participant;
|
|
32
|
+
- [#712](https://github.com/verana-labs/vs-agent/issues/712): the verifier trust decision on the
|
|
33
|
+
eight steps the spec now defines, with no `trust` block anywhere;
|
|
34
|
+
- [#713](https://github.com/verana-labs/vs-agent/issues/713): status lists.
|
|
20
35
|
|
|
21
|
-
|
|
22
|
-
docker --context colima build \
|
|
23
|
-
--target vs-agent-openid4vc \
|
|
24
|
-
-t vs-agent-openid4vc:dev \
|
|
25
|
-
-f apps/vs-agent/Dockerfile .
|
|
36
|
+
## Enable it
|
|
26
37
|
|
|
27
|
-
|
|
38
|
+
```bash
|
|
39
|
+
docker run --rm \
|
|
28
40
|
--env-file ./env-vars \
|
|
29
|
-
-e
|
|
41
|
+
-e OID4VC_CONFIG_FILE_LOCATION=/run/config/openid4vc.json \
|
|
30
42
|
-v "$PWD/openid4vc.json:/run/config/openid4vc.json:ro" \
|
|
31
|
-
-p 3000:3000 \
|
|
32
|
-
-
|
|
33
|
-
vs-agent-openid4vc:dev
|
|
43
|
+
-p 3000:3000 -p 3001:3001 \
|
|
44
|
+
veranalabs/vs-agent
|
|
34
45
|
```
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
`env-vars` carries the normal VS Agent settings, with an `https://` `PUBLIC_API_BASE_URL`. The
|
|
48
|
+
location can also be an `https://` URL, which the agent fetches once at startup without following
|
|
49
|
+
a redirect. With Helm, put the JSON in `openid4vc.config`.
|
|
37
50
|
|
|
38
|
-
|
|
51
|
+
## Configuration file
|
|
39
52
|
|
|
40
|
-
|
|
53
|
+
The agent reads and validates the file at startup, and refuses to start when it cannot read the
|
|
54
|
+
location or validation fails. Keys are camelCase. Full reference: [[VSA-VTI-CFG-ENV-OID]](https://github.com/verana-labs/verana-spec/blob/main/v4/vs-agent/spec.md#vsa-vti-cfg-env-oid-openid4vc).
|
|
41
55
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
"verifier": {
|
|
55
|
-
"id": "development-verifier",
|
|
56
|
-
"displayName": "Development Verifier",
|
|
57
|
-
"signing": {
|
|
58
|
-
"development": {
|
|
59
|
-
"enabled": true,
|
|
60
|
-
"commonName": "Local OpenID4VC Verifier"
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
"trust": {
|
|
65
|
-
"resolverUrl": "https://resolver.example/v1/trust",
|
|
66
|
-
"timeoutMs": 5000,
|
|
67
|
-
"allowedDidWebHosts": ["issuer.example"],
|
|
68
|
-
"credentialIssuerCertificates": [],
|
|
69
|
-
"developmentCertificateFingerprints": [
|
|
70
|
-
"SHA256:0000000000000000000000000000000000000000000000000000000000000000"
|
|
71
|
-
]
|
|
72
|
-
},
|
|
73
|
-
"credentialConfigurations": [
|
|
74
|
-
{
|
|
75
|
-
"id": "employee",
|
|
76
|
-
"format": "dc+sd-jwt",
|
|
77
|
-
"vct": "https://agent.example/oid4vc/vct/employee",
|
|
78
|
-
"name": "Employee credential",
|
|
79
|
-
"description": "Development employee credential",
|
|
80
|
-
"vtjscId": "https://trust.example/vtjsc/employee",
|
|
81
|
-
"claims": ["given_name", "family_name", "role"],
|
|
82
|
-
"disclosureFrame": ["given_name", "family_name", "role"],
|
|
83
|
-
"ttlSeconds": 3600
|
|
84
|
-
}
|
|
85
|
-
],
|
|
86
|
-
"verifierPolicies": [
|
|
87
|
-
{
|
|
88
|
-
"id": "employee-check",
|
|
89
|
-
"credentialConfigurationId": "employee",
|
|
90
|
-
"requestedClaims": ["given_name", "family_name", "role"]
|
|
91
|
-
}
|
|
92
|
-
]
|
|
93
|
-
}
|
|
94
|
-
```
|
|
56
|
+
Every key is OPTIONAL and `{}` is a valid file. The agent runs both capabilities whenever
|
|
57
|
+
`OID4VC_CONFIG_FILE_LOCATION` is set; the file only carries what the agent cannot derive by
|
|
58
|
+
itself.
|
|
59
|
+
|
|
60
|
+
| Key | Requirement |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| `issuer` | OPTIONAL. Holds `signing`, `walletAttestationCertificates` and `keyAttestationCertificates`, each OPTIONAL. |
|
|
63
|
+
| `issuer.walletAttestationCertificates` | X.509 roots of the accepted wallet providers. When non-empty, the agent requires a wallet attestation. |
|
|
64
|
+
| `issuer.keyAttestationCertificates` | Roots for OpenID4VCI key attestations. When non-empty, the issuer metadata requires a key attestation on every proof. Absent, the `attestation` proof type is neither advertised nor accepted. |
|
|
65
|
+
| `verifier` | OPTIONAL. Holds an OPTIONAL `signing`. |
|
|
95
66
|
|
|
96
|
-
|
|
67
|
+
The identifier segment of each capability is fixed: `issuer` and `verifier`, so the public paths
|
|
68
|
+
read `/oid4vci/issuer/...` and `/oid4vp/verifier/...`. The file declares neither, and the agent
|
|
69
|
+
refuses to start on an `issuer.id` or a `verifier.id`, as it does on any other unknown key.
|
|
97
70
|
|
|
98
|
-
The
|
|
71
|
+
The display name and the logo the agent publishes come from the ECS Service credential it holds
|
|
72
|
+
about its own DID; no key of the file overrides them.
|
|
99
73
|
|
|
100
|
-
|
|
101
|
-
- the auto-published public key must remain present in the DID document under `assertionMethod` for issuance and `authentication` for verifier request signing.
|
|
74
|
+
### Signing modes
|
|
102
75
|
|
|
103
|
-
|
|
76
|
+
**Development signing** (`signing` absent): the agent generates and persists a self-signed P-256
|
|
77
|
+
certificate for the capability, with a common name and a DNS SAN derived from
|
|
78
|
+
`PUBLIC_API_BASE_URL` and a DID URI SAN with the agent DID, and publishes the public key in its
|
|
79
|
+
DID Document before it completes startup (`assertionMethod` for the issuer, `authentication` for
|
|
80
|
+
the verifier). A peer verifier still has to pin the fingerprint that
|
|
81
|
+
`GET /v2/openid4vc/signing-certificates` returns. Unsuitable for production.
|
|
104
82
|
|
|
105
|
-
|
|
83
|
+
**Configured signing** (`signing.configured`): `certificateChain` (a non-self-signed leaf first,
|
|
84
|
+
then the intermediates and the root) and the `privateJwk` P-256 key of the leaf. The leaf must
|
|
85
|
+
carry the agent DID as a URI SAN. The agent never publishes a configured key; the operator
|
|
86
|
+
publishes it under `assertionMethod` or `authentication` before startup. Keep the file out of
|
|
87
|
+
source control, logs and image layers.
|
|
106
88
|
|
|
107
|
-
|
|
89
|
+
### Development example
|
|
108
90
|
|
|
109
91
|
```json
|
|
110
|
-
{
|
|
111
|
-
"signing": {
|
|
112
|
-
"configured": {
|
|
113
|
-
"certificateChain": [
|
|
114
|
-
"MIIB...REDACTED_LEAF_BASE64...",
|
|
115
|
-
"MIIC...REDACTED_INTERMEDIATE_BASE64...",
|
|
116
|
-
"MIIC...REDACTED_ROOT_BASE64..."
|
|
117
|
-
],
|
|
118
|
-
"privateJwk": {
|
|
119
|
-
"kty": "EC",
|
|
120
|
-
"crv": "P-256",
|
|
121
|
-
"x": "REDACTED",
|
|
122
|
-
"y": "REDACTED",
|
|
123
|
-
"d": "REDACTED",
|
|
124
|
-
"alg": "ES256",
|
|
125
|
-
"kid": "issuer-signing-key"
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
"trust": {
|
|
130
|
-
"resolverUrl": "https://resolver.example/v1/trust",
|
|
131
|
-
"timeoutMs": 5000,
|
|
132
|
-
"allowedDidWebHosts": ["issuer.example"],
|
|
133
|
-
"credentialIssuerCertificates": ["MIIC...REDACTED_TRUSTED_ROOT_BASE64..."]
|
|
134
|
-
}
|
|
135
|
-
}
|
|
92
|
+
{}
|
|
136
93
|
```
|
|
137
94
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
`allowedDidWebHosts` is the explicit network trust boundary for issuer DIDs read from verified certificates. Only exact `did:web` and `did:webvh` hosts on this operator-managed list are resolved. Do not populate it from a peer request or certificate. Credo owns the underlying fetch and redirect behavior, so an allowlisted host must have operator-trusted DNS and redirect behavior. Loopback, private, link-local, and unsupported DID targets are rejected before Credo resolution. Resolution returns after at most `timeoutMs`, which must not exceed 30000 milliseconds. The agent's own DID host is derived from `AGENT_PUBLIC_DID` and does not need to be repeated in this list.
|
|
95
|
+
A file with no key at all runs both capabilities under development signing.
|
|
141
96
|
|
|
142
|
-
|
|
97
|
+
## Administration API
|
|
143
98
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
| `issuer` | Optional when `verifier` is present. Defines `id`, `displayName`, and exactly one signing mode. |
|
|
147
|
-
| `issuer.requireWalletAttestation` | Optional. When `true`, `walletAttestationCertificates` must contain locally configured X.509 roots. Trust-list distribution is not implemented. |
|
|
148
|
-
| `verifier` | Optional when `issuer` is present. Defines `id`, `displayName`, and exactly one signing mode. |
|
|
149
|
-
| `trust` | Required by the verifier. Defines the HTTPS Verana resolver, a 1–30000 ms resolver timeout, exact allowed issuer DID web hosts, valid issuer CA roots, and optional development leaf fingerprints in `SHA256:` plus 64 lowercase hex format. |
|
|
150
|
-
| `credentialConfigurations` | Array of stable IDs, `dc+sd-jwt` format, VCT and VTJSC URLs, display fields, allowed claims, disclosure frame, and a 60–31,536,000 second lifetime. |
|
|
151
|
-
| `verifierPolicies` | Array mapping a policy ID to one credential configuration and a subset of its claims. |
|
|
99
|
+
Every method lives under `/v2/openid4vc`, behind the Admin API authentication of the agent, and
|
|
100
|
+
answers in the v2 error envelope. Without `OID4VC_CONFIG_FILE_LOCATION`, every path answers `404`.
|
|
152
101
|
|
|
153
|
-
|
|
102
|
+
| Method | Path | Notes |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| `createCredentialOffer` | `POST /credential-offer` | `jsonSchemaCredentialId`, `claims`, `ttlSeconds` (60 to 7776000), optional `statusListId` and `statusListIndex` together. Returns `credentialExchangeId` and `url`. `404 UNKNOWN_ID`, `400 INVALID_INPUT`. Answers `UNKNOWN_ID` for every credential type until #711 and for every status list until #713. |
|
|
105
|
+
| `listCredentialExchanges` | `GET /credential-exchanges` | Filters `jsonSchemaCredentialId`, `state`. Keyset pagination. |
|
|
106
|
+
| `getCredentialExchange` | `GET /credential-exchanges/{credentialExchangeId}` | `credentialExchangeId`, `jsonSchemaCredentialId`, `state`, `createdAt`, `updatedAt`, `expiresAt`, `errorMessage`. Never the claims, the offer URL or the pre-authorized code. |
|
|
107
|
+
| `deleteCredentialExchange` | `DELETE /credential-exchanges/{credentialExchangeId}` | `204`. Deletes the record only, never a credential that a wallet holds. |
|
|
108
|
+
| `createPresentationRequest` | `POST /presentation-request` | `jsonSchemaCredentialId`, optional `requestedClaims` (defaults to every claim of the type), optional `queryLanguage` (`dcql`, `presentation_exchange`), optional `requestSigner` (`x5c`, `did`). Returns `proofExchangeId` and `url`. `404 UNKNOWN_ID`, `400 INVALID_INPUT`, `409 INVALID_STATE`. Answers `UNKNOWN_ID` for every credential type until #711. |
|
|
109
|
+
| `listPresentations` | `GET /presentations` | Filters `jsonSchemaCredentialId`, `state`. Keyset pagination. |
|
|
110
|
+
| `getPresentation` | `GET /presentations/{proofExchangeId}` | Adds the stored `jsonSchemaCredentialId` and `requestedClaims` of the request, then `cryptographicVerified`, `accepted`, `trust` and `credential` once the wallet answered. |
|
|
111
|
+
| `deletePresentation` | `DELETE /presentations/{proofExchangeId}` | `204`. |
|
|
112
|
+
| `listSigningCertificates` | `GET /signing-certificates` | Bare array of `role`, `development`, `fingerprint`, `certificateChain`. Never a private key. |
|
|
154
113
|
|
|
155
|
-
|
|
114
|
+
Session states are credo's: `OfferCreated`, `OfferUriRetrieved`, `AuthorizationInitiated`,
|
|
115
|
+
`AuthorizationGranted`, `AccessTokenRequested`, `AccessTokenCreated`, `CredentialRequestReceived`,
|
|
116
|
+
`CredentialsPartiallyIssued`, `Completed`, `Error` for an issuance; `RequestCreated`,
|
|
117
|
+
`RequestUriRetrieved`, `ResponseVerified`, `Error` for a verification.
|
|
156
118
|
|
|
157
|
-
The
|
|
119
|
+
The agent stores `jsonSchemaCredentialId` and `requestedClaims` on the verification session when
|
|
120
|
+
it creates the request, and never infers either from the response of the wallet. A list never
|
|
121
|
+
decides: it reports the stored decision, and a verified session that nobody read yet shows
|
|
122
|
+
`cryptographicVerified: true` and `accepted: false` without `trust`.
|
|
158
123
|
|
|
159
|
-
|
|
160
|
-
| -------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
161
|
-
| Internal admin | `POST /v1/oid4vc/offers` | Plugin controller. Creates a pre-authorized offer from `credentialConfigurationId` and all configured claims. |
|
|
162
|
-
| Internal admin | `GET /v1/oid4vc/offers/:id` | Plugin controller. Returns safe issuance state only. |
|
|
163
|
-
| Internal admin | `POST /v1/oid4vc/verifier/requests` | Plugin controller. Creates a request from `policyId`. |
|
|
164
|
-
| Internal admin | `GET /v1/oid4vc/verifier/sessions/:id` | Plugin controller. Returns protocol state and the bounded trust result. |
|
|
165
|
-
| Internal admin | `GET /v1/oid4vc/certificates` | Plugin controller. Returns the configured roles' public signing certificates: leaf fingerprint (`SHA256:` pin format) and base64 chain. Never returns private keys. |
|
|
166
|
-
| Public | `GET /oid4vc/vct/:configurationId` | Plugin route. Returns configured SD-JWT VC type metadata, extended with `relatedJsonSchemaCredentialId` (the ecosystem VTJSC) so wallets can verify schema governance and issuer/verifier accreditation through the Verana resolver. |
|
|
167
|
-
| Public | dynamic paths below `/.well-known/*`, `/oid4vci/:issuerId/*`, and `/oid4vp/:verifierId/*` | Pinned Credo router. Serves issuer/OAuth metadata, returned offer and request URIs, and wallet token, credential, authorization-request, and authorization-response traffic. |
|
|
124
|
+
## Public endpoints
|
|
168
125
|
|
|
169
|
-
|
|
126
|
+
Served on the public listener, without Admin API authentication. A wallet follows the URLs the
|
|
127
|
+
Admin API and the metadata return; it never builds a path itself.
|
|
170
128
|
|
|
171
|
-
|
|
129
|
+
| Path | Purpose |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `/.well-known/openid-credential-issuer`, `/.well-known/oauth-authorization-server`, `/.well-known/jwt-vc-issuer` | Issuer and authorization-server metadata, also at the path-inserted forms. |
|
|
132
|
+
| `/oid4vci/issuer/...` | Token and credential traffic of the issuer capability. |
|
|
133
|
+
| `/oid4vp/verifier/...` | Authorization request and response traffic of the verifier capability. |
|
|
172
134
|
|
|
173
135
|
## Trust decision
|
|
174
136
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
##
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
137
|
+
There is none yet. Nothing configures a resolver URL, allowed `did:web` hosts, credential-issuer
|
|
138
|
+
roots or development fingerprints: the file rejects a `trust` block, and
|
|
139
|
+
[#712](https://github.com/verana-labs/vs-agent/issues/712) builds the decision on the eight steps
|
|
140
|
+
the spec now defines, on the indexer and on DID key binding, without one. Until it lands, a
|
|
141
|
+
verified presentation answers `cryptographicVerified: true`, `accepted: false` and the verdict
|
|
142
|
+
`RESOLVER_UNAVAILABLE`, and is never accepted.
|
|
143
|
+
|
|
144
|
+
What the agent still enforces before that point: credo verifies the OpenID4VP response, the
|
|
145
|
+
nonce, the audience, the holder binding, the SD-JWT disclosures and the signature, and the plugin
|
|
146
|
+
fails a presented credential that carries no numeric `exp`. The session then ends in `Error`.
|
|
147
|
+
|
|
148
|
+
## Wallet accommodations
|
|
149
|
+
|
|
150
|
+
The public router adapts a few responses to specific wallets, each one scoped as narrowly as the
|
|
151
|
+
wallet's behaviour allows: openid4vci-kt (EUDI reference wallet) accept header and
|
|
152
|
+
`key_attestations_required`; swiyu plain-JSON metadata and closed `ProofType` enum; wwWallet
|
|
153
|
+
`scope` and DPoP algorithms; NL Wallet certificate-bound signed metadata; MOSIP Inji EdDSA
|
|
154
|
+
request signing under the parallel did:web and Presentation Exchange details. Each lives next to
|
|
155
|
+
the code it changes, with a one-line note.
|
|
156
|
+
|
|
157
|
+
## Tests
|
|
158
|
+
|
|
159
|
+
`pnpm --filter @verana-labs/vs-agent-plugin-openid4vc exec vitest run` runs the unit tests and the
|
|
160
|
+
in-process end-to-end tests, which start real credo agents for the issuer, the holder and the
|
|
161
|
+
verifier and drive a pre-authorized issuance through to a stored holder-bound credential. The
|
|
162
|
+
presentation round trip comes back with #712, which gives the verifier a trust anchor for the
|
|
163
|
+
credential it receives. No external wallet or conformance evidence is recorded here; see the
|
|
164
|
+
Verana Playground for recorded wallet scenarios.
|
package/build/config.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import type { OpenId4VcCredentialConfiguration, OpenId4VcPluginOptions
|
|
2
|
-
export declare
|
|
1
|
+
import type { OpenId4VcConfigurationFile, OpenId4VcCredentialConfiguration, OpenId4VcPluginOptions } from './types';
|
|
2
|
+
export declare const ISSUER_CAPABILITY_ID = "issuer";
|
|
3
|
+
export declare const VERIFIER_CAPABILITY_ID = "verifier";
|
|
4
|
+
export declare const OFFER_TTL_SECONDS_MIN = 60;
|
|
5
|
+
export declare const OFFER_TTL_SECONDS_MAX = 7776000;
|
|
6
|
+
/** [VSA-VTI-CFG-ENV-OID] Validation of the OpenID4VC configuration file. */
|
|
7
|
+
export declare function parseOpenId4VcConfiguration(document: unknown): OpenId4VcConfigurationFile;
|
|
3
8
|
export declare function findCredentialConfiguration(options: Pick<OpenId4VcPluginOptions, 'credentialConfigurations'>, id: string): OpenId4VcCredentialConfiguration | undefined;
|
|
4
|
-
export declare function findVerifierPolicy(options: Pick<OpenId4VcPluginOptions, 'verifierPolicies'>, id: string): OpenId4VcVerifierPolicy | undefined;
|
|
5
9
|
export declare function parseOfferClaims(configuration: OpenId4VcCredentialConfiguration, input: unknown): Record<string, unknown>;
|
|
10
|
+
export declare function parseOfferTtlSeconds(input: unknown): number;
|
|
11
|
+
export declare function parseOfferIssuanceMetadata(configuration: OpenId4VcCredentialConfiguration, input: unknown): {
|
|
12
|
+
claims: Record<string, unknown>;
|
|
13
|
+
ttlSeconds: number;
|
|
14
|
+
};
|