<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % CustomDTD SYSTEM "../../../../../../docbook/custom.dtd">
%CustomDTD;
]>
<chapter id="dataroles">
    <title>Data Roles</title>
    <para>Data roles, also called entitlements, are sets of permissions defined 
    per VDB that dictate data access (create, read,  update, delete). Data roles use a fine-grained permission system that Teiid will enforce
     at runtime and provide audit log entries for access violations (see that Admin and Developers Guide for more on Audit Logging).</para>
    
    <para>Prior to applying data roles, you should consider restricting source system access through the fundamental design of your VDB.  
    Foremost, Teiid can only access source entries that are represented in imported metadata.  You should narrow imported metadata to only what
     is necessary for use by your VDB.  When using Teiid Designer, you may then go further and modify the imported metadata at a granular
      level to remove specific columns, mark tables as non-updatable, etc.</para>
    
    <para>If data roles is enabled and data roles are defined in a VDB, then access permissions will be enforced by the Teiid Server.  
    The use of data roles may be disabled system wide via the
    &jboss-beans; file, by setting the property <code>useDataRoles</code> to false in the configuration section of the <code>RuntimeEngineDeployer</code>.</para>
    
    <warning><para>Unlike previous versions of Teiid data roles will only be checked if present in a VDB.  
    A VDB deployed without data roles is open for use by any authenticated user.</para></warning>

    <section>
    	<title>Permissions</title>

		<para>CREATE, READ, UPDATE, DELETE (CRUD) permissions can be set for any resource path in a VDB.  
		A resource path can be as specific as the fully qualified name of a column or as general a top level model (schema) name.
		Permissions granted to a particular path apply to it and any resource paths that share the same partial name.  
		For example, granting read to "model" will also grant read to "model.table", "model.table.column", etc.
		Allowing or denying a particular action is determined by searching for permissions from the most to least specific resource paths.
		The first permission found with a specific allow or deny will be used.  
		Thus it is possible to set very general permissions at high-level resource path names and to override only as necessary at more specific resource paths. 
		</para>

		<para>Permission grants are only needed for resources that a role needs access to.
			Permissions are also only applied to the columns/tables/procedures in the user query - not to every resource
			accessed transitively through view and procedure definitions.
			It is important therefore to ensure that permission grants are applied
			consistently across models that access the same resources.
		</para>
		
		<warning><para>Unlike previous versions of Teiid, non-visible models are accessible by user queries.  
		To restrict user access at a model level, at least one data role should be created to enable data role checking.  
		In turn that role can be mapped to any authenticated user and should not grant permissions to models that should be inaccessable.</para></warning>
		
		<para>Permissions are not applicable to the SYS and pg_catalog schemas.  These metadata reporting schemas are always accessible regardless of the user.
		The SYSADMIN schema however may need permissions as applicable.</para>
		    	
   	    <orderedlist>
	        <para>To process a <emphasis>SELECT</emphasis> statement or a stored procedure execution, the user account requires the following access rights:</para>
	        <listitem> <para><emphasis>READ</emphasis> - on the Table(s) being accessed or the procedure being called.</para></listitem>
	        <listitem> <para><emphasis>READ</emphasis> - on every column referenced.</para></listitem>
	    </orderedlist>   
	    
	    <orderedlist>
	        <para>To process an <emphasis>INSERT</emphasis> statement, the user account requires the following access rights:</para>
	        <listitem> <para><emphasis>CREATE</emphasis> - on the Table being inserted into.</para></listitem>
	        <listitem> <para><emphasis>CREATE</emphasis> - on every column being inserted on that Table.</para></listitem>
	    </orderedlist>   
	    
	    <orderedlist>
	        <para>To process an <emphasis>UPDATE</emphasis> statement, the user account requires the following access rights:</para>
	        <listitem> <para><emphasis>UPDATE</emphasis> - on the Table being updated.</para></listitem>
	        <listitem> <para><emphasis>UPDATE</emphasis> - on every column being updated on that Table.</para></listitem>
	        <listitem> <para><emphasis>READ</emphasis> - on every column referenced in the criteria.</para></listitem>
	    </orderedlist>    
	    
	    <orderedlist>
	    	<para>To process a <emphasis>DELETE</emphasis> statement, the user account requires the following access rights:</para>
	        <listitem> <para><emphasis>DELETE</emphasis> - on the Table being deleted.</para></listitem>
	        <listitem> <para><emphasis>READ</emphasis> - on every column referenced in the criteria.</para></listitem>
	    </orderedlist> 
	    
	    <orderedlist>
	    	<para>To process a <emphasis>EXEC/CALL</emphasis> statement, the user account requires the following access rights:</para>
	        <listitem> <para><emphasis>EXECUTE (or READ)</emphasis> - on the Procedure being executed.</para></listitem>
	    </orderedlist>
	    
	    <orderedlist>
	    	<para>To process any function, the user account requires the following access rights:</para>
	        <listitem> <para><emphasis>EXECUTE (or READ)</emphasis> - on the Function being called.</para> <note><para>For backwards compatibility RuntimeEngineDeployer.allowFunctionCallsByDefault located in the &jboss-beans; file in the <code>RuntimeEngineDeployer</code> section defaults to true. 
	        This means that to actually require permissions for functions, you need to set this property to false.</para></note></listitem>
	    </orderedlist>
	    
	    <orderedlist>
	    	<para>To process any ALTER or CREATE TRIGGER statement, the user account requires the following access rights:</para>
	        <listitem> <para><emphasis>ALTER</emphasis> - on the view or procedure that is effected.  INSTEAD OF Triggers (update procedures) are not yet treated as full schema objects and are instead treated as attributes of the view.</para></listitem>
	    </orderedlist>
	       
    </section>
    
    <section>
    	<title>Role Mapping</title>
    	<para>Each Teiid data role can be mapped to any number of container roles or any authenticated user.  
    	You may control role membership through whatever system the Teiid security domain login modules are associated with. 
    	The kit includes example files for use with the UsersRolesLoginModule - see teiid-security-roles.properties.</para>
    	<para>It is possible for a user to have any number of container roles, which in turn imply a subset of Teiid data roles.  
    	Each applicable Teiid data role contributes cumulatively to the permissions of the user. 
    	No one role supercedes or negates the permissions of the other data roles.</para>
    </section>

	<section>
		<title>XML Definition</title>
	    <para>Data roles are defined inside the <code>vdb.xml</code> file (inside the .vdb Zip archive under META-INF/vdb.xml) if you used Designer.  
	    The "vdb.xml" file is checked against the schema file <code>vdb-deployer.xsd</code>, which can be found in the kit under teiid-docs/schema.
	    This example will show a sample "vdb.xml" file with few simple data roles.</para>
    
    <para>For example, if a VDB defines a table "TableA" in schema "modelName" with columns (column1, column2) - note that the column types do not matter.  And we wish to define three roles "RoleA", "RoleB", "RoleC" with following permissions:
   <orderedlist>
    <listitem><para>RoleA has permissions to read, write access to TableA, but can not delete.</para></listitem>
    <listitem><para>RoleB has no permissions that allow access to TableA</para></listitem>
    <listitem><para>RoleC has permissions that only allow read access to TableA.column1</para></listitem>
   </orderedlist>
	</para>
    <example><title>vdb.xml defining RoleA, RoleB, and RoleC</title>
   <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<vdb name="sample" version="1">

    <model name="modelName">
        <source name="source-name" translator-name="oracle" connection-jndi-name="java:myDS" />
    </model>

    <data-role name="RoleA">
        <description>Allow all, except Delete</description>

        <permission>
            <resource-name>modelName.TableA</resource-name>
            <allow-create>true</allow-create>
            <allow-read>true</allow-read>
            <allow-update>true</allow-update>
        </permission>

        <mapped-role-name>role1</mapped-role-name>

    </data-role>

    <data-role name="RoleC">
        <description>Allow read only</description>

        <permission>
            <resource-name>modelName.TableA</resource-name>
            <allow-read>true</allow-read>
        </permission>

        <permission>
            <resource-name>modelName.TableA.colum2</resource-name>
            <allow-read>false</allow-read>
        </permission>

        <mapped-role-name>role2</mapped-role-name>
    </data-role>
