Re: Additional role attributes && superuser review

From: Stephen Frost <sfrost(at)snowman(dot)net>
To: Magnus Hagander <magnus(at)hagander(dot)net>
Cc: Adam Brightwell <adam(dot)brightwell(at)crunchydatasolutions(dot)com>, Andrew Dunstan <andrew(at)dunslane(dot)net>, Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>, Petr Jelinek <petr(at)2ndquadrant(dot)com>, "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Additional role attributes && superuser review
Date: 2014-12-31 14:08:42
Message-ID: 20141231140841.GQ3062@tamriel.snowman.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

* Magnus Hagander (magnus(at)hagander(dot)net) wrote:
> On Tue, Dec 30, 2014 at 4:16 PM, Stephen Frost <sfrost(at)snowman(dot)net> wrote:
> > The approach I was thinking was to document and implement this as
> > impliciting granting exactly USAGE and SELECT rights, no more (not
> > BYPASSRLS) and no less (yes, the role could execute functions). I agree
>
> If the role could execute functions, it's *not* "exactly USAGE and SELECT
> rights", it's now "USAGE and SELECT and EXECUTE" rights... Just to be
> nitpicking, but see below.

We seem to be coming at it from two different directions, so I'll try to
clarify. What I'm suggesting is that this role attribute be strictly
*additive*. Any other privileges granted to the role with this role
attribute would still be applicable, including grants made to PUBLIC.

This role attribute would *not* include EXECUTE rights, by that logic.
However, if PUBLIC was granted EXECUTE rights for the function, then
this role could execute that function.

What it sounds like is you're imagining this role attribute to mean the
role has *only* USAGE and SELECT (or COPY or whatever) rights across the
board and that any grants done explicitly to this role or to public
wouldn't be respected. In my view, that moves this away from a role
*attribute* to being a pre-defined *role*, as such a role would not be
usable for anything else.

> > that doing so would be strictly more than what pg_dump actually requires
> > but it's also what we actually have support for in our privilege system.
>
> Yeah, but would it also be what people would actually *want*?

I can certainly see reasons why you'd want such a role to be able to
execute functions- in particular, consider xlog_pause anx xlog_resume.
If this role can't execute those functions then they probably can't
successfully run pg_dump against a replica.

> I think having it do exactly what pg_dump needs, and not things like
> execute functions etc, would be the thing people want for a 'DUMP'
> privilege.

What if we want pg_dump in 9.6 to have an option to execute xlog_pause
and xlog_resume for you? You wouldn't be able to run that against a 9.5
database (or at least, that option wouldn't work).

> We might *also* want a USAGEANDSELECTANDEXECUTEANDWHATNOTBUTNOBYPASSURL
> (crap, it has to fit within NAMEDATALEN?) privilege, but I think that's a
> different thing.

Our privilege system doesn't currently allow for negative grants (deny
user X the ability to run functions, even if EXECUTE is granted to
PUBLIC). I'm not against that idea, but I don't see it as the same as
this.

> > it would only give you COPY access. (And also
> > > COPY != SELECT in the way that the rule system applies, I think? And this
> > > one could be for COPY only)
> >
> > COPY certainly does equal SELECT rights.. We haven't got an independent
> > COPY privilege and I don't think it makes sense to invent one. It
>
> We don't, but I'm saying it might make sense to implement this. Not as a
> regular privilige, but as a role attribute. I'm not sure it's the right
> thing, but it might actually be interesting to entertain.

We've discussed having a role attribute for COPY-from-filesystem, but
pg_dump doesn't use that ever, it only uses COPY TO STDOUT. I'm not
a fan of making a COPY_TO_STDOUT-vs-SELECT distinction just for this..

> > sounds like you're suggesting that we add a hack directly into COPY for
> > this privilege, but my thinking is that the right place to change for
> > this is in the privilege system and not hack it into individual
> > commands.. I'm also a bit nervous that we'll end up painting ourselves
> > into a corner if we hack this to mean exactly what pg_dump needs today.
>
> One point would be that if we define it as "exactly what pg_dump needs",
> that definition can change in a future major version.

Sure, but that then gets a bit ugly because we encourage running the
latest version of pg_dump against the prior-major-version.

> > > I think BYPASSRLS would have to be implicitly granted by the DUMP
> > > privilege. Without that, the DUMP privilege is more or less meaningless
> > > (for anybody who uses RLS - but if they don't use RLS, then having it
> > > include BYPASSRLS makes no difference). Worse than that, you may end up
> > > with a dump that you cannot restore.
> >
> > The dump would fail, as I mentioned before. I don't see why BYPASSRLS
> > has to be implicitly granted by the DUMP privilege and can absolutely
> > see use-cases for it to *not* be. Those use-cases would require passing
> > pg_dump the --enable-row-security option, but that's why it's there.
>
> So you're basically saying that if RLS is in use anywhere, this priviliege
> alone would be useless, correct?

