Thread: Seeking practice recommendation: is there ever a use case to have two or more superusers?

The detail below leads to a simply stated question:

Given that the bootstrap superuser must exist, is there ever a reason to create another role with "superuser"?

My intuition tells me that the answer is a resounding "No!".

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — 

*Detail*

An earlier thread:


reached the interim conclusion that the term "bootstrap superuser" is the generally accepted term of art for the superuser whose name you specify to "initdb" with its -U option when you create a new cluster. I said "interim" because the current PG doc has no glossary entry for this notion. (Sometimes, the explicit use of "initdb" is hidden behind a wrapper like "pg_createcluster". You use this after installing PG with "apt install postgresql" on Ubuntu. This detail is of no consequence for my question.)

The bootstrap superuser is uniquely special in that, in each database, it owns, for example, the "pg_catalog" and "information_schema" schemas and the objects in them. In other words, this role owns the SQL component of the implementation of the PG RDBMS and is essential to allow it to function.

However, you can create as many additional superusers as you please—and each is as unstoppable as all the others. I wondered, at first, if it might be a good practice to create a second superuser, say "super" with "login", to alter the bootstrap superuser with "nologin", and then to use "super" on an "ordinary" daily basis for tasks that might need this. The thought was that this practice might protect the artifacts that the bootstrap superuser owns from damage. But this thought dissolved into thin air, before it was fully formed, on the realization that the unstoppable "super" could anyway do arbitrary damage to the bootstrap superuser's artifacts.

Moreover, it seems that there are, anyway, no (or exceedingly few) tasks that ever need the power of a superuser. At the very least, there seems to be no defensible notion of "daily superuser tasks".

I noticed this in a recent post to this list by Christophe Petus:


The typical configuration is to not permit the PostgreSQL superuser to log in remotely. The database can be managed by a different, non-superuser role, including schema migrations.

The implication is clear: you should allow a cluster to have just a single superuser, the inevitable bootstrap superuser, and you should think very carefully indeed before ever starting a session as this role because of the risks that doing so brings. Rather, you should realize that there are hardly any tasks that cannot be carried out by an appropriately configured role with "nosuperuser".

David Johnston strengthened this notion with his turn in the same thread:


You only need superuser once to configure the system in such a way, through role and grants and possibly default permissions, that from then on most everything an application user would want to do can be done by the role(s) you have created.

This thinking is reflected further in the "22.2. Role Attributes" section in the PG doc:


It is good practice to create a role that has the CREATEDB and CREATEROLE privileges, but is not a superuser, and then use this role for all routine management of databases and roles. This approach avoids the dangers of operating as a superuser for tasks that do not really require it.

*Yet more detail — only if you're interested*

I have a nicely working prototype that honors these principles. (I've mentioned it before.) It implements a "multitenancy by convention" scheme that avoids collisions of global names by following a naming convention that's enforced with "security definer" procedures for role provisioning.

Just as David described, I set up the scheme as a postlude to "initdb" by using a session authorized as the bootstrap superuser. This creates my "clstr$mgr" role with "createdb" and "createrole" and installs the role-provisioning procedures in a dedicated "mgr" schema in the customized "template1" database. (Both the "mgr" schema and the objects in it are owned by "clstr$mgr".) Once this set-up is done, no session needs ever agin to authorize as the bootstrap superuser—unless bug fixes or enhancements are needed to the implementation of the scheme itself. (But most of this patching could, anyway, be done by a session that authorizes as "clstr$mgr".) This patching would anyway require stopping all ordinary user sessions and doing the task in a self-imposed single-user mode. So it's most certainly natural to disallow authorizing a bootstrap superuser session remotely—just as Christophe said.

It's rare, even, to need to authorize as "clstr$mgr". This needed only to create and configure, or to drop, a tenant database. These operations are mechanical, and are therefore scripted. "Configure" here means creating a dedicated local manager role (local in the sense that it has "connect" only on the subject database). The local manager has no special role attributes and is empowered entirely by (uniquely) having "execute" on the role-provisioning "security definer" procedures.
On 2022-11-17 11:36:15 -0800, Bryn Llewellyn wrote:
> The detail below leads to a simply stated question:
>
> Given that the bootstrap superuser must exist, is there ever a reason to create
> another role with "superuser"?
>
> My intuition tells me that the answer is a resounding "No!".

Is there ever a reason? Yes. Does that reason apply to you? I don't know.
Maybe, maybe not.


> — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
> I wondered, at first, if it might be a good practice to create a
> second superuser, say "super" with "login", to alter the bootstrap
> superuser with "nologin", and then to use "super" on an "ordinary"
> daily basis for tasks that might need this. The thought was that this
> practice might protect the artifacts that the bootstrap superuser owns
> from damage. But this thought dissolved into thin air, before it was
> fully formed, on the realization that the unstoppable "super" could
> anyway do arbitrary damage to the bootstrap superuser's artifacts.

You could create additional superusers and restrict those to certain
databases and/or IP ranges. That probably won't stop an attacker (I can
think of at least one way to get around that and it's probably even
easier than I think) but it might prevent accidental damage.


