Problem
Users want an identity that can be used across the web and different devices, to comment, edit and interact.
The identity must have a private key that is not held on any centralized server infrastructure.
Our hyper.media domain accomplishes this for signing by keeping a local resident key in the browser. But it does not work on other domains.
Solution
Other domains can utilize hyper.media to sign content on their behalf. This must have a design that is resilient to domains who are bad actors, keeping the user's identity safe and only allowing some content to be delegated.
Workflow
Suppose a publisher is self-hosting a Seed site on ai-revolution.com (for brevity, air.com). The identity provider in this workflow is hyper.media but it could be another host if the user wants and if the publisher supports it.
The user wants to create comments on air.com using their existing identity from hyper.media.
On air.com the publisher has a local storage that is empty, so the first prompt is to sign in with the identity provider. The user clicks that button which opens a new window: hyper.media/hm/auth#site=air.com&abilities=...
This redirect includes the host that will receive the (cross-site) ability to sign, and details about those abilities, such as blob types and locations where commenting is allowed. The identity provider shows a screen to the user, asking if air.com should have the ability to sign for them.
The identity provider will first make sure the identity exists, or will prompt the user to create it. When the user confirms the cross-site abilities, the hyper.media client will store that information to indexeddb. This window can now be closed. At this point the user can close that window, cross-site authentication is complete.
In the original window where the comment draft exists, there is an iframe which has loaded the identity provider hyper.media/hm/embed/auth. Internally it is polling the indexeddb for the containing origin's abilities. When they change, they are and communicated via postmessage so the publisher knows what sort of content can be signed in the iframe.
When the comment is submitted, air.com passes in the unsigned comment blob to the identity provider iframe (again, via postmessage). The identity provider iframe will make sure the ability is present and valid. Then will sign it. It will pass the signed comment back to the air.com who requested it.
At this point the signed comment needs to be saved to at least one server, and it can be sent to air.com or hyper.media, or both, whoever is willing to distribute it. For now, air.com will be the one responsible for saving and distributing the comment blob, which will result in a good UX because the comments will be refetched after saving to show the user the comment they just created.
Why this is Secure
The postMessage to the identity provider iframe includes the origin, so the identity provider knows what origin is trying to sign something.
Resident key is still locally saved in the identity provider
To be cautious, all embeds will be prohibited via a content security policy, aside from paths that begin with /hm/embed
The abilities are saved in indexeddb and checked from the iframe before any signing is done
Concerns
I'm not sure if the resident key can be accessed by the identity provider client from an iframe. This needs to be tested.