Dolt Root Superuser Changes

RELEASEREFERENCE
5 min read

Version 1.46.0 of Dolt makes two important changes to improve the default root superuser. This default superuser is now persisted to disk, just like any other user account, and it is also now restricted to localhost by default. These changes fix a behavior that had surprised some customers, improve the default security posture of a Dolt sql-server, and change Dolt to more closely match MySQL's handling of the default root superuser.

The main behavior change we expect customers to see is that Docker customers will need to pass a new argument when starting a new Dolt sql-server Docker container, if they want to connect to the server from outside the Docker container. This behavior matches how the MySQL Docker image works, and is explained in detail below.

In this blog post, we explain the changes, why we made them, and show you how to control the root superuser initialization from a Docker container.

Previous Behavior

Let's start off by explaining how Dolt's root superuser worked before these changes. Dolt maintains user account and privilege data in a separate database, backed by a file called .doltcfg/privileges.db by default. This privileges database would be created the first time you created a user account. When no privileges database existed, an ephemeral root@% superuser was created with no password by default when you ran dolt sql-server. This was convenient and made it easy to access a Dolt sql-server, even if it was running inside a Docker container. However, one obvious downside of this, was that any host that had network access to the Dolt sql-server host could log in as the root superuser. We advised customers to use this default root account for initial testing and to create additional user accounts and passwords for production use.

One other effect of this implementation was that once you created any user accounts, the next time you restarted your Dolt sql-server the ephemeral root@% superuser wouldn't exist anymore. From a security perspective, this was good to limit root's access, but it caught many customers by surprise since they expected the root superuser to behave like MySQL's root superuser and not to disappear after user accounts were explicitly created.

New Behavior

The new initialization behavior for the root superuser is more secure and more intuitive. Now, the first time a Dolt sql-server is launched, the privileges database is initialized and a root@localhost superuser is created and persisted to the privileges database. This means that when you create new user accounts, the root superuser account won't disappear the next time you restart your sql-server. It also means that, by default, only connections from localhost are allowed to log in as the root superuser, which makes it easier to secure your Dolt sql-server.

The next time you restart your Dolt sql-server, the privileges database will already be initialized, so Dolt will not initialize the root superuser. Similarly, if you take an existing privileges database and configure a new Dolt sql-server to use it, Dolt will see that the privielges database has already been initialized and will not initialize a root superuser.

Docker Containers

The biggest user-facing change is for customers who use the Dolt sql-server Docker image. This Docker image is a really easy way to launch a Dolt sql-server inside a Docker container. Now that the root superuser is restricted to localhost, there's an extra argument you need to provide when you launch the image if you want to connect to the server as root from outside the Docker container.

To allow connections as the root user from outside the Docker container, we followed how the MySQL Docker image solves this same problem. When running your Docker container, you can use the -e flag to provide the DOLT_ROOT_HOST or DOLT_ROOT_PASSWORD environment variables, and the Docker entrypoint script will ensure the root superuser is configured according to those environment variables.

Here's an example of how to launch a Dolt sql-server Docker container with the root superuser configured to allow connections from any host (i.e. %) and with a password set for the root account. Whenever you open up an account to log in from any host, we strongly recommend you set a password, too.

docker run -e DOLT_ROOT_PASSWORD=secret2 -e DOLT_ROOT_HOST=% -p 3307:3306 dolthub/dolt-sql-server:latest

Here's a breakdown of what each parameter does:

  • docker run starts up a new container from a Docker image.
  • -e DOLT_ROOT_PASSWORD=secret2 sets the DOLT_ROOT_PASSWORD environment variable, which tells the Docker image to set that password for the root account, instead of the default empty password.
  • -e DOLT_ROOT_HOST=% set the DOLT_ROOT_HOST environment variable, which tells the Docker image to set the host wildcard % for the root account, which will allow root logins from any host, instead of restricting logins to localhost.
  • -p 3307:3306 maps port 3307 on the host system to port 3306 in the container, so you can connect to the Dolt sql-server from your host system.
  • dolthub/dolt-sql-server:latest is the Docker image to run, and the latest tag indicates to use the latest version of the image that your local Docker agent knows about. Keep in mind that this is the version your local Docker agent last saw mapped to latest, so you may need to first run docker pull dolthub/dolt-sql-server:latest to be sure you've got the latest version available on DockerHub.

Emergency Privileges Repair

A quick reminder that if you do ever lose the password for the root superuser, you can always launch dolt sql from the command line to get superuser access and repair privileges or reset passwords.

Alternatively, if you want to completely start fresh and remove all privilege information, you can delete the privileges database at .doltcfg/privileges.db. When you run dolt sql-server the root@localhost superuser will be recreated and you'll be able to manually recreate all users and grants.

Design Tenet: Early Initialization

One design tenet that helped guide this change was to ensure key components are initialized early to avoid having modes with different behaviors. Before this change, there were two modes of operation possible: one where the privileges component was active and one where it wasn't fully activated yet. Many parts of the system use the privileges database component, so many behaviors could change depending on whether the privilege database was active or not.

In practice, this meant Dolt had subtle differences in behavior depending on whether the privileges database had been initialized or not. As part of this work, we found a few behaviors that didn't work properly when the privilege system was enabled at server startup. Changing to initialize the privilege system whenever a sql-server was started made these hidden issues visible so we could fix them. For example, one of the issues we found and fixed was that the event scheduler couldn't properly reload existing events on sql-server restarts when privileges were in use.

Summary

These changes to Dolt's default root superuser make the root user behavior more predictable and more secure. The changes also better line up with MySQL's root superuser behavior, particularly when used in a Docker container.

If you want to talk about security, databases, or distributed versioning, come join us on the DoltHub Discord server! We're always happy to help people get started with Dolt and discuss ways Dolt can help you.

SHARE

JOIN THE DATA EVOLUTION

Get started with Dolt

Or join our mailing list to get product updates.