> The implication is clear: you should allow a cluster to have just a single
> superuser, the inevitable bootstrap superuser, and you should think very
> carefully indeed before ever starting a session as this role because of the
> risks that doing so brings. Rather, you should realize that there are hardly
> any tasks that cannot be carried out by an appropriately configured role with
> "nosuperuser".

One important task that can AFAIK only be performed by superusers is the
creation of functions in untrusted languages like plpython3u and
plperlu.

If your application uses functions in those languages you need a
superuser to install or upgrade it.

        hp

--
   _  | Peter J. Holzer    | Story must make more sense than reality.
|_|_) |                    |
| |   | hjp@hjp.at         |    -- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |       challenge!"

Attachment
hjp-pgsql@hjp.at wrote:


The detail below leads to a simply stated question:

Given that the bootstrap superuser must exist, is there ever a reason to create
another role with "superuser"?

My intuition tells me that the answer is a resounding "No!".

Is there ever a reason? Yes. Does that reason apply to you? I don't know. Maybe, maybe not.

I wondered, at first, if it might be a good practice to create a second superuser, say "super" with "login", to alter the bootstrap superuser with "nologin", and then to use "super" on an “ordinary" daily basis for tasks that might need this. The thought was that this practice might protect the artifacts that the bootstrap superuser owns from damage. But this thought dissolved into thin air, before it was fully formed, on the realization that the unstoppable "super” could anyway do arbitrary damage to the bootstrap superuser's artifacts.

You could create additional superusers and restrict those to certain databases and/or IP ranges. That probably won't stop an attacker (I can think of at least one way to get around that and it's probably even easier than I think) but it might prevent accidental damage.

The implication is clear: you should allow a cluster to have just a single superuser, the inevitable bootstrap superuser, and you should think very carefully indeed before ever starting a session as this role because of the risks that doing so brings. Rather, you should realize that there are hardly any tasks that cannot be carried out by an appropriately configured role with "nosuperuser".

One important task that can AFAIK only be performed by superusers is the creation of functions in untrusted languages like plpython3u and plperlu. If your application uses functions in those languages you need a superuser to install or upgrade it.

Thanks, Peter. I experimented with the notion of restricting a superuser to certain databases. My set-up has this in the “hba_file”:

# TYPE  DATABASE  USER            METHOD  [auth-options]
# ----  --------  --------------  ------  ----------------------------
  local all       postgres        peer

So that gave me an easy way to test the notion. (This is a sandbox cluster in a VM. So I can do arbitrary destructive tests and recover in a heartbeat.) Before the test, this command at the O/S prompt (as the O/S user “postgres”):

psql -d d0 -U postgres

succeeded and took me where it specified. I changed the “hba_file” thus:

# TYPE  DATABASE  USER            METHOD  [auth-options]
# ----  --------  --------------  ------  ----------------------------
  local 
postgres  postgres        peer

It had the effect that you promised. This command at the O/S prompt (as the O/S user “postgres”):

psql -d postgres -U postgres

succeeded. But this attempt:

psql -d d0 -U postgres

now failed with this error:

...no pg_hba.conf entry for host "[local]", user "postgres", database "d0"...

as promised by the doc. But this seems to achieve very little. Having authorized using the first command, I then did "drop database d0". I had no reason to think that it might fail. And it didn't. I see that it's careless to say that a superuser is *unstoppable*. But it seems that, as long as a superuser can start as session at all, then it can certainly do untold harm.

The experiment, then, doesn't seem to change the thinking. In other words, only a highly trusted person should know the password(s) needed to start a superuser session. This might well be done is a "four eyes" partnership, as such tasks often are, to increase the level of trust and responsibility that the organization relies upon. Given this, I cannot see how it would help increase the trust given to such people to have more than one superuser to connect as.

I don't see that the point about maintenance changes for functions written in untrusted languages changes anything. You already have the inevitable bootstrap superuser and, if the organization chooses, robust "four eyes" practices to govern how people use sessions that authorize as this role. You don't need a second superuser just because this kind of task is to be done a long time after the initial cluster creation and configuration.

On 2022-11-18 13:11:24 -0800, Bryn Llewellyn wrote:
>     hjp-pgsql@hjp.at wrote:
>     bryn@yugabyte.com wrote:
>         Given that the bootstrap superuser must exist, is there ever a reason
>         to create
>         another role with "superuser"?
>
>         My intuition tells me that the answer is a resounding "No!".
>
>
>     Is there ever a reason? Yes. Does that reason apply to you? I don't
>     know. Maybe, maybe not.
[...]
>     You could create additional superusers and restrict those to
>     certain databases and/or IP ranges. That probably won't stop an attacker (I
>     can think of at least one way to get around that and it's probably
>     even easier than I think) but it might prevent accidental damage.
[...]
>     One important task that can AFAIK only be performed by superusers is
>     the creation of functions in untrusted languages like plpython3u
>     and plperlu. If your application uses functions in those languages you need
>     a superuser to install or upgrade it.
>
>
> Thanks, Peter. I experimented with the notion of restricting a superuser to
> certain databases. My set-up has this in the “hba_file”:
[...]
> now failed with this error:
>
> ...no pg_hba.conf entry for host "[local]", user "postgres", database "d0"...
>
> as promised by the doc. But this seems to achieve very little. Having
> authorized using the first command, I then did "drop database d0". I had no
> reason to think that it might fail. And it didn't. I see that it's careless to
> say that a superuser is *unstoppable*. But it seems that, as long as a
> superuser can start as session at all, then it can certainly do untold harm.

Yes, you can drop the database. But that will be noticed soon enough.
You can even recreate it, but if you don't know the contents, this will
also be quite conspicuous. I am much more worried about subtle changes:
Altering a few records, installing a different version of a trigger.
That might not be noticed for a long time and by the time you notice it
you can't restore from backup because you have a lot of new changes.

So preventing a user from connecting to to a database has some value
even if it doesn't prevent that user from dropping the database as a
whole.

(And as I said, it only helps against *accidental* damage. An attacker
who already has some superuser role can almost certainly escalate to any
other superuser role.)

> I don't see that the point about maintenance changes for functions written in
> untrusted languages changes anything. You already have the inevitable bootstrap
> superuser and, if the organization chooses, robust "four eyes" practices to
> govern how people use sessions that authorize as this role. You don't need a
> second superuser just because this kind of task is to be done a long time after
> the initial cluster creation and configuration.

You almost certainly want to automate software upgrades. So the actual
session will be "zero eyes". One would hope that configuring the job is
done with proper care, but editing errors happen and are not always
caught by a reviewer. Having to get the database, the role and the
password consistently wrong is a much greater hurdle that getting just
the database wrong.

So you can give these credentials to you developers or devops folks
(whom you trust not attack the system - they could do that by adding
backdoors to the code - but don't trust to never make a mistake).

        hp

--
   _  | Peter J. Holzer    | Story must make more sense than reality.
|_|_) |                    |
| |   | hjp@hjp.at         |    -- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |       challenge!"

Attachment
On 11/18/22 16:13, Peter J. Holzer wrote:
[snip]
> So you can give these credentials to you developers or devops folks
> (whom you trust not attack the system -

They like to "fix" things without documenting what they did, and then, when 
something breaks, denying they did anything (or honestly not believing that 
whatever "trivial" thing they did could any major or deliterious impact).

-- 
Angular momentum makes the world go 'round.



On 11/18/22 15:08, Peter J. Holzer wrote:
On 2022-11-17 11:36:15 -0800, Bryn Llewellyn wrote:
The detail below leads to a simply stated question:

Given that the bootstrap superuser must exist, is there ever a reason to create
another role with "superuser"?

My intuition tells me that the answer is a resounding "No!".
Is there ever a reason? Yes. Does that reason apply to you? I don't know.
Maybe, maybe not.


— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — 
I wondered, at first, if it might be a good practice to create a
second superuser, say "super" with "login", to alter the bootstrap
superuser with "nologin", and then to use "super" on an "ordinary"
daily basis for tasks that might need this. The thought was that this
practice might protect the artifacts that the bootstrap superuser owns
from damage. But this thought dissolved into thin air, before it was
fully formed, on the realization that the unstoppable "super" could
anyway do arbitrary damage to the bootstrap superuser's artifacts.
You could create additional superusers and restrict those to certain
databases and/or IP ranges. That probably won't stop an attacker (I can
think of at least one way to get around that and it's probably even
easier than I think) but it might prevent accidental damage.


The implication is clear: you should allow a cluster to have just a single
superuser, the inevitable bootstrap superuser, and you should think very
carefully indeed before ever starting a session as this role because of the
risks that doing so brings. Rather, you should realize that there are hardly
any tasks that cannot be carried out by an appropriately configured role with
"nosuperuser".
One important task that can AFAIK only be performed by superusers is the
creation of functions in untrusted languages like plpython3u and
plperlu.

If your application uses functions in those languages you need a
superuser to install or upgrade it.
        hp

Yes, there is such a reason. On several servers that I have to work with, the user "postgres" is not a log-in user. In other words, I can't log in as "postgres", I can only log in as my own user and su to the user "postgres". All users must be authenticated by the LDAP system and the user "postgres" is not in the LDAP. Since I am lazy, I granted superuser privilege to my own user so that I don't have to switch to the user "postgres" every time I want to do something that affects everybody, like using "ALTER SYSTEM". I am also a member of the "dba" group on the Oracle servers, so that I can do "sqlplus / as sysdba" without switching to the user "oracle". It's the same thing. If I was to respond by a single word, the word would be "convenience". Or maybe "covfefe"?

-- 
Mladen Gogala
Database Consultant
Tel: (347) 321-1217
https://dbwhisperer.wordpress.com
On 2022-11-18 16:21:18 -0600, Ron wrote:
> On 11/18/22 16:13, Peter J. Holzer wrote:
> > So you can give these credentials to you developers or devops folks
> > (whom you trust not attack the system -
>
> They like to "fix" things without documenting what they did, and then, when
> something breaks, denying they did anything (or honestly not believing that
> whatever "trivial" thing they did could any major or deliterious impact).

Which is why you want to automate deployments. When the easiest way to
fix something in production is to just push the change into the repo,
this is what people will do. When doing it the "proper" way is much more
complicated than just fudging it, people will do the latter.

        hp

--
   _  | Peter J. Holzer    | Story must make more sense than reality.
|_|_) |                    |
| |   | hjp@hjp.at         |    -- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |       challenge!"

Attachment
> hjp-pgsql@hjp.at wrote:
>
>> ronljohnsonjr@gmail.com wrote:
>>
>> [developers or devops folks] like to "fix" things without documenting what they did, and then, when
>> something breaks, denying they did anything (or honestly not believing that
>> whatever "trivial" thing they did could any major or deliterious impact).
>
> Which is why you want to automate deployments. When the easiest way to fix something in production is to just push
thechange into the repo, this is what people will do. When doing it the "proper" way is much more complicated than just
fudgingit, people will do the latter. 

Thanks to all who offered their views on my question. It seems that different people will reach different conclusions.
I’lltake this as permission to reach my own conclusion. 

Software systems in general often offer some freedoms that most people think should never be exercise. For example, PG
letsyou define a domain that has a not null constraint on one, or more, of its data attributes. But the doc 

https://www.postgresql.org/docs/current/sql-createdomain.html

tells you not to do this. (Look for « Best practice therefore is to design a domain's constraints so that a null value
isallowed... ».) I was rather slow to grasp the risks that ignoring this advice brings.. But I get it now.) 

At the other end of the spectrum, there’s generally accepted thinking on how to choose between a procedure or a
functionfor a particular new use case. But there are still plenty of such cases where opinions will vary and where each
preferencecan be defended with reasonable arguments. 

I haven’t seen anything in the PG doc that warns against creating additional superusers—so I suppose that this fact
tellsme something. Nevertheless, I remain convinced about what I’d recommend here: 

The default choice must be to allow only one superuser: the inevitable bootstrap superuser.

But I’ll concede that I should see this like many rules of recommended practice. Sometimes they get broken. This seems
mostoften to happen  as an expedient because the recommended practice requires too much effort. The general
second-orderadvice for such scenarios is to write down the rationale and to offer it up for peer review. And if there
areno peers who care, then all bets are anyway off... 


On Sun, Nov 20, 2022 at 6:48 PM Bryn Llewellyn <bryn@yugabyte.com> wrote:
I haven’t seen anything in the PG doc that warns against creating additional superusers—so I suppose that this fact tells me something. Nevertheless, I remain convinced about what I’d recommend here:

The default choice must be to allow only one superuser: the inevitable bootstrap superuser.

If you are talking about your specific setup then it isn't a recommendation, it's a policy that you are defining.  Do what you've concluded is best, you are the one that will end up answering for it.

IMO, there is no good blanket recommendation to give to someone else as to how their policy should be written.  Security, especially of this sort, needs to be architected.  And when doing that evaluation, and drawing those conclusions, there is no reason to exclude, a priori, having multiple named superusers as part of the final policy.  Especially since any policy of this requires not only discussion of PostgreSQL itself but operation systems, configuration management, etc....

David J.

On 11/20/22 17:48, Bryn Llewellyn wrote:
>> hjp-pgsql@hjp.at wrote:
>>
>>> ronljohnsonjr@gmail.com wrote:
>>>
>>> [developers or devops folks] like to "fix" things without documenting what they did, and then, when
>>> something breaks, denying they did anything (or honestly not believing that
>>> whatever "trivial" thing they did could any major or deliterious impact).
>>
>> Which is why you want to automate deployments. When the easiest way to fix something in production is to just push
thechange into the repo, this is what people will do. When doing it the "proper" way is much more complicated than just
fudgingit, people will do the latter.
 
