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.