doc: improve role option documentation
authorBruce Momjian <bruce@momjian.us>
Thu, 1 Feb 2024 11:11:53 +0000 (06:11 -0500)
committerBruce Momjian <bruce@momjian.us>
Thu, 1 Feb 2024 11:11:53 +0000 (06:11 -0500)
Role option management was changed in Postgres 16.  This patch improves
the docs around these changes, including CREATE ROLE's INHERIT option,
inheritance handling, and grant's ability to change role options.

Discussion: https://postgr.es/m/Zab9GiV63EENDcWG@momjian.us

Co-authored-by: David G. Johnston
Backpatch-through: 16

doc/src/sgml/ref/create_role.sgml
doc/src/sgml/ref/grant.sgml
doc/src/sgml/user-manag.sgml

index 8dd2a6395c4273a02d2bd764d0df7f24d97ed56f..f3b89e7239b6caf8404dd23918384c73762679f6 100644 (file)
@@ -66,6 +66,17 @@ in sync when changing the above synopsis!
    Note that roles are defined at the database cluster
    level, and so are valid in all databases in the cluster.
   </para>
+
+  <para>
+   During role creation it is possible to immediately assign the newly created
+   role to be a member of an existing role, and also assign existing roles
+   to be members of the newly created role.  The rules for which initial
+   role membership options are enabled described below in the
+   <literal>IN ROLE</literal>, <literal>ROLE</literal>, and
+   <literal>ADMIN</literal> clauses.  The <xref linkend="sql-grant"/>
+   command has fine-grained option control during membership creation,
+   and the ability to modify these options after the new role is created.
+  </para>
  </refsect1>
 
  <refsect1>
@@ -133,24 +144,21 @@ 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>
         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 that controlled all runtime
+        membership checks for that role.
        </para>
       </listitem>
      </varlistentry>
@@ -285,9 +293,10 @@ 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> option is specified.
        </para>
       </listitem>
      </varlistentry>
@@ -297,8 +306,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 the <literal>INHERIT</literal> attribute will have
+        the <literal>INHERIT</literal> option enabled in the new membership.
+        New memberships will have the <literal>ADMIN</literal> option disabled.
        </para>
       </listitem>
      </varlistentry>
@@ -307,10 +320,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 has the same effect as
+        <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 the new role to others.
        </para>
       </listitem>
      </varlistentry>
@@ -353,15 +366,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>
@@ -460,8 +477,10 @@ CREATE ROLE <replaceable class="parameter">name</replaceable> [ WITH ADMIN <repl
 
   <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.
+   creating SQL-standard users as <productname>PostgreSQL</productname>
+   roles with the <literal>NOINHERIT</literal> option, and SQL-standard
+   roles as <productname>PostgreSQL</productname> roles with the
+   <literal>INHERIT</literal> option.
   </para>
 
   <para>
index 1ae5770fbbf3203382ca71d1072bfe1927fee481..9d27b7fcde5695ecd18e0bed88ecebc0c9835b0f 100644 (file)
@@ -249,11 +249,16 @@ 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 options <literal>SET</literal>, <literal>INHERIT</literal>,
+   and <literal>ADMIN</literal>;  see <xref linkend="role-membership"/>
+   for details.  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 options of
+   an existing membership, simply specify the membership with updated
+   option values.
   </para>
 
   <para>
@@ -261,7 +266,9 @@ GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replace
    <literal>TRUE</literal> or <literal>FALSE</literal>. The keyword
    <literal>OPTION</literal> is accepted as a synonym for
    <literal>TRUE</literal>, so that <literal>WITH ADMIN OPTION</literal>
-   is a synonym for <literal>WITH ADMIN TRUE</literal>.
+   is a synonym for <literal>WITH ADMIN TRUE</literal>.  When altering
+   an existing membership the omission of an option results in the current
+   value being retained.
   </para>
 
   <para>
@@ -275,15 +282,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="role-membership"/> 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 when create a new role membership this defaults to
+   the inheritance attribute of the role being added.
   </para>
 
   <para>
index 1c011ac62b57397fc21fad7aec9a960dcc0e93c5..e026a4e27178096e89752127eacb3bed155df53f 100644 (file)
@@ -409,10 +409,10 @@ REVOKE <replaceable>group_role</replaceable> FROM <replaceable>role1</replaceabl
    than the original login role, and any database objects created are
    considered owned by the group role not the login role.  Second, member
    roles that have been granted membership with the
-   <literal>INHERIT</literal> option automatically have use
-   of the privileges of those roles, including any
-   privileges inherited by those roles.
-   As an example, suppose we have done:
+   <literal>INHERIT</literal> option automatically have use of the
+   privileges of those directly or indirectly a member of, though the
+   chain stops at memberships lacking the inherit option.  As an example,
+   suppose we have done:
 <programlisting>
 CREATE ROLE joe LOGIN;
 CREATE ROLE admin;