FYI: This article is a bit heavy on the technical solution and architectural side explaining the inner workings of the solution 🤓 . I promise the next article would be more user friendly with a demo.
In this post, I would like to describe the architectural flow of the solution I came up with to resolve the problem discussed before.
The Base Setup
Let's start by looking at the flow chart below (higher quality available here):
I built a Chrome extension that will allow a Sign-in with Coil, providing Project Insulate the credential access without releasing any personal identification information (PII). It also creates a user on the Insulate platform using a custom identifiable token on Firebase and keeps the user logged in the extension. Also, the provider (the one providing exclusive data) can easily register with Insulate with an email address to receive a clientId
and corresponding clientSecret
.
The Main Flow
This section delves deeper into how Insulate helps a provider verify the open unprotected call. The short description would be:
When a user opens a webpage, the Insulate Chrome Extension will automatically update the Insulate backend which in turn will verify an active subscription on the Coil account at that very moment. When the webpage makes the open call to the provider's backend to fetch data, the provider can now check-in with the Insulate backend to verify whether to allow access to the user or not.
The image below (higher quality available here) shows the step-by-step calls made to achieve this.
Looking at the diagram, you will notice that the Insulate extension will look for two particular tags on every webpage: monetization
and insulateId
. The provider needs to add the clientId
they received in the base setup step as the insulateId
meta tag on their webpage. If both the meta tags are found, the extension automatically sends a request to the Insulate backend (protected by Firebase user credentials) which indeed verifies the subscription on the Coil account for the user.
If valid, it creates and stores a block by hashing paymentPointer
(passed from the monetization
meta tag), clientSecret
(extracted using clientId
) and a uniquely created transactionId
. This transactionId
is passed on to the Chrome extension which then forwards it to the webpage via insulateTransactionId
event which can be fetched by the webpage as:
window.addEventListener("message", function (event) {
if (event.data.type && (event.data.type == "insulateTransactionId")) {
let transactionId = event.data.text;
insulateIdElement.textContent = transactionId;
// *** TODO: Make call to backend (provider) and send transactionId ***
}
}, false)
The provider can now use this transactionId
to be sent to its backend, which in-turn can verify the validity of this transaction by passing in the transactionId
, paymentPointer
used on the webpage, and the clientSecret
received in the base setup.
The Insulate backend will double-check by recreating the hash, and check if this block was created within the past 5 minutes. If so, it will return positively and mark the block used. If a second call is made within 5 minutes, it will let the provider know that the block exists but has already been used once.
Using this information, providers can be sure whether to provide the access to the exclusive content or not, while not requiring a user to sign in on their website and still being able to protect the data 💃 💃
I'll be posting a final post of the series in the coming days showcasing the project with a working demo.
Top comments (6)
Am I right in thinking that Insulate is a SSO service that masks user email address by mediating a session-based auth token between user agent and provider backend?
Couple questions:
Does this require everyone to have the Insulate extension along with the Coil?
Does Insulate stream micropayments on behalf of the user agent?
Who maintains provider inventory of exclusive content? It looks like both models are possible (i.e. managed by provider or on Insulate itself)?
How does provider trust
transactionId
generated by Insulate? This basically shifts the trust from user agent to Insulate right?Thanks for digging into this problem!
Insulate does not maintain any user session between the user and the provider; it only maintains a user session between the insulation infrastructure i.e. Chrome extension and Insulate backend. The provider backend can verify by connecting with Insulate backend via the clientId/clientSecret pair.
The aim is to not let the provider have any access to the user information, so there is no chance of PII leakage of any form.
Answering the questions:
transactionId
is generated uniquely once the extension registers a block (which is an authenticated process), and this sametransactionId
is used to create a hash when the provider's backend passes it for verification. So in any instance, if a faketransactionId
is being tried to pass (or even a repeated id), Insulate backend would not verify it, to keep the process secure.I hope that answers your doubts, but feel absolutely free to ask more questions here 😁
Thanks for clarifying on the approach, I think your project is really important because the current model of Web Monetization has two risks:
I don't actually think the intention of Coil is to track users, and there is no real reason that payments need to be coupled to this orthogonal problem of identity. I think an architecture that differentiates the two, and still prioritizes end-user and provider UX, will be key to ecosystem growth.
Agreed. That's a great way to put it!
Same, I don't think it's Coil's intention to do so, but since they hold the data, they do have the capability to do so. For me, it's more about providers not being able to track users, even if Coil can. Personally, keep anonymity between the content-viewing user and content-providing provider while still smoothly processing payments is really exciting!
Having Insulate extension definitely aids the cause, but at the end of the day, you do not want people to install two extensions. So somehow, if similar concept could be inherited within Coil, it would be nice (I'll say an easier and probably more efficient method over the receipt verifier for most providers)
Love the series and the detail, thank you!
Thanks, Chris! 🤗