> 
> Thanks to all who offered their views on my question. It seems that different people will reach different
conclusions.I’ll take this as permission to reach my own conclusion.
 

Not sure why you think you need permission to take whatever action you 
desire on a database whose only usage stipulation is that you maintain a 
copy of the license.

-- 
Adrian Klaver
adrian.klaver@aklaver.com




> adrian.klaver@aklaver.com wrote:
>
>> Karsten.Hilbert@gmx.net:
>>
>>> adrian.klaver@aklaver.com wrote:
>>>
>>>> bryn@yugabyte.com
>>>>
>>>> Thanks to all who offered their views on my question. It seems that different people will reach different
conclusions.I’ll take this as permission to reach my own conclusion. 
>>>
>>> Not sure why you think you need permission to take whatever action you desire on a database whose only usage
stipulationis that you maintain a copy of the license. 
>>
>> Adrian, I think Bryn's speaking metaphorically there.
>
> It is hard to tell with him. He makes much of his Oracle background and I think misses an overlord that lays down the
rules.

I didn’t mean to speak metaphorically. But I made a bad word choice when I used “permission”. A couple of turns back,
DavidJohnston wrote this: 

> there is no good blanket recommendation to give to someone else as to how their [security] policy should be written.
Security,especially of this sort, needs to be architected. 

And some time ago, in a different thread, he wrote this:

> You only need superuser once to configure the system in such a way, through role and grants and possibly default
permissions,that from then on most everything an application user would want to do can be done by the role(s) you have
created.

That second quote reads like a recommendation—which puts it at odds with the first quote. (But doubtless I’m reading it
wrongly.)

Then there’s this (from the doc):

> It is good practice to create a role that has the CREATEDB and CREATEROLE privileges, but is not a superuser, and
thenuse this role for all routine management of databases and roles. This approach avoids the dangers of operating as a
superuserfor tasks that do not really require it. 


That, too, reads like a recommendation that intends to inform a security policy. But, I suppose, one could argue that
sayingsomething “is good practice” is very different from making a recommendation. 

Consider this wording. It also uses “good practice”.

«
It is good practice to limit the number of superuser roles that exist in a cluster to exactly one: the inevitable
bootstrapsuperuser. This recognizes the fact that, once the initial configuration of a cluster has been done
immediatelyafter its creation (which configuration is done while still in self-imposed single-user mode), there are
thenvery few, and infrequent, tasks that require the power of the superuser role. 
»

Nobody supports it!

I’m puzzled why the good practice statement about a role with the CREATEDB and CREATEROLE attributes earns a place in
thedoc while nobody at all is prepared to make a practice statement about how many superusers is good. I’d like very
muchto understand the critical parts that I’m missing of the essential mental model in this general space. 





On 11/21/22 9:40 AM, Bryn Llewellyn wrote:
>> adrian.klaver@aklaver.com wrote:

> Then there’s this (from the doc):
> 
>> It is good practice to create a role that has the CREATEDB and CREATEROLE privileges, but is not a superuser, and
thenuse this role for all routine management of databases and roles. This approach avoids the dangers of operating as a
superuserfor tasks that do not really require it.
 
> 
> 
> That, too, reads like a recommendation that intends to inform a security policy. But, I suppose, one could argue that
sayingsomething “is good practice” is very different from making a recommendation.
 
> 
> Consider this wording. It also uses “good practice”.
> 
> «
> It is good practice to limit the number of superuser roles that exist in a cluster to exactly one: the inevitable
bootstrapsuperuser. This recognizes the fact that, once the initial configuration of a cluster has been done
immediatelyafter its creation (which configuration is done while still in self-imposed single-user mode), there are
thenvery few, and infrequent, tasks that require the power of the superuser role.
 
> »
> 
> Nobody supports it!

I went back through the thread and don't anywhere when you made the 
above statement, correct me if I am wrong. In that case there was 
nothing to support or not support until now.

What people where responding to the title of the thread:

"Seeking practice recommendation: is there ever a use case to have two 
or more superusers?"

That is a different ask.


> 
> I’m puzzled why the good practice statement about a role with the CREATEDB and CREATEROLE attributes earns a place in
thedoc while nobody at all is prepared to make a practice statement about how many superusers is good. I’d like very
muchto understand the critical parts that I’m missing of the essential mental model in this general space.
 
> 
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com



On Mon, Nov 21, 2022 at 10:40 AM Bryn Llewellyn <bryn@yugabyte.com> wrote:
 

Consider this wording. It also uses “good practice”.

