<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Srinivasa Raghavan</title>
    <description>The latest articles on DEV Community by Srinivasa Raghavan (@srinivasa_raghavan).</description>
    <link>https://dev.to/srinivasa_raghavan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F814663%2F57be8f7f-7809-4caa-b6ea-d98a471ca59b.png</url>
      <title>DEV Community: Srinivasa Raghavan</title>
      <link>https://dev.to/srinivasa_raghavan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/srinivasa_raghavan"/>
    <language>en</language>
    <item>
      <title>Restrict and grant privileges on public schema to users</title>
      <dc:creator>Srinivasa Raghavan</dc:creator>
      <pubDate>Sun, 26 Jun 2022 08:32:40 +0000</pubDate>
      <link>https://dev.to/srinivasa_raghavan/restrict-and-grant-privileges-on-public-schema-to-users-5chg</link>
      <guid>https://dev.to/srinivasa_raghavan/restrict-and-grant-privileges-on-public-schema-to-users-5chg</guid>
      <description>&lt;p&gt;Before we get to the topic, first things first you might have to know answer to the following questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is access control?
&lt;/h2&gt;

&lt;p&gt;Access control is a fundamental component in security compliance where we control who can access what.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we want to do access control ?
&lt;/h2&gt;

&lt;p&gt;Access control might sound a bit scary like as if we are control freaks, right? That is not the case. We need to ensure that we provide only the set of privileges that a particular user will need. Because a Postgres user could be used by a human and an application. In case of system compromise or remote code execution by an attacker, user access control definitely protects against major damage.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the prerequisites to understand this blog ?
&lt;/h2&gt;

&lt;p&gt;You need to know what Postgres is, and the commands associated with SQL and &lt;a href="https://www.postgresql.org/docs/13/ddl-priv.html"&gt;privileges&lt;/a&gt; at each level for a user in Postgres. &lt;/p&gt;

&lt;h2&gt;
  
  
  Who might find this useful ?
&lt;/h2&gt;

&lt;p&gt;Those who wants to apply user access control to an existing database with tables in public schema that cannot be moved to a different schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the default access privileges for a user in Postgres ?
&lt;/h2&gt;

&lt;p&gt;By default, all users are given connect access to any database and public schema of a database allows creation of new data objects and usage of them within it unless revoked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ycrldkm2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vh8p8ee44c6dhb9526p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ycrldkm2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vh8p8ee44c6dhb9526p.png" alt="Image showing Authorised personnel only sign" width="880" height="1139"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Let's get started
&lt;/h2&gt;

&lt;p&gt;For demonstration we can consider the following scenario :&lt;/p&gt;

&lt;p&gt;There is a web application that uses &lt;code&gt;PostgreSQL&lt;/code&gt;, and database migration tool like &lt;code&gt;Liquibase&lt;/code&gt; or &lt;code&gt;Flyway&lt;/code&gt;. There is a database admin who maintains the database. &lt;br&gt;
We have created different users for application &lt;code&gt;application_user&lt;/code&gt;, migration tool &lt;code&gt;migration_user&lt;/code&gt; and the admin &lt;code&gt;admin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;application_user requires privilege to run only DML commands. migration_user requires both DDL and DML. admin has all the privileges.&lt;/p&gt;

&lt;p&gt;Grant privileges works in such a way that if a user has higher privilege to an object already, granting a lower privilege will only retain the existing privilege, so they have to be revoked before granting.&lt;/p&gt;

&lt;p&gt;There are various layers in database access which is illustrated in the diagram below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pnTEDlJC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n4fk4zky7s2xq6pjxfpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pnTEDlJC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n4fk4zky7s2xq6pjxfpa.png" alt="Image showing various layers in Postgres DB" width="611" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Database accesses
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;REVOKE ALL ON DATABASE  FROM PUBLIC;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here public is the pseudo user group that all users in Postgres belong to by default.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;GRANT CONNECT ON DATABASE  to migration_user;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GRANT CONNECT ON DATABASE  to application_user;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Schema accesses
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Revokes all privileges (CREATE/USAGE) on public schema from all existing and future users(public role). By default
public schema has all privileges unless revoked.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;REVOKE ALL ON SCHEMA public FROM PUBLIC&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Grants CREATE and USAGE (all) access to migration user as they need to create tables inside public schema and also use them.'&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;GRANT ALL ON SCHEMA public to migration_user;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Grants only usage access to app user as they should not be able to create new tables and only need to access the tables inside public schema.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;GRANT USAGE ON SCHEMA public to application_user;&lt;/p&gt;

&lt;h3&gt;
  
  
  Table accesses
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Revokes all privileges (SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER) on all tables in public schema
from all existing &amp;amp; future users(public), default privilege for tables in public schema is all privileges unless revoked.'&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Grants (SELECT, INSERT, UPDATE, DELETE) access to application_user by default when migration user creates a table in future or else the grant command has to be executed everytime a new object is created by migration_user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ALTER DEFAULT PRIVILEGES FOR USER migration_user IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO application_user&lt;/p&gt;

&lt;h3&gt;
  
  
  Sequence accesses
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Grants usage access to app user by default when migration user creates a sequence in future&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ALTER DEFAULT PRIVILEGES FOR USER migration_user IN SCHEMA public GRANT USAGE ON SEQUENCES TO application_user;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>sql</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
