On Wed, Jan 17, 2024 at 02:32:47PM -0700, David G. Johnston wrote:
> I had a go at this.
>
> I went with a more "bullet item" approach with my wording for INHERIT/
> NOINHERIT.
I tried to address that.
> The entire paragraph regarding how the INHERIT "option" works, as opposed to
> the attribute, seems out of place where it was and the material is already
> covered in the GRANT page. We should either improve that page or extract this
> level of detail somewhere else, not try to clutter up the CREATE ROLE page
> with
> it.
Because the CREATE ROLE is the way to create roles, and GRANT does much
more than just grant membership, I ended up moving the details from the
GRANT page to the CREATE ROLE page.
> We consistently say what the default is for these attribute pairs, do so here
> as well.
I added that, I hope in all the right places.
> Turn the parenthetical in the IN ROLE section into actual assertive
> documentation of what the clause does. Tweak ROLE and ADMIN as well to fit in
> better.
Yes, that needed help.
> Reword the discussion regarding non-inheritance to be more direct.
>
> I added mention of the grantee aspect of privileges as a soft way of further
> pointing out that the IN ROLE, ROLE, ADMIN clauses are limited in what they
> can
> control in the resulting membership grants.
>
> I choose to use the phrasing "giving ... roles" for both parts of the sentence
> instead of switching to "... roles are given" for the second half. More of a
> style choice but I didn't think switching really added much and just makes it
> a
> bit wordier and possibly a bit more effort to mentally parse.
I adjusted that working, but in a different way. Patch attached.
I also found we didn't document that GRANT can be used to modify a
membership's attributes even after it is created; I added that.
Just a reminder, this is for PG 16 and master.
--
Bruce Momjian <[email protected]> https://momjian.us
EDB https://enterprisedb.com
Only you can decide what is important to you.
diff --git a/doc/src/sgml/ref/create_role.sgml b/doc/src/sgml/ref/create_role.sgml
index 8dd2a6395c..f2dc841b85 100644
--- a/doc/src/sgml/ref/create_role.sgml
+++ b/doc/src/sgml/ref/create_role.sgml
@@ -133,24 +133,33 @@ in sync when changing the above synopsis!
<term><literal>NOINHERIT</literal></term>
<listitem>
<para>
- When the <literal>GRANT</literal> statement is used to confer
- membership in one role to another role, the <literal>GRANT</literal>
- may use the <literal>WITH INHERIT</literal> clause to specify whether
- the privileges of the granted role should be <quote>inherited</quote>
- by the new member. If the <literal>GRANT</literal> statement does not
- specify either inheritance behavior, the new <literal>GRANT</literal>
- will be created <literal>WITH INHERIT TRUE</literal> if the member
- role is set to <literal>INHERIT</literal> and to
- <literal>WITH INHERIT FALSE</literal> if it is set to
- <literal>NOINHERIT</literal>.
+ This affects the membership inheritance status when this
+ role is added as a member of another role, both in this and
+ future commands. Specifically, it controls the inheritance
+ status of memberships added with this command using the
+ <literal>IN ROLE</literal> clause, and in later commands using
+ the <literal>ROLE</literal> clause. It is also used as the
+ default inheritance status when adding this role as a member
+ using the <literal>GRANT</literal> command. If not specified,
+ <literal>INHERIT</literal> is the default.
+ </para>
+
+ <para>
+ Role membership with the inherit attribute can automatically use
+ whatever database privileges have been granted to all roles it
+ is directly or indirectly a member of, though the chain stops
+ at memberships lacking the inherit attribute. Without role
+ inheritance, the only other value of membership is the use of
+ <command>SET ROLE</command>, assuming the membership chain has
+ <literal>SET</literal> attributes.
</para>
<para>
In <productname>PostgreSQL</productname> versions before 16,
- the <literal>GRANT</literal> statement did not support
- <literal>WITH INHERIT</literal>. Therefore, changing this role-level
- property would also change the behavior of already-existing grants.
- This is no longer the case.
+ inheritance was a role-level attribute. It could not be specified
+ during role addition with <literal>GRANT</literal>, and changing
+ this role-level property would also change the inheritance behavior
+ of all existing memberships. This is no longer the case.
</para>
</listitem>
</varlistentry>
@@ -285,9 +294,13 @@ in sync when changing the above synopsis!
<para>
The <literal>IN ROLE</literal> clause causes the new role to
be automatically added as a member of the specified existing
- roles. (Note that there is no option to add the new role as an
- administrator; use a separate <command>GRANT</command> command
- to do that.)
+ roles. The new membership will have the <literal>SET</literal>
+ option enabled and the <literal>ADMIN</literal> option disabled.
+ The <literal>INHERIT</literal> option will be enabled unless the
+ <literal>NOINHERIT</literal> attribute is specified. See the <xref
+ linkend="sql-grant"/> command, which has additional attribute
+ control during membership creation and to modify these options
+ after the new role is created.
</para>
</listitem>
</varlistentry>
@@ -297,8 +310,12 @@ in sync when changing the above synopsis!
<listitem>
<para>
The <literal>ROLE</literal> clause causes one or more specified
- existing roles to be automatically added as members of the new
- role. This in effect makes the new role a <quote>group</quote>.
+ existing roles to be automatically added as members, with the
+ <literal>SET</literal> option enabled. This in effect makes the
+ new role a <quote>group</quote>. Roles named in this clause
+ with role-level <literal>INHERIT</literal> attributes will have
+ <literal>INHERIT</literal> enabled in the new membership. New
+ memberships will have the <literal>ADMIN</literal> option disabled.
</para>
</listitem>
</varlistentry>
@@ -307,10 +324,10 @@ in sync when changing the above synopsis!
<term><literal>ADMIN</literal> <replaceable class="parameter">role_name</replaceable></term>
<listitem>
<para>
- The <literal>ADMIN</literal> clause is like <literal>ROLE</literal>,
- but the named roles are added to the new role <literal>WITH ADMIN
- OPTION</literal>, giving them the right to grant membership in this role
- to others.
+ The <literal>ADMIN</literal> clause is similar to
+ <literal>ROLE</literal>, but the named roles are added as members
+ of the new role with <literal>ADMIN</literal> enabled, giving
+ them the right to grant membership in this role to others.
</para>
</listitem>
</varlistentry>
@@ -353,15 +370,19 @@ in sync when changing the above synopsis!
</para>
<para>
- The <literal>INHERIT</literal> attribute governs inheritance of grantable
- privileges (that is, access privileges for database objects and role
- memberships). It does not apply to the special role attributes set by
- <command>CREATE ROLE</command> and <command>ALTER ROLE</command>. For example, being
- a member of a role with <literal>CREATEDB</literal> privilege does not immediately
- grant the ability to create databases, even if <literal>INHERIT</literal> is set;
- it would be necessary to become that role via
- <link linkend="sql-set-role"><command>SET ROLE</command></link> before
- creating a database.
+ The role attributes defined here are non-inheritable, i.e., being a
+ member of a role with, e.g., <literal>CREATEDB</literal> will not
+ allow the member to create new databases even if the membership grant
+ has the <literal>INHERIT</literal> option. Of course, if the membership
+ grant has the <literal>SET</literal> option the member role would be able to
+ <link linkend="sql-set-role"><command>SET ROLE</command></link> to the
+ createdb role and then create a new database.
+ </para>
+
+ <para>
+ The membership grants created by the
+ <literal>IN ROLE</literal>, <literal>ROLE</literal>, and <literal>ADMIN</literal>
+ clauses have the role executing this command as the grantee.
</para>
<para>
@@ -459,9 +480,11 @@ CREATE ROLE <replaceable class="parameter">name</replaceable> [ WITH ADMIN <repl
</para>
<para>
- The behavior specified by the SQL standard is most closely approximated
- by giving users the <literal>NOINHERIT</literal> attribute, while roles are
- given the <literal>INHERIT</literal> attribute.
+ The behavior specified by the SQL standard is most closely approximated
+ creating SQL-standard users as <productname>PostgreSQL</productname>
+ roles with the <literal>NOINHERIT</literal> attribute, and SQL-standard
+ roles as <productname>PostgreSQL</productname> roles with the
+ <literal>INHERIT</literal> attribute.
</para>
<para>
diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml
index 1ae5770fbb..fbf98b0cad 100644
--- a/doc/src/sgml/ref/grant.sgml
+++ b/doc/src/sgml/ref/grant.sgml
@@ -249,11 +249,14 @@ GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replace
<para>
This variant of the <command>GRANT</command> command grants membership
- in a role to one or more other roles. Membership in a role is significant
+ in a role to one or more other roles, and the modification of
+ membership attributes. Membership in a role is significant
because it potentially allows access to the privileges granted to a role
to each of its members, and potentially also the ability to make changes
to the role itself. However, the actual permissions conferred depend on
- the options associated with the grant.
+ the options associated with the grant. To modify that attributes of
+ an existing membership, simply specify the membership with updated
+ attribute values.
</para>
<para>
@@ -275,15 +278,13 @@ GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replace
</para>
<para>
- The <literal>INHERIT</literal> option, if it is set to
- <literal>TRUE</literal>, causes the member to inherit the privileges of
- the granted role. That is, it can automatically use whatever database
- privileges have been granted to that role. If set to
- <literal>FALSE</literal>, the member does not inherit the privileges
- of the granted role. If this clause is not specified, it defaults to
- true if the member role is set to <literal>INHERIT</literal> and to false
- if the member role is set to <literal>NOINHERIT</literal>.
- See <link linkend="sql-createrole"><command>CREATE ROLE</command></link>.
+ The <literal>INHERIT</literal> option controls the inheritance status
+ of the new membership; see <xref linkend="sql-createrole"/> for
+ details on inheritance. If it is set to <literal>TRUE</literal>,
+ it causes the new member to inherit from the granted role. If
+ set to <literal>FALSE</literal>, the new member does not inherit.
+ If unspecified, it defaults to the inheritance status of the role
+ being added.
</para>
<para>