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

User controlled Authorization App and App launcher proposal #45

Open
bblfish opened this issue Oct 3, 2019 · 9 comments
Open

User controlled Authorization App and App launcher proposal #45

bblfish opened this issue Oct 3, 2019 · 9 comments

Comments

@bblfish
Copy link
Member

bblfish commented Oct 3, 2019

A requirement for Solid apps is that each App (even from a remote origin) needs to make authenticated requests for a user to resources on the Web. The problem is that if any such App must authenticate to a resource by signing headers in the case of HTTP-Sig or passing signed tokens with OAuth, those private keys or tokens can be shared by the App with other origins, which makes the authenticated user quite vague: is it the user, the App, the Origin or a friend of the Origin that is authenticating (see discussion)?

The proposal here is to allow a user to select an Authentication App whose JS is placed on an Origin it fully trusts, to deal with Apps, generate keys for them, and provide an authentication service in browser for those apps using Window.postMessage or something similar (see Information Security Stack Exchange Question: Can JavaScript from Different Origins Communicate Securely?). Given that the Auth App is also the one used to launch those apps, it will know which apps it is signing auth requests for, allowing us to solve the problem of Identifiers for Applications too.

The user can link from his WebID Profile to the trusted Authentication App like this:

<#me> :authenticationApp </safe/authentication> . 

With the potentially protected </safe/authentication> file

<#> a SecureLauncherApp;
   :launchSrc <AppLaunchner.html>;
   :appCollection <myApps/> .

And the Authentication App can keep track of all the Apps that the user likes to use, each App
keeping info about the app, browser environment, date used, public keys, ... with something like the following, any restrictions about what it is able to do,...

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

The process here is the following. Alice is behind the computer, and it is hers.

  1. the App Launcher is loaded from the Alice's Origin (her Pod/Freedom Box), and displays all the apps that it can find in the user's profile following the links above (illustrated in the computer as
    the app to the left of the screen)
  2. Alice launches one of her Apps, which opens in another frame, window, or whatever is right. (In the depiction we see a Calendar App to the right of the computer)
  3. the Calendar App wants to download a resource that requires authentication from Alice's friend Bob's Freedom Box.

We then have the following exchange (numbers fit illustration below)

  1. The Calendar App requests a signature of some content (headers in the case of HTTP-Sig) from the App Launcher running in another window using Window.postMessage
  2. The App Launcher finds the private key for the Calendar App that it stored in its local storage, and signs the request.
  3. The Calendar App makes the requests with the signed token (http headers, or whatever) to Bob's server.

image

This could fulfill many roles, of which:

  • keeping track of each app a user likes, with preferences and rights for that app (can the app write to any resource or only limited resources). This would allow it to be clear which app is speaking for the user, and indeed allow identification of apps via this launch url.
  • showing the user a panel of his all his apps, and allowing the user to launch them, without restriction as to which origins they are located on.
  • creating public/private keys securely for each app using eg. JS Crypto's Generate Key
  • doing all the authentication for these launched apps for any origin using Window.postMessage.
  • the App could furthermore keep a log of all authorizations made to allow the user to see what each app was up to.

There may be better methods than Window.postMessage to do this. Ideally all authenticated requests could go through a browser based HTTP proxy (perhaps using Service Workers?) controlled by the App launcher. This would further enable

  • A way to completely limit the visibility of OAuth tokens to the trusted OAuth app.
  • The Auth App to work with a HTTP proxy.
  • The Auth App to restrict where an App can write to, so if a user wants to try an app as a display app, but does not trust it to write yet, the Auth App can do this
  • Move all the Authentication logic into one App that can specialise in doing this very well, and so relieve all other apps from having to implement these correctly, and give a consistent authentication UI
  • a place to set authentication policies, which the Auth App can then use to reduce the need to ask the user if she wants to authenticate to each origin.
  • select the best ID or Credential to use for each resource given the ACLs published by the resource following the principle of least privilege,

Can this be done with current browser technology?

Note: This extends @elf-pavlik's notion of an App Authorization manager, by specifying a method for the App to actually do the authentication for other apps (using either postMessage) - and proposing to find potentially better ones (eg. ServiceWorkers?)