«
It is good practice to limit the number of superuser roles that exist in a cluster to exactly one: the inevitable bootstrap superuser. This recognizes the fact that, once the initial configuration of a cluster has been done immediately after its creation (which configuration is done while still in self-imposed single-user mode), there are then very few, and infrequent, tasks that require the power of the superuser role.
»

Nobody supports it!

I’m puzzled why the good practice statement about a role with the CREATEDB and CREATEROLE attributes earns a place in the doc while nobody at all is prepared to make a practice statement about how many superusers is good. I’d like very much to understand the critical parts that I’m missing of the essential mental model in this general space.

My policy would be that no one is supposed to login to the database cluster using the postgres role.  Period.  Upon initialization whomever is responsible for creating the cluster gets their personal user credentials installed into the cluster as superuser and from that point on never uses postgres.  They will, however, in the interest of business continuity, create additional superusers for any others who share the superuser responsibility.

In short, there is very little room to argue against the principle of least privilege.  I don't see where that principle supports "only have one superuser" nor does it seem better than another security principle: "everyone must have their own credentials".

I suppose the suggestion I would be willing to consider is:  only have the postgres superuser, never grant superuser to login roles explicitly, instead if those persons require superuser grant them membership in the postgres role.  Except I don't think that actually works in a desirable way today.  Having multiple roles in service of least-privilege while retaining users must use personal login credentials is my suggested starting point absent some more improvements in the authorization systems (or a better understanding of existing ones by your truly).

So yes I, like everyone else, is going to end up forming their own generalities.  Ideas that I cannot wholly discredit as bad, but that don't fit into my generality, get the "if the specific circumstances warrant it" treatment.  My own presuppositions ultimately should get the same treatment by whomever is implementing such policies.

David J.

adrian.klaver@aklaver.com wrote:

bryn@yugabyte.com:

Consider this wording. It also uses “good practice”.
«
It is good practice to limit the number of superuser roles that exist in a cluster to exactly one: the inevitable bootstrap superuser. This recognizes the fact that, once the initial configuration of a cluster has been done immediately after its creation (which configuration is done while still in self-imposed single-user mode), there are then very few, and infrequent, tasks that require the power of the superuser role.
»

No
body supports it!

I went back through the thread and don't anywhere when you made the above statement, correct me if I am wrong. In that case there was nothing to support or not support until now. What people where responding to the title of the thread:

"Seeking practice recommendation: is there ever a use case to have two or more superusers?"

That is a different ask.

I didn't mean to say that I'd already written the sentence that starts "It is good practice to limit the number of superuser roles that exist in a cluster...". Sorry if I gave that impression. It was just a strawman version of what I practice recommendation might look like that used the same general wording style as the one about "a role that has the CREATEDB and CREATEROLE".






On 11/21/22 11:46, Bryn Llewellyn wrote:

>>>
>>> Nobody supports it!
>>
>> I went back through the thread and don't anywhere when you made the 
>> above statement, correct me if I am wrong. In that case there was 
>> nothing to support or not support until now. What people where 
>> responding to the title of the thread:
>>
>>> "Seeking practice recommendation: is there ever a use case to have 
>>> two or more superusers?"
>>
>> That is a different ask.
> 
> I didn't mean to say that I'd already written the sentence that starts 
> "It is good practice to limit the number of superuser roles that exist 
> in a cluster...". Sorry if I gave that impression. It was just a 
> strawman version of what I practice recommendation might look like that 
> used the same general wording style as the one about "a role that has 
> the CREATEDB and CREATEROLE".
> 

Still, why the "Nobody supports it!" statement for a recommendation that 
only appeared at the same time? I for one have a poor record of mind 
reading and/or predicting the future:)

-- 
Adrian Klaver
adrian.klaver@aklaver.com




> adrian.klaver@aklaver.com wrote:
>
>> bryn@yugabyte.com wrote:
>>
>> Consider this wording. It also uses “good practice”.
>>
>> «
>> It is good practice to limit the number of superuser roles that exist in a cluster to exactly one: the inevitable
bootstrapsuperuser. This recognizes the fact that, once the initial configuration of a cluster has been done
immediatelyafter its creation (which configuration is done while still in self-imposed single-user mode), there are
thenvery few, and infrequent, tasks that require the power of the superuser role. 
>> »
>>
>> Nobody supports it!
>
> ...why the "Nobody supports it!" statement for a recommendation that only appeared at the same time? I for one have a
poorrecord of mind reading and/or predicting the future:) 

Here’s what I wrote in the post that started this thread, archived at this URL:

https://www.postgresql.org/message-id/290EF7B8-D150-4AE1-8FFE-A38912CD1A8B@yugabyte.com

