doc: improve role option documentation

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
This commit is contained in:
Bruce Momjian 2024-02-01 06:11:53 -05:00
parent 16a80e8912
commit 21912e3c02
3 changed files with 74 additions and 50 deletions

View File

@ -66,6 +66,17 @@ in sync when changing the above synopsis!
Note that roles are defined at the database cluster Note that roles are defined at the database cluster
level, and so are valid in all databases in the cluster. level, and so are valid in all databases in the cluster.
</para> </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>
<refsect1> <refsect1>
@ -133,24 +144,21 @@ in sync when changing the above synopsis!
<term><literal>NOINHERIT</literal></term> <term><literal>NOINHERIT</literal></term>
<listitem> <listitem>
<para> <para>
When the <literal>GRANT</literal> statement is used to confer This affects the membership inheritance status when this
membership in one role to another role, the <literal>GRANT</literal> role is added as a member of another role, both in this and
may use the <literal>WITH INHERIT</literal> clause to specify whether future commands. Specifically, it controls the inheritance
the privileges of the granted role should be <quote>inherited</quote> status of memberships added with this command using the
by the new member. If the <literal>GRANT</literal> statement does not <literal>IN ROLE</literal> clause, and in later commands using
specify either inheritance behavior, the new <literal>GRANT</literal> the <literal>ROLE</literal> clause. It is also used as the
will be created <literal>WITH INHERIT TRUE</literal> if the member default inheritance status when adding this role as a member
role is set to <literal>INHERIT</literal> and to using the <literal>GRANT</literal> command. If not specified,
<literal>WITH INHERIT FALSE</literal> if it is set to <literal>INHERIT</literal> is the default.
<literal>NOINHERIT</literal>.
</para> </para>
<para> <para>
In <productname>PostgreSQL</productname> versions before 16, In <productname>PostgreSQL</productname> versions before 16,
the <literal>GRANT</literal> statement did not support inheritance was a role-level attribute that controlled all runtime
<literal>WITH INHERIT</literal>. Therefore, changing this role-level membership checks for that role.
property would also change the behavior of already-existing grants.
This is no longer the case.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -285,9 +293,10 @@ in sync when changing the above synopsis!
<para> <para>
The <literal>IN ROLE</literal> clause causes the new role to The <literal>IN ROLE</literal> clause causes the new role to
be automatically added as a member of the specified existing be automatically added as a member of the specified existing
roles. (Note that there is no option to add the new role as an roles. The new membership will have the <literal>SET</literal>
administrator; use a separate <command>GRANT</command> command option enabled and the <literal>ADMIN</literal> option disabled.
to do that.) The <literal>INHERIT</literal> option will be enabled unless the
<literal>NOINHERIT</literal> option is specified.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -297,8 +306,12 @@ in sync when changing the above synopsis!
<listitem> <listitem>
<para> <para>
The <literal>ROLE</literal> clause causes one or more specified The <literal>ROLE</literal> clause causes one or more specified
existing roles to be automatically added as members of the new existing roles to be automatically added as members, with the
role. This in effect makes the new role a <quote>group</quote>. <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> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -307,10 +320,10 @@ in sync when changing the above synopsis!
<term><literal>ADMIN</literal> <replaceable class="parameter">role_name</replaceable></term> <term><literal>ADMIN</literal> <replaceable class="parameter">role_name</replaceable></term>
<listitem> <listitem>
<para> <para>
The <literal>ADMIN</literal> clause is like <literal>ROLE</literal>, The <literal>ADMIN</literal> clause has the same effect as
but the named roles are added to the new role <literal>WITH ADMIN <literal>ROLE</literal>, but the named roles are added as members
OPTION</literal>, giving them the right to grant membership in this role of the new role with <literal>ADMIN</literal> enabled, giving
to others. them the right to grant membership in the new role to others.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -353,15 +366,19 @@ in sync when changing the above synopsis!
</para> </para>
<para> <para>
The <literal>INHERIT</literal> attribute governs inheritance of grantable The role attributes defined here are non-inheritable, i.e., being a
privileges (that is, access privileges for database objects and role member of a role with, e.g., <literal>CREATEDB</literal> will not
memberships). It does not apply to the special role attributes set by allow the member to create new databases even if the membership grant
<command>CREATE ROLE</command> and <command>ALTER ROLE</command>. For example, being has the <literal>INHERIT</literal> option. Of course, if the membership
a member of a role with <literal>CREATEDB</literal> privilege does not immediately grant has the <literal>SET</literal> option the member role would be able to
grant the ability to create databases, even if <literal>INHERIT</literal> is set; <link linkend="sql-set-role"><command>SET ROLE</command></link> to the
it would be necessary to become that role via createdb role and then create a new database.
<link linkend="sql-set-role"><command>SET ROLE</command></link> before </para>
creating a database.
<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>
<para> <para>
@ -460,8 +477,10 @@ CREATE ROLE <replaceable class="parameter">name</replaceable> [ WITH ADMIN <repl
<para> <para>
The behavior specified by the SQL standard is most closely approximated The behavior specified by the SQL standard is most closely approximated
by giving users the <literal>NOINHERIT</literal> attribute, while roles are creating SQL-standard users as <productname>PostgreSQL</productname>
given the <literal>INHERIT</literal> attribute. roles with the <literal>NOINHERIT</literal> option, and SQL-standard
roles as <productname>PostgreSQL</productname> roles with the
<literal>INHERIT</literal> option.
</para> </para>
<para> <para>

View File

@ -249,11 +249,16 @@ GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replace
<para> <para>
This variant of the <command>GRANT</command> command grants membership 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 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 each of its members, and potentially also the ability to make changes
to the role itself. However, the actual permissions conferred depend on 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>
<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>TRUE</literal> or <literal>FALSE</literal>. The keyword
<literal>OPTION</literal> is accepted as a synonym for <literal>OPTION</literal> is accepted as a synonym for
<literal>TRUE</literal>, so that <literal>WITH ADMIN OPTION</literal> <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>
<para> <para>
@ -275,15 +282,13 @@ GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replace
</para> </para>
<para> <para>
The <literal>INHERIT</literal> option, if it is set to The <literal>INHERIT</literal> option controls the inheritance status
<literal>TRUE</literal>, causes the member to inherit the privileges of of the new membership; see <xref linkend="role-membership"/> for
the granted role. That is, it can automatically use whatever database details on inheritance. If it is set to <literal>TRUE</literal>,
privileges have been granted to that role. If set to it causes the new member to inherit from the granted role. If
<literal>FALSE</literal>, the member does not inherit the privileges set to <literal>FALSE</literal>, the new member does not inherit.
of the granted role. If this clause is not specified, it defaults to If unspecified when create a new role membership this defaults to
true if the member role is set to <literal>INHERIT</literal> and to false the inheritance attribute of the role being added.
if the member role is set to <literal>NOINHERIT</literal>.
See <link linkend="sql-createrole"><command>CREATE ROLE</command></link>.
</para> </para>
<para> <para>

View 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 than the original login role, and any database objects created are
considered owned by the group role not the login role. Second, member considered owned by the group role not the login role. Second, member
roles that have been granted membership with the roles that have been granted membership with the
<literal>INHERIT</literal> option automatically have use <literal>INHERIT</literal> option automatically have use of the
of the privileges of those roles, including any privileges of those directly or indirectly a member of, though the
privileges inherited by those roles. chain stops at memberships lacking the inherit option. As an example,
As an example, suppose we have done: suppose we have done:
<programlisting> <programlisting>
CREATE ROLE joe LOGIN; CREATE ROLE joe LOGIN;
CREATE ROLE admin; CREATE ROLE admin;