We are excited to announce a new authentication system that has been rolled out to all GrapheneDB databases last week (Feb 14th 2017).
Back in the days when we launched GrapheneDB in 2013, Neo4j did not support authentication.
Common patterns to deploy Neo4j included setting up a proxy to deal with SSL encryption and enforce HTTP basic authentication or installing an unmanaged server extension to take care of authentication.
We had to roll out our own authentication mechanism from scratch, if we were to provide a hosting service. From the beginnings until some days ago, we created a set of credentials including a random password upon database creation. These credentials would be up for display on the UI any time if the user needed them. This fact implied storing the credentials in plain text within our database.
Fast forward to 2015. In version 2.2.0, Neo4j introduced user management and secured the HTTP REST endpoint with HTTP basic authentication, which was at that point a standard for any Neo4j driver supporting authentication. Because HTTP basic authentication is a standard, our authentication was 100% transparent and compatible with all Neo4j drivers available.
Then, in Neo4j 3.0 user authentication was consolidated and integrated into the Bolt protocol as well. At GrapheneDB we implemented a Bolt-aware proxy layer, one of its purposes being to extend our authentication system to work with Bolt too.
Drawbacks of our legacy authentication system
The main drawbacks about GrapheneDB’s legacy authentication system come down to various risks related to, and ultimately the security of the database.
The credentials were stored in plain text in our database and up for display in the UI any time. It was easy to copy & paste credentials and accidentally expose them via unsafe channels: sending them in emails, posting them on Stackoverflow, on Github or in a support ticket.
We usually pay a lot of attention to this and reach out to users to rotate their credentials when we are aware that they have been exposed, but having credentials in front of you in plain text makes one automatically less concerned about protecting them.
When submitting support requests, our users have the option to allow GrapheneDB engineers to access their databases. In order to connect to a users’ database our engineers need valid credentials, so internally our engineers have been using the one set of credentials to connect.
While our engineers are very security concerned and well trained to never expose credentials, this is problematic in terms of auditing and might raise concerns with our users. As soon as a set of credentials is shared by several individuals, it becomes very challenging to keep track of who has copies of them and who might have used them to connect.
Credentials for one-off sessions
Another challenge is dealing with temporary connections. If you need to briefly connect to your Neo4j instance via Neo4j Browser or CLI, which credentials do you use?
It is extremely easy to accidentally store credentials in a web browser. In fact, most of modern browsers ask the user by default if they wish to store the credentials they have provided to log in.
When using CLI tools such as cycli, it is also extremely easy for credentials to land in your command line history. The history file is usually stored in plain text in your home directory, while the browsers at least tend to default to some sort of secure encryption to store credentials.
Our new secure and flexible authentication system
Our new authentication system addresses many of the issues with the legacy authentication system:
- it’s compatible with any Bolt and HTTP REST drivers that support authentication
- we only use strong passwords through lengthy, randomly generated tokens
- all tokens are stored encrypted and are only visible once upon creation. After that no one (not even our engineers) can retrieve a password
- should we need to connect to a user’s database (assuming we have been given permission by the owner) we will use specific internal temporary passwords that can be audited, not any of the database users
- plain text passwords have been removed from the interface and sharing passwords is discouraged, because it’s much easier for any team member to create database users as needed
- it supports temporary credentials for one-off connections, such as connecting from CLIs or with the Neo4j Browser
- users can drop and rotate credentials anytime: unused credentials, when someone leaves the team or if you think a secret might have been compromised or leaked
Making your GrapheneDB databases safer
We are very excited to improve the security for all our databases and ultimately our users. Moving forward:
- New databases support the new authentication system only, making them safer by default
- Existing databases will continue to support the legacy password system to authenticate. Create pairs of credentials as needed and drop the legacy password as soon as you can to make them safer. You will find clear step by step instructions to guide in the transition process here.
Managing database users
You can find more information on the new database authentication system in the dedicated section of our developer docs.