commit 5363c5402617b83d7073dcd45c64564af46e0d63
parent 0daca842bb20b503a23e4045a1c9bd09fa44015e
Author: Henrique Chan Carvalho Machado <henriqueccmachado@tecnico.ulisboa.pt>
Date: Tue, 9 Dec 2025 12:28:36 +0100
oauth2_gateway: update api spec
Diffstat:
1 file changed, 149 insertions(+), 117 deletions(-)
diff --git a/oauth2_gateway/openapi.yaml b/oauth2_gateway/openapi.yaml
@@ -1,48 +1,36 @@
openapi: 3.0.4
info:
- title: Oauth2 Gateway API
+ title: OAuth2 Gateway API
version: '0.0.1'
description: |
- The Oauth2 Gateway service orchestrates the Know-Your-Customer (KYC) verification flow
- between the Taler Exchange and the Swiyu Verifier, acting as a resource server for the
+ The OAuth2 Gateway service orchestrates the Know-Your-Customer (KYC) verification flow
+ between OAuth2 clients and the Swiyu Verifier, acting as a resource server for the
final Verifiable Credential (VC) proof.
servers:
- url: https://oauth2gw.example.com
- description: Oauth2 Gateway server
+ description: OAuth2 Gateway server
security:
- - ExchangeAuth: []
+ - ClientAuth: []
components:
securitySchemes:
- ExchangeAuth:
+ ClientAuth:
type: http
scheme: bearer
description: |
Bearer token (Shared Secret) used for server-to-server authentication
- of the Exchange (Client) identity when calling /setup and /token.
+ of the client identity when calling /setup.
BearerToken:
type: http
scheme: bearer
description: |
- The access_token issued by the Oauth2 Gateway at the /token endpoint,
+ The access_token issued by the OAuth2 Gateway at the /token endpoint,
used to authenticate access to the protected resource at /info.
schemas:
- SetupRequest:
- type: object
- required:
- - scope
- properties:
- scope:
- type: string
- description: |
- A space-delimited string of desired attributes the Exchange wishes to verify,
- defining the selective disclosure parameters.
- example: 'first_name last_name date_of_birth age_over_18'
-
SetupResponse:
type: object
required:
@@ -51,60 +39,85 @@ components:
nonce:
type: string
description: |
- The nonce to be used by the client Browser to construct the /authorize URL.
- example: 'abc-123-xyz'
+ The nonce to be used to construct the /authorize URL.
+ example: '7f3e9d2a8b1c4f6e5a9d8c7b3e2f1a4d'
AuthorizeResponse:
type: object
required:
- - verificationId
+ - verification_id
- verification_url
+ - state
properties:
- verificationId:
+ verification_id:
type: string
format: uuid
description: |
- The unique ID generated by the SwiyuVerifier for the OID4VP session,
- used internally by the Oauth2 Gateway.
+ The unique ID generated by the Swiyu Verifier 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 TalerWallet/Browser must open/scan (as a QR code)
- to start the OID4VP flow.
- example: 'swiyu://verify?request_uri=...'
-
+ The URL that must be opened/scanned (as a QR code) to start the OID4VP flow.
+ example: 'swiyu://verify?request_uri=https://verifier.example.com/api/v1/request/d8c1e4f9-2b0e-4a6c-9a3d-5f8b7c2d1e0a'
+ verification_deeplink:
+ type: string
+ format: uri
+ description: |
+ Optional deeplink URL for mobile wallet applications.
+ example: 'swiyu://verify?request_uri=https://verifier.example.com/api/v1/request/d8c1e4f9-2b0e-4a6c-9a3d-5f8b7c2d1e0a'
+ state:
+ type: string
+ description: |
+ The state parameter echoed back from the authorize request for CSRF protection.
+ example: 'payto://iban/CH9300762011623852957'
+
NotificationRequest:
type: object
required:
- - nonce
+ - verification_id
+ - timestamp
properties:
- nonce:
+ verification_id:
+ type: string
+ format: uuid
+ description: |
+ The verification session ID from the Swiyu Verifier.
+ example: 'd8c1e4f9-2b0e-4a6c-9a3d-5f8b7c2d1e0a'
+ timestamp:
type: string
+ format: date-time
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
-
+ Timestamp when the notification was sent.
+ example: '2025-12-09T10:30:00Z'
+
TokenRequest:
type: object
required:
- grant_type
- code
+ - client_id
+ - client_secret
properties:
grant_type:
type: string
enum: [authorization_code]
- description: Must be 'authorization_code' for this flow. WARNING - RFC 6749 requires other parameters here!.
+ description: Must be 'authorization_code' for this flow.
code:
type: string
- description: The `nonce` returned from the initial /setup endpoint.
- example: 'abc-123-xyz'
-
+ description: The authorization code received from the client notification webhook.
+ example: '9a4f2e7c8d1b6a3e5f9c8d7e2a1b4c6f'
+ client_id:
+ type: string
+ description: The registered client identifier.
+ example: 'client_production_01'
+ client_secret:
+ type: string
+ description: The client secret for authentication.
+ example: 'cs_8f7e6d5c4b3a2f1e9d8c7b6a5f4e3d2c'
+
TokenResponse:
type: object
required:
@@ -115,7 +128,7 @@ components:
access_token:
type: string
description: Token used to authenticate access to the protected /info endpoint.
- example: 'tok_zyxw-0987'
+ example: 'at_3d2c1b9a8f7e6d5c4b3a2f1e9d8c7b6a'
token_type:
type: string
enum: [Bearer]
@@ -124,45 +137,38 @@ components:
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.
+ description: The Verifiable Credential (VC) proof object.
properties:
- address:
+ data:
type: object
- description: Key-value pairs of the verified attributes derived from the VC.
+ description: The verified attributes derived from the VC.
example:
- name: 'Jane Doe'
- country: 'CH'
- address_type:
- type: string
- description: The type of data verified (e.g., 'age_over_18').
- example: 'age_over_18'
+ vct: 'betaid-sdjwt'
+ age_over_18: true
+ iat: 1733741234
+ exp: 1765277234
paths:
/setup/{clientId}:
post:
- summary: Initiate KYC verification session (Server-to-Server)
+ summary: Initiate KYC verification session
description: |
- The Exchange calls this endpoint to begin a KYC process. It creates a new session and returns a `nonce`.
+ The client calls this endpoint to begin a KYC process. It creates a new session and returns a `nonce`.
tags:
- Authorization Flow
security:
- - ExchangeAuth: []
+ - ClientAuth: []
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/SetupRequest'
+ description: The registered client identifier.
+ example: 'client_production_01'
responses:
'200':
description: Session successfully created and nonce returned.
@@ -171,14 +177,16 @@ paths:
schema:
$ref: '#/components/schemas/SetupResponse'
'401':
- description: Authentication failed (Invalid or missing Exchange Shared Secret).
+ description: Authentication failed (Invalid or missing client secret).
+ '404':
+ description: Client not found.
/authorize/{nonce}:
get:
- summary: Redirect to initiate the OID4VP flow (Browser-facing)
+ summary: Initiate the OID4VP verification flow
description: |
- 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.
+ The client constructs a URL to this endpoint using the `nonce` from /setup.
+ The OAuth2 Gateway initiates the Swiyu verification and returns the verification URL.
tags:
- Authorization Flow
parameters:
@@ -187,29 +195,85 @@ paths:
schema:
type: string
required: true
- description: The unique ID returned from the /setup endpoint. WARNING - RFC 6749 requires other parameters here!.
+ description: The nonce returned from the /setup endpoint.
+ example: '7f3e9d2a8b1c4f6e5a9d8c7b3e2f1a4d'
+ - in: query
+ name: response_type
+ schema:
+ type: string
+ enum: [code]
+ required: true
+ description: Must be 'code' for authorization code flow.
+ - in: query
+ name: client_id
+ schema:
+ type: string
+ required: true
+ description: The registered client identifier.
+ example: 'client_production_01'
+ - in: query
+ name: redirect_uri
+ schema:
+ type: string
+ format: uri
+ required: true
+ description: The client redirect URI where the authorization code will be sent.
+ example: 'https://client.example.com/kyc-proof/oauth2'
+ - in: query
+ name: state
+ schema:
+ type: string
+ required: true
+ description: Opaque value used by the client to maintain state between request and callback (CSRF protection).
+ example: 'payto://iban/CH9300762011623852957'
+ - in: query
+ name: scope
+ schema:
+ type: string
+ required: true
+ description: Space-delimited string of desired attributes to verify.
+ example: 'age_over_18'
responses:
'200':
- description: QR code/verification URL returned in the body (to be rendered by the browser).
+ description: Verification URL returned.
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.
-
+ description: Nonce not found or session expired.
+ '410':
+ description: Session expired.
+ '409':
+ description: Invalid session status.
+
+ /notification:
+ post:
+ summary: Webhook notification from Swiyu Verifier
+ description: |
+ The Swiyu Verifier calls this endpoint to notify the OAuth2 Gateway that
+ a verification session has been completed. The gateway then notifies the client
+ via GET request to the redirect_uri with the authorization code.
+ tags:
+ - Webhooks
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/NotificationRequest'
+ responses:
+ '200':
+ description: Notification received and processed.
+
/token:
post:
- summary: Exchange nonce for an access_token (OAuth 2.0 /token)
+ summary: Exchange authorization code for access token
description: |
- The Exchange calls this endpoint to complete the Authorization flow, obtaining an
- access token after the verification is complete.
+ The client calls this endpoint to exchange the authorization code for an access token
+ after receiving the code via the notification webhook.
tags:
- Authorization Flow
- security:
- - ExchangeAuth: []
requestBody:
required: true
content:
@@ -223,15 +287,17 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/TokenResponse'
+ '400':
+ description: Invalid request or invalid authorization code.
'401':
- description: Authentication failed (Invalid Exchange Shared Secret or invalid nonce).
+ description: Client authentication failed.
/info:
get:
- summary: Retrieve the final Verifiable Credential proof (OAuth 2.0 /info)
+ summary: Retrieve the Verifiable Credential proof
description: |
- The Exchange calls this endpoint using the `access_token` to retrieve the protected
- resource (the Verifiable Credential proof).
+ The client calls this endpoint using the access_token to retrieve the
+ Verifiable Credential proof (protected resource).
tags:
- Resource Retrieval
security:
@@ -245,37 +311,3 @@ paths:
$ref: '#/components/schemas/VerifiableCredential'
'401':
description: Authentication failed (Invalid or missing access_token).
- '404':
- description: The access_token is invalid (includes unknown or expired) or no data available.
-
- /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).