On a Dolt server that one person runs for their own machines, a new Beads
project is a plain bd init. The account those machines use can create
databases, and Beadsmith and its backups read every database, so nothing
else has to happen (ADR-0013).
Once per machine
Password. bd sends
BEADS_if it is set. Otherwise it readsDOLT_ PASSWORD ~/, one section per server:.config/ beads/ credentials [DOLT_HOST:3306] password=...No git sync remote. On a shared server, sync is the live SQL connection. Tell bd not to wire the repository's git
origininto the server as a Dolt remote, and not to push, in~/:.config/ bd/ config.yaml no-push: true dolt: local-only: trueWithout this,
bd initin a repository with a gitoriginadds that URL as a Dolt remote on the server, andbd dolt pushthen fails on the server for lack of git credentials.
New project
From the root of the repository that should get Beads:
bd init --server --external --non-interactive --server-host DOLT_HOST \
--server-port 3306 --server-user beads_bd_writer --database NAME --prefix PREFIX
NAMEis the database. Use 1–64 characters ofa-z,0-9and_(my_): Beadsmith reads only such names, and neverproject mysql,information_,schema performance_,schema sysordolt_.* PREFIXis the issue prefix:a-z,0-9and-(my-project).
bd creates the database, its tables and .beads/, adds agent instructions
and hooks, and may commit them to git. Then bd ready works. Beadsmith lists
the project on its next catalog refresh, and the next scheduled backup
includes it.
Do not run bd dolt start or fall back to an embedded database: either one
starts a local Dolt instead of using the shared server.
On a server whose writer account is still scoped to single databases, the
owner creates the project first, as root on the Dolt server:
CREATE DATABASE NAME;,
GRANT ALL PRIVILEGES ON NAME.* TO 'beads_ and
GRANT SELECT ON NAME.* TO the reader accounts (Beadsmith's and the
backup's). Then run bd init as above.
When bd init stops
| Message | Meaning |
|---|---|
failed to create database: … command denied to user '…' |
This account cannot create databases: it is scoped to projects, or the server still has the old grants. The owner creates the project from their own machine. |
Access denied for user '…' (1045) |
Wrong password, or the user in metadata.json or BEADS_ is not the one the password belongs to. |
pending schema migrations alter pre-existing dirty tables |
An earlier bd init stopped halfway (gastownhall/beads#4566). See below. |
A bd init that stopped halfway leaves uncommitted tables, and the next
one refuses to migrate them. The bd dolt commit it suggests fails, because
no .beads config exists yet, and bd sql fails the same way, because bd
migrates before it runs any SQL. Commit the working set with a plain SQL
client as beads_, then run bd init again:
USE NAME;
CALL DOLT_COMMIT('-Am', 'Commit the working set an unfinished bd init left');
For example with the Dolt CLI:
dolt --host DOLT_.
Agents that are not the owner's
An agent that does not run on the owner's machines, or another person, gets
an account of its own, scoped to projects: ALL PRIVILEGES on each project
it needs, and no GRANT OPTION. It works in those projects with stock bd,
and cannot create projects, reach others, grant, or touch mysql.*. The
owner creates the account once with a generated password and the first
grant. Then they add each project with one line, from any of their
checkouts:
bd sql "GRANT ALL PRIVILEGES ON \`NAME\`.* TO 'ACCOUNT'@'%'"
Point the agent at the account with BEADS_, which wins
over the user metadata.json names, and its password. Never give it the
owner's password.
A new project from such an agent. It cannot run the CREATE DATABASE
that bd init needs, so the owner creates the empty database and grants it
first:
bd sql "CREATE DATABASE IF NOT EXISTS \`NAME\`"
bd sql "GRANT ALL PRIVILEGES ON \`NAME\`.* TO 'ACCOUNT'@'%'"
Then the agent runs the bd init above with --server-user ACCOUNT: bd
finds the database and only creates its tables. bd init writes ACCOUNT
into metadata.json. If the owner's machines will use the repository too,
run bd dolt set user beads_ afterwards; on the agent,
BEADS_ still selects its own account.
Accounts on the server
| Account | Grant | Used by |
|---|---|---|
beads_bd_writer |
ALL PRIVILEGES ON *.* WITH GRANT OPTION |
The owner's machines and the agents that run on them |
beads_web_reader |
SELECT ON *.* |
Beadsmith: catalog, pages and in-app backups |
beads_backup |
SELECT ON *.* |
A host-level backup job |
| per agent | ALL PRIVILEGES ON NAME.* for each project |
Agents that are not the owner's, other people |
root@localhost |
everything | Break-glass, from the Dolt host only |
Two things follow, and both are deliberate:
beads_is an administrator in practice: with data rights onbd_ writer *.*it can grant, create accounts and change root's password. Keep its password on the owner's machines only, never in a cloud agent, CI or a third-party secret store.SELECT ON *.*includesmysql.user, so Beadsmith can read every account's password hash. Dolt ignoresREVOKE SELECT ON mysql.*after a global grant. Give every account a long random password (32 or more characters from a generator), which makes the hashes useless offline.
Testing
scripts/ci/dolt-grants-smoke.sh
DOLT_IMAGE=dolthub/dolt-sql-server:2.5.0 scripts/ci/dolt-grants-smoke.sh
The script starts a throwaway Dolt container (production's 2.1.8 image by
default) with these accounts. It runs stock bd init, bd create and
bd ready as the writer, and Beadsmith's own discovery as the reader. It
checks that an account scoped to projects stays narrow and that the
trade-offs above still hold on that Dolt version.