docs/flow-cache-design-doc.md
This design doc outlines the proposed solution for caching the flow object in the OAuth2 exchange between the Client, Ory Hydra, and the Consent and Login UIs. The flow object contains the state of the authorization request.
Currently, the flow object is stored in the database on the Ory Hydra server. This approach has several drawbacks:
The proposed solution is to store the flow object in client cookies and URLs. This way, the flow object is written only once when the flow is completed and the final authorization code is generated.
The proposed architecture for the flow cache is as follows:
sequenceDiagram
actor Client
participant Hydra
participant LoginUI as Login UI
participant ConsentUI as Consent UI
% participant Callback
autonumber
Client->>+Hydra: GET /oauth2/auth?client_id=CLIENT_ID&response_type=code&scope=SCOPES&state=STATE
Hydra->>-Client: Redirect to
http://login.local/?login_challenge=LOGIN_CHALLENGE
Client->>+LoginUI: GET /?login_challenge=LOGIN_CHALLENGE
LoginUI->>Hydra: GET /admin/oauth2/auth/requests/login
Hydra->>LoginUI: oAuth2LoginRequest
alt accept login
LoginUI->>Hydra: PUT /admin/oauth2/auth/requests/login/accept
else reject login
LoginUI->>Hydra: PUT /admin/oauth2/auth/requests/login/reject
end
Hydra->>LoginUI: oAuth2RedirectTo
LoginUI->>-Client: Redirect to
http://hydra.local/oauth2/auth?client_id=CLIENT_ID&login_verifier=LOGIN_VERIFIER&response_type=code&scope=SCOPES&state=STATE
Client->>+Hydra: GET /oauth2/auth?client_id=CLIENT_ID&login_verifier=LOGIN_VERIFIER&response_type=code&scope=SCOPES&state=STATE
Hydra->>-Client: Redirect to
http://consent.local/?consent_challenge=CONSENT_CHALLENGE
Client->>+ConsentUI: GET /?consent_challenge=CONSENT_CHALLENGE
ConsentUI->>Hydra: GET /admin/oauth2/auth/requests/consent
Hydra->>ConsentUI: oAuth2ConsentRequest
alt accept login
ConsentUI->>Hydra: PUT /admin/oauth2/auth/requests/consent/accept
else reject login
ConsentUI->>Hydra: PUT /admin/oauth2/auth/requests/consent/reject
end
Hydra->>ConsentUI: oAuth2RedirectTo
ConsentUI->>-Client: Redirect to
http://hydra.local/oauth2/auth?client_id=CLIENT_ID&consent_verifier=CONSENT_VERIFIER&response_type=code&scope=SCOPES&state=STATE
Client->>+Hydra: GET /oauth2/auth?client_id=CLIENT_ID&consent_verifier=CONSENT_VERIFIER&response_type=code&scope=SCOPES&state=STATE
Hydra->>-Client: Redirect to
http://callback.local/callback?code=AUTH_CODE&scope=SCOPES&state=STATE
Note over Hydra,Client: next, exchange code for token.
% Client->>+Callback: GET /callback?code=AUTH_CODE&scope=SCOPES&state=STATE
% Callback->>-Client: Return Authorization Code
Step 2:
state, so that multiple flows can run in parallel
from one cookie jarLOGIN_CHALLENGE to the AEAD-encrypted flowStep 5:
LOGIN_CHALLENGE, return the oAuth2LoginRequestStep 8:
oAuth2RedirectTo as the
LOGIN_VERIFIERStep 11
LOGIN_VERIFIER matches the challenge
in the flow cookie.LOGIN_VERIFIERCONSENT_CHALLENGE to the AEAD-encrypted flowStep 14:
CONSENT_CHALLENGEStep 17:
oAuth2RedirectTo as the
CONSENT_VERIFIERStep 20
CONSENT_VERIFIER matches the
challenge in the flow cookie.CONSENT_VERIFIERFor reference, these HTTP requests are issued by the client:
GET http://hydra.local/oauth2/auth?client_id=CLIENT_ID&nonce=NONCE&response_type=code&scope=SCOPES&state=STATE
Redirect to http://login.local/?login_challenge=LOGIN_CHALLENGE
GET http://login.local/?login_challenge=LOGIN_CHALLENGE
Redirect to http://hydra.local/oauth2/auth?client_id=CLIENT_ID&login_verifier=LOGIN_VERIFIER&nonce=NONCE&response_type=code&scope=SCOPES&state=STATE
GET http://hydra.local/oauth2/auth?client_id=CLIENT_ID&login_verifier=LOGIN_VERIFIER&nonce=NONCE&response_type=code&scope=SCOPES&state=STATE
Redirect to http://consent.local/?consent_challenge=CONSENT_CHALLENGE
GET http://consent.local/?consent_challenge=CONSENT_CHALLENGE
Redirect to http://hydra.local/oauth2/auth?client_id=CLIENT_ID&consent_verifier=CONSENT_VERIFIER&nonce=NONCE&response_type=code&scope=SCOPES&state=STATE
GET http://hydra.local/oauth2/auth?client_id=CLIENT_ID&consent_verifier=CONSENT_VERIFIER&nonce=NONCE&response_type=code&scope=SCOPES&state=STATE
Redirect to http://callback.local/callback?code=AUTH_CODE&scope=SCOPES&state=STATE
GET http://callback.local/callback?code=AUTH_CODE&scope=SCOPES&state=STATE
The implementation of the flow cache will involve the following steps:
The proposed solution for caching the flow object in the OAuth2 exchange between the Client, Ory Hydra, and the Consent and Login UIs is to store the flow object in client cookies and URLs. This approach eliminates the need for a distributed cache and provides a scalable and secure solution. The flow object will be stored in an AEAD encrypted cookie and passed around in the URL. HTTPS will be used to protect against unauthorized access.