No, it would still be *extremely* useful. We have an option to pg_dump
to say "please dump with RLS enabled". What that means is that you'd be
able to dump the entire database for all data you're allowed to see
through RLS policies. How is that useless? I certainly think it'd be
very handy and a good way to get *segregated* dumps according to policy.

> And you would get a hard failure at *dump
> time*, not at reload time?

If you attempt to pg_dump a relation which has RLS enabled, and you
don't enable RLS with pg_dump, then you'll get a failure at dump time,
yes. That's far better than a reload-time failure.

> That would at least make it acceptable, as you
> would know it's wrong. and we could make the error messages shown
> specifically hint that you need to grant both privileges to make it useful.

Agreed, having such a hint makes sense.

> We could/should also throw a WARNING if DUMP Is granted to a role without
> BYPASSRLS in case row level security is enabled in the system, I think. But
> that's more of an implementation detail.

That's a bit ugly and RLS could be added to a relation after the DUMP
privilege is granted.

What I think this part of the discussion is getting at is that there's a
lot of people who view pg_dump as explicitly for "dump the ENTIRE
database". While that's one use-case it is certainly not the only one.
I find "pg_dump schema X" to be very common and often find that pg_dump
against an entire database isn't practical because of the size of the
database.

> Implementations which don't use RLS are not impacted either way, so we
> > don't need to consider them. Implementations which *do* use RLS, in my
> > experience, would certainly understand and expect BYPASSRLS to be
> > required if they want this role to be able to dump all data out
> > regardless of the RLS policies. What does implicitly including
> > BYPASSRLS in this privilege gain us? A slightly less irritated DBA who
> > forgot to include BYPASSRLS and ended up getting a pg_dump error because
> > of it. On the other hand, it walls off any possibility of using this
> > privilege for roles who shouldn't be allowed to bypass RLS or for
> > pg_dumps to be done across the entire system for specific RLS policies.
> >
>
> Yeah, I think that's acceptable as long as we get the error at dump, and
> not at reload (when it's too late to fix it).

Right, that's the same decision we came to in the general RLS
discussion.

> > Similar concerns would exist for the existing REPLICATION role for example
> > > - that one clearly lets you bypass RLS as well, just not with a SQL
> > > statement.
> >
> > I'm not sure that I see the point you're making here. Yes, REPLICATION
> > allows you to do a filesystem copy of the entire database and that
> > clearly bypasses RLS and *all* of our privilege system. I'm suggesting
> > that this role attribute work as an implicit grant of privileges we
> > already have. That strikes me as easy to document and very clear for
> > users.
>
> It does - though documenting that it implicitly gives you a different
> privilege as well is also easy :)
>
> But it does potentially limit us to what we can actually do with the
> priviliges. One reason to use them is exactly because we *cannot* express
> this with our regular permissions (such as BYPASSRLS or REPLICATION).

Ok, I see the point you're making that we could make this into a
capability which isn't something which can be expressed through our
existing GRANT system. That strikes me as a solution trying to find a
problem though. There's no need to invent such an oddity for this
particular use-case, I don't think.

> For regular permissions, we could just pre-populate the system with
> predefined roles and use regular GRANTs to those roles, instead of relying
> on role attributes, which might in that case make it even more clear?

The reason for this approach is to address exactly the nightmare that is
trying to maintain those regular permissions across all the objects in
the system. Today, people simply give the role trying to do the pg_dump
superuser, which is the best option we have. Saying 'grant SELECT on
all the tables and USAGE on all the schemas' isn't suggested because
it's a huge pain. This role attribute provides a middle ground where
the pg_dump'ing role isn't a superuser, but you don't have to ensure
usage and select are granted to it for every relation.

> > should work 'sanely' with any combination of the two options.
> > > > Similairly, DUMP shouldn't imply BACKUP or visa-versa. In particular,
> > > > I'd like to see roles which have only the BACKUP privilege be unable to
> > > > directly read any data (modulo things granted to PUBLIC). This would
> > > > allow an unprivileged user to manage backups, kick off ad-hoc ones,
> > etc,
> > > > without being able to actually access any of the data (this would
> > > > require the actual backup system to have a similar control, but that's
> > > > entirely possible with more advanced SANs and enterprise backup
> > > > solutions).
> > >
> > > So you're saying a privilege that would allow you to do
> > > pg_start_backup()/pg_stop_backup() but *not* actually use pg_basebackup?
> >
> > Yes.
>
> What's really the usecase for that? I'd say that pg_start/stop backup is a
> superset and a higher privilige than using pg_basebackup, since you can for
> example destroy other peoples backups using it (by running pg_stop_backup
> while they are running).

One use-case is to allow unprivileged users to run adhoc backups.
Another is simply that you don't want the cronjob that runs the backup
to be able to read any of the data directly (why would you?). I agree
that the individuals who have this capability would still need to
coordinate or at lesat not step on each other or they could end up with
bad backups.

Another way to address that would be to require that the role calling
stop_backup be a member of the role which called start_backup (that also
address the superuser case, as superusers are considered members of all
roles). That seems like a pretty reasonable sanity check requirement.

