rbactool.py
Role-based access control (RBAC) is only available in SciDB Enterprise Edition.
Use the rbactool.py script for saving and restoring SciDB access control information, independently of any save or restore of SciDB array data. By default this script is located in /opt/scidb/<version>/bin/rbactool.py .
The scidb_backup.py script incorporates the functionality of rbactool.py. If you use scidb_backup.py, you may not need to use rbactool.py.
Usage rbactool.py [-h]Â [-A AUTHFILE] [-H HOST] [-f {afl,raw-json,json}] [-i INPUT] | |
---|---|
Option | Explanation |
-A/--auth-file AUTHFILE | SciDB authentication file. Only needed if the -r/--restore option is used. See Using iquery in Security Mode. |
-h/--help | Print usage and help information. |
-H/--host HOST | Host where the SciDB system catalog resides, usually the coordinator host. Default is 127.0.0.1. |
-f/--format FORMAT | Desired output format. Default is JSON. |
-i/--input FILE | Input file, assumed to be in JSON format. |
-p/--port PORT | System catalog port. Default is 5432. |
-r/--restore | Load the input data into Postgres. Requires both -i/--input and dbname arguments. Skips pre-existing entities to avoid accidental privilege escalation. |
-U/--username USER | Postgres role name for reading or modifying the system catalog. |
-v/--verbose | Print more debugging information. |
dbname | Name of the Postgres database being used as the system catalog. |
Operation Modes
Rbactool.py takes different actions depending on the presence or absence of the -i/--input, -r/--restore, and dbname options. The table below summarizes these operation modes.
--input ? | dbname ? | --restore ? | Action |
---|---|---|---|
Y | N | -- | Print the input file on stdout, in the format specified by -f/--format . |
N | Y | -- | Print the contents of the system catalog access control tables in the format specified by -f/--format . |
Y | Y | N | Compare the input file against the contents of the system catalog, and print only the access control information present in the input file but not in the system catalog. That is, print the access control information that would be created if we were restoring this input file, or if we were using scidb_backup.py to restore a backup archive with %rbac.json equivalent to the input file.  This "dry run" mode shows what access control would have been restored had the -r/--restore option been given. |
Y | Y | Y | Compare the input file against the contents of the system catalog, compute the access control information present in the input file but not in the system catalog, and execute AFL queries to add that access control information to the system catalog. Your SciDB account must have sufficient privileges to execute the generated AFL. |
The first three modes are display modes, printing access control information from a file or from the system catalog, or printing the difference between the two. The last mode is restore mode, and actually updates the system catalog with access control information from a file. The scidb_backup.py script uses the same code path as rbactool.py's restore mode when restoring access control information from a backup archive's %rbac.json
metadata file.
Restore Mode Avoids Privilege Escalation
In restore mode, not all of the input file's contents are injected into the catalog. Instead, restore mode takes a conservative approach to avoid accidental privilege escalation. In particular:
- If a role, user, role membership, or namespace in the input file is already in the catalog, it will not be restored. This avoids "already exists" or "already belongs to role" errors for those entities.
- If a user was not restored because the user already exists in the catalog, then none of the user's role memberships will be restored from the input file. Restore mode assumes that if a user exists in the catalog, that user's access permissions are correct as-is and should not be modified.
- If a role was not restored because the role already exists in the catalog, then none of the role's permission entries for pre-existing namespaces will be restored from the input file. Restore mode assumes that if a role exists in the catalog, that role's access permissions are correct as-is and should not be modified. The role's permissions for any namespaces restored from backup will be restored, however.
- Permissions (that is, <namespace, role, rights> triples) in the input file are not restored if the catalog already contains a permission for that <namespace, role> combination. For example, if user bob had
crlud
permissions on namespace customer1 at the time a backup was taken, and in the meantime bob's access to customer1 has been reduced torl
, then when the backup is restored bob's access will remainrl
. He will not regain hiscrlud
access rights just because a backup was restored.
These rules are intended to be general enough for most purposes while preventing accidental security problems. If your installation has special requirements, you can use one of the display modes and the --format afl
option to generate an AFL script suitable for use with iquery. You can use a text editor to modify the JSON input file, the AFL output file, or both.
Removing Users vs. Suspending Users
A consequence of item 1 above is that, if user andrew's account was removed using drop_user but later on a backup is restored that contains an entry for andrew in its metadata, the andrew user account will be recreated. To avoid this, use the spaam.py script to suspend accounts rather than removing them with drop_user.
$ spaam.py --suspend andrew Suspended user andrew $
This prevents future logins, but leaves the account record in the catalog.
Examples
The output of some of these examples has been edited to keep the listings short.
With just the cluster name "kif" as argument, rbactool.py shows the existing access control data for the cluster.
$ rbactool.py kif > kif-rbac-snapshot-2019-04-17.json $ cat kif-rbac-snapshot-2019-04-17.json { "is_canonical": true, "metadata_version": "5", "perms": [ { "namespace": "beta", "permissions": "cu", "role": "uploader" }, { "namespace": "beta", "permissions": "lr", "role": "paulo" }, { "namespace": "public", "permissions": "clrud", "role": "paulo" }, { "namespace": "public", "permissions": "cu", "role": "uploader" }, { "namespace": "public", "permissions": "rl", "role": "alice" } ], "role_members": [ { "role": "admin", "user": "alice" }, { "role": "operator", "user": "paulo" } ], "roles": [ "admin", "operator", "uploader" ], "spaces": [ "beta", "public" ], "users": [ { "method": "raw", "name": "alice", "password": "66gd/3H+SS8Xb+nwsz67SBeYoFbLULJlgucuS1aSUPU8PSmFQurO9yG21CXWzyRxW4HpK+7vNFBkVw6V2PLx7A==", "salt": "" }, { "method": "raw", "name": "paulo", "password": "x1nClCH+U4kKrcFTEDyMg5l/EnaVWCBwdNCg/9pn3aBQGEIEaTUyXVLZ1oqfKhfGv+IALry8KTYZ8w026xUl2w==", "salt": "" }, { "method": "raw", "name": "scidbadmin", "password": "eUCUk3B57IVO9ZfJB6CIEHl/0lxrWg/7PV8KytUNY6kPLhTX2db48GHGHoizKyH+uGkCfNTYZrJgKzjWOhjuvg==", "salt": "" } ] } $
Use the
-f/--format
option to show the AFL commands necessary to recreate the current kif access control from scratch.$ rbactool.py -f afl kif create_user('alice', '66gd/3H+SS8Xb+nwsz67SBeYoFbLULJlgucuS1aSUPU8PSmFQurO9yG21CXWzyRxW4HpK+7vNFBkVw6V2PLx7A==', _method:'raw', _salt:''); create_user('paulo', 'x1nClCH+U4kKrcFTEDyMg5l/EnaVWCBwdNCg/9pn3aBQGEIEaTUyXVLZ1oqfKhfGv+IALry8KTYZ8w026xUl2w==', _method:'raw', _salt:''); create_namespace(beta); create_role('admin'); create_role('operator'); create_role('uploader'); add_user_to_role('alice', 'admin'); add_user_to_role('paulo', 'operator'); set_role_permissions('uploader', beta, 'cu'); set_role_permissions('paulo', beta, 'lr'); set_role_permissions('paulo', public, 'clrud'); set_role_permissions('uploader', public, 'cu'); set_role_permissions('alice', public, 'rl'); $
Show the access control data recorded in a recent backup of the cluster.
$ ls -l /tmp/Bkp total 56 -rw-rw-r-- 1 scidb scidb 627 Apr 16 18:26 ARROW -rw-rw-r-- 1 scidb scidb 621 Apr 16 18:26 ARROW.alpha -rw-rw-r-- 1 scidb scidb 618 Apr 16 18:26 ARROW.beta -rw-rw-r-- 1 scidb scidb 631 Apr 16 18:26 BOTTLE -rw-rw-r-- 1 scidb scidb 625 Apr 16 18:26 BOTTLE.alpha -rw-rw-r-- 1 scidb scidb 623 Apr 16 18:26 BOTTLE.beta -rw-rw-r-- 1 scidb scidb 627 Apr 16 18:26 GLOVE -rw-rw-r-- 1 scidb scidb 621 Apr 16 18:26 GLOVE.alpha -rw-rw-r-- 1 scidb scidb 619 Apr 16 18:26 GLOVE.beta -rw------- 1 scidb scidb 931 Apr 16 18:26 %manifest -rw-rw-r-- 1 scidb scidb 619 Apr 16 18:26 PEN -rw-rw-r-- 1 scidb scidb 610 Apr 16 18:26 PEN.alpha -rw-rw-r-- 1 scidb scidb 608 Apr 16 18:26 PEN.beta -rw------- 1 scidb scidb 1991 Apr 16 18:26 %rbac.json $ $ rbactool.py -i /tmp/Bkp/%rbac.json { "is_canonical": true, "metadata_version": "5", "perms": [ { "namespace": "alpha", "permissions": "clrud", "role": "alice" }, { "namespace": "alpha", "permissions": "cu", "role": "uploader" }, ...LOTS OF JSON DELETED, BUT SEE NEXT EXAMPLE... } $
Show the same access control information from the backup archive, formatted as AFL commands.
$ rbactool.py -i /tmp/Bkp/%rbac.json -f afl create_user('alice', '66gd/3H+SS8Xb+nwsz67SBeYoFbLULJlgucuS1aSUPU8PSmFQurO9yG21CXWzyRxW4HpK+7vNFBkVw6V2PLx7A==', _method:'raw', _salt:''); create_user('betty', 'u1eT+bBSZB4n/7VWyurhoxyNtoIfmU8XPcYhdpwgn3z/Kb/5hqGBUnaF5O/k3zq7QidDPw0lqvBXLaQcva8vQw==', _method:'raw', _salt:''); create_user('paulo', 'x1nClCH+U4kKrcFTEDyMg5l/EnaVWCBwdNCg/9pn3aBQGEIEaTUyXVLZ1oqfKhfGv+IALry8KTYZ8w026xUl2w==', _method:'raw', _salt:''); create_namespace(alpha); create_namespace(beta); create_role('admin'); create_role('operator'); create_role('uploader'); add_user_to_role('alice', 'admin'); add_user_to_role('paulo', 'operator'); add_user_to_role('betty', 'uploader'); set_role_permissions('alice', alpha, 'clrud'); set_role_permissions('uploader', alpha, 'cu'); set_role_permissions('betty', alpha, 'rl'); set_role_permissions('betty', beta, 'clrud'); set_role_permissions('paulo', beta, 'clrud'); set_role_permissions('uploader', beta, 'cu'); set_role_permissions('paulo', public, 'clrud'); set_role_permissions('uploader', public, 'cu'); set_role_permissions('alice', public, 'rl'); $
When both the
-i/--input
option and the cluster name are given, rbactool.py shows the access control that would be added to the cluster if the backup archive were restored. This example uses-f afl
for brevity. Some warnings ("scidb_rbac: ...") are printed on stderr, since some of the access control records from the backup are already present in the running cluster.$ rbactool.py -i /tmp/Bkp/%rbac.json -f afl kif scidb_rbac: Skipping users who already exist: [u'alice', u'paulo'] scidb_rbac: Skipping roles that already exist: [u'admin', u'operator', u'uploader'] scidb_rbac: Skipping namespaces that already exist: [u'beta'] scidb_rbac: Skipping role memberships for pre-existing users: [{u'role': u'admin', u'user': u'alice'}, {u'role': u'operator', u'user': u'paulo'}] scidb_rbac: Skipping permissions that would overwrite an existing entry: [{u'namespace': u'beta', u'permissions': u'clrud', u'role': u'paulo'}, {u'namespace': u'beta', u'permissions': u'cu', u'role': u'uploader'}, {u'namespace': u'public', u'permissions': u'clrud', u'role': u'paulo'}, {u'namespace': u'public', u'permissions': u'cu', u'role': u'uploader'}, {u'namespace': u'public', u'permissions': u'rl', u'role': u'alice'}] create_user('betty', 'u1eT+bBSZB4n/7VWyurhoxyNtoIfmU8XPcYhdpwgn3z/Kb/5hqGBUnaF5O/k3zq7QidDPw0lqvBXLaQcva8vQw==', _method:'raw', _salt:''); create_namespace(alpha); add_user_to_role('betty', 'uploader'); set_role_permissions('alice', alpha, 'clrud'); set_role_permissions('uploader', alpha, 'cu'); set_role_permissions('betty', alpha, 'rl'); set_role_permissions('betty', beta, 'clrud'); $
When this backup is restored:
- The namespace alpha will be re-created.
- User betty will be re-created, since she was removed and not suspended. She will regain her old access rights to namespaces alpha and beta, and her role as an uploader.
- The existing user alice will regain her old access rights to alpha.
- The existing role uploader will regain its old access rights to alpha.
- The existing user paulo will not regain his old access rights to beta, since in the interim his access rights have been changed to
rl
(read, lookup).