Dolt Signed Commits

FEATURE RELEASE
11 min read

Introducing Signed Commits in Dolt

At the core of Dolt is a commit graph which tracks the changes made to your database over time. Just like a Git commit, a Dolt commit is a snapshot of the database at a point in time. Dolt commits are immutable, and attached to each commit is the identity of the person that made the commit. By default, neither Git nor Dolt do any kind of verification of the identity of the person who made the commit. This means that anyone can make a commit and claim to be anyone else. This is where signed commits come in. Signed commits allow you to cryptographically verify that a commit was made by a known and trusted author. The next release of Dolt will include support for signed commits.

Setup

Before you can sign a commit you must have gpg installed, and you must have a gpg key. To install gpg on your machine I will make the same recommendation that Github does:

To store your GPG key passphrase so you don't have to enter it every time you sign a commit, we recommend using the following tools:

For Mac users, the GPG Suite allows you to store your GPG key passphrase in the macOS Keychain.
For Windows users, the Gpg4win integrates with other Windows tools.
You can also manually configure gpg-agent to save your GPG key passphrase, but this doesn't integrate with macOS Keychain like ssh-agent and requires more setup.

Now that gpg is set up you'll need to create a gpg key using gpg --gen-key. Now you should see your key when you run gpg --list-keys.

~>gpg --gen-key
gpg (GnuPG/MacGPG2) 2.2.41; Copyright (C) 2022 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Note: Use "gpg --full-generate-key" for a full featured key generation dialog.

GnuPG needs to construct a user ID to identify your key.

Real name: Example User
Email address: example@dolthub.com
You selected this USER-ID:
    "Example User <example@dolthub.com>"

Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: revocation certificate stored as '/Users/brian/.gnupg/openpgp-revocs.d/2B586AA46696F41F13AEF7C14661D5B1DDBBF14C.rev'
public and secret key created and signed.

pub   rsa3072 2024-09-16 [SC] [expires: 2026-09-16]
      2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
uid                      Example User <example@dolthub.com>
sub   rsa3072 2024-09-16 [E] [expires: 2026-09-16]

~>gpg --list-keys
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   3  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 3u
gpg: next trustdb check due at 2026-09-16
/Users/brian/.gnupg/pubring.kbx
-------------------------------
pub   dsa2048 2010-08-19 [SC] [expired: 2024-05-11]
      85E38F69046B44C1EC9FB07B76D78F0500D026C4
uid           [ expired] GPGTools Team <team@gpgtools.org>
uid           [ expired] [jpeg image of size 6329]

pub   rsa4096 2020-05-04 [SC] [expired: 2024-05-03]
      B97E9964ACAD1907970D37CC8A9E3745558E41AF
uid           [ expired] GPGTools Support <support@gpgtools.org>

pub   rsa3072 2024-09-16 [SC] [expires: 2026-09-16]
      2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
uid           [ultimate] Example User <example@dolthub.com>
sub   rsa3072 2024-09-16 [E] [expires: 2026-09-16]

Once you have a gpg key you can sign a commit by running dolt commit -S <key_id> -m "message". The -S flag tells Dolt to sign the commit, and <key_id> is the id of the key you want to use to sign the commit. This should be the id of the key created with gpg --gen-key as seen when you run gpg --list-keys.

Need either a screenshot or a code block showing the usage dolt commit -S <key_id> -m "message"

Now that we have a signed commit we can verify the signature and view the commit using dolt log --show-signature.

~/datasets/dolt/signedtest>dolt init
Successfully initialized dolt data repository.
~/datasets/dolt/signedtest>dolt sql -q 'CREATE TABLE t (pk int primary key)'
~/datasets/dolt/signedtest>dolt add .
~/datasets/dolt/signedtest>dolt status
On branch main
Changes to be committed:
  (use "dolt reset <table>..." to unstage)
	new table:        t
~/datasets/dolt/signedtest>dolt commit -S 2B586AA46696F41F13AEF7C14661D5B1DDBBF14C -m "signed commit"
commit vat0pftfoul1i3kdaf2tmm6a61acui8c (HEAD -> main)
Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:29:14 -0700 2024

        signed commit

