kych

OAuth 2.0 API for Swiyu to enable Taler integration of Swiyu for KYC (experimental)
Log | Files | Refs

commit ae7b802bf6091ba7c01c8fd555ed2f60313cb9be
parent 187eca3e5cf68dabf4beaf5760e19b19a2b64db2
Author: Henrique Chan Carvalho Machado <henriqueccmachado@tecnico.ulisboa.pt>
Date:   Tue, 14 Oct 2025 17:53:43 +0200

oauth2_gateway: updated api spec, reflects sequence diagram changes

Diffstat:
Moauth2_gateway/openapi.yaml | 247+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 191 insertions(+), 56 deletions(-)

diff --git a/oauth2_gateway/openapi.yaml b/oauth2_gateway/openapi.yaml @@ -21,34 +21,40 @@ components: scheme: bearer description: | Bearer token (Shared Secret) used for server-to-server authentication - between the Taler Exchange and the Oauth2 Gateway. + of the Exchange (Client) identity when calling /setup and /token. + + BearerToken: + type: http + scheme: bearer + description: | + The access_token issued by the Oauth2 Gateway at the /token endpoint, + used to authenticate access to the protected resource at /info. schemas: - AuthorizationRequest: + SetupRequest: type: object required: - - client_id - scope properties: - client_id: - type: string - description: The registered client identifier of the Exchange (or the operation). - example: 'taler-exchange-client-kyc' scope: type: string description: | A space-delimited string of desired attributes the Exchange wishes to verify, defining the selective disclosure parameters. - example: 'swiyu:name swiyu:date_of_birth' - redirect_uri: + example: 'first_name last_name date_of_birth age_over_18' + + SetupResponse: + type: object + required: + - nonce + properties: + nonce: type: string - format: uri description: | - The URI where the Exchange expects the user to be redirected after - initial setup (optional, as the flow is mostly asynchronous). - This is included for compliance with RFC 6749. - - AuthorizationResponse: + The nonce to be used by the client Browser to construct the /authorize URL. + example: 'abc-123-xyz' + + AuthorizeResponse: type: object required: - verificationId @@ -58,89 +64,218 @@ components: type: string format: uuid description: | - The unique identifier for this verification session, generated by the SwiyuVerifier. - This ID is used in subsequent notification and retrieval calls. + The unique ID generated by the SwiyuVerifier for the OID4VP session, + used internally by the Oauth2 Gateway. + example: 'd8c1e4f9-2b0e-4a6c-9a3d-5f8b7c2d1e0a' verification_url: type: string format: uri description: | - The URL that the Browser must scan/open to start the OID4VP flow. - This is typically presented as a QR code. + The URL that the TalerWallet/Browser must open/scan (as a QR code) + to start the OID4VP flow. example: 'swiyu://verify?request_uri=...' - VerifiableCredential: + NotificationRequest: + type: object + required: + - nonce + properties: + nonce: + type: string + description: | + The nonce for the session that has completed verification. + example: 'abc-123-xyz' + verification_complete: + type: boolean + description: Flag indicating that the verification process is complete and the VC is ready to fetch. + example: true + + TokenRequest: type: object - description: The Verifiable Credential (VC) JSON object containing the verified proof. + required: + - grant_type + - code properties: - proof: + grant_type: + type: string + enum: [authorization_code] + description: Must be 'authorization_code' for this flow. + code: type: string - description: The actual cryptographic proof/signed data from the SwiyuVerifier. - attributes: + description: The `nonce` returned from the initial /setup endpoint. + example: 'abc-123-xyz' + + TokenResponse: + type: object + required: + - access_token + - token_type + - expires_in + properties: + access_token: + type: string + description: Token used to authenticate access to the protected /info endpoint. + example: 'tok_zyxw-0987' + token_type: + type: string + enum: [Bearer] + description: Must be "Bearer". + expires_in: + type: integer + description: Amount of time that the access token is valid (in seconds). + example: 3600 + + VerifiableCredential: + type: object + description: The Verifiable Credential (VC) proof object, mirroring the protected resource. + properties: + address: type: object - description: Parsed key-value pairs of the verified attributes. + description: Key-value pairs of the verified attributes derived from the VC. example: - name: 'John Doe' - date_of_birth: '1990-01-01' + name: 'Jane Doe' + country: 'CH' + address_type: + type: string + description: The type of data verified (e.g., 'age_over_18'). + example: 'age_over_18' paths: - /kyc/authorize: + /setup/{clientId}: post: - summary: Initiate KYC verification via Swiyu OID4VP flow + summary: Initiate KYC verification session (Server-to-Server) description: | - The Exchange calls this endpoint to start a new verification session. - This is analogous to the OAuth 2.0 `/authorize` endpoint but immediately - returns the deep link/QR code for the user's wallet. + The Exchange calls this endpoint to begin a KYC process. It creates a new session and returns a `nonce`. tags: - - Authorization + - Authorization Flow + security: + - ExchangeAuth: [] + parameters: + - in: path + name: clientId + schema: + type: string + required: true + description: The registered client identifier of the Exchange. requestBody: required: true content: application/json: schema: - $ref: '#/components/schemas/AuthorizationRequest' + $ref: '#/components/schemas/SetupRequest' responses: '200': - description: Verification session successfully started and QR code returned. + description: Session successfully created and nonce returned. content: application/json: schema: - $ref: '#/components/schemas/AuthorizationResponse' + $ref: '#/components/schemas/SetupResponse' '401': - description: Authentication failed (Invalid or missing Exchange Bearer token). - '400': - description: Invalid request (e.g., missing required 'scope'). + description: Authentication failed (Invalid or missing Exchange Shared Secret). - /kyc/info/{verificationId}: + /authorize/{nonce}: get: - summary: Retrieve the Verifiable Credential (VC) proof + summary: Redirect to initiate the OID4VP flow (Browser-facing) description: | - The Exchange calls this endpoint using the `verificationId` after receiving the - asynchronous notification (`/oauth2gw/kyc/notify`). This is analogous to the - OAuth 2.0 `/info` (Userinfo) endpoint - and returns the protected resource (the VC). + The Exchange constructs a redirect URL to this endpoint using the `nonce`. The Oauth2Gateway + uses this call to initiate the Swiyu verification and returns the QR code/verification URL to the user's browser. tags: - - Resource Retrieval + - Authorization Flow parameters: - in: path - name: verificationId + name: nonce schema: type: string - format: uuid required: true - description: The unique ID of the completed verification session. + description: The unique ID returned from the /setup endpoint. responses: '200': - description: Proof successfully retrieved. + description: QR code/verification URL returned in the body (to be rendered by the browser). + content: + application/json: + schema: + $ref: '#/components/schemas/AuthorizeResponse' + '404': + description: Nonce not found or expired. + '302': + description: Redirect to a URL that immediately displays the QR code. + + /token: + post: + summary: Exchange nonce for an access_token (OAuth 2.0 /token) + description: | + The Exchange calls this endpoint to complete the Authorization flow, obtaining an + access token after the verification is complete. + tags: + - Authorization Flow + security: + - ExchangeAuth: [] + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/TokenRequest' + responses: + '200': + description: Access token successfully issued. + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + '401': + description: Authentication failed (Invalid Exchange Shared Secret or invalid nonce). + + /info: + get: + summary: Retrieve the final Verifiable Credential proof (OAuth 2.0 /info) + description: | + The Exchange calls this endpoint using the `access_token` to retrieve the protected + resource (the Verifiable Credential proof). + tags: + - Resource Retrieval + security: + - BearerToken: [] + responses: + '200': + description: Verifiable Credential proof successfully retrieved. content: application/json: schema: $ref: '#/components/schemas/VerifiableCredential' '401': - description: Authentication failed (Invalid or missing Exchange Bearer token). + description: Authentication failed (Invalid or missing access_token). '404': - description: The `verificationId` is unknown or the verification is not yet complete. - '403': - description: Authorization failed (Token is valid but lacks scope/permissions). + description: The access_token is invalid (includes unknown or expired) or no data available. - # Note: The Oauth2Gateway also needs to define an internal webhook receiver - # for the SwiyuVerifier, but that is generally considered an internal/private endpoint. + /oauth2gw/kyc/notify/{clientId}: + post: + summary: Asynchronous webhook notification of verification completion (Server-to-Server) + description: | + The Oauth2 Gateway calls this protected endpoint on the Exchange to notify it that + the asynchronous Swiyu verification process for the given client is complete, + and the Exchange can now call /token. + tags: + - Webhooks + security: + # Note: This is an Exchange-exposed endpoint, but it is called by the Oauth2 Gateway. + # It must be secured to only accept calls from the Oauth2 Gateway (using a shared secret). + - ExchangeAuth: [] + parameters: + - in: path + name: clientId + schema: + type: string + required: true + description: The registered client identifier of the Exchange to route the notification. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationRequest' + responses: + '200': + description: Notification successfully received and acknowledged by the Exchange. + '401': + description: Authentication failed (Invalid or missing Oauth2 Gateway Bearer token).