hydra icon indicating copy to clipboard operation
hydra copied to clipboard

Add a 'management of existing consents for a subject' flow from Public API -> Login&Consent App -> Admin API using challenge tokens

Open mig5 opened this issue 2 years ago • 0 comments

Preflight checklist

Describe your problem

Following on from these two discussions:

https://github.com/ory/hydra/discussions/3130 https://github.com/ory/hydra/discussions/2938

There exists an endpoint to list all Consents for a subject, but it is on the Admin API. Therefore, the subject is merely a payload argument, there is nothing to make or prove that the subject is the one doing the request.

If a subject wants to see a list of OAuth 2.0 Clients to which they have Consented, the implementor has to somehow hit the Admin API for this but protect such an app from just 'anyone' being able performing a brute-force attack by requesting any subject. The 'subject' might be easily guessable, unlike an id_token or an access token

Describe your ideal solution

Using the id_token or (access token?), make a request on the public endpoint to say 'I am subject X, I want to view my consents'.

The public endpoint:

  • validates the id_token, and if it is valid:
  • makes a 'manage_challenge' and maps it to this subject
  • redirects to a new 'route' on the Login&Consent app (URLS_MANAGE ?) with the 'manage_challenge' query param, similar to the login, consent and logout challenges

The Manage screen ( which is left to the implementor to add on their Login&Consent app):

  • consumes the manage_challenge token in the query param, and makes a POST request to the Admin API (perhaps POST /oauth2/auth/sessions/consent ?) with this challenge
  • The Admin API verifies the 'manage_challenge' token, and if OK, returns the list of consents that GET /oauth2/auth/sessions/consent currently offers - the only difference is that it's responding to a POST and has validated the challenge. It should also return the 'subject' as a query param so the Manage screen can consume it
  • The Manage screen renders with whatever the implementor wants - but typically would be a list of the consents, perhaps with 'Revoke' or 'View claims' buttons against each consent

Clicking on 'Revoke' of a consent, sends a standard DELETE /oauth2/auth/sessions/consent with the client and subject as a payload, to the Admin API to delete the consent, as normal

Workarounds or alternatives

The only workaround I can think of right now is that I must make a 'middleware' app, accessed from my 'Management RP app' which the user has signed into with OIDC.

The middleware app needs to be logically situated near (or as part of) the Login&Consent app, so it can access the Admin API in order to perform the GET and DELETE requests to /oauth2/auth/sessions/consent

The 'subject' argument is what the Management RP app will need to send to the 'Middleware' app so the Middleware app can pass along the subject in the Admin API requests. I can send the subject from info in the Management RP app's user session so that the user can't 'forge' it.

But I somehow have to prevent the Middleware app from being called directly (bypassing the Management RP app) with an arbitrary subject. This means some other form of access control over the Middleware app, either firewall or some other ACL auth that only the Management RP app knows in order to call it.

The beauty of Hydra and its Login/Consent/Logout flows is the use of these 'challenge' tokens which prevents brute-forcing of the Admin API via the Login&Consent app for those flows. So all I wish is for same flow design here, to 'manage' prior consents.

Version

v.1.11.8

Additional Context

Bonus points: many services online (Twitter, Github etc) have a section in the profile where the user can see other still-active sessions from other devices. In OIDC I think this would translate as 'other sids'. It might be nice to use this same 'management' flow to let the user revoke the sessions for those SIDs. (I know this doesn't do front/back-channel logout, but it would be better than nothing. Anyway, why not let it do back-channel logout on such a request to end another sid session? You might as well, since it's a server-to-server request)

I guess this requires the Admin API to have a one-to-many mapping of subject -> sid(s) . I am not sure if it does already.

This would be like or via the DELETE /oauth2/auth/sessions/login that exists today on the Admin API, except right now that endpoint only takes subject as the argument. It could optionally take sid as an argument, that way you could revoke just that sid (e.g another device's sid, from this device).

mig5 avatar Jun 02 '22 23:06 mig5