@bblfish
Copy link
Member Author

bblfish commented Oct 3, 2019

According to this blog post Service Workers! Your first step towards Progressive Web Apps Service Workers are limited to fetch from the Origin they were loaded from. (This may still make it useful for working with a Proxy server.)

There used to be something called Foreign Fetch but this was removed in 2017 from Chrome, see Remove foreign fetch #1188.

It could be that one can use WebWorkers for fetching remote documents, I am not sure.

@jaxoncreed
Copy link
Contributor

jaxoncreed commented Oct 4, 2019

which makes the authenticated user quite vague: is it the user, the App, the Origin or a friend of the Origin that is authenticating

The token that we have set up does allow you to interpret what the user is.

jwtSign({
  "iss": THE_APP_ORIGIN example: "https://www.decentphotos.example",
  "aud": THE_RESOURCE_SERVER_BEING_QUERIED example: "https://bob.solid.example",
  id_token: jwtSign({
    "iss": IDENTITY_PROVIDER example"https://secureauth.example",
    "sub": USER_WEBID example: "https://alice.coolpod.example/profile/card#me",
    "aud": THE_APP_ORIGIN example: "https://www.decentphotos.example",
    "cnf":  CLIENT_PUBLIC_KEY
  }, IDENTITY_PROVIDER_PUBLIC_KEY)
}, CLIENT_PRIVATE_KEY)

Some things have been omitted from the token but as you can see, from this token you can deduce the app based on the origin and the user.

@bblfish
Copy link
Member Author

bblfish commented Oct 4, 2019

Thanks for those details. I think during the teleconf we discussed quite a lot the problem of signing things with private keys made by remote apps. The problems were as follows

  • If the token is not signed by a key owned only by the user, then such a token sent by the OAuth service can be forwarded by the App to it's origin or elsewhere, which can then also use it to authenticate. This is why there is a need to keep the life of OAuth tokens short.
  • If the token is signed say by a key in the browser created by a less trusted App, then there is no way to limit the use of the private key: the less trusted App can forward the private key to it's origin or elsewhere to also sign such tokens.

The idea of having a trusted key store is that this would allow:

  • signing of HTTP headers as with HTTP-Sig proposal without the private key being accessible to less-trusted apps.
  • perhaps (I know less about OAuth) signing of OAuth token in a way that would guarantee that the less trusted App was not the one doing the signing, but that it was signed by a key in the control of the user. Perhaps by combined this with HTTP-Sig we can even tie the token to that session.

Another advantage of this App Launcher/Keychain is that it makes the "redirect_url" used by OAuth tokens now efficient. The launcher App knows which URL was launched in which frame, and so can precisely identify the current instance as a running of that app type. See the discussion on Origins and redirect_url in issue issue 22 of Authentication Panel: how are redirect_urls authenticated.

@bblfish
Copy link
Member Author

bblfish commented Oct 7, 2019

This was discussed on Mon 7 Oct in the Authentication Panel, see Panel notes

@elf-pavlik
Copy link
Member

How would this work with use case described in https://github.com/solid/authentication-panel/issues/31 ?

@bblfish
Copy link
Member Author

bblfish commented Dec 2, 2019

I don't see any difference as far as access control and authentication goes between RDF and other content @elf-pavlik . I implemented a Hyper Address Book in ScalaJS that could download RDF, people's pictures linked to from their foaf files, sign HTTP-Signature headers and display all that as a single page app.

@bblfish bblfish closed this as completed Dec 2, 2019
@bblfish
Copy link
Member Author

bblfish commented Dec 2, 2019

Must have accidentally closed the "close issue button"

@bblfish bblfish reopened this Dec 2, 2019
@elf-pavlik
Copy link
Member

elf-pavlik commented Dec 2, 2019

@bblfish if Bob shares with Alice https://bob.example/postcards/alice-b-day which responds only with text/html. When Alice navigates to that URL directly with her browser, how would you see Launcher App playing any role here?

@bblfish
Copy link
Member Author

bblfish commented Dec 2, 2019

Ah I see. That could be an interesting use case for a browser plug-in.

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

3 participants