commit 23771669dfd29c9083a2d650112e0d2c0b474601
parent 934160a4cda12497115e3ea7bf2d1e27a520dc59
Author: Henrique Chan Carvalho Machado <henriqueccmachado@tecnico.ulisboa.pt>
Date: Mon, 19 Jan 2026 23:11:43 +0100
Align OAuth2 sequence docs with implementation
Update the setup, authorize, and token sequence documentation to match current
behavior, including bearer token and client authentication, parameter placement,
redirect URI and scope validation, issuer handling, and corrected error codes.
Diffstat:
3 files changed, 92 insertions(+), 65 deletions(-)
diff --git a/documentation/sequence_diagrams/authorize_sequence.txt b/documentation/sequence_diagrams/authorize_sequence.txt
@@ -3,35 +3,45 @@ sequenceDiagram
participant Kych oauth2 Gateway
participant Kych oauth2 Gateway DB
participant Swiyu Verifier
-
- Client ->> Kych oauth2 Gateway: GET /authorize?\nresponse_type=code&\nclient_id={client_id}&\nnonce={nonce}
-
+
+ Client ->> Kych oauth2 Gateway: GET /authorize/{nonce}?\nresponse_type=code&\nclient_id={client_id}&\nredirect_uri={redirect_uri}&\nstate={state}&\nscope={scope}
+
Kych oauth2 Gateway ->> Kych oauth2 Gateway: Validate parameters:\n- response_type == 'code'
-
+
alt Invalid parameters
Kych oauth2 Gateway -->> Client: 400 BAD REQUEST\n{error: 'invalid_request'}
else Valid parameters
- Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: UPDATE verification_sessions s \nSET status = s.status \nFROM clients c \nWHERE s.client_id = c.id \nAND s.nonce = $1 AND c.client_id = $2 \nRETURNING s.id, s.status, s.expires_at, \ns.scope, s.verification_url, \ns.request_id, s.verifier_nonce, \nc.verifier_url, c.verifier_management_api_path
-
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: SELECT s.id, s.status, s.expires_at,\ns.scope, s.verification_url, s.request_id,\ns.verification_deeplink, c.verifier_url,\nc.verifier_management_api_path,\nc.allowed_redirect_uris, c.accepted_issuer_dids\nFROM verification_sessions s\nJOIN clients c ON s.client_id = c.id\nWHERE s.nonce = $1 AND c.client_id = $2
+
Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: Query result
end
-
- alt Session error
- Kych oauth2 Gateway -->> Client: Error Response:\n- 404 NOT FOUND (session not found)\n- 410 GONE (expired)\n- 409 CONFLICT (not pending)
+
+ alt Session not found
+ Kych oauth2 Gateway -->> Client: 404 NOT FOUND\n{error: 'session_not_found'}
+ else Invalid redirect_uri
+ Kych oauth2 Gateway -->> Client: 400 BAD REQUEST\n{error: 'invalid_redirect_uri'}
+ else Session expired
+ Kych oauth2 Gateway -->> Client: 410 GONE\n{error: 'session_expired'}
+ else Session not pending (already processed)
+ Kych oauth2 Gateway -->> Client: 409 CONFLICT\n{error: 'invalid_session_status'}
else Session already authorized (idempotent)
- Kych oauth2 Gateway -->> Client: 200 OK \n{verification_id, verification_url}
+ Kych oauth2 Gateway -->> Client: 200 OK\n{verification_id, verification_url,\nverification_deeplink, state}
else Session valid and pending - proceed
- Kych oauth2 Gateway ->> Kych oauth2 Gateway: build_presentation_definition(scope)
-
- Kych oauth2 Gateway ->> Swiyu Verifier: POST /management/api/verifications \n{presentation_definition, response_mode, ...}
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway: Validate scope against allowed_scopes\nbuild_presentation_definition(scope)
+
+ Kych oauth2 Gateway ->> Swiyu Verifier: POST /management/api/verifications\n{presentation_definition, response_mode,\naccepted_issuer_dids, ...}
Swiyu Verifier -->> Kych oauth2 Gateway: Response
-
- alt Error
- Kych oauth2 Gateway -->> Client: Error Response:\n- 502 BAD GATEWAY (verifier error)\n- 500 INTERNAL SERVER ERROR (DB error)
+
+ alt Verifier error
+ Kych oauth2 Gateway -->> Client: 502 BAD GATEWAY\n{error: 'verifier_error'}
else Success
- Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: UPDATE verification_sessions \nSET verification_url = $1, request_id = $2, \nverifier_nonce = $3, status = 'authorized', \nauthorized_at = NOW() \nWHERE id = $4 \nRETURNING verification_url, request_id
-
- Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: Updated session
- Kych oauth2 Gateway -->> Client: 200 OK \n{verification_id, verification_url}
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: UPDATE verification_sessions\nSET verification_url = $1, request_id = $2,\nverification_deeplink = $3, status = 'authorized',\nauthorized_at = NOW(), scope = $4,\nredirect_uri = $5, state = $6\nWHERE id = $7\nRETURNING verification_url, request_id
+
+ alt DB error
+ Kych oauth2 Gateway -->> Client: 500 INTERNAL SERVER ERROR
+ else Success
+ Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: Updated session
+ Kych oauth2 Gateway -->> Client: 200 OK\n{verification_id, verification_url,\nverification_deeplink, state}
+ end
end
end
diff --git a/documentation/sequence_diagrams/setup_sequence.txt b/documentation/sequence_diagrams/setup_sequence.txt
@@ -2,20 +2,31 @@ sequenceDiagram
participant Client
participant Kych oauth2 Gateway
participant Kych oauth2 Gateway DB
-
- Client ->> Kych oauth2 Gateway: POST /setup/{client_id}\n{scope: "first_name last_name"}
-
- Kych oauth2 Gateway ->> Kych oauth2 Gateway: generate_nonce()\n(256-bit CSPRNG)
-
- Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: INSERT INTO verification_sessions\n(client_id, nonce, scope, expires_at)\nSELECT c.id, $1, $2, NOW() + INTERVAL '15 minutes'\nFROM clients c WHERE c.client_id = $3\nRETURNING id, nonce, expires_at
-
+
+ Client ->> Kych oauth2 Gateway: POST /setup/{client_id}\nAuthorization: Bearer {client_secret}
+
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: SELECT secret_hash FROM clients\nWHERE client_id = $1
+
alt Client not found
Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: 0 rows
- Kych oauth2 Gateway -->> Client: 404 NOT FOUND\n{error: "client_not_found"}
- else DB error
- Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: Error
- Kych oauth2 Gateway -->> Client: 500 INTERNAL SERVER ERROR
- else Success
- Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: session {id, nonce, expires_at}
- Kych oauth2 Gateway -->> Client: 200 OK {nonce}
+ Kych oauth2 Gateway -->> Client: 401 UNAUTHORIZED\n{error: "unauthorized"}
+ else Client found
+ Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: secret_hash
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway: bcrypt_verify(bearer_token, secret_hash)
+
+ alt Invalid secret
+ Kych oauth2 Gateway -->> Client: 401 UNAUTHORIZED\n{error: "unauthorized"}
+ else Valid secret
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway: generate_nonce()\n(256-bit CSPRNG)
+
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: INSERT INTO verification_sessions\n(client_id, nonce, expires_at)\nSELECT c.id, $1, NOW() + INTERVAL '15 minutes'\nFROM clients c WHERE c.client_id = $2\nRETURNING id, nonce, expires_at
+
+ alt DB error
+ Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: Error
+ Kych oauth2 Gateway -->> Client: 500 INTERNAL SERVER ERROR
+ else Success
+ Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: session {id, nonce, expires_at}
+ Kych oauth2 Gateway -->> Client: 200 OK {nonce}
+ end
+ end
end
diff --git a/documentation/sequence_diagrams/token_sequence.txt b/documentation/sequence_diagrams/token_sequence.txt
@@ -2,39 +2,45 @@ sequenceDiagram
participant Client
participant Kych oauth2 Gateway
participant Kych oauth2 Gateway DB
-
- Client ->> Kych oauth2 Gateway: POST /token \n{code, grant_type}
-
- Kych oauth2 Gateway ->> Kych oauth2 Gateway: Validate grant_type == \n'authorization_code'
-
+
+ Client ->> Kych oauth2 Gateway: POST /token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=authorization_code&\ncode={code}&\nclient_id={client_id}&\nclient_secret={client_secret}&\nredirect_uri={redirect_uri}
+
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway: Validate grant_type ==\n'authorization_code'
+
alt Invalid grant type
- Kych oauth2 Gateway -->> Client: 400 BAD REQUEST \n{error: 'unsupported_grant_type'}
+ Kych oauth2 Gateway -->> Client: 400 BAD REQUEST\n{error: 'unsupported_grant_type'}
else Valid grant type
- Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: WITH code_data AS (\n SELECT id, used AS was_already_used, session_id\n FROM authorization_codes\n WHERE code = $1 AND expires_at > NOW()\n FOR UPDATE\n),\nupdated_code AS (\n UPDATE authorization_codes ac\n SET used = TRUE,\n used_at = CASE WHEN NOT ac.used THEN NOW() ELSE ac.used_at END\n FROM code_data cd\n WHERE ac.id = cd.id\n RETURNING ac.id, ac.session_id\n)\nSELECT uc.id AS code_id,\n cd.was_already_used,\n uc.session_id,\n vs.status AS session_status,\n at.token AS existing_token,\n at.expires_at AS token_expires_at\nFROM updated_code uc\nJOIN code_data cd ON uc.id = cd.id\nJOIN verification_sessions vs ON vs.id = uc.session_id\nLEFT JOIN access_tokens at\n ON at.session_id = vs.id AND at.revoked = FALSE
-
- alt No code found or DB error
- Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: 0 rows / Error
- Kych oauth2 Gateway -->> Client: Error Response:\n- 400 BAD REQUEST {error: 'invalid_grant'}\n- 500 INTERNAL SERVER ERROR
- else Code found
- Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: code, session, and token data
-
- Kych oauth2 Gateway ->> Kych oauth2 Gateway: Check state
-
- alt Token already exists (idempotent)
- Kych oauth2 Gateway -->> Client: 200 OK \n{access_token: existing_token, \ntoken_type: 'Bearer', expires_in: 3600}
- else Invalid state
- Kych oauth2 Gateway -->> Client: 400 BAD REQUEST \n{error: 'invalid_grant'}\n- Code already used\n- Session not verified
- else Valid - create token
- Kych oauth2 Gateway ->> Kych oauth2 Gateway: generate_access_token()
-
- Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: WITH updated AS (\n UPDATE verification_sessions \n SET status = 'completed', completed_at = NOW() \n WHERE id = $1 RETURNING id\n)\nINSERT INTO access_tokens \n(session_id, token, expires_at) \nVALUES ($1, $2, NOW() + INTERVAL '1 hour') \nRETURNING token, expires_at
-
- alt Error
- Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: Error
- Kych oauth2 Gateway -->> Client: 500 INTERNAL SERVER ERROR
- else Success
- Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: token, expires_at
- Kych oauth2 Gateway -->> Client: 200 OK \n{access_token, token_type: 'Bearer', expires_in: 3600}
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: SELECT id, secret_hash\nFROM clients WHERE client_id = $1
+
+ alt Client not found or invalid secret
+ Kych oauth2 Gateway -->> Client: 401 UNAUTHORIZED\n{error: 'invalid_client'}
+ else Client authenticated
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: WITH code_data AS (\n SELECT id, used AS was_already_used, session_id\n FROM authorization_codes\n WHERE code = $1 AND expires_at > NOW()\n FOR UPDATE\n),\nupdated_code AS (\n UPDATE authorization_codes ac\n SET used = TRUE,\n used_at = CASE WHEN NOT ac.used THEN NOW() ELSE ac.used_at END\n FROM code_data cd\n WHERE ac.id = cd.id\n RETURNING ac.id, ac.session_id\n)\nSELECT uc.id AS code_id,\n cd.was_already_used,\n uc.session_id,\n vs.status AS session_status,\n vs.client_id,\n vs.redirect_uri,\n at.token AS existing_token,\n at.expires_at AS token_expires_at\nFROM updated_code uc\nJOIN code_data cd ON uc.id = cd.id\nJOIN verification_sessions vs ON vs.id = uc.session_id\nLEFT JOIN access_tokens at\n ON at.session_id = vs.id AND at.revoked = FALSE
+
+ alt No code found or DB error
+ Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: 0 rows / Error
+ Kych oauth2 Gateway -->> Client: Error Response:\n- 400 BAD REQUEST {error: 'invalid_grant'}\n- 500 INTERNAL SERVER ERROR
+ else Code found
+ Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: code, session, and token data
+
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway: Validate:\n- code belongs to client\n- redirect_uri matches stored value\n- code not already used\n- session status == 'verified'
+
+ alt Token already exists (idempotent)
+ Kych oauth2 Gateway -->> Client: 200 OK\n{access_token: existing_token,\ntoken_type: 'Bearer', expires_in: 3600}
+ else Invalid state
+ Kych oauth2 Gateway -->> Client: 400 BAD REQUEST\n{error: 'invalid_grant'}\n- Code belongs to different client\n- redirect_uri mismatch\n- Code already used\n- Session not verified
+ else Valid - create token
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway: generate_access_token()
+
+ Kych oauth2 Gateway ->> Kych oauth2 Gateway DB: WITH updated AS (\n UPDATE verification_sessions\n SET status = 'completed', completed_at = NOW()\n WHERE id = $1 RETURNING id\n)\nINSERT INTO access_tokens\n(session_id, token, expires_at)\nVALUES ($1, $2, NOW() + INTERVAL '1 hour')\nRETURNING token, expires_at
+
+ alt Error
+ Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: Error
+ Kych oauth2 Gateway -->> Client: 500 INTERNAL SERVER ERROR
+ else Success
+ Kych oauth2 Gateway DB -->> Kych oauth2 Gateway: token, expires_at
+ Kych oauth2 Gateway -->> Client: 200 OK\n{access_token, token_type: 'Bearer', expires_in: 3600}
+ end
end
end
end