> The implication is clear: you should allow a cluster to have just a single superuser, the inevitable bootstrap
superuser,and you should think very carefully indeed before ever starting a session as this role because of the risks
thatdoing so brings. Rather, you should realize that there are hardly any tasks that cannot be carried out by an
appropriatelyconfigured role with "nosuperuser”. 


The essential content of each (what I wrote in my opening post and what stands between « ... » above) is the same:
allowmaximum one superuser. Each is a strawman. And, as such, carries its own implicit invitation for challenge or
support.The outcome was all challenge and no support. I don’t know why observing that this was the outcome has, itself,
becomecontroversial. 

In fact, David Johnston did unequivocally challenge my strawman a couple of turns back, thus:

> no one is supposed to login to the database cluster using the postgres role. Period. Upon initialization whomever is
responsiblefor creating the cluster gets their personal user credentials installed into the cluster as superuser and
fromthat point on never uses postgres.   


That’s actionable advice. I mentioned that I had implemented that scheme and then, later, abandoned it. I can easily
re-implementit. 

Because PG allows a cluster to have as many superusers as you please, and because any one of these can create or drop
another,any convention in this space needs some extra mechanisms to enforce it.. 

I believe that the fact that a superuser's ability to start a session can be limited by what the "hba_file" says is
criticalhere—together with the fact that the ability to edit this file is governed by the regime of O/S users and file
privileges.Maybe this is the key to the effectively tamper-proof implementation of the scheme that David recommends.
(Havingsaid this, there's always the "set role" backdoor.) 

There's also the caveat that a "drop" attempt by a superuser for a single object owned by the bootstrap superuser (say,
the"pg_catalog.pg_terminate_backend()" function) in some database causes an error with the message "cannot drop
function...because it is required by the database system". (At least, this is what my tests have shown with a smallish
sampleof drop targets.) This seems to be a Very Good Thing. But the fact that this is the behavior makes me wonder what
harmcan be done by a session that authorizes as the bootstrap superuser that cannot be done by a session that
authorizesas a regular superuser. I'll try to find out. 




On Mon, Nov 21, 2022 at 4:05 PM Bryn Llewellyn <bryn@yugabyte.com> wrote:

I believe that the fact that a superuser's ability to start a session can be limited by what the "hba_file" says is critical here—together with the fact that the ability to edit this file is governed by the regime of O/S users and file privileges. Maybe this is the key to the effectively tamper-proof implementation of the scheme that David recommends. (Having said this, there's always the "set role" backdoor.)

If you are worried about back-doors here you gave the wrong people superuser.  That may be unavoidable, but this scheme really isn't about bullet-proofing security.  It's about ease of administration and knowing just who all has permission do what on a server by inspecting its role table.

Yes, you should lock-down pg_hba.conf to avoid other people without superuser from being able to easily hack into the system using one of these accounts (admittedly, a decent reason to limit how many there are, but all of them should be equally/maximally secure so it isn't that strong an argument).

David J.

On 22 Nov 2022, at 10:05, Bryn Llewellyn wrote:

> Because PG allows a cluster to have as many superusers as you please, and because any one of these can create or drop
another,any convention in this space needs some extra mechanisms to enforce it.. 
>
> …  effectively tamper-proof implementation of the scheme …
>
Somewhat interesting thread so far but seems to be asking more than one question —
Q1. Is there ever a use case to have two or more superusers? Answer: Yes, but entirely depending on the use case.
Q2. [IMPLIED] How to make the database tamper-proof since at least one superuser is unavoidable? Answer: Not possible,
ever— see below. 

It is best to consider a database security system’s design objectives to be tamper proof from the outside (ie., general
clientaccess perspective), and tamper evident from within the database. As far as the server is concerned one person’s
superusertampering is another person’s maintenance. There is no way to configure login credentials to prevent malicious
ormistaken changes when you need to have the occasional superuser role that can repair a serious fault or process a
systemupgrade. If an upgrade or repair can be anticipated it should already be done, the superuser is needed for the
thingsthat were not expected or too complex to pre-automate. 

AFAICT minimal tamper evident criteria will include logs being kept of changes made and these on a system the database
superusercannot change. At worst the logs will still have recorded when they were turned off. And the logs should have
recordedthe credentials used to assume the superuser role. After that it is basic business management — was the person
actingbadly, were the credentials stolen, what damage was done, and are the backups useful? 

The full security analysis is complex and searches around “threat landscape” will help widen the perspective. The
questionbecomes one of identifying what is possible to prevent, what can only be mitigated, and what can only be
repairedafter the fact. Database security is a lot more complicated than just trying to restrict the superuser role. 

Gavan Schneider
——
Gavan Schneider, Sodwalls, NSW, Australia
Explanations exist; they have existed for all time; there is always a well-known solution to every human problem —
neat,plausible, and wrong. 
— H. L. Mencken, 1920



On 11/21/22 15:05, Bryn Llewellyn wrote:
>> adrian.klaver@aklaver.com wrote:

>> ...why the "Nobody supports it!" statement for a recommendation that only appeared at the same time? I for one have
apoor record of mind reading and/or predicting the future:)
 
