-
Notifications
You must be signed in to change notification settings - Fork 4
Support request byValue and byReference and presentationDefinition #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -104,6 +104,18 @@ logging: | |||||
verifier: | ||||||
# did to be used by the verifier. | ||||||
did: | ||||||
# identification of the verifier in communication with wallets | ||||||
clientIdentification: | ||||||
# identification used by the verifier when requesting authorization. Can be a did, but also methods like x509_san_dns | ||||||
id: | ||||||
# path to the signing key(in pem format) for request object. Needs to correspond with the id | ||||||
keyPath: | ||||||
# algorithm to be used for signing the request. Needs to match the signing key | ||||||
requestKeyAlgorithm: | ||||||
# depending on the id type, the certificate chain needs to be included in the object(f.e. in case of x509_san_dns) | ||||||
certificatePath: | ||||||
# supported modes for requesting authentication. in case of byReference and byValue, the clientIdentification needs to be properly configured | ||||||
supportedModes: ["urlEncoded", "byReference","byValue"] | ||||||
# address of the (ebsi-compliant) trusted-issuers-registry to be used for verifying the issuer of a received credential | ||||||
tirAddress: | ||||||
# Expiry(in seconds) of an authentication session. After that, a new flow needs to be initiated. | ||||||
|
@@ -118,6 +130,8 @@ verifier: | |||||
# * `baseContext`: validates that only the fields and values (when applicable)are present in the document. No extra fields are allowed (outside of credentialSubject). | ||||||
# Default is set to `none` to ensure backwards compatibility | ||||||
validationMode: | ||||||
# algorithm to be used for the jwt signatures - currently supported: RS256 and ES256, default is RS256 | ||||||
keyAlgorithm: | ||||||
|
||||||
# configuration of the service to retrieve configuration for | ||||||
configRepo: | ||||||
|
@@ -126,28 +140,57 @@ configRepo: | |||||
# static configuration for services | ||||||
services: | ||||||
# name of the service to be configured | ||||||
testService: | ||||||
# scope to be requested from the wallet | ||||||
scope: | ||||||
- VerifiableCredential | ||||||
- CustomerCredential | ||||||
# trusted participants endpoint configuration | ||||||
trustedParticipants: | ||||||
# the credentials type to configure the endpoint(s) for | ||||||
VerifiableCredential: | ||||||
- https://tir-pdc.ebsi.fiware.dev | ||||||
# the credentials type to configure the endpoint(s) for | ||||||
CustomerCredential: | ||||||
- https://tir-pdc.ebsi.fiware.dev | ||||||
# trusted issuers endpoint configuration | ||||||
trustedIssuers: | ||||||
# the credentials type to configure the endpoint(s) for | ||||||
VerifiableCredential: | ||||||
- https://tir-pdc.ebsi.fiware.dev | ||||||
# the credentials type to configure the endpoint(s) for | ||||||
CustomerCredential: | ||||||
- https://tir-pdc.ebsi.fiware.dev | ||||||
|
||||||
- id: testService | ||||||
# default scope for the service | ||||||
defaultOidcScope: "default" | ||||||
# the concrete scopes for the service, defining the trust for credentials and the presentation definition to be requested | ||||||
oidcScopes: | ||||||
# the concrete scope configuration | ||||||
default: | ||||||
# credentials and their trust configuration | ||||||
credentials: | ||||||
- type: CustomerCredential | ||||||
# trusted participants endpoint configuration | ||||||
trustedParticipantsLists: | ||||||
# the credentials type to configure the endpoint(s) for | ||||||
VerifiableCredential: | ||||||
- https://tir-pdc.ebsi.fiware.dev | ||||||
# the credentials type to configure the endpoint(s) for | ||||||
CustomerCredential: | ||||||
- https://tir-pdc.ebsi.fiware.dev | ||||||
# trusted issuers endpoint configuration | ||||||
trustedIssuersLists: | ||||||
# the credentials type to configure the endpoint(s) for | ||||||
VerifiableCredential: | ||||||
- https://tir-pdc.ebsi.fiware.dev | ||||||
# the credentials type to configure the endpoint(s) for | ||||||
CustomerCredential: | ||||||
- https://tir-pdc.ebsi.fiware.dev | ||||||
# configuration for verifying the holder of a credential | ||||||
holderVerification: | ||||||
# should it be checked? | ||||||
enabled: true | ||||||
# claim to retrieve the holder from | ||||||
claim: subject | ||||||
# credentials and claims to be requested | ||||||
presentationDefinition: | ||||||
id: my-presentation | ||||||
# List of requested inputs | ||||||
input_descriptors: | ||||||
id: my-descriptor | ||||||
# defines the infromation to be requested | ||||||
constraints: | ||||||
# array of objects to describe the information to be included | ||||||
fields: | ||||||
- id: my-field | ||||||
path: | ||||||
- $.vct | ||||||
filter: | ||||||
const: "CustomerCredential" | ||||||
# format of the credential to be requested | ||||||
format: | ||||||
'sd+jwt-vc': | ||||||
alg: ES256 | ||||||
``` | ||||||
#### Templating | ||||||
|
||||||
|
@@ -165,6 +208,11 @@ In order to ease the integration into frontends, VCVerifier offers a login-page | |||||
|
||||||
In order to start a ```same-device```-flow(e.g. the credential is hold by the requestor, instead of an additional device like a mobile wallet) call: | ||||||
```shell | ||||||
# scope to be requested from the wallet | ||||||
scope: | ||||||
- VerifiableCredential | ||||||
- CustomerCredential | ||||||
|
||||||
curl -X 'GET' \ | ||||||
'http://localhost:8080/api/v1/samedevice?state=274e7465-cc9d-4cad-b75f-190db927e56a' | ||||||
``` | ||||||
|
@@ -235,6 +283,11 @@ configRepo: | |||||
# the credentials type to configure the endpoint(s) for | ||||||
VerifiableCredential: | ||||||
- type: ebsi | ||||||
# scope to be requested from the wallet | ||||||
scope: | ||||||
- VerifiableCredential | ||||||
- CustomerCredential | ||||||
|
||||||
url: https://tir-pdc.ebsi.fiware.dev | ||||||
``` | ||||||
|
||||||
|
@@ -258,7 +311,12 @@ configRepo: | |||||
|
||||||
### Gaia-X Registry | ||||||
|
||||||
When using the [Gaia-X Digital Clearing House's](https://gaia-x.eu/services-deliverables/digital-clearing-house/) Registry Services, the issuer to be checked needs to fullfill the requirements of a Gaia-X participant. Thus, only did:web is supported for such and they need to provide a valid ```x5u``` location as part of their ```publicKeyJwk```. Usage of such registries can than be configured as following: | ||||||
When using the [Gaia-X Digital Clearing House's](https://gaia-x.eu/services-deliverables/digital-clearing-house/) Registry Services, the issuer to be checked needs to fullfill the requirements of | ||||||
# scope to be requested from the wallet | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again C&P? 😅 |
||||||
scope: | ||||||
- VerifiableCredential | ||||||
- CustomerCredential | ||||||
a Gaia-X participant. Thus, only did:web is supported for such and they need to provide a valid ```x5u``` location as part of their ```publicKeyJwk```. Usage of such registries can than be configured as following: | ||||||
```yaml | ||||||
configRepo: | ||||||
# static configuration for services | ||||||
|
@@ -298,6 +356,64 @@ configRepo: | |||||
url: https://registry.lab.gaia-x.eu | ||||||
``` | ||||||
|
||||||
### Request modes | ||||||
|
||||||
In order to support various wallets, the verifier supports 3 modes of requesting authentication: | ||||||
- Passing as URL with encoded parameters: "urlEncoded" | ||||||
- Passing a request object as value: "byValue" | ||||||
- Passing a request object by reference: "byReference" | ||||||
|
||||||
Following the [RFC9101](https://www.rfc-editor.org/rfc/rfc9101.html), in the second and third case the request is encoded as a signed JWT. Therefor ```clientIdentification``` for the verifier needs to be properly configured. | ||||||
|
||||||
The mode can be set during the intial requests, by sending the parameter "requestMode"(see [API Spec](./api/api.yaml)).Since requestObjects can become large and therefor also the QR-Codes generated out of them, the 3rd mode is recommended. | ||||||
|
||||||
#### urlEncoded | ||||||
|
||||||
Example: | ||||||
``` | ||||||
openid4vp://?response_type=vp_token&response_mode=direct_post&client_id=did:key:verifier&redirect_uri=https://verifier.org/api/v1/authentication_response&state=randomState&nonce=randomNonce | ||||||
``` | ||||||
|
||||||
#### byValue | ||||||
Example: | ||||||
``` | ||||||
openid4vp://?client_id=did:key:verifier&request=eyJhbGciOiJFUzI1NiIsInR5cCI6Im9hdXRoLWF1dGh6LXJlcStqd3QifQ.eyJjbGllbnRfaWQiOiJkaWQ6a2V5OnZlcmlmaWVyIiwiZXhwIjozMCwiaXNzIjoiZGlkOmtleTp2ZXJpZmllciIsIm5vbmNlIjoicmFuZG9tTm9uY2UiLCJwcmVzZW50YXRpb25fZGVmaW5pdGlvbiI6eyJpZCI6IiIsImlucHV0X2Rlc2NyaXB0b3JzIjpudWxsLCJmb3JtYXQiOm51bGx9LCJyZWRpcmVjdF91cmkiOiJodHRwczovL3ZlcmlmaWVyLm9yZy9hcGkvdjEvYXV0aGVudGljYXRpb25fcmVzcG9uc2UiLCJyZXNwb25zZV90eXBlIjoidnBfdG9rZW4iLCJzY29wZSI6Im9wZW5pZCIsInN0YXRlIjoicmFuZG9tU3RhdGUifQ.Z0xv_E9vvhRN2nBeKQ49LgH8lkjkX-weR7R5eCmX9ebGr1aE8_6usa2PO9nJ4LRv8oWMg0q9fsQ2x5DTYbvLdA | ||||||
``` | ||||||
Decoded: | ||||||
```json | ||||||
{ | ||||||
"alg": "ES256", | ||||||
"typ": "oauth-authz-req+jwt" | ||||||
}. | ||||||
{ | ||||||
"client_id": "did:key:verifier", | ||||||
"exp": 30, | ||||||
"iss": "did:key:verifier", | ||||||
"nonce": "randomNonce", | ||||||
"presentation_definition": { | ||||||
"id": "", | ||||||
"input_descriptors": null, | ||||||
"format": null | ||||||
}, | ||||||
"redirect_uri": "https://verifier.org/api/v1/authentication_response", | ||||||
"response_type": "vp_token", | ||||||
"scope": "openid", | ||||||
"state": "randomState" | ||||||
}. | ||||||
signature | ||||||
``` | ||||||
|
||||||
#### byReference | ||||||
|
||||||
Example: | ||||||
``` | ||||||
openid4vp://?client_id=did:key:verifier&request_uri=verifier.org/api/v1/request/randomState&request_uri_method=get" | ||||||
``` | ||||||
The object than can be retrived via: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
```shell | ||||||
curl https://verifier.org/api/v1/request/randomState | ||||||
``` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it help to show an example value of the retrieved data here? |
||||||
|
||||||
## API | ||||||
|
||||||
The API implements enpoints defined in [OIDC4VP](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-terminology) and [SIOP-2](https://openid.net/specs/openid-connect-self-issued-v2-1_0.html). The OpenAPI Specification of the implemented endpoints can be found at: [api/api.yaml](api/api.yaml). | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -18,6 +18,7 @@ paths: | |||||
- $ref: '#/components/parameters/QueryState' | ||||||
- $ref: '#/components/parameters/ClientCallback' | ||||||
- $ref: '#/components/parameters/ClientId' | ||||||
- $ref: '#/components/parameters/RequestMode' | ||||||
operationId: VerifierPageDisplayQRSIOP | ||||||
summary: Presents a qr as starting point for the auth process | ||||||
description: Returns a rendered html with a QR encoding the login-starting point for the siop flow - e.g. 'openid://?scope=somethign&response_type=rt&response_mode=rm&client_id=ci&redirect_uri=uri&state=state&nonce=nonce' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
@@ -34,7 +35,30 @@ paths: | |||||
application/json: | ||||||
schema: | ||||||
$ref: '#/components/schemas/ErrorMessage' | ||||||
|
||||||
|
||||||
/api/v1/request/{id}: | ||||||
get: | ||||||
tags: | ||||||
- api | ||||||
parameters: | ||||||
- $ref: '#/components/parameters/Id' | ||||||
operationId: GetRequestByReference | ||||||
summary: Get the request object by reference | ||||||
description: Returns the request object by reference as defined in https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#section-5 | ||||||
responses: | ||||||
'200': | ||||||
description: The jwt encoded request object | ||||||
content: | ||||||
text/html: | ||||||
schema: | ||||||
type: string | ||||||
'400': | ||||||
description: In case of broken requests. | ||||||
content: | ||||||
application/json: | ||||||
schema: | ||||||
$ref: '#/components/schemas/ErrorMessage' | ||||||
|
||||||
/api/v1/samedevice: | ||||||
get: | ||||||
tags: | ||||||
|
@@ -248,6 +272,16 @@ components: | |||||
schema: | ||||||
type: string | ||||||
example: packet-delivery-portal | ||||||
RequestMode: | ||||||
name: request_mode | ||||||
description: Mode to be used for the authorization request. | ||||||
in: query | ||||||
required: false | ||||||
schema: | ||||||
type: string | ||||||
enum: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. byReference missing? |
||||||
- urlEncoded | ||||||
- byValue | ||||||
ServiceId: | ||||||
name: service_id | ||||||
description: The id of the client/service that intents to start the authentication flow. Will be used to retrieve the scope and trust services to be used for verification. | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package common | ||
|
||
import "os" | ||
|
||
// file system interfaces | ||
|
||
type FileAccessor interface { | ||
ReadFile(filename string) ([]byte, error) | ||
} | ||
type DiskFileAccessor struct{} | ||
|
||
func (DiskFileAccessor) ReadFile(filename string) ([]byte, error) { | ||
return os.ReadFile(filename) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,15 @@ | ||
package common | ||
|
||
import ( | ||
"github.com/lestrrat-go/jwx/jwa" | ||
"github.com/lestrrat-go/jwx/jwt" | ||
"github.com/lestrrat-go/jwx/v3/jwt" | ||
) | ||
|
||
type TokenSigner interface { | ||
Sign(t jwt.Token, alg jwa.SignatureAlgorithm, key interface{}, options ...jwt.SignOption) ([]byte, error) | ||
Sign(t jwt.Token, options ...jwt.SignOption) ([]byte, error) | ||
} | ||
|
||
type JwtTokenSigner struct{} | ||
|
||
func (JwtTokenSigner) Sign(t jwt.Token, alg jwa.SignatureAlgorithm, key interface{}, options ...jwt.SignOption) ([]byte, error) { | ||
return jwt.Sign(t, alg, key, options...) | ||
func (JwtTokenSigner) Sign(t jwt.Token, options ...jwt.SignOption) ([]byte, error) { | ||
return jwt.Sign(t, options...) | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -58,6 +58,10 @@ type Logging struct { | |||||
type Verifier struct { | ||||||
// did to be used by the verifier | ||||||
Did string `mapstructure:"did"` | ||||||
// Identification to be used for the verifier | ||||||
ClientIdentification ClientIdentification `mapstructure:"clientIdentification"` | ||||||
// supported request modes - currently 'urlEncoded', 'byValue' an 'byReference' are available. In case of byValue, the keyPath has to be set. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
SupportedModes []string `mapstructure:"supportedModes" default:"urlEncoded"` | ||||||
// address of the (ebsi-compatible) trusted-issuers-registry for verifying the issuer | ||||||
TirAddress string `mapstructure:"tirAddress"` | ||||||
// expiry of the tir-cache entries | ||||||
|
@@ -80,6 +84,17 @@ type Verifier struct { | |||||
KeyAlgorithm string `mapstructure:"keyAlgorithm" default:"RS256"` | ||||||
} | ||||||
|
||||||
type ClientIdentification struct { | ||||||
// path to the did signing key(in pem format) for request object mode | ||||||
KeyPath string `mapstructure:"keyPath"` | ||||||
// algorithm used for the request signing key | ||||||
KeyAlgorithm string `mapstructure:"requestKeyAlgorithm"` | ||||||
// identification used by the verifier when requesting authorization. Can be a did, but also methods like x509_san_dns | ||||||
Id string `mapstructure:"id"` | ||||||
// optional path to the certifcate to embed in the jwt header | ||||||
CertificatePath string `mapstructure:"certificatePath"` | ||||||
} | ||||||
|
||||||
type Elsi struct { | ||||||
// should the support for did:elsi be enabled | ||||||
Enabled bool `mapstructure:"enabled" default:"false"` | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Misplaced C&P?