Introducing PostgreSQL Anonymizer

The extension can be used to put dynamic masks on certain users or permanently modify sensitive data. Various masking techniques are available : randomization, partial scrambling, custom rules, etc.

Here’s a basic example :

Imagine a people table

<span class="o">=#</span> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">people</span><span class="p">;</span>
  <span class="n">id</span>  <span class="o">|</span>      <span class="n">name</span>      <span class="o">|</span>   <span class="n">phone</span>
<span class="c1">------+----------------+------------</span>
 <span class="n">T800</span> <span class="o">|</span> <span class="n">Schwarzenegger</span> <span class="o">|</span> <span class="mi">0609110911</span>

Step 1. Activate the masking engine

<span class="o">=#</span> <span class="k">CREATE</span> <span class="n">EXTENSION</span> <span class="n">IF</span> <span class="k">NOT</span> <span class="k">EXISTS</span> <span class="n">anon</span> <span class="k">CASCADE</span><span class="p">;</span>
<span class="o">=#</span> <span class="k">SELECT</span> <span class="n">anon</span><span class="p">.</span><span class="n">mask_init</span><span class="p">();</span>

Step 2. Declare a masked user

<span class="o">=#</span> <span class="k">CREATE</span> <span class="k">ROLE</span> <span class="n">skynet</span><span class="p">;</span>
<span class="o">=#</span> <span class="k">COMMENT</span> <span class="k">ON</span> <span class="k">ROLE</span> <span class="n">skynet</span> <span class="k">IS</span> <span class="s1">'MASKED'</span><span class="p">;</span>

Step 3. Declare the masking rules

<span class="o">=#</span> <span class="k">COMMENT</span> <span class="k">ON</span> <span class="k">COLUMN</span> <span class="n">people</span><span class="p">.</span><span class="n">name</span> <span class="k">IS</span> <span class="s1">'MASKED WITH FUNCTION anon.random_last_name()'</span><span class="p">;</span>

<span class="o">=#</span> <span class="k">COMMENT</span> <span class="k">ON</span> <span class="k">COLUMN</span> <span class="n">people</span><span class="p">.</span><span class="n">phone</span> <span class="k">IS</span> <span class="s1">'MASKED WITH FUNCTION anon.partial(phone,2,$$******$$,2)'</span><span class="p">;</span>

Step 4. Connect with the masked user

<span class="o">=#</span> <span class="err">\</span><span class="o">!</span> <span class="n">psql</span> <span class="n">test</span> <span class="o">-</span><span class="n">U</span> <span class="n">skynet</span> <span class="o">-</span><span class="k">c</span> <span class="s1">'SELECT * FROM people;'</span>
  <span class="n">id</span>  <span class="o">|</span>   <span class="n">name</span>   <span class="o">|</span>   <span class="n">phone</span>
<span class="c1">------+----------+------------</span>
 <span class="n">T800</span> <span class="o">|</span> <span class="n">Nunziata</span> <span class="o">|</span> <span class="mi">06</span><span class="o">******</span><span class="mi">11</span>

Of course this project is a work in progress. I need your feedback and ideas ! Let me know what you think of this tool, how it fits your needs and what features are missing.