Oracle‘s VPD provides access control at the row level.
It works by appending clauses (predicates) to sql statement executed by the user. To make this happen a Pl/Sql function (policy function) is attached to a table which, when executed, returns a string that will be appended to the sql before it is parsed and executed.
A more realistic application of the previous example would require changing the country depending on the user.
This requires always knowing the users id from within the database regardless of which db account is in use. This information is not available where the user makes access through connection pools within the middle tier based on the front end user account.
To overcome this Oracle provides the Client Identifier.
The client identifier is a 64 character string that can be defined to uniquely identify the user currently using the connection. Before a connection can be obtained from the connection pool the client identifier must be set correctly.
It is unique to a session and stays in the memory attached to that session as long as the session is active.
The current value of the Client Identifier can be viewed using
Set the Client Identifier and check it for yourself:
Although the Client Identifier provides a means of identifing the user, it does not solve the issue of applying user specific criteria to SELECT statements.
To get over this limitation we use the Application Context
Application contexts are akin to session variables. Once set, they can be accessed in a session any time. A different value can be set in another session and the values will not be visible across the sessions (as long as the db user is different). However, if the same db user (front end login) is used the changes will be visible across sessions.
A context has attributes, similar to the columns of a table.
The attributes of contexts can be defined at runtime.
To insert a value into the context you use the following command.
Initialise the application context ( the context must contain the information required to fulfill the policy function requests )
Policy Function Execution
Execute Select -
Oracle parses sql and scan the sql for tables that have policies attached
For each table with a policy the policy function will be called. This function returns a predicate that Oracle cleverly appends to the sql. The context is necessary to resolve these predicates.
Results sent to user
The VPD framework is triggered at two specific points in the lifetime of a session. Firstly upon login and secondly when a select statement is submitted. This corresponds to the creation of the user Application Context at login time and the addition of the predicates when a select is executed.
To meet our performance needs we have chosen to user static predicates. That is, they will be fired once and meet the restriction requirements for all users.
AND tbl_vpd_empl_xref.empl_id <> tbl_vpd_empl_xref.empl_id) OR
(SYS_CONTEXT(‘VPD_CONTEXT’, ‘LOCATION_FLAG’) = ‘I’ AND LOCN_CTRY IN (select generic_id from tbl_dimension_values where user_profile_DIMENSION_ID = SYS_CONTEXT(‘VPD_CONTEXT’,‘LOCATION’)) OR (SYS_CONTEXT(‘VPD_CONTEXT’, ‘LOCATION_FLAG’) = ‘E’ AND LOCN_CTRY NOT IN (select generic_id from tbl_dimension_values where user_profile_DIMENSION_ID = SYS_CONTEXT(‘VPD_CONTEXT’,‘LOCATION’)))
The preceding example can help you get started, but there is much more to RLS than this. The security policies can be much more complex, and the policy functions typically return dramatically different strings based on user authorizations.
object_schema IN VARCHAR2 NULL,
object_name IN VARCHAR2,
policy_name IN VARCHAR2,
function_schema IN VARCHAR2 NULL,
policy_function IN VARCHAR2,
statement_types IN VARCHAR2 NULL,
update_check IN BOOLEAN FALSE,
enable IN BOOLEAN TRUE,
static_policy IN BOOLEAN FALSE,
policy_type IN BINARY_INTEGER NULL,
long_predicate IN BOOLEAN FALSE,
sec_relevant_cols IN VARCHAR2,
sec_relevant_cols_opt IN BINARY_INTEGER NULL
New In 10g:
policy type, long_predicate,
sec_relevant_cols, and sec_relevant_cols_opt
Other DBMS_RLS Procedures (Not Covered in this presentation)
The PL/SQL functions are registered to tables, views, or synonyms by invoking the DBMS_RLS.ADD_POLICY procedure. The DBMS_RLS package is not granted to everyone; administrators will require direct execute privileges on the package. The ADD_POLICY procedure requires, at minimum, the name of the object to which the policy will be applied, a name for the policy, and the name of a PL/SQL function that will implement the security policy.
Creating A Policy Function – e.g. CREATE OR REPLACE FUNCTION dept_only (
DELETE FROM people; will be effectively transformed into
DELETE FROM people where username = sys_context(''userenv'',''session_user'')
Viewing the Original SQL and Predicate – The View you may find helpful in inspecting your VPD implementations is the V$VPD_POLICY view. This will tell you what policies have been successfully applied to your SQL statements. The PREDICATE column will actually show the SQL string that was appended to the query. You can join this record with V$SQL, which has the original SQL.
1. While the RLS provides wonderful security, it can be problematic when doing database administration tasks such as performing data backups. As you have seen, even the DBAs and the data owner cannot bypass the RLS policy. If you perform an export as the data owner or another administrator while an RLS policy was enabled, you may very well end up with a dataless backup file. For this reason (and a few others), there is an EXEMPT ACCESS POLICY privilege
SQL>DELETE FROM scott.people_ro;
SQL> 0 rows deleted.
SQL> GRANT EXEMPT ACCESS POLICY TO SYSTEM;
SQL>DELETE FROM scott.people_ro;
SQL>14 rows deleted.
2. The system privilege EXEMPT ACCESS POLICY allows a user to be exempted from all fine-grained access control policies on any DML operation such as SELECT, INSERT, UPDATE, and DELETE. If a user is granted the EXEMPT ACCESS POLICY privilege, then the user is exempt from fine-grained access control enforcement. then the user is exempt from fine-grained access control enforcement.
Virtual Private Database (VPD) helps resolve some of the challenges associated with views. An RLS policy is defined as a mapping from a PL/SQL implemented security function to a table, view, or synonym.
To ensure high performance, the RLS mechanism has been written to modify the SQL before it is parsed and executed. This allows the database to use indexes and optimization plans to ensure fast access to data. Using bind variables and application contexts and enabling policy caching can significantly improve RLS performance.
Project : Please check out a dummy project at : http://www.psoug.org/reference/fgac_demo.html