> > Personalyl I think using the DUMP name makes that a lot more clear. Maybe
> > > we need to avoid using BACKUP alone as well, to make sure it doesn't go
> > the
> > > other way - using BASEBACKUP and EXCLUSIVEBACKUP for those two different
> > > ones perhaps?
> >
> > DUMP - implicitly grants existing rights, to facilitate pg_dump and
> > perhaps some other use-cases
> > BASEBACKUP - allows pg_basebackup, which means bypassing all in-DB
> > privilege systems
>
> That's equivalent of REPLICATION, yes?

Ah, yeah, seems like it would be. Got ahead of myself. :)

> > EXCLUSIVEBACKUP - just allows pg_start/stop_backup and friends
>
> I'd say there is no "just" there really - that's a higher level privilege,
> but I see your point :)

Well, see above, but ok.

> I'm still not entirely happy with the naming, but I feel like we're
> > getting there. One thought I had was using ARCHIVE somewhere, but I
> > kind of like BASEBACKUP meaning what's needed to run pg_basebackup, and,
> > well, we say 'backup' in the pg_start/stop_backup function names, so
> > it's kind of hard to avoid that. EXCLUSIVEBACKUP seems really long tho.
> >
>
> I don't like ARCHIVE in that it sounds like something to do with log
> archiving. If anything, that would affect pg_receivexlog, but that's
> definitely REPLICATION. I'd rather keep that one for a future time where we
> might let users actually do something about log archiving directly, which
> would then use the name.

Ok.

> The reason I like EXCLUSIVEBACKUP is that it's a term we already use. It's
> only 4 chars longer than REPLICATION for example - does that really matter?

Eh, I guess not. :)

> As long as we don't store the name, it should have no effect at all, and
> even if we do, I'm not sure it matters. If you want it shorter, we can have
> EXCLBACKUP :)

Eh.

> > I had defined them when I started the thread:
>
> Apologies - I had missed that part.

No prob.

> pg_start_backup
> > pg_stop_backup
> > pg_switch_xlog
> > pg_create_restore_point
> >
>
> Ok. That makes sense.
>
>
> Later I added:
> >
> > pg_xlog_replay_pause
> > pg_xlog_replay_resume
> >
> > Though I'd be find if the xlog_replay ones were their own privilege (eg:
> > REPLAY or something).
> >
>
> I think it makes more sense to have those replay functions to be a separate
> privilege, yes. They have nothing to actually do with taking the backups -
> they are for restoring them. And to restore the backups, you clearly
> already have superuser level privileges on the system outside the db (at
> least as long as we only allow full cluster restores).

Not quite- remember that reply_pause/resume can be done on a replica, so
they are useful to be able to grant independent from superuser. Perhaps
we call such a role attribute XLOGREPLAY ?

> > I don't actually see REPLICATION as being the same.
> >
> > The point is to have a role which can log into the replica, pause
> > the stream to be able to run whatever queries they're permitted to
> > (which might not include all of the data) and then resume it when done.
> > Perhaps that needs to be independent of the EXCLUSIVEBACKUP role, but
> > it's definitely different from the REPLICATION privilege.
> >
>
> Agreed per above, now that I realize what we mean. I do think it needs to
> be at least as independent from EXCLUSIVEBACKUP as it does froM REPLICATION
> though.

Ok.

> > > You mean something that restricts the user to read even *if* write
> > > permissions has been granted on an individual table? Yeah, that would
> > > actually be quite useful, I think - sort of a "reverse privilege".
> >
> > Yes. My thinking on how to approach this was to forcibly set all of
> > their transactions to read-only.
>
> Agreed that this would be very useful.

Glad we agree.. Any thoughts on implementation? :)

> > > Well, from an actual security perspective that would make it equivalent
> > to
> > > superuser in the case of anybody using password auth. I'm not sure we
> > cant
> > > to grant that out to DUMP by default - perhaps we need a separate one for
> > > DUMPAUTH or DUMPPASSWORDS.
> >
> > That makes sense to me- DUMPAUTH or maybe just DUMPALL (to go with
> > pg_dumpall).
> >
>
> I'd prefer DUMPAUTH specifically because it makes it glaringly obvious that
> you're going to be dumping authentication data.

Ok.

> > (We could dump all the users *without* passwords with just the DUMP
> > > privilege)
> >
> > Agreed. That's actually something that I think would be *really* nice-
> > an option to dump the necessary globals for whatever database you're
> > running pg_dump against. We have existing problems in this area
> > (database-level GUCs aren't considered database-specific and therefore
> > aren't picked up by pg_dump, for example..), but being able to also dump
> > the roles which are used in a given database with pg_dump would be
> > *really* nice..
> >
>
> Yes. Shouldn't be *that* hard, completely independent of this privilege
> work. Famous last words, I'm sure...

Indeed.

Thanks!

Stephen

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2014-12-31 14:13:45 Re: Using 128-bit integers for sum, avg and statistics aggregates
Previous Message David Rowley 2014-12-31 14:00:50 Re: Using 128-bit integers for sum, avg and statistics aggregates