> 
> Here’s what I wrote in the post that started this thread, archived at this URL:
> 
> https://www.postgresql.org/message-id/290EF7B8-D150-4AE1-8FFE-A38912CD1A8B@yugabyte.com
> 
>> The implication is clear: you should allow a cluster to have just a single superuser, the inevitable bootstrap
superuser,and you should think very carefully indeed before ever starting a session as this role because of the risks
thatdoing so brings. Rather, you should realize that there are hardly any tasks that cannot be carried out by an
appropriatelyconfigured role with "nosuperuser”.
 
> 
> 
> The essential content of each (what I wrote in my opening post and what stands between « ... » above) is the same:
allowmaximum one superuser. Each is a strawman. And, as such, carries its own implicit invitation for challenge or
support.The outcome was all challenge and no support. I don’t know why observing that this was the outcome has, itself,
becomecontroversial.
 

You must be reading a different thread. What I saw in the replies was 
people answering '...is there ever a use case to have two or more 
superusers?' with, maybe but in the end it is up to you to decide what 
works in your case.

> 
> In fact, David Johnston did unequivocally challenge my strawman a couple of turns back, thus:
> 
>> no one is supposed to login to the database cluster using the postgres role. Period. Upon initialization whomever is
responsiblefor creating the cluster gets their personal user credentials installed into the cluster as superuser and
fromthat point on never uses postgres.
 

You left out the preface to the above,  'My policy would be that ...`

And the equivocal additions later in the post:

"I suppose the suggestion I would be willing to consider is:  only have 
the postgres superuser, never grant superuser to login roles explicitly,
instead if those persons require superuser grant them membership in the
postgres role."

and

"
So yes I, like everyone else, is going to end up forming their own
generalities.  Ideas that I cannot wholly discredit as bad, but that 
don't fit into my generality, get the "if the specific circumstances 
warrant it" treatment.  My own presuppositions ultimately should get the 
same treatment by whomever is implementing such policies."

> 
> 
> That’s actionable advice. I mentioned that I had implemented that scheme and then, later, abandoned it. I can easily
re-implementit.
 
> 
> Because PG allows a cluster to have as many superusers as you please, and because any one of these can create or drop
another,any convention in this space needs some extra mechanisms to enforce it..
 
> 
> I believe that the fact that a superuser's ability to start a session can be limited by what the "hba_file" says is
criticalhere—together with the fact that the ability to edit this file is governed by the regime of O/S users and file
privileges.Maybe this is the key to the effectively tamper-proof implementation of the scheme that David recommends.
(Havingsaid this, there's always the "set role" backdoor.)
 
> 
> There's also the caveat that a "drop" attempt by a superuser for a single object owned by the bootstrap superuser
(say,the "pg_catalog.pg_terminate_backend()" function) in some database causes an error with the message "cannot drop
function...because it is required by the database system". (At least, this is what my tests have shown with a smallish
sampleof drop targets.) This seems to be a Very Good Thing. But the fact that this is the behavior makes me wonder what
harmcan be done by a session that authorizes as the bootstrap superuser that cannot be done by a session that
authorizesas a regular superuser. I'll try to find out.
 

Superuser is superuser, there is no magic associated with the bootstrap 
superuser.

FYI, the answer is won't make a difference.

-- 
Adrian Klaver
adrian.klaver@aklaver.com




On Mon, Nov 21, 2022 at 5:30 PM Adrian Klaver <adrian.klaver@aklaver.com> wrote:
On 11/21/22 15:05, Bryn Llewellyn wrote:
>
> In fact, David Johnston did unequivocally challenge my strawman a couple of turns back, thus:
>


And the equivocal additions later in the post:

Yeah, even when I try to be unequivocal I tend to fail...Devil's Advocate is another role I enjoy playing.

 
>
> There's also the caveat that a "drop" attempt by a superuser for a single object owned by the bootstrap superuser (say, the "pg_catalog.pg_terminate_backend()" function) in some database causes an error with the message "cannot drop function... because it is required by the database system". (At least, this is what my tests have shown with a smallish sample of drop targets.)

There are some protections in place to prevent the superuser from shooting themselves in the foot accidentally.  They are readily disabled though, through a simple SET command in the session.


Superuser is superuser, there is no magic associated with the bootstrap
superuser.


Not quite true, it is magical in that every initdb thing that needs an owner has it as an owner.  And, at least not easily or desirably, that ownership cannot be transferred, which makes dropping said role problematic.

David J.