</vdb>]]></programlisting>    
</example>   
   <para>The above XML defined two data roles, "RoleA" which allows everything except delete on the table, "RoleC" that 
   allows only read operation on the table. Since Teiid uses deny by default, there is no explicit data-role entry needed for "RoleB".  Note that explicit column permissions are 
   not needed for RoleA, since the parent resource path, modelName.TableA, permissions still apply.  RoleC however must explicitly disallow read to column2.</para>  
   
   <para>The "mapped-role-name" defines the container JAAS roles that are assigned the data role.  For assigning roles to your users in the JBoss AS, 
   check out the instructions for the selected Login Module. Check the "Admin Guide" for configuring Login Modules.  You may also choose to allow any
   authenticated user to have a data role by setting the any-authenticated attribute value to true on data-role element.</para>
   
   <para>The "allow-create-temporary-tables" data-role boolean attribute is used to explicitly enable or disable temporary table usage for the role.  If it is left unspecified, then the value will be determined by the configuration setting allowCreateTemporaryTablesByDefault located in the &jboss-beans; file in the <code>RuntimeEngineDeployer</code> section.</para> 
   
	</section>
	<section>
		<title>System Functions</title>
		<para>The <code>hasRole</code> system function will return true if the current user has the given data role.  
		The <code>hasRole</code> function can be used in procedure or view definitions to allow for a more dynamic application of security - which allows for things such as value masking or row level security.</para>
	</section>
	<section>
		<title>Customizing</title>
		<para>See the Developer's Guide Custom Security Chapter for details on using an alternative authorization scheme.</para>
	</section>
</chapter>