Pothibo

Building a password-less system - Part One

If you enjoy post that talks about coding paradigm and show snippet, you may want to skip this one. For the rest of you, I will talk you through an idea, a concept that I came about a few weeks back. This is obviously a proof of concept and I submit to you an idea that could replace password in modern web application. Why? Because password aren't as safe as they used to be and also because the security level fluctuates enormously between web services. Passwords need to be hashed in a safe manner, solutions are not all equal (MD5 vs SHA1 for example) and staying up to date is a job by itself. Different solutions arose in the past years that either made your account more secure or tried to completely remove  the need to store your password on their server.

OpenID, Facebook Connect / Open Graph API, Persona are all different approaches each reaching a different level of adoption. In those examples, the developer needs to bridge third parties and connect the dot between the authentication provider and their own backend. It can brings confusion, bugs, instability, unavailability, etc. Basically, you authorize access through a third party then you match that session with a user you have in your database (if any) and binds the current session to that user.

Are we taking the problem backward?

The general audience do not care about password-less systems. That just doesn't compute in their brain, you would tell them it would be better for them and their answer could very well be: "meh". If you think I'm wrong, then feel free to explain why so many people have absurdly obvious and unsafe password (password, 12345, list goes on...). People don't care. Flat and simple. I believe it's us, the people that builds stuff, that loathe password.s Personally, I hate passwords because:

  • There's so many views, error handling, forms to build and customize just for the authentication process (signup, signin, recovery, error messages, etc);
  • The login process is something that is irrelevant to what you build. You build a bank system, need a login. You build wikipedia, still need a login;
  • Support (Forgot my password, can't remember which e-mail I signed up with, etc);
  • People use  stupid ass password and then expect the site to be secure;
  • Writing my 25 character long password on my iPhone drives me insane;
  • So many web apps have different rules about how long, which character needs to be in your password;
  • A service I use leaker my password, I need to reset it. Ok, what other service has the same password? Argh!

The solution I mentioned above (OpenID, FB Connect, Persona, etc) tackles some of the issues but it's still not perfect. Here's a few thing that happens to me on a daily basis. I have to login and enter my password every time one of those thing happen:

  • Clear my cache;
  • My girlfriend decided to check her mail on my computer;
  • Use a different browser;
  • Session with the provider expired;

What could replace the passwords altogether?

In order to replace passwords, there's one rule I believe that needs to be set.

The bar on entry must be as low for the general audience then it is right now by entering their password.

So I thought about this and I came to the following conclusion:

  • No system can be secured if they are infected, rooted, etc;
  • People use the function remember my password on their computer all the time;

  • If they use that function it's because they trust their own computer;
  • If they trust their own computer with saving their passwords, why not bind it to their account?

Doesn't make sense? Let me clarify.

URL Scheme can be used to communicate with a native application.

Schema

You know http://, ssl://, ftp://. Well Linux, OS X and Windows, iOS and probably others support application to register themselves with a custom URL Scheme. From there, if a user trigger a link on a webpage with the given scheme, it will call the registered application. The handshake is done by a native application that was previously downloaded and bound to the service by the user. Let's focus on the way the application works for now.

When a user clicks on login://domain.com/?{query_params}, the request is sent to the native application. From the URL, the application knows which key it needs to retrieve and who to contact using the base URL. This means that if your service is http://mycoolapp.com, you would create a link on the page login://mycoolapp.com and you would pass a session_id the server can associate the authenticator with your current browser session.

So the app knows you are trying to log in mycoolapp.com and fetches its key for that domain. It then communicates with mycoolapp.com and authenticate to the webserver. If the request is successful, the server authenticate the session and the browser is authenticated as the proper user. No password needed! To make things even more transparent, a websocket is connected between the server and the browser so when the authentication is fulfilled, the browser sends a refresh command to the browser. Refreshing the page would present the logged in page as you would normally expect when submitting your e-mail/password for example.

Authenticators do not need a third service provider

One of the reason I don't like OpenID, FB Connect, Persona is that the handshake is done through a third party. Anyone who has dealt with third parties in the past know that this link can be unstable, buggy, etc. I'm sure I don't have to list the reason why I don't personally like third party authentication: You probably have your reasons too.

Authenticator can be added and removed at any time

Let's say you lose your phone and you had the authenticator running on your device. Because every authenticator generates a unique key, you can remove a specific device from your account and still keep the other ones running.

What happens if the service I use leak my password?

Because every keys are unique, if a service you use is hacked and keys are leaked, the server can reset those keys and everything is safe again. Keys are unique to each services you bind your device to so it's impossible for someone who has your key on ABC to access XYZ.

Using this concept, would we need an application for every web app out there?

That would be silly, right? What would be nice is that everyone willing to use this system share the same authentication process. This way, we could use a single application to manage all our presences. Like KeyChain in OS X.

What happens when a user doesn't have an authenticator?

When a user wants to log in and doesn't have an authenticator (Someone else's computer, etc), you can fallback to a token sent by e-mail. What it does is, like during a confirmation process, it sends a unique token by e-mail to the user. The user logs in his email, and uses the link provided in the e-mail.

Prototype & Open source

So I have this prototype that runs on my computer and a demo server. It's been working for the past week now but it still needs to be tweaked. I will open-source the native OS X application & the library I created once they are in a working state for others to use. The plan is to include this authenticator process to two different projects I'm building right now to see how it behaves in production. If you'd like to add this authenticator to your personal project, please let me know in the comments or via Twitter!

If you have any other question, let me know.

Get more ideas like this to your inbox

You will never receive spam, ever.