~/datasets/dolt/signedtest>dolt log --show-signature
commit vat0pftfoul1i3kdaf2tmm6a61acui8c (HEAD -> main)
gpg: Signature made Mon Sep 16 15:29:14 2024 PDT
gpg:                using RSA key 2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
gpg: Good signature from "Example User <example@dolthub.com>" [ultimate]

Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:29:14 -0700 2024

        signed commit

commit pgaf1fmkbjnqtbaq4f8jnprnkpul8os8
Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:28:14 -0700 2024

        Initialize data repository

To avoid specifying the key id every commit, you can specify the key id to your dolt config by running dolt config --global sqlserver.global.signingkey <key_id>. Once this is done you can sign commits by running dolt commit -S -m "message" omitting the key_id that was required before.

Finally to avoid the need to specify the -S flag on every commit you can set the sqlserver.global.gpgsign key in your config by running dolt config --global sqlserver.global.gpgsign true. Once this is done you can sign commits by running dolt commit -m "message". If you want to turn on signed commits for specific repositories and not other you can use the dolt config --local command instead of dolt config --global.

~/datasets/dolt/signedtest>dolt config --global --add sqlserver.global.signingkey 2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
Config successfully updated.
~/datasets/dolt/signedtest>dolt config --global --add sqlserver.global.gpgsign true
Config successfully updated.
~/datasets/dolt/signedtest>dolt sql -q 'INSERT INTO t VALUES (0);'
Query OK, 1 row affected (0.01 sec)
~/datasets/dolt/signedtest>dolt add .
~/datasets/dolt/signedtest>dolt status
On branch main
Changes to be committed:
  (use "dolt reset <table>..." to unstage)
	modified:         t
~/datasets/dolt/signedtest>dolt commit -m "signing turned on through the config"
commit 2tnc84paqi6lhs1p0vedm81kkm1lli66 (HEAD -> main)
Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:33:39 -0700 2024

        signing turned on through the config

~/datasets/dolt/signedtest>dolt log --show-signature
commit 2tnc84paqi6lhs1p0vedm81kkm1lli66 (HEAD -> main)
gpg: Signature made Mon Sep 16 15:33:39 2024 PDT
gpg:                using RSA key 2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
gpg: Good signature from "Example User <example@dolthub.com>" [ultimate]

Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:33:39 -0700 2024

        signing turned on through the config

commit vat0pftfoul1i3kdaf2tmm6a61acui8c
gpg: Signature made Mon Sep 16 15:29:14 2024 PDT
gpg:                using RSA key 2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
gpg: Good signature from "Example User <example@dolthub.com>" [ultimate]

Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:29:14 -0700 2024

        signed commit

commit pgaf1fmkbjnqtbaq4f8jnprnkpul8os8
Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:28:14 -0700 2024

        Initialize data repository

Signed Commits on dolt sql-server

The dolt sql-server command is a way to run a MySQL compatible server on top of a Dolt database. Server's configured to sign commits as specified above will sign commits made by the database user verifying that the commit was made by a user signed in to the database with the appropriate credentials. This can be useful for auditing purposes, or for ensuring that the data in the database is coming from a trusted source.

In this example I am going to run dolt sql-server after configuring signing as above. Next I will create some users and make commits as those users. Finally I will show that the commits made by the users are signed by the key specified in the config.

Below is the server window showing the server starting up.

~/datasets/dolt/signedtest>dolt sql-server -udolt -ppass -H127.0.0.1
Starting server with Config HP="127.0.0.1:3306"|T="28800000"|R="false"|L="info"
INFO[0000] Server ready. Accepting connections.
WARN[0000] secure_file_priv is set to "", which is insecure.
WARN[0000] Any user with GRANT FILE privileges will be able to read any file which the sql-server process can read.
WARN[0000] Please consider restarting the server with secure_file_priv set to a safe (or non-existent) directory.

Now the first client will connect as the main user "dolt" and create some new users.

