~egtann/sum

9d713f3f568dc3d92c4e07117e811f58b22d4204 — Evan Tann 4 months ago 5a82fd4
update readme
1 files changed, 18 insertions(+), 99 deletions(-)

M README.md
M README.md => README.md +18 -99
@@ 1,116 1,35 @@
# sf

sf (SQL filter) declaratively configures user roles and permissions in SQL
databases. Its configuration is based heavily on the syntax of pf firewall in
OpenBSD.
sf(1) declaratively configures user roles and permissions in SQL databases. Its
configuration is based heavily on the syntax of pf firewall in OpenBSD.

sf works around incredible shortcomings in MySQL user management, but it may be
useful for other databases as well. Currently there's only support for MySQL
sf(1) works around incredible shortcomings in MySQL user management, but it may
be useful for other databases as well. Currently there's only support for MySQL
but patches for additional databases are welcome.

## Why use sf?
See this article on [SQL User
Management](https://www.egt.run/~egtann/sql-user-management) to understand the
rational for this.

* MySQL doesn't have roles in the widely available v5.7. Users need to be
  individually managed. v8 is often not offered in cloud environments.
* Columns and tables cannot be individually denied. You either grant access to
  all tables, or you have to manually list out each and every table you want to
  allow.
## Install

Doing this by hand means:

* You need to update permissions everytime the database changes, which you'll
  likely forget to do.
* You need to do the same updates for every user, and it's easy to make a
  mistake or have users go out-of-sync.
* Since user management in MySQL is so tedious, it's likely to be ignored,
  where you'll have a single `root` user shared by everybody, or users
  according to role-levels (read, write, root), but then you lose access to
  logging to see who specifically performed each action.

These issues can have catastrophic security consequences. sf solves these
problems and makes user management easy and automatic.

## How it works

Given a SQL schema like the following:

```
> SHOW TABLES
admins
admin_recovery_codes
messages

> DESCRIBE admins
id            INTEGER
email         TEXT
password_hash TEXT
```

And a `sf.conf` input similar to the following:

```
read  = { bob jim }
write = { alice@localhost _dashboard }

# default deny
deny all

# allow root to do anything
allow root

# grant access to specific statements across any table
allow $write db dashboard table any statement { select insert update delete }

# allow all select statements, except for admins.password and everything in
# admin recovery tables
allow $read db dashboard table any statement select
deny  $read db dashboard table admins statement select column password_hash
deny  $read db dashboard table admin_recovery_codes statement select
```

This will be outputted to stdout using `-d` for a dry run:

```
$ sf -d
REVOKE ALL PRIVILEGES FROM '%'@'%';

GRANT ALL PRIVILEGES TO root@'%' WITH GRANT OPTION;

GRANT SELECT, INSERT, UPDATE, DELETE TO alice@localhost;
GRANT SELECT, INSERT, UPDATE, DELETE TO _dashboard@'%';

GRANT SELECT (id, email) ON dashboard.admins   TO bob@'%';
GRANT SELECT (id, email) ON dashboard.admins   TO jim@'%';
GRANT SELECT             ON dashboard.messages TO bob@'%';
GRANT SELECT             ON dashboard.messages TO jim@'%';

FLUSH PRIVILEGES;
```

Notice that the `admins.password` field is not allowed for the readers, nor is
access to the `admin_recovery_codes` table.

## Usage

$ git clone git@git.sr.ht:~egtann/sf && cd sf
$ make
$ sudo make install
```
sf [-f sf.conf] [-d] [-u root] [-p] [-H 127.0.0.1] [-P 3306] [-ssl-key]
	[-ssl-cert] [-ssl-ca]

# see all flags and their uses
$ sf -h

# see grants that will be applied
$ sf -d
After installation, check the man pages for usage information for sf(1) and
sf.conf(5).

# once happy with them, run without -d to apply the roles directly in your
# database
$ sf
```
## Contact

Since columns and tables are whitelisted, you'll want to re-run `sf` after
every database migration.
To report bugs, discuss functionality or submit patches, email [this
list](mailto:~egtann/all@lists.sr.ht).

## TODO

* quoted values, e.g. multi-word statement "alter routine"
* combine users into the `permissions` struct to simplify code?
* more tests
* Postgres, MariaDB, MySQL v8 support