role self-revocation - Mailing list pgsql-hackers
From | Robert Haas |
---|---|
Subject | role self-revocation |
Date | |
Msg-id | CA+TgmobNfJvG6keNU6YcykJnntDm_-BxN_5JDacakusr5E0hEg@mail.gmail.com Whole thread Raw |
In response to | Re: CREATEROLE and role ownership hierarchies (Stephen Frost <sfrost@snowman.net>) |
Responses |
Re: role self-revocation
Re: role self-revocation |
List | pgsql-hackers |
On Mon, Feb 28, 2022 at 2:09 PM Stephen Frost <sfrost@snowman.net> wrote: > The ability of a role to revoke itself from some other role is just > something we need to accept as being a change that needs to be made, and > I do believe that such a change is supported by the standard, in that a > REVOKE will only work if you have the right to make it as the user who > performed the GRANT in the first place. Moving this part of the discussion to a new thread to reduce confusion and hopefully get broader input on this topic. It seems like Stephen and I agree in principle that some change here is a good idea. If anyone else thinks it's a bad idea, then this would be a great time to mention that, ideally with reasons. If you agree that it's a good idea, then it would be great to have your views on the follow-up questions which I shall pose below. To the extent that it is reasonably possible to do so, I would like to try to keep focused on specific design questions rather than getting tangled up in general discussion of long-term direction. First, a quick overview of the issue for those who have not followed the earlier threads in their grueling entirety: rhaas=# create user boss; CREATE ROLE rhaas=# create user peon; CREATE ROLE rhaas=# grant peon to boss; GRANT ROLE rhaas=# \c - peon You are now connected to database "rhaas" as user "peon". rhaas=> revoke peon from boss; -- i don't like being bossed around! REVOKE ROLE I argue (and Stephen seems to agree) that the peon shouldn't be able to undo the superuser's GRANT. Furthermore, we also seem to agree that you don't necessarily have to be the exact user who performed the grant. For example, it would be shocking if one superuser couldn't remove a grant made by another superuser, or for that matter if a superuser couldn't remove a grant made by a non-superuser. But there are a few open questions in my mind: 1. What should be the exact rule for whether A can remove a grant made by B? Is it has_privs_of_role()? is_member_of_role()? Something else? 2. What happens if the same GRANT is enacted by multiple users? For example, suppose peon does "GRANT peon to boss" and then the superuser does the same thing afterwards, or vice versa? One design would be to try to track those as two separate grants, but I'm not sure if we want to add that much complexity, since that's not how we do it now and it would, for example, implicate the choice of PK on the pg_auth_members table. An idea that occurs to me is to say that the first GRANT works and becomes the grantor of record, and any duplicate GRANT that happens later issues a NOTICE without changing anything. If the user performing the later GRANT has sufficient privileges and wishes to do so, s/he can REVOKE first and then re-GRANT. On the other hand, for other types of grants, like table privileges, we do track multiple grants by different users, so maybe we should do the same thing here: rhaas=# create table example (a int, b int); CREATE TABLE rhaas=# grant select on table example to foo with grant option; GRANT rhaas=# grant select on table example to bar with grant option; GRANT rhaas=# \c - foo You are now connected to database "rhaas" as user "foo". rhaas=> grant select on table example to exemplar; GRANT rhaas=> \c - bar You are now connected to database "rhaas" as user "bar". rhaas=> grant select on table example to exemplar; GRANT rhaas=> select relacl from pg_class where relname = 'example'; relacl ------------------------------------------------------------------------------- {rhaas=arwdDxt/rhaas,foo=r*/rhaas,bar=r*/rhaas,exemplar=r/foo,exemplar=r/bar} (1 row) 3. What happens if a user is dropped after being recorded as a grantor? We actually have a grantor column in pg_auth_members today, but it's not properly maintained. If the grantor is dropped the OID remains in the table, and could eventually end up pointing to some other user if the OID counter wraps around and a new role is created with the same OID. That's completely unacceptable for something we want to use for any serious purpose. I suggest that what ought to happen is the role should acquire a dependency on the grant, such that DROP fails and the GRANT is listed as something to be dropped, and DROP OWNED BY drops the GRANT. I think this would require adding an OID column to pg_auth_members so that a dependency can point to it, which sounds like a significant infrastructure change that would need to be carefully validated for adverse side effects, but not a huge crazy problem that we can't get past. 4. Should we apply this rule to other types of grants, rather than just to role membership? Why or why not? Consider this: rhaas=# create user accountant; CREATE ROLE rhaas=# create user auditor; CREATE ROLE rhaas=# create table money (a int, b text); CREATE TABLE rhaas=# alter table money owner to accountant; ALTER TABLE rhaas=# grant select on table money to auditor; GRANT rhaas=# \c - accountant You are now connected to database "rhaas" as user "accountant". rhaas=> revoke select on table money from auditor; REVOKE I would argue that's exactly the same problem. The superuser has decreed that the auditor gets to select from the money table owned by the accountant. The fact that the accountant may not be not in favor of the auditor seeing what the accountant is doing with the money is precisely the reason why we have auditors. That said, if we apply this to all object types, it's a much bigger change. Unlike role membership, we do record dependencies on table privileges, which makes any change here a bit simpler, and you can't drop a role without removing the associated grants first. However, when the superuser performs the GRANT as in the above example, the grantor is recorded as the table owner, not the superuser! So if we really want role membersip and other kinds of grants to behave in the same way, we have our work cut out for us here. Please note that it is not really my intention to try to shove anything into v15 here. If it so happens that we quickly agree on something that already exists in the patches Mark's already written, and we also agree that those patches are in good enough shape that we can commit something in the next few weeks, fantastic, but I'm not necessarily expecting that. What I do want to do is agree on a plan so that, if somebody does the work to implement said plan, we do not then end up relitigating the whole thing and coming to a different conclusion the second time. This being a community whose membership varies from time to time and the opinions of whose members vary from time to time, such misadventure can never be entirely ruled out. However, I would like to minimize the chances of such an outcome as much as we can. Thanks, -- Robert Haas EDB: http://www.enterprisedb.com
pgsql-hackers by date: