doc-exports/docs/dws/dev/dws_04_0061.html
Lu, Huayi ef0ada5a59 DWS DEV 20240716 version
Reviewed-by: Pruthi, Vineet <vineet.pruthi@t-systems.com>
Co-authored-by: Lu, Huayi <luhuayi@huawei.com>
Co-committed-by: Lu, Huayi <luhuayi@huawei.com>
2024-11-02 09:07:47 +00:00

162 lines
21 KiB
HTML

<a name="EN-US_TOPIC_0000001510402509"></a><a name="EN-US_TOPIC_0000001510402509"></a>
<h1 class="topictitle1">GaussDB(DWS) Row-Level Access Control</h1>
<div id="body1560407392207"><p id="EN-US_TOPIC_0000001510402509__p1873119554919">The row-level access control feature enables database access control to be accurate to each row of data tables. In this way, the same SQL query may return different results for different users.</p>
<p id="EN-US_TOPIC_0000001510402509__p7731353497">You can create a row-level access control policy for a data table. The policy defines an expression that takes effect only for specific database users and SQL operations. When a database user accesses the data table, if a SQL statement meets the specified row-level access control policies of the data table, the expressions that meet the specified condition will be combined by using <strong id="EN-US_TOPIC_0000001510402509__b1515912910316">AND</strong> or <strong id="EN-US_TOPIC_0000001510402509__b18655812935">OR</strong> based on the attribute type (<strong id="EN-US_TOPIC_0000001510402509__b0452172816312">PERMISSIVE</strong> | <strong id="EN-US_TOPIC_0000001510402509__b1581013314319">RESTRICTIVE</strong>) and applied to the execution plan in the query optimization phase.</p>
<p id="EN-US_TOPIC_0000001510402509__p17317514916">Row-level access control is used to control the visibility of row-level data in tables. By predefining filters for data tables, the expressions that meet the specified condition can be applied to execution plans in the query optimization phase, which will affect the final execution result. Currently, the SQL statements that can be affected include <strong id="EN-US_TOPIC_0000001510402509__b191811411553">SELECT</strong>, <strong id="EN-US_TOPIC_0000001510402509__b859234313517">UPDATE</strong>, and <strong id="EN-US_TOPIC_0000001510402509__b159005441157">DELETE</strong>.</p>
<p id="EN-US_TOPIC_0000001510402509__p1796912257556">Scenario 1: A table summarizes the data of different users. Users can view only their own data.</p>
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001510402509__screen62701712114315"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span>
<span class="normal">16</span>
<span class="normal">17</span>
<span class="normal">18</span>
<span class="normal">19</span>
<span class="normal">20</span>
<span class="normal">21</span>
<span class="normal">22</span>
<span class="normal">23</span>
<span class="normal">24</span>
<span class="normal">25</span>
<span class="normal">26</span>
<span class="normal">27</span>
<span class="normal">28</span>
<span class="normal">29</span>
<span class="normal">30</span>
<span class="normal">31</span>
<span class="normal">32</span>
<span class="normal">33</span>
<span class="normal">34</span>
<span class="normal">35</span>
<span class="normal">36</span>
<span class="normal">37</span>
<span class="normal">38</span>
<span class="normal">39</span>
<span class="normal">40</span>
<span class="normal">41</span>
<span class="normal">42</span>
<span class="normal">43</span>
<span class="normal">44</span>
<span class="normal">45</span>
<span class="normal">46</span>
<span class="normal">47</span>
<span class="normal">48</span>
<span class="normal">49</span>
<span class="normal">50</span>
<span class="normal">51</span>
<span class="normal">52</span>
<span class="normal">53</span>
<span class="normal">54</span>
<span class="normal">55</span>
<span class="normal">56</span>
<span class="normal">57</span>
<span class="normal">58</span>
<span class="normal">59</span>
<span class="normal">60</span>
<span class="normal">61</span>
<span class="normal">62</span>
<span class="normal">63</span>
<span class="normal">64</span>
<span class="normal">65</span>
<span class="normal">66</span>
<span class="normal">67</span>
<span class="normal">68</span>
<span class="normal">69</span>
<span class="normal">70</span>
<span class="normal">71</span>
<span class="normal">72</span>
<span class="normal">73</span></pre></div></td><td class="code"><div><pre><span></span><span class="c1">-- Create users alice, bob, and peter.</span>
<span class="k">CREATE</span><span class="w"> </span><span class="k">ROLE</span><span class="w"> </span><span class="n">alice</span><span class="w"> </span><span class="n">PASSWORD</span><span class="w"> </span><span class="s1">'password'</span><span class="p">;</span>
<span class="k">CREATE</span><span class="w"> </span><span class="k">ROLE</span><span class="w"> </span><span class="n">bob</span><span class="w"> </span><span class="n">PASSWORD</span><span class="w"> </span><span class="s1">'password'</span><span class="p">;</span>
<span class="k">CREATE</span><span class="w"> </span><span class="k">ROLE</span><span class="w"> </span><span class="n">peter</span><span class="w"> </span><span class="n">PASSWORD</span><span class="w"> </span><span class="s1">'password'</span><span class="p">;</span>
<span class="c1">-- Create the public.all_data table that contains user information.</span>
<span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">public</span><span class="p">.</span><span class="n">all_data</span><span class="p">(</span><span class="n">id</span><span class="w"> </span><span class="nb">int</span><span class="p">,</span><span class="w"> </span><span class="k">role</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">100</span><span class="p">),</span><span class="w"> </span><span class="k">data</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">100</span><span class="p">));</span>
<span class="c1">-- Insert data into the data table.</span>
<span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">all_data</span><span class="w"> </span><span class="k">VALUES</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s1">'alice'</span><span class="p">,</span><span class="w"> </span><span class="s1">'alice data'</span><span class="p">);</span>
<span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">all_data</span><span class="w"> </span><span class="k">VALUES</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="s1">'bob'</span><span class="p">,</span><span class="w"> </span><span class="s1">'bob data'</span><span class="p">);</span>
<span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">all_data</span><span class="w"> </span><span class="k">VALUES</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="s1">'peter'</span><span class="p">,</span><span class="w"> </span><span class="s1">'peter data'</span><span class="p">);</span>
<span class="c1">-- Grant the read permission for the all_data table to users alice, bob, and peter.</span>
<span class="k">GRANT</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="n">all_data</span><span class="w"> </span><span class="k">TO</span><span class="w"> </span><span class="n">alice</span><span class="p">,</span><span class="w"> </span><span class="n">bob</span><span class="p">,</span><span class="w"> </span><span class="n">peter</span><span class="p">;</span>
<span class="c1">-- Enable row-level access control.</span>
<span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">all_data</span><span class="w"> </span><span class="n">ENABLE</span><span class="w"> </span><span class="k">ROW</span><span class="w"> </span><span class="k">LEVEL</span><span class="w"> </span><span class="k">SECURITY</span><span class="p">;</span>
<span class="c1">-- Create a row-level access control policy to specify that the current user can view only their own data.</span>
<span class="k">CREATE</span><span class="w"> </span><span class="k">ROW</span><span class="w"> </span><span class="k">LEVEL</span><span class="w"> </span><span class="k">SECURITY</span><span class="w"> </span><span class="n">POLICY</span><span class="w"> </span><span class="n">all_data_rls</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="n">all_data</span><span class="w"> </span><span class="k">USING</span><span class="p">(</span><span class="k">role</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">CURRENT_USER</span><span class="p">);</span>
<span class="c1">-- View table details.</span>
<span class="w"> </span><span class="err">\</span><span class="n">d</span><span class="o">+</span><span class="w"> </span><span class="n">all_data</span>
<span class="w"> </span><span class="k">Table</span><span class="w"> </span><span class="ss">&quot;public.all_data&quot;</span>
<span class="w"> </span><span class="k">Column</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">Type</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Modifiers</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">Storage</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Stats</span><span class="w"> </span><span class="n">target</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Description</span>
<span class="c1">--------+------------------------+-----------+----------+--------------+-------------</span>
<span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nb">integer</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">plain</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span>
<span class="w"> </span><span class="k">role</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nb">character</span><span class="w"> </span><span class="nb">varying</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">extended</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span>
<span class="w"> </span><span class="k">data</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nb">character</span><span class="w"> </span><span class="nb">varying</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">extended</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span>
<span class="k">Row</span><span class="w"> </span><span class="k">Level</span><span class="w"> </span><span class="k">Security</span><span class="w"> </span><span class="n">Policies</span><span class="p">:</span>
<span class="w"> </span><span class="n">POLICY</span><span class="w"> </span><span class="ss">&quot;all_data_rls&quot;</span>
<span class="w"> </span><span class="k">USING</span><span class="w"> </span><span class="p">(((</span><span class="k">role</span><span class="p">)::</span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ss">&quot;current_user&quot;</span><span class="p">()))</span>
<span class="n">Has</span><span class="w"> </span><span class="k">OIDs</span><span class="p">:</span><span class="w"> </span><span class="k">no</span>
<span class="n">Distribute</span><span class="w"> </span><span class="k">By</span><span class="p">:</span><span class="w"> </span><span class="n">HASH</span><span class="p">(</span><span class="n">id</span><span class="p">)</span>
<span class="k">Location</span><span class="w"> </span><span class="n">Nodes</span><span class="p">:</span><span class="w"> </span><span class="k">ALL</span><span class="w"> </span><span class="n">DATANODES</span>
<span class="k">Options</span><span class="p">:</span><span class="w"> </span><span class="n">orientation</span><span class="o">=</span><span class="k">row</span><span class="p">,</span><span class="w"> </span><span class="n">compression</span><span class="o">=</span><span class="k">no</span><span class="p">,</span><span class="w"> </span><span class="n">enable_rowsecurity</span><span class="o">=</span><span class="k">true</span>
<span class="c1">-- Switch to user alice and run SELECT * FROM all_data.</span>
<span class="k">SET</span><span class="w"> </span><span class="k">ROLE</span><span class="w"> </span><span class="n">alice</span><span class="w"> </span><span class="n">PASSWORD</span><span class="w"> </span><span class="s1">'password'</span><span class="p">;</span>
<span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">all_data</span><span class="p">;</span>
<span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">role</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">data</span>
<span class="c1">----+-------+------------</span>
<span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">alice</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">alice</span><span class="w"> </span><span class="k">data</span>
<span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="k">row</span><span class="p">)</span>
<span class="k">EXPLAIN</span><span class="p">(</span><span class="n">COSTS</span><span class="w"> </span><span class="k">OFF</span><span class="p">)</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">all_data</span><span class="p">;</span>
<span class="w"> </span><span class="n">QUERY</span><span class="w"> </span><span class="n">PLAN</span>
<span class="c1">----------------------------------------------------------------</span>
<span class="w"> </span><span class="n">Streaming</span><span class="w"> </span><span class="p">(</span><span class="k">type</span><span class="p">:</span><span class="w"> </span><span class="n">GATHER</span><span class="p">)</span>
<span class="w"> </span><span class="n">Node</span><span class="o">/</span><span class="n">s</span><span class="p">:</span><span class="w"> </span><span class="k">All</span><span class="w"> </span><span class="n">datanodes</span>
<span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">Seq</span><span class="w"> </span><span class="n">Scan</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="n">all_data</span>
<span class="w"> </span><span class="n">Filter</span><span class="p">:</span><span class="w"> </span><span class="p">((</span><span class="k">role</span><span class="p">)::</span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'alice'</span><span class="p">::</span><span class="n">name</span><span class="p">)</span>
<span class="w"> </span><span class="n">Notice</span><span class="p">:</span><span class="w"> </span><span class="n">This</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">influenced</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="k">row</span><span class="w"> </span><span class="k">level</span><span class="w"> </span><span class="k">security</span><span class="w"> </span><span class="n">feature</span>
<span class="p">(</span><span class="mi">5</span><span class="w"> </span><span class="k">rows</span><span class="p">)</span>
<span class="c1">-- Switch to user peter and run SELECT * FROM .all_data.</span>
<span class="k">SET</span><span class="w"> </span><span class="k">ROLE</span><span class="w"> </span><span class="n">peter</span><span class="w"> </span><span class="n">PASSWORD</span><span class="w"> </span><span class="s1">'password'</span><span class="p">;</span>
<span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">all_data</span><span class="p">;</span>
<span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">role</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">data</span>
<span class="c1">----+-------+------------</span>
<span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">peter</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">peter</span><span class="w"> </span><span class="k">data</span>
<span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="k">row</span><span class="p">)</span>
<span class="w"> </span><span class="k">EXPLAIN</span><span class="p">(</span><span class="n">COSTS</span><span class="w"> </span><span class="k">OFF</span><span class="p">)</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">all_data</span><span class="p">;</span>
<span class="w"> </span><span class="n">QUERY</span><span class="w"> </span><span class="n">PLAN</span>
<span class="c1">----------------------------------------------------------------</span>
<span class="w"> </span><span class="n">Streaming</span><span class="w"> </span><span class="p">(</span><span class="k">type</span><span class="p">:</span><span class="w"> </span><span class="n">GATHER</span><span class="p">)</span>
<span class="w"> </span><span class="n">Node</span><span class="o">/</span><span class="n">s</span><span class="p">:</span><span class="w"> </span><span class="k">All</span><span class="w"> </span><span class="n">datanodes</span>
<span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">Seq</span><span class="w"> </span><span class="n">Scan</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="n">all_data</span>
<span class="w"> </span><span class="n">Filter</span><span class="p">:</span><span class="w"> </span><span class="p">((</span><span class="k">role</span><span class="p">)::</span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'peter'</span><span class="p">::</span><span class="n">name</span><span class="p">)</span>
<span class="w"> </span><span class="n">Notice</span><span class="p">:</span><span class="w"> </span><span class="n">This</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">influenced</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="k">row</span><span class="w"> </span><span class="k">level</span><span class="w"> </span><span class="k">security</span><span class="w"> </span><span class="n">feature</span>
<span class="p">(</span><span class="mi">5</span><span class="w"> </span><span class="k">rows</span><span class="p">)</span>
</pre></div></td></tr></table></div>
</div>
</div>
<div>
<div class="familylinks">
<div class="parentlink"><strong>Parent topic:</strong> <a href="dws_04_0994.html">GaussDB(DWS) Sensitive Data Management</a></div>
</div>
</div>