~>mysql -udolt -ppass -h127.0.0.1
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 8.0.33 Dolt

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CREATE USER 'u1'@'%' IDENTIFIED BY 'u1pass';
Query OK, 0 rows affected (0.02 sec)

mysql> CREATE USER 'u2'@'%' IDENTIFIED BY 'u2pass';
Query OK, 0 rows affected (0.02 sec)

mysql> GRANT ALL ON *.* TO 'u1'@'%';
Query OK, 0 rows affected (0.02 sec)

mysql> GRANT ALL ON *.* TO 'u2'@'%';
Query OK, 0 rows affected (0.01 sec)

mysql> exit
Bye

Now I will connect as user "u1" and make a commit.

~>mysql -uu1 -pu1pass -h127.0.0.1 -Dsignedtest
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 8.0.33 Dolt

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> INSERT INTO t VALUES (1);
Query OK, 1 row affected (0.02 sec)

mysql> CALL dolt_commit('-Am','signed commit made by u1');
+----------------------------------+
| hash                             |
+----------------------------------+
| dlr1tb05stmgh7j0d7nof5crbsp9geq6 |
+----------------------------------+
1 row in set (0.35 sec)

Now I will connect as user "u2" and make a commit.

~>mysql -uu2 -pu2pass -h127.0.0.1 -Dsignedtest
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 8.0.33 Dolt

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> INSERT INTO t VALUES (2);
Query OK, 1 row affected (0.01 sec)

mysql> CALL dolt_commit('-Am','signed commit made by u2');
+----------------------------------+
| hash                             |
+----------------------------------+
| hklae59puktibf6mqbq9iq27tl9tphgs |
+----------------------------------+
1 row in set (0.15 sec)

Now that we have our commits we will close the server and check the output of dolt log --show-signature.

commit hklae59puktibf6mqbq9iq27tl9tphgs (HEAD -> main)
gpg: Signature made Mon Sep 16 15:54:36 2024 PDT
gpg:                using RSA key 2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
gpg: Good signature from "Example User <example@dolthub.com>" [ultimate]

Author: u2 <u2@%>
Date:  Mon Sep 16 15:54:36 -0700 2024

        signed commit made by u2

commit dlr1tb05stmgh7j0d7nof5crbsp9geq6
gpg: Signature made Mon Sep 16 15:51:07 2024 PDT
gpg:                using RSA key 2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
gpg: Good signature from "Example User <example@dolthub.com>" [ultimate]

Author: u1 <u1@%>
Date:  Mon Sep 16 15:51:07 -0700 2024

        signed commit made by u1

commit 2tnc84paqi6lhs1p0vedm81kkm1lli66
gpg: Signature made Mon Sep 16 15:33:39 2024 PDT
gpg:                using RSA key 2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
gpg: Good signature from "Example User <example@dolthub.com>" [ultimate]

Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:33:39 -0700 2024

        signing turned on through the config

commit vat0pftfoul1i3kdaf2tmm6a61acui8c
gpg: Signature made Mon Sep 16 15:29:14 2024 PDT
gpg:                using RSA key 2B586AA46696F41F13AEF7C14661D5B1DDBBF14C
gpg: Good signature from "Example User <example@dolthub.com>" [ultimate]

Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:29:14 -0700 2024

        signed commit

commit pgaf1fmkbjnqtbaq4f8jnprnkpul8os8
Author: Brian Hendriks <brian@dolthub.com>
Date:  Mon Sep 16 15:28:14 -0700 2024

        Initialize data repository

As you can see, all the commits were signed by the key specified in the config. The original commits made through the command line have the author of the locally configured dolt user, and the commits made by connecting to the dolt server using the mysql command line client are signed by server saying that the changes were committed by users u1, and u2.

Conclusion

Signed commits are a powerful tool for verifying the authenticity of commits in a Dolt database. They allow you to verify that a commit was made by a known author, and that the commit has not been tampered with. We hope that this feature will be useful to our users, and we look forward to hearing your feedback. If you have any questions or comments please reach out to us on Discord.

SHARE

JOIN THE DATA EVOLUTION

Get started with Dolt

Or join our mailing list to get product updates.