Reference

Every command and flag of baresql, as of version 0.1.0. baresql help lists the commands in the terminal and baresql help COMMAND shows the flags of one. A flag works with one dash or two, so -out and --out are the same. The README on GitHub is the full manual.

baresql audit [flags] [connection]      who can read what in a PostgreSQL database
baresql diff old.json new.json          compare two audits and list what changed
baresql lint [flags] file.sql ...       SQL that answers differently on SQLite, PostgreSQL, MySQL, MariaDB
baresql compare [engines] file.sql ...  run SQL on several engines and show where the answers differ
baresql rules [code]                    the differences lint knows, with each engine's recorded answer
baresql version                         print the version
baresql help [command]                  show help

audit

baresql audit [flags] [connection]
Flag Meaning
--out DIR where to write report.html and audit.json (default baresql-report)
--login NAME audit only these logins (repeat, or separate with commas)
--schema NAME audit only these schemas (repeat, or separate with commas)
--no-sample read no table data: find personal data by column names only
--sample-rows N rows to read per table when sampling, 1 to 10000 (default 200)
--baseline FILE an earlier audit.json: exit 1 if any login can now reach more
--timeout D time limit for each query, such as 30s (default 60s)
--format F what to print: summary (default), lines (one fact per line) or json

The connection is a postgres:// URL or a key=value string, as for psql. Whatever it leaves out comes from the usual PG* variables (PGHOST, PGUSER, PGPASSWORD and the rest) and from ~/.pgpass, so the password never has to be on the command line. TLS follows sslmode: disable, prefer (the default), require, verify-ca or verify-full, with sslrootcert for the certificate authority; sslrootcert=system uses the system’s certificates and implies verify-full. Unix sockets work as with psql (host=/var/run/postgresql). The login uses SCRAM-SHA-256 (with channel binding over TLS), MD5 or a cleartext password, whichever the server asks for.

diff

baresql diff [--format text|json] old.json new.json

Compares two audit.json files and lists the reach that grew, the reach that is gone and the other changes. --format json prints the comparison as JSON. It exits 1 when any login can reach more than before.

lint

baresql lint [flags] file.sql ...
Flag Meaning
--all also report notes
--engines LIST only differences among these engines matter, such as sqlite,postgres
--ignore CODES leave these rule codes out (repeat, or separate with commas)
--format F text (default) or json

- reads standard input. Lint learns column types from the CREATE TABLE statements it reads, so pass the schema along with the queries. A comment -- baresql:ignore integer-division on the line of a problem, or the line before it, silences that rule there; several codes are separated by commas, and -- baresql:ignore alone silences every rule on the line.

compare

baresql compare --sqlite --postgres URL --mysql URL --mariadb URL [flags] file.sql ...
Flag Meaning
--sqlite run on SQLite, in a new temporary database
--sqlite=FILE run on SQLite, in a temporary copy of FILE (the file itself is never opened)
--sqlite-program PATH the sqlite3 program to use (default: sqlite3 on PATH)
--postgres URL run on PostgreSQL
--mysql URL run on MySQL
--mariadb URL run on MariaDB
--all list every statement, also those answered alike
--format F text (default) or json

Name two engines or more. Connections are URLs: postgres://user@host/db (or any form baresql audit takes), mysql://user@host:3306/ and mariadb://user@host:3307/. MySQL and MariaDB URLs take tls=disable|preferred|require|verify, tlsca=FILE and socket=PATH. Leave passwords out of the URLs and set PGPASSWORD or MYSQL_PWD.

A statement may run for 60 seconds on every engine. On MySQL, statements other than SELECT meet a client limit of 75 seconds, after which compare stops. SQLite runs through the sqlite3 program, version 3.37 or later, in its safe mode.

rules

baresql rules [--format text|json] [code]

Without a code, lists every difference BareSQL Portable knows. With one, shows what differs and why, a minimal example with the answer each engine gave, a form that answers the same everywhere and what to write instead. --format json prints the whole catalog with its recorded answers.

Exit Codes

Code Meaning
0 nothing to report
1 the command found something: lint problems, answers that differ, access that grew past a baseline
2 the command could not run: bad arguments, no connection, unreadable files

baresql audit exits 0 when it finishes, findings or not, unless --baseline finds that access grew.

Output for Scripts

baresql audit --format lines prints one fact per line, sorted, the form the tests compare exactly:

read <login> <table>.<column> [<categories>] <route>
write <login> <table> <PRIVILEGE>[(<columns>)] <route>
function <login> <function> <route>
server <login> <capability> <route>
foreign-server <login> <server> <route>
default <creator> <schema> <objects> <PRIVILEGE> to <grantee>
finding <severity> <code> <subject>

The categories are the codes below, - for none. A ~ after them marks a view column computed from personal data, such as a name built from first and last names. audit.json holds the server, the settings of the run, every table and column with what it holds, each login with what it can read, change and run, the findings and what the audit couldn’t see.

baresql lint --format json prints a list of problems, each with its code, severity, file, line, column, the text it flagged, the message and the advice. baresql compare --format json and baresql rules --format json print what their text forms show.

Personal Data Categories

These codes are part of audit.json and never renamed.

Category Meaning
email email address
phone phone number
name person’s name
address postal address
birth-date date of birth
national-id national ID number
passport passport or licence number
tax-id tax ID
card payment card number
bank-account bank account (IBAN)
password password or password hash
secret key, token or secret
ip-address IP address
location precise location
health health data
sensitive special category data (religion, ethnicity, beliefs …)
gender gender
insurance-id insurance number

Finding Codes

Code Severity What it means
public-reads-personal high every role, including roles created later, can read personal data in a table
superuser-login medium a login is a superuser
set-role-superuser high a login can SET ROLE to a superuser
read-all-data medium a login is a member of pg_read_all_data or pg_write_all_data, or can SET ROLE to one
createrole-escalation high a login has CREATEROLE before PostgreSQL 16, where it can grant itself any role but superuser
see-all-queries low a login can read the text of every session’s queries
server-file-access high a login can read or write files, or run programs, on the database server
grant-option-personal medium a login may grant read access to personal data to others
admin-option medium a login can add members to a role that reads personal data
foreign-server-mapping low a login can use a foreign server through a user mapping
secdef-no-search-path high a security-definer function others can run does not set search_path
secdef-executable medium a security-definer function runs with the rights of an owner who reads personal data
rls-no-policies low row security is on for a table without any policy (its rows may still be read through a parent table)
rls-owner-login medium row security is not forced and the table’s owner can log in
view-bypasses-row-security high a view reads a row-security table with rights that skip its policies
default-grants-to-public medium default privileges grant future tables or functions to PUBLIC
md5-passwords medium logins have MD5 password hashes
connection-not-encrypted low the audit’s own connection did not use TLS (not reported for localhost and unix sockets)
cleartext-password-login medium the server asked for a cleartext password over an unencrypted connection
unexplained-access medium the catalogs and the server’s own checks disagree; please report it

Rule Codes

The 58 rule codes of BareSQL Portable are listed on the BareSQL Portable page, each with a post of its own.