Use this page when your bot runs on a machine you cannot log in to, such as a server or a chat bot’s host, and you only talk to it in a chat. The bot installs and runs the engine there. You run one command on your own computer, with the admin connection string. The admin connection string never reaches the bot’s machine.
Who does what
Section titled “Who does what”| Where | Who | What |
|---|---|---|
| The bot’s machine | Bot | Runs basalt init --remote. Gets a setup code. Starts the engine afterwards. |
| The chat | Both | The bot shows you the setup code and its fingerprint. You tell it when done. |
| Your own computer | You | Runs basalt init --setup-code with your admin connection string. |
| Your Postgres | You | Receives the guard, the agent role and its tables, in one transaction. |
Before you start
Section titled “Before you start”basaltis installed on the bot’s machine and on your own computer. See Install. Your own computer must be macOS or Linux.- You know the Postgres connection string without its password. Supabase shows it with a
[YOUR-PASSWORD]placeholder. See Hosts for which string to pick. - You can reach your Postgres from your own computer. The bot’s machine needs to reach it too, because the engine connects from there.
1. The bot makes a setup code
Section titled “1. The bot makes a setup code”The bot runs this on its own machine. The connection string has no password in it.
basalt init --remote --agent my_bot --operated-by=agent \
--write public.leads --read public.lead_notes \
--database-url "postgresql://postgres@HOST:5432/postgres"
--operated-by=agenttells BasaltDB that the bot, not you, runs machine steps such as starting the engine.--writelists tables the bot may read and change.--readlists tables it may only read.- If the connection string has a password, the command refuses it, does not write it anywhere, and tells you to change your database password. Never paste it to a bot.
- The command does not ask for an admin credential. It ignores
BASALT_ADMIN_DATABASE_URL. It has no prompt.
The bot generates the agent’s password and keeps it in a file only it can read. Only a verifier of that password goes into the setup code. Nobody can log in with a verifier.
The command prints the setup code in a block of its own, then its fingerprint:
basalt-setup.1.eJxVjMEKwjAQRP9lzhJMPWjzK6WHEFcb...
Setup fingerprint: 3f9a 21c0 7d44 e1b2 90ac
The code is valid for 24 hours and works once. While the code waits, running the command again prints the same code. A change to the tables, or --new-code, makes a new code and retires the old one. An expired code is replaced by running the command again.
The bot shows you the code and the fingerprint in the chat. Use a code block, so the chat does not read the underscores as emphasis.
2. You run the code on your own computer
Section titled “2. You run the code on your own computer”basalt init --setup-code SETUP_CODE
It asks for the admin connection string at a hidden prompt, or reads BASALT_ADMIN_DATABASE_URL. It is used once and never written anywhere.
Before it changes anything, the command checks the code and shows you a summary:
- The code is whole, not expired, and not dated more than 5 minutes ahead of your computer’s clock.
- Your connection string names the same database as the one the bot’s engine connects to. A mismatch is refused, not asked about.
- It shows the fingerprint. Check that it matches the fingerprint your bot gave you in the chat. If it does not, stop and ask the bot for a new code. A code someone else posted in the chat would show a different one.
- It says what will happen, in fixed words. A first setup reads
This creates the agent my_bot (role basalt_agent_my_bot). Its password comes from the code: only whoever made this code can log in as basalt_agent_my_bot. - It lists what the bot can do: read and change rows in the tables you named, up to 10 rows at a time without asking you, 11 to 50 with your approval, never more. It cannot change your tables’ structure. Tables outside
publicare flagged. - It asks the row-level security question for each table that hides its rows, as
basalt initdoes. See Hosts. - It shows the SQL and asks
Run this? [y/N]. Add--yesto skip the question, or--dry-runto print everything and run nothing.
Answer y. The setup runs in one transaction, so it is all or nothing: every table or none. If a step fails, your database is as it was.
If no passkey is registered, the command then opens a page to register one. Open it, confirm with your passkey and paste the code the page shows. See Passkeys. Add --add-passkey to register another.
It ends with:
Done. Tell my_bot to check its status.
3. The bot starts its engine
Section titled “3. The bot starts its engine”basalt init --remote does not install or start the engine. The bot does that on its own machine, by running basalt engine --config PATH, or by installing it as a service. Until your setup has run, the engine answers every call with UNAVAILABLE and the reason SETUP_PENDING, and tells the bot to ask you to run the code.
When the engine sees that your setup ran, it serves the bot normally. It needs no restart.
4. Tell the bot
Section titled “4. Tell the bot”Tell the bot in the chat that you ran the code. It calls its status tool and confirms it is ready. You can also check on the bot’s machine:
basalt status --agent my_bot
Change something later
Section titled “Change something later”Any change after the first setup goes the same way: the bot makes a new code, and you run it on your own computer.
| You want to | The bot runs | You run |
|---|---|---|
| Add or remove a table | basalt init --remote with the new --write and --read lists |
basalt init --setup-code CODE |
| Give the bot a new password | basalt init --remote --new-code |
basalt init --setup-code CODE |
| Upgrade the guard | basalt init --remote, which makes an upgrade code when the guard is older |
basalt init --setup-code CODE |
basalt upgrade refuses on an engine your bot runs, because it would ask for your admin connection string on the bot’s machine. See Upgrade.
If it does not work
Section titled “If it does not work”Messages you can see on your own computer:
| Message | What to do |
|---|---|
This setup code expired on <time> |
Ask the bot for a new code. It makes one by running basalt init --remote again. |
This setup code is damaged; copy it again. |
The chat cut or changed the code. Copy it again from a code block. |
This setup code was already used on <time> |
A code works once. Ask the bot for a new one. |
A newer setup for my_bot already ran |
An older code is refused after a newer one ran. Use the newest code. |
This setup code is for database ... |
Your admin connection string points at another database. Use the one for the database in the code. |
... already exists. This code would replace its password |
The agent role already exists. Ask the bot for a new code for that agent. |
Update basalt on this computer to at least ... |
Your basalt is older than the one that made the code. Install the current version. |
This is not a Basalt setup code. |
The text is not a setup code. Copy the whole line that starts with basalt-setup.1.. |
This setup code is for guard version N, but setup codes need guard version 16 or later |
The bot’s basalt is too old. Ask it to upgrade basalt and make a new code. |
This setup code claims a time in the future |
Check this computer’s clock, or ask the bot for a new code. |
What keeps this safe
Section titled “What keeps this safe”- The admin connection string is used only on your own computer. No command on the bot’s machine asks for it or accepts it.
- The setup code holds no secret. It holds the table lists, the role name, a verifier for the bot’s password, and the database it is for.
- The SQL that runs comes from your own
basalt, not from the code. - The fingerprint lets you check that the code you run is the one your own bot made.
- The code is valid for 24 hours and works once. Postgres enforces that, as well as your computer’s clock.
- An existing agent’s role is never taken over by a first-setup code.
Approving on a bot’s engine
Section titled “Approving on a bot’s engine”An engine your bot runs serves its approval and undo pages from the BasaltVault portal (portal.basaltvault.app), not from the bot’s machine. Ask the bot to undo a run, and it shows you a link. See Undo a run and Passkeys.
- Connect an agent: the short version, next to OpenCode, Claude Code and Codex.
- Hosts: the connection string for your database host.
- Upgrade: keep the guard current.
BasaltDB · Apache-2.0