sgo.to

The Mozilla Personas Protocol

This is a write down of the Mozila Personas protocol (1) as if the messages were exchanged over instant messaging.

+1 654 3434-6945 Yo, @example.com!
example.com Hey! What's up?
+1 654 3434-6945 Not much. Can I buy stuff?
example.com Sure.
example.com Hey @Browser, who is this?
Browser joined
Browser Just a sec, BRB.

In the first exchange, a website (in this example example.com) asks for the browser for an assertion:

navigator.id.get(callback);

The browser takes it from there and switches to a private group with the user to figure out which IDP they'd like to use:

Browser Yo, I hear you want to sign-in with example.com?
+1 654 3434-6945 Yep
Browser Ah, cool, just checking. What's your email address again?
+1 654 3434-6945 cooldude@email.com
Browser K. Just a sec, BRB.

Knowing which IDP to use, the Browser uses a convention to figure out how to load the provisioning URL:

https://email.com/.well-known/browserid

Which points the user to:

https://email.com/browserid/provision.html,

The Browser then proceeds to chat with the IDP:

email.com joined
Browser Yo
Browser Hey. @+1 654 3434-6945 is claiming they are cooldude@email.com. Is that right?
email.com Yep, cool dude.
Browser K. Can you put that on paper and send me his contact?
email.com Sure. What public key would you like to use?
Browser 7369130657357778596659
email.com Sure. What public key would you like to use?
email.com I attest that Sam Goto (cooldude@email.com) has an account here. 7369130657357778596659 can generate certificates on their behalf.
Browser K. Can you put that on paper and send me his contact?
Browser Neat, thanks!
Browser I'll kick you off right now because you don't need to be involved anymore.
email.com left

This conversation happens via newly introduced APIs:

 // get parameters of provisioning
navigator.id.beginProvisioning(function(email, cert_duration) {

// ... check if the current user is authenticated as 'email' ...
if (notAuthenticated()) {
navigator.id.raiseProvisioningFailure("user isn't authenticated");
return;
}

// request a keypair be generated by browserid and get the public key
navigator.id.genKeyPair(function(pubkey) {

// ... interact with the server to sign the public key and get
// a certificate ...
someServerInteraction(function(cert){
// pass the certificate back to BrowserID and complete the
// provisioining process
navigator.id.registerCertificate(cert);
});
});
});

With a newly minted certificate, the browser takes it back to the chat with example.com:

Browser Here is the certificate we got from email.com:
email.com I attest that Sam Goto (cooldude@email.com) has an account here. 7369130657357778596659 can generate certificates on their behalf.
example.com Neat, thanks! Sam, you are in, whats up?
Sam Goto Yay!

And the user is now logged in.

This is a large oversimplification, but should give you a sense of the kinda of privacy property it has.

Specifically, the IDP is unaware of most of the interaction here, namelly:

  • which relying party the user is signing-in to
  • at which moment the user is signing in

References