Home Explore Blog CI



postgresql

34th chunk of `doc/src/sgml/ddl.sgml`
0b12dfdd8cbb5626aaeb8aa9decf9e43ab05b52566f097930000000100000fa3
 <para>
   If no role is specified, or the special user name
   <literal>PUBLIC</literal> is used, then the policy applies to all
   users on the system.  To allow all users to access only their own row in
   a <literal>users</literal> table, a simple policy can be used:
  </para>

<programlisting>
CREATE POLICY user_policy ON users
    USING (user_name = current_user);
</programlisting>

  <para>
   This works similarly to the previous example.
  </para>

  <para>
   To use a different policy for rows that are being added to the table
   compared to those rows that are visible, multiple policies can be
   combined.  This pair of policies would allow all users to view all rows
   in the <literal>users</literal> table, but only modify their own:
  </para>

<programlisting>
CREATE POLICY user_sel_policy ON users
    FOR SELECT
    USING (true);
CREATE POLICY user_mod_policy ON users
    USING (user_name = current_user);
</programlisting>

  <para>
   In a <command>SELECT</command> command, these two policies are combined
   using <literal>OR</literal>, with the net effect being that all rows
   can be selected.  In other command types, only the second policy applies,
   so that the effects are the same as before.
  </para>

  <para>
   Row security can also be disabled with the <command>ALTER TABLE</command>
   command.  Disabling row security does not remove any policies that are
   defined on the table; they are simply ignored.  Then all rows in the
   table are visible and modifiable, subject to the standard SQL privileges
   system.
  </para>

  <para>
   Below is a larger example of how this feature can be used in production
   environments.  The table <literal>passwd</literal> emulates a Unix password
   file:
  </para>

<programlisting>
-- Simple passwd-file based example
CREATE TABLE passwd (
  user_name             text UNIQUE NOT NULL,
  pwhash                text,
  uid                   int  PRIMARY KEY,
  gid                   int  NOT NULL,
  real_name             text NOT NULL,
  home_phone            text,
  extra_info            text,
  home_dir              text NOT NULL,
  shell                 text NOT NULL
);

CREATE ROLE admin;  -- Administrator
CREATE ROLE bob;    -- Normal user
CREATE ROLE alice;  -- Normal user

-- Populate the table
INSERT INTO passwd VALUES
  ('admin','xxx',0,0,'Admin','111-222-3333',null,'/root','/bin/dash');
INSERT INTO passwd VALUES
  ('bob','xxx',1,1,'Bob','123-456-7890',null,'/home/bob','/bin/zsh');
INSERT INTO passwd VALUES
  ('alice','xxx',2,1,'Alice','098-765-4321',null,'/home/alice','/bin/zsh');

-- Be sure to enable row-level security on the table
ALTER TABLE passwd ENABLE ROW LEVEL SECURITY;

-- Create policies
-- Administrator can see all rows and add any rows
CREATE POLICY admin_all ON passwd TO admin USING (true) WITH CHECK (true);
-- Normal users can view all rows
CREATE POLICY all_view ON passwd FOR SELECT USING (true);
-- Normal users can update their own records, but
-- limit which shells a normal user is allowed to set
CREATE POLICY user_mod ON passwd FOR UPDATE
  USING (current_user = user_name)
  WITH CHECK (
    current_user = user_name AND
    shell IN ('/bin/bash','/bin/sh','/bin/dash','/bin/zsh','/bin/tcsh')
  );

-- Allow admin all normal rights
GRANT SELECT, INSERT, UPDATE, DELETE ON passwd TO admin;
-- Users only get select access on public columns
GRANT SELECT
  (user_name, uid, gid, real_name, home_phone, extra_info, home_dir, shell)
  ON passwd TO public;
-- Allow users to update certain columns
GRANT UPDATE
  (pwhash, real_name, home_phone, extra_info, shell)
  ON passwd TO public;
</programlisting>

  <para>
   As with any security settings, it's important to test and ensure that
   the system is behaving as expected.  Using the example above, this
   demonstrates that the permission system is working properly.
  </para>

<programlisting>
-- admin can view all rows and fields
postgres=&gt; set role admin;
SET
postgres=&gt; table passwd;
 user_name | pwhash

Title: Row Security Policy Examples and Disabling Row Security
Summary
This section presents practical examples of row security policies, including allowing all users to access their own rows in a 'users' table and combining policies for different access control scenarios. It also demonstrates how to disable row security using the ALTER TABLE command and provides a comprehensive example using a 'passwd' table, emulating a Unix password file, with policies for administrators and normal users. The example covers viewing, updating, and restricting shell settings for normal users, including how to test and verify the security settings.