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
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>

View 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>

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
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;