Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identifiers for applications #30

Open
elf-pavlik opened this issue Sep 3, 2019 · 20 comments
Open

Identifiers for applications #30

elf-pavlik opened this issue Sep 3, 2019 · 20 comments

Comments

@elf-pavlik
Copy link
Member

I think whatever flows we come up with for granting / changing / revoking authorizations for applications we need clear way to identify those applications. We most likely will represent those authorizations using RDF so we will need to have IRI denoting an application.

This issue may overlap to some degree with authentication panel, for example if we want to require that OP includes application redirect_uri in the token and it gets used to identify the application.

We may also need to address to what degree we can rely on Origin header whenever available.

@jaxoncreed
Copy link
Contributor

It would make everything much easier for authorization if every application had a WebID. Part of the problem with using the redirect_uri as the identifier is the inability to associate apps if they're at different URIs. For example, an app might be at app.com while it's mobile "redirect_uri" would be "app://confirm".

Another benefit to requiring apps to have WebIDs is you can just make .acl rules for the apps themselves, though depending on your perspective, that might be a drawback.

@elf-pavlik
Copy link
Member Author

RS needs to have a way to authenticate the user as well as authenticate the app. To my understanding in some cases RS could authenticate app just based on Origin header which can get spoofed if malicious app uses proxy as explained in solid/web-access-control-spec#34 ( further discussed in solid/webid-oidc-spec#12 ) I think this panel can tackle how app proves it's identity to RS.

@jaxoncreed
Copy link
Contributor

We're not using the Origin anymore. As you've pointed out, that's easy to spoof. Instead, the IDP embeds the origin of the redirect uri in the token. One problem with this is that if the idp and client are in collusion, they'll be able to select any app identity they want.

@elf-pavlik
Copy link
Member Author

I think we can't avoid users trusting the OP they chose as their IDP, they assert it using that statement with solid:oidcIssuer in their WebID Profile.

For example, an app might be at app.com while it's mobile "redirect_uri" would be "app://confirm".

What does OP embed in the token here?

@elf-pavlik
Copy link
Member Author

@zenomt based on today's call I understand that problem with verifying identity of application doesn't relate to resource owner (with acl:Control access) or not. It seems to relate to malicious user or trusted user, where malicious user may lie about what application they use but for trusted user we can have a way to verify identity of application they use, since trusted user will not lie about it.

@zenomt
Copy link
Contributor

zenomt commented Sep 4, 2019

It seems to relate to malicious user or trusted user, where malicious user may lie about what application they use

the user might not be malicious (with bad intent):

  • the user might want to obfuscate what app she's using for privacy reasons. a cooperating OP and web browser could (consistently) hash origins and URIs so that a resource server, being presented with a token bound with an "application identifier", might not know what real origin or redirect_uri or whatever is being used, but from access-to-access the user would use a consistent identifier that could be used in per-user access control.
  • alternatively, the user might want to access a resource that its controller has marked "that user can access, but only with what i call https://appA". that might be an oversight, a misunderstanding, a technical limitation of the server, or intentional on the part of the controller.

generally (not including special environments), the user's trusted web browser and Open ID Connect Provider operate on the user's behalf, not on the behalf of a server or any other party, so in general those components shouldn't be trusted by any other party to be acting for anyone's benefit other than the user's. systems should be designed with this in mind.

@elf-pavlik
Copy link
Member Author

Thank you for clarifying @zenomt !

the user might want to obfuscate what app she's using for privacy reasons

I think here it still doesn't matter if user has acl:Control access mode (resource owner) or just some more restrictive access mode. Any user having any access mode to the resource could do that. At the same time if they choose to hide from the server what application they use, they shouldn't expect RS to check if they use application they approved. I think in that case they pretty much can't put any app specific access restrictions since they don't intend to communicate to RS which app they use.

On the other hand, any user (no matter what access mode they have in ACL) may want RS to check that they approve particular application to access particular resource or set of resources (no matter how they defined that set). In that case they need to communicate to RS what application they use in we can rely on RS having a way to verify identity of that application.

@dmitrizagidulin
Copy link
Member

dmitrizagidulin commented Sep 16, 2019

I think this issue is a crucial dependency for any other work we do in the App Authorization Panel.
We need to find terminology to clearly differentiate the identity of an application on three levels:

  1. App source identity
  2. Deployed app instance
  3. (ephemeral, relevant for in-browser apps only) App instance on a particular browser session

1. App source identity

This is the identity of the app that persists across various devices or browser sessions, and across different installations or instances of the app. This is what appears on the Consent / Authorize screen, "App X requests access to your user profile" or whatever. For example, for mobile (and most desktop) apps, the app source identifier would be the url of the app in the App Store (which includes the app name, icon, developer; note the app itself is signed by the developer and the OS, in many app stores). For many existing Solid apps, the app source identity would be the link to the Github repo for the app's source code.

(This is related to the concept of a machine-readable App Manifest, though this is just the identifier for it)

2. Deployed app instance

This is the identity of a particular installation/deployment of an app.
Secure clients:

  • For server-side apps, this is often the OAuth2 client_id, as provided from Static registration.

Public clients:

  • For mobile and desktop apps: The app's instance ID, provided by the OS, or an OAuth2 client_id from static registration
  • For Solid-style in-browser apps: This is the app's redirect_uri (which is basically the only way to authenticate / identify an app like that). (We're currently using a client_id received from Dynamic Registration, for this identifier, but there are several problems with that.)

Note that in-browser apps have no way to persist secrets or keys on this level (they can only store secrets on a browser-session level, below).

3. App instance on a particular browser session

This is the identity of an in-browser application running a) from a particular deployed instance / redirect_uri and b) during a particular user's browser session.
This is an ephemeral identity, as it only exists during a particular browsing session (in many cases, until the user clears localStorage or switches to a different browser).
Note that by itself, the identity of this ephemeral app instance is largely meaningless to the user (it must be at least linked to a particular Deployed app instance identity).

@elf-pavlik
Copy link
Member Author

elf-pavlik commented Sep 17, 2019

@dmitrizagidulin for apps running in a web browser, does this diagram map to your tree levels?

app-identity

I also included User here, who can use the same App Deployment on multiple devices, and wants to manage authorizations per app deployment not app device instance. Also 'review based certifications' which @RubenVerborgh mentioned in some other issue would probably reference the App Source. For deployments, as people get more used to technology I would expect more common for individuals and collectives to use their own deployments rather than some 'public deployment'.

@dmitrizagidulin
Copy link
Member

@elf-pavlik Sort of! With a couple of differences.

For the App Source layer:

It would be great to include the most common types of app sources - a Github repo (for an OSS project or for a proprietary enterprise software), an iOS or Android store entry (for mobile apps), and a Windows/Mac/Ubuntu/etc store entry (for desktop software).
In addition to App Review certification, I'd include App Manifest at this level.

For the App Deployment layer:

Again, let's include the various different types of Deployments:

  • An in-browser Javascript app deployed on several different domains (like https://saywhat.alice.example and https://demo.saywhat.example from the diagram)
  • An individual mobile app installed on a mobile device
  • A server-side app deployed on, say, a VM or AWS instance
  • A desktop app installed on a user's desktop computer

For the ephemeral App Instance on a Browser Session layer:

Note that only in-browser Javascript apps exist on this layer. Mobile, desktop and traditional server-side apps only exist on the previous Deployment layer.

@elf-pavlik
Copy link
Member Author

For the App Deployment layer
Again, let's include the various different types of Deployments:

Those two cases seem different to me, https://demo.saywhat.example can get used by any number of people on any number of devices, while mobile app installed on a mobile device stays bound to that device. If app deployed on https://demo.saywhat.example uses service worker, that ServiceWorkerRegistration looks more comparable to a native app installed on mobile device.

It looks like most if not all approaches require some kind of asymmetric key pair, for local clients they probably should stay on device and CryptoKey.extractable to my understanding allows it. The context which has access to private key may come helpful with definition here.

It would be great to include the most common types of app sources - a Github repo (for an OSS project or for a proprietary enterprise software), an iOS or Android store entry (for mobile apps), and a Windows/Mac/Ubuntu/etc store entry (for desktop software).

Same app source can get distributed via more than one store, eg. Google Playstore as well as https://f-droid.org/ etc. Unless we need to make assumptions about result of dereferencing IRI denoting the app source, I think whoever maintains the app can choose whatever IRI they want.

Those distribution channels in some ways look comparable to how I would see https://demo.saywhat.example. In both cases app binary (or source) gets downloaded to the device and executed locally, for native apps OS does it and for progressive web apps the web browser. In both cases we can distinguish the app 'instance' executing locally on the device from the remote 'app distribution channel'.

For the ephemeral App Instance on a Browser Session layer:
Note that only in-browser Javascript apps exist on this layer. Mobile, desktop and traditional server-side apps only exist on the previous Deployment layer.

I think some native apps have notion of 'user session', for example Youtube on iOS allows to switch between users and persists multiple logins.

@elf-pavlik
Copy link
Member Author

elf-pavlik commented Oct 1, 2019

solid-client-patterns

I've tried to illustrate different patters of solid clients. First two look quite straight forward:

  • Confidential Client uses independent session between local client and remote server running solid client, local client doesn't run solid client and can communicate with server running the solid client however it wants to. We also have clear OIDC Relying Party - the server that runs remote solid client.
  • Public Client uses solid client locally on device to directly communicate with solid resource servers.

Other two cases may need more clarifications

  • Bot could get deployed by power user and possibly rely on user WebID from some kind of configuration source
  • Hybrid client for cases where we have local client running solid client on device but also remote client running solid client on the server and sending push notifications to the local client. We also have scenario where we have per user local client but possibly one remote client for many users. Given that we want to bind tokens to the client we need to treat each (per user) local client and the shared remote client separately. They may even require separate consent from the user.

I suggest we forget about Implicit OAuth flow and assume that all those clients use Authorization Code Grant with PKCE or Client Credentials Grant.

@elf-pavlik
Copy link
Member Author

Considering case of same user with multiple devices. For Confidential Client we have just one OAuth client so User authorizations could stay assigned to that specific client.
In case of Public Cient, we get an OAuth client per device. User of multiple devices sometimes may want authorizations to apply for the same app on all their devices, in some cases may actually want to have different authorizations for the same app depending on device. The first case sounds like authorizations for 'clients group' which can have multiple clients. I think we could consider some kind of inheritance where clients have either direct authorizations or indirect from a clients group.

@elf-pavlik
Copy link
Member Author

For Confidential Client we have just one OAuth client so User authorizations could stay assigned to that specific client.

Actually it looks more like one OAuth Client per Authorization Server when different Users use different Authorization Servers.

In case of Public Cient, we get an OAuth client per device.

I've noticed https://tools.ietf.org/html/rfc7591#appendix-A.4 Client ID per Client Instance or per Client Software which we should probably also somehow address and possibly try to reuse the terminology.

@bblfish
Copy link
Contributor

bblfish commented Oct 5, 2019

The User controlled Authorization App and App launcher proposal opens up an architectural possibility that I think allows us to rethink the presuppositions of this discussion and give some good technical answers to some of the questions raised here.

By creating a secure Auth/Launcher App started from a secure origin trusted by the user we can do the following:

  • know the URL of the Apps launched (since the Launcher App launches them)
  • allow that Launcher App to keep keys securely in the browser for instances of the launched apps, without those less secure Launched Apps getting access to the private keys
  • save the information about the user's preferred apps on the Users Pod (securely) and store the keys there as well as giving those app instances WebIDs.

The App launcher would keep for each App information about the App (including its public keys potentially) with something like:

</app/calendar#FirefoxOnLinux> a :App;
   :appLaunch <https://office.app/2019/Calendar.html>;
   :browser "...";
   cert:key [ ... ] . 

The full ontology would still need to be worked out of course.
This may well reduce or remove the distinction between in browser apps and mobile apps, making browser apps a lot closer to mobile ones.

@elf-pavlik
Copy link
Member Author

@dmitrizagidulin could you please clarify the difference you see between on device instance of a client running in web browser (Public Client on diagram above #30 (comment)) and on device instance of a client running as native app.

In my opinion both cases seem very similar. In Authorization Code flow different instances of different devices will use same redirect_url. When authenticating solid/authentication-panel#25 those clients will use some form of on device credential. When (and if) using refresh tokens they will also store them on device.

@elf-pavlik
Copy link
Member Author

Today on authentication panel call we touched OAuth 2.0 Device Authorization Grant which doesn't use redirect_url, I think we should document identifying clients which use that grant and who and how verifies that identity solid/authentication-panel#25

@dmitrizagidulin
Copy link
Member

dmitrizagidulin commented Oct 15, 2019

@elf-pavlik

please clarify the difference you see between on device instance of a client running in web browser and on device instance of a client running as native app.

Sure. The difference is in two things - 1) how that app is identified, and 2) at which identity level the app can store secrets.

Mobile app (on device instance of a client running as native app):

  • Deployed app instance identified by mobile OS-provided identifier (essentially, redirect_uri)
  • Can store secrets (private keys etc) on a deployed instance level
  • Has access to OS keychain / trusted key storage modules

Web app running on mobile browser (on device instance of a client running in web browser):

  • No different than an app running in a desktop web browser
  • Deployed app instance identified by the URL of the web server it's served from (essentially, redirect_uri)
  • No standard identifier for the ephemeral session instance, but could be identified by an ephemeral session key pair
  • Cannot store secrets on deployed instance level, but CAN store secrets on ephemeral session level (in IndexDB etc)
  • No access to OS keychain or trusted key storage modules

@elf-pavlik
Copy link
Member Author

We could probably adopt terminology from https://tools.ietf.org/html/rfc7591#section-1.2

Client Software
Software implementing an OAuth 2.0 client.

Client Instance
A deployed instance of a piece of client software.

We've just had conversation with @dmitrizagidulin https://gitter.im/solid/app-authorization-panel?at=5da5f407870fa33a4df9abf3

We discussed it around OAuth 2.0 Dynamic Client Registration Protocol: A.4. Client ID per Client Instance or per Client Software

It looks that reusing client_id across multiple registrations may prevent distinguishing same client on different devices. While having different client_id with same redirect_uri may allow distinguishing them and still applying authorizations on redirect_uri level and not just on client_id level.

Mobile App A v.1.0 on Dmitri's iPhone is requesting permission to do !
Would you like to:

  1. grant that permission just for that app v1 on Dmitri's iPhone
  2. all versions of that app on all your devices

@bblfish
Copy link
Contributor

bblfish commented Oct 16, 2019

The Launcher App Proposal explains how the Launcher App can be in charge of building a AppId for an instance running for a particular user, and how it can authenticate a particular app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants