I’d like to start a discussion around the permissions in Passbolt, as I have several requirements in a small company environment which are currently hard to meet.
PART ONE: I’d like to start by ensuring I understand the existing rights model.
As far as I can see, the only documentation for Passbolt is the FAQ, and it doesn’t cover this in any detail.
Here’s what I’ve managed to gather so far.
(1) Firstly: there are the system roles. In the database there are four roles defined:
mysql> select name,description from roles;
+-------+----------------------------+
| name | description |
+-------+----------------------------+
| admin | Organization administrator |
| guest | Non logged in user |
| root | Super Administrator |
| user | Logged in user |
+-------+----------------------------+
However in my installation, I don’t see the “root” (Super Administrator) role in use at all:
mysql> select r.name,count(*) from users u join roles r on u.role_id=r.id group by r.name;
+-------+----------+
| name | count(*) |
+-------+----------+
| admin | 7 |
| guest | 1 |
| user | 21 |
+-------+----------+
3 rows in set (0.00 sec)
Nor can I see how to promote anyone to the root role. When I’m logged in as administrator and look at other users, the GUI just has a check box (“This user is an administrator”).
I believe that the purpose of “admin” is to create and delete users and groups, and that admins can see all users and groups on the system (can normal users??)
I’m not sure if there’s anything else that Admins can do. In particular, being an admin doesn’t let you add users to groups (only Group Managers can do that). And being an Admin does not let you even see the existence of passwords which are not shared with you.
I don’t have any idea of the purpose of the “root” role, nor the “guest” role. I see there is one guest user, with username anonymous@passbolt.com
.
(2) Next, there are the rights on passwords (or “resources” as they’re known in the database).
I see three types of permission: “can read” (1), “can update” (7), and “is owner” (15).
mysql> select type,count(*) from permissions group by type;
+------+----------+
| type | count(*) |
+------+----------+
| 1 | 29 |
| 7 | 25 |
| 15 | 109 |
+------+----------+
3 rows in set (0.00 sec)
“can read” and “can update” are obvious. As far as I understand it, “is owner” can also modify which Users and/or Groups it is shared with, and what levels of access those Users and Groups have.
Each permission row refers to one resource (aco), and adds a permission either for one User or Group (aro).
mysql> select aro, aco, count(*) from permissions group by aro, aco;
+-------+----------+----------+
| aro | aco | count(*) |
+-------+----------+----------+
| Group | Resource | 64 |
| User | Resource | 99 |
+-------+----------+----------+
2 rows in set (0.00 sec)
You can get a full list of permissions for each resource like this:
mysql> select r.id,r.name,p.type,p.aro,IFNULL(u.username,g.name) as name
from resources r
left join permissions p on p.aco='Resource' and p.aco_foreign_key=r.id
left join users u on p.aro='User' and p.aro_foreign_key=u.id
left join groups g on p.aro='Group' and p.aro_foreign_key=g.id
order by r.id;
There is a view called “users_resources_permissions” which does something similar, but it is quite a complex query (I think it flattens out groups).
(3) There are permissions for Groups.
Groups can contain Users (but not other groups, i.e. no nesting).
A user can either be “Member” or “Group Manager” in a group. I presume this is the “is_admin” flag in the groups_users table.
As far as I can tell, only a Group Manager can add/remove users into a group.
So if I understand all this correctly, there are three ways that a user can gain access to a password:
- The password Owner can add sharing access directly to that User
- The password Owner can add sharing access to some Group that the User is already a member of
- If the password is already shared with a group, then the Group Manager can add the User to that group
Am I right so far? This means that the “Admin” role doesn’t come into play at all, for controlling access to passwords.
PART TWO: The problems
I have deployed passbolt in a small company. It’s becoming extremely useful, but there are number of issues which have come to light.
(1) Whenever a new password is created, it has by default only a single owner. If that person leaves the company, then:
- there’s no way to delete the user (since PB refuses to delete a user who is the sole owner on one or more resources)
- there’s no longer any way to change the sharing settings on that password
And if the owner is away temporarily (e.g. on holiday) it’s not possible to modify the sharing on that password.
WORKAROUND: if the password is shared with some other user or group, they can be promoted to owner by a SQL update on their permission, to set type=15.
(2) Audit: we need to be able to list all passwords which are in the system, and who they are shared with. Currently, if you are logged in as Admin role you can see all Users and Groups, but you cannot see any passwords which are not shared with you (not even the fact that they exist).
WORKAROUND: direct SQL query, like the one I showed above.
(3) Password recovery: all stored passwords in our server are (by definition) the property of the company. However if they are not shared, then they cannot be recovered in emergency, when the user(s) it is shared with are not available.
(4) Group recovery: if only a single individual is a group manager, but we need to add/remove users from a group when that person is not available, we cannot do so.
I am thinking about working around these problems as follows.
-
We already have a “System Operations” group which the key trusted sysadmins are members of (i.e. the same people who have root access to the passbolt server itself)
-
We make a new company policy that every password in Passbolt must be shared with the “System Operations” group with “Owner” privileges. We use a SQL report to identify violations
-
Ideally we would also say that every group must have the “System Operations” group as Group Manager, but unfortunately there are no nested groups; the best we can do is to add all members of the System Operations group individually as Managers of every group.
-
Passwords which are shared ad-hoc with individuals, rather than groups, are frowned upon; but as long as they are shared with the System Operations group as Owner, we can fix this when required.
I think this approach will work, but it would be nice if Passbolt itself could help enforce this - in particular that every password has a specific recovery group as Owner which cannot be removed, in addition to the creator.
In addition, it seems to me that there is some scope for increasing the capabilities of the “Admin” role without breaking the security model. This would include:
-
Any Admin should be able to see the existence of all passwords and their metadata, even if they don’t have rights to decrypt them. Possibly also be able to delete them.
-
If an Admin already has read or modify access to a password, then let them change or add user and group rights to that password.
Note that anyone who has read or modify rights can already view the password, and therefore at worst could simply create a new password containing the same data and share it with whichever users or groups they like. So, letting admins update the sharing rights for passwords they can already see doesn’t add any security risk that I can see.
Sorry for the long post, but this is actually quite an involved topic!
Regards,
Brian.
Aside 1: as far as I can see there is no database unique constraint on resources.name
, so reports need to show resources.id
to distinguish them.
Aside 2: when I checked permissions on resource objects in my database, I found a few resources which are completely orphaned with no permissions at all - not even an owner. I thought they might be deleted, but not all of them are:
mysql> select r.id,r.expiry_date,r.deleted from resources r left join permissions p on p.aco_foreign_key=r.id where p.id is null;
+--------------------------------------+-------------+---------+
| id | expiry_date | deleted |
+--------------------------------------+-------------+---------+
| 59bf8f34-9870-4ad8-a436-486cb92d621e | NULL | 1 |
| 59c92c45-fb5c-4a57-a905-029cb92d621e | NULL | 1 |
| 5a0436f0-4428-4275-afbb-7625b92d621e | NULL | 0 |
| 5a13ff70-1dc0-4765-8a61-5b31b92d621e | NULL | 0 |
+--------------------------------------+-------------+---------+
4 rows in set (0.00 sec)
This seems like it could be a bug: perhaps the resource and its initial owner were not added in the same DB transaction?
Conversely, there are some deleted resources which do still have permissions attached, although that’s not unreasonable:
mysql> select distinct r.id from resources r join permissions p on p.aco_foreign_key=r.id where r.deleted=1;
+--------------------------------------+
| id |
+--------------------------------------+
| 59b2bdd0-2084-4d60-a6b5-4307b92d621e |
| 59b2c114-66c4-4a33-b160-450bb92d621e |
| 59b69d49-9224-466d-896b-5691b92d621e |
| 59b7ae63-29b4-4baa-98b0-0ca1b92d621e |
+--------------------------------------+
4 rows in set (0.00 sec)