Skip to content
BasaltDBBasaltDB
Star

Configuration

View as Markdown

The engine reads one JSON file, engine.json. basalt init writes it and updates it each time you run init. You rarely edit it by hand. This page lists every key, so you know what a value does when you see it.

What Linux macOS
Engine config (default) /etc/basalt/engine.json /Library/Application Support/Basalt/engine.json
Agent sockets and the person socket /run/basalt/ /Library/Application Support/Basalt/run/
State directory (stateDir) /var/lib/basalt /Library/Application Support/Basalt/state
The agent’s connection string <config dir>/agents/NAME.url, mode 0600 <config dir>/agents/NAME.url, mode 0600

If you run init with --config, --socket-dir or --credential-file, the engine runs as you in the foreground. Init writes the config and the credential file itself, under your config directory, and prints the one basalt engine --config ... command. Without them, init offers to install the engine as a background service. The connection string with the agent’s password goes into the credential file, never into engine.json.

{
  "socketDir": "/run/basalt",
  "mode": "SERVICE",
  "personUids": [501],
  "pagesUrl": "http://localhost:8787",
  "limits": { "statementTimeoutMs": 5000, "readRowLimit": 1000 },
  "agents": [
    {
      "name": "demo_bot",
      "osUser": "imantumorang",
      "credentialFile": "/etc/basalt/agents/demo_bot.url",
      "initArgs": ["--agent=demo_bot", "--write=basalt_demo.leads,basalt_demo.lead_notes"]
    }
  ]
}
Key Type Default What it does
socketDir string the path in the table above Holds one socket per agent, <socketDir>/<name>.sock. Required.
agents array One entry per agent. At least one. See Agent keys.
limits object see below The read row limit and the time limit.
stateDir string the path in the table above Where the engine keeps each agent’s last verified ledger chain head (<stateDir>/<agent>.head.json, mode 0600) It verifies from that head on start and every hour.
pagesUrl string http://localhost:8787 The base URL of the approval, undo and passkey pages. The page origin, and so the passkey’s origin, is this URL. The older key approvalPage is still read, origin only.
pagesAddr string 127.0.0.1:<port of pagesUrl> Where the engine serves those pages on loopback. "off" turns them off. A non-loopback address is refused. If the port is taken the engine refuses to start and names it.
linkBudget integer 1800 The longest long link, in characters, that the engine hands an agent as the way to open a page. Short links are never measured.
operatedBy string PERSON PERSON or AGENT: who runs machine steps on the engine’s machine. See A bot on its own computer.
mode string SAME_USER SERVICE when init installed the background service, else SAME_USER. Only SERVICE opens the person socket.
personUids array none OS user ids that may use the person socket. Init records yours. An empty list admits nobody.
directAddr string off A loopback address that a tunnel of yours forwards to, for the direct transport. "off" or empty is off. Only with the portal as pagesUrl.
vault string OFF ON or OFF. Whether the engine dials out to the Vault for portal short links.
vaultUrl string the Vault Overrides the Vault’s address, for development and tests only: a ws:// URL on a loopback address.
devLocalPages boolean false Lets an agent-operated engine use local pages, for development only. Every personMessage then carries a warning.
pii object see below Sizes the classification dictionary. See Column classes.

With operatedBy: AGENT, pagesUrl is the hosted portal, because the loopback pages would belong to the bot’s machine.

Key Default What it does
statementTimeoutMs 5000 The time limit on a query. The agent role has its own limit, --statement-timeout on basalt init (30 seconds by default), which also covers preview_revert. Between 1 ms and 10 minutes.
readRowLimit 1000 The most rows a query may return. Between 1 and 100,000. A query over it is QUERY_TIMEOUT.

Agents never set limits. The numbers in context: Limits and defaults.

Key Default What it does
pii.maxMemoryMB 512 The memory budget of the classification dictionary. The engine sets GOMEMLIMIT to twice this unless the environment sets it.
pii.scanRowsPerSecond 20000 How fast the engine scans your tables to build the classification dictionary.

basalt service install writes the service’s memory limits from maxMemoryMB at install time. After raising it, run basalt service install again with the same flags so the unit is rewritten.

Each entry of agents has:

Key What it does
name The agent’s name: lowercase letters, digits and _. Its role is <prefix>_agent_<name>. person is reserved.
osUser The OS user the agent runs as, the only one allowed on its socket. Defaults to you at init.
credentialFile The file that holds the agent’s connection string. Mode 0600, owned by the engine’s user.
initArgs The flags basalt init was run with, saved as strings. Every “run init again” step uses exactly these, plus the one change it is for.
setup A pending setup from your laptop: setupId, kind, guardVersion, expiresAt, code and fingerprint. Removed once the setup runs. Nothing secret.

initArgs saves a flag only when its value is not the default, except --agent and --os-user. It never holds the admin connection string, --database-url or a one-shot flag such as --yes, --dry-run or --rotate-password. A value that is a connection URL or holds password= is refused.

Variable Used by What it holds
BASALT_ADMIN_DATABASE_URL init, uninstall, passkey remove, classify Your admin connection string. Without it these commands ask at a hidden prompt. It is never written anywhere.
BASALT_DATABASE_URL log, approve, revert, passkey, upgrade An agent connection string, in same-user mode. A flag always wins over it.

BASALT_ADMIN_DATABASE_URL must be a postgres:// or postgresql:// URL. A keyword and value string is refused before init connects. basalt init --remote ignores it, on purpose.

What Name
Prefix basalt, set with --prefix.
The guard’s schema basalt_meta, with its owner role <prefix>_guard.
An agent’s role <prefix>_agent_<name>. Through Supabase’s pooler, <prefix>_agent_<name>.<ref>.
The group of agent roles <prefix>_agents.

An agent role must be a plain role. Init refuses an existing role that is a superuser, can create roles or databases, bypasses row-level security, belongs to any role other than <prefix>_agents, or owns objects in the database. A role name is at most 63 bytes.

Init builds the agent’s connection string from yours. It keeps the scheme, hosts, ports and database, swaps in the agent’s user and password, and keeps only these parameters: host, port, dbname, sslmode, sslrootcert, sslcrl, sslcertmode, sslnegotiation, sslsni, channel_binding, require_auth, target_session_attrs, connect_timeout, application_name, min_protocol_version, max_protocol_version and default_query_exec_mode. It drops every other parameter, among them user, password, passfile, service, servicefile and your TLS client identity (sslcert, sslkey, sslpassword). sslrootcert and sslcrl are file paths. After basalt service install, the engine’s OS user must be able to read them.

Run basalt status --agent NAME. It prints the config path, whether the engine runs, the socket and state directories, the pages URL, operatedBy and each problem with its fix. It never prints the credential file’s contents. See CLI.

BasaltDB · Apache-2.0