Every table, sequence, view, or other object in a PostgreSQL database has an associated set of permissions. These permissions allow fine grained control over the actions allowed for a particular role or user. The psql application can be used to show the object permissions assigned to roles and users as shown in the example below. For the purposes of illustration we are using a fictitious database taken from our DNS server using PowerDNS how-to guide.
template1=# \dp
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
--------+----------------+----------+-------------------------+--------------------------
public | domains | table | dbadmin=arwdDxt/dbadmin+|
| | | dns=r/dbadmin +|
| | | dns_admin=arwd/dbadmin |
public | domains_id_seq | sequence | dbadmin=rwU/dbadmin +|
| | | dns_admin=rwU/dbadmin |
public | records | table | dbadmin=arwdDxt/dbadmin+|
| | | dns=r/dbadmin +|
| | | dns_admin=arwd/dbadmin |
public | records_id_seq | sequence | dbadmin=rwU/dbadmin +|
| | | dns_admin=rwU/dbadmin |
public | supermasters | table | dbadmin=arwdDxt/dbadmin+|
| | | dns=r/dbadmin +|
| | | dns_admin=arwd/dbadmin |
You can see in the above example that for each database object a set of access privileges is displayed in the format shown below. If the <user> portion of the string is empty then the privileges which follow are assigned to the special PUBLIC role. As you can see the dbadmin user has full control of all objects, the dns_admin user has the permissions required to administer the DNS system and all members of the dns role have sufficient read permissions to serve DNS records from the database.
<user> = <permissions> / <granted by>
The access privileges displayed in the above example output are summed up in the following table. More information on available access privileges is available in the GRANT section of the PostgreSQL documentation◳.
We showed, in the section of this guide, that permissions can be removed using the REVOKE command. As we have no need to allow the dns_admin user SELECT access to any tables, they inherit this from their membership of the dns role we can remove this permission as shown below.
dns=# REVOKE SELECT ON domains FROM dns_admin;
REVOKE
dns=# REVOKE SELECT ON records FROM dns_admin;
REVOKE
dns=# REVOKE SELECT ON supermasters FROM dns_admin;
REVOKE
You can verify that the commands had the desired effect by displaying a list of objects as shown in the following example. As you can see SELECT privileges are no longer directly granted to the dns_admin user.
dns=# \dp
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
--------+----------------+----------+-------------------------+--------------------------
public | domains | table | dbadmin=arwdDxt/dbadmin+|
| | | dns=r/dbadmin +|
| | | dns_admin=awd/dbadmin |
public | domains_id_seq | sequence | dbadmin=rwU/dbadmin +|
| | | dns_admin=rwU/dbadmin |
public | records | table | dbadmin=arwdDxt/dbadmin+|
| | | dns=r/dbadmin +|
| | | dns_admin=awd/dbadmin |
public | records_id_seq | sequence | dbadmin=rwU/dbadmin +|
| | | dns_admin=rwU/dbadmin |
public | supermasters | table | dbadmin=arwdDxt/dbadmin+|
| | | dns=r/dbadmin +|
| | | dns_admin=awd/dbadmin |
(5 rows)
Of course, permissions can be granted using the GRANT command in exactly the same way. Assuming we wanted to give the dns role, and therefore by implication all of its members, SELECT permissions on the two sequences we could do so with the following commands.
template1=# GRANT SELECT ON domains_id_seq TO dns;
GRANT
template1=# GRANT SELECT ON records_id_seq TO dns;
GRANT
As before you can verify that the commands had the desired effect by displaying a listing of database objects from within the psql application.
template1=# \dp
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
--------+----------------+----------+-------------------------+--------------------------
public | domains | table | dbadmin=arwdDxt/dbadmin+|
| | | dns=r/dbadmin +|
| | | dns_admin=awd/dbadmin |
public | domains_id_seq | sequence | dbadmin=rwU/dbadmin +|
| | | dns_admin=rwU/dbadmin +|
| | | dns=r/dbadmin |
public | records | table | dbadmin=arwdDxt/dbadmin+|
| | | dns=r/dbadmin +|
| | | dns_admin=awd/dbadmin |
public | records_id_seq | sequence | dbadmin=rwU/dbadmin +|
| | | dns_admin=rwU/dbadmin +|
| | | dns=r/dbadmin |
public | supermasters | table | dbadmin=arwdDxt/dbadmin+|
| | | dns=r/dbadmin +|
| | | dns_admin=awd/dbadmin |
(5 rows)