Fine-Grained Data Authorization

Learn how Oracle Deep Data Security (Deep Sec) enforces row and column security, validates privileges through access check functions, and applies mandatory access control for comprehensive data protection.

Topics:

Architectural Overview

To provide context for Deep Sec’s fine-grained authorization model, let’s review the authentication and authorization flow in a typical three-tier architecture and examine the components involved.

Authorization flow

The following figure illustrates the authentication and authorization flow in a typical three-tier application architecture with Deep Sec enabled:

A typical authentication and authorization flow of a three-tier application.

Key components

About Data Grants and Security Context

Deep Sec introduces data grants to precisely control access at the row, column, and cell levels. Learn about data grants and how to use the runtime security context to create dynamic, identity-based predicates within data grants.

Data grant

Central to the Deep Sec authorization model is the data grant, a policy statement that authorizes access to specific rows and columns within a table or view. Through multiple data grants, a user can hold different privileges on different row sets and column values (cells) within the same table or view; for example, SELECT privilege on some rows, UPDATE on certain columns for a subset of those rows, and full modification privileges on another set of rows. The grants are additive, meaning a user’s data access is determined based on the union of all data grants assigned to them.

You define data grants using the CREATE DATA GRANT statement. Each grant specifies the privileges (SELECT, UPDATE, INSERT, DELETE), the target object, an optional WHERE clause (predicate) to identify rows, and the grantee.

Simplified syntax:

CREATE [OR REPLACE] DATA GRANT [schema.]grant_name AS
    <SELECT | UPDATE | INSERT | DELETE> [(column [, column] ...)]
    ON <object>
    [WHERE <predicate>]
    TO {<end_user> | <data_role>};

Where:

See Configure Data Grants for complete details on the syntax and data privilege semantics for DML operations.

Security context reference

To define data grants, it is essential to understand how to reference the end-user security context in SQL. Data grants in Deep Sec typically rely on the end-user security context payload (the user’s identity, roles, and attributes) that the application propagates to the database at runtime.

You can access this context in the database using the ORA_END_USER_CONTEXT SQL function. It returns the context parameters as JSON accessible through standard dot-notation. For example, ORA_END_USER_CONTEXT.username returns the current end user’s name.

You’ll typically use this function in data grant predicates to identify rows based on the current user’s identity or attributes. For more details, see End-User Contexts and Attributes.

Row and Column Controls

Understand how data grants enforce fine-grained security at the row, column, and cell levels.

You can create data grants for data roles or directly for local end users. In an IAM-managed environment, data grants are created for data roles that are mapped to external application roles. End users are provisioned in an IAM system and assigned application roles. In the database, data roles are mapped to the external roles, and these data roles hold the data grants. In a locally managed environment, you can create data grants for data roles that are managed within the database or directly for local end users. This flexibility supports both centralized identity governance and simpler standalone configurations. For details on data roles and role mapping, see User and Role Management in the Database.

When an end user queries a table protected by data grants, the database performs the following actions:

Note:

Data grant examples throughout this section are based on the following hr.employees table.

EMPLOYEE_ID  FIRST_NAME  LAST_NAME  EMAIL       MANAGER     SSN          SALARY  PHONE
-----------  ----------  ---------  ----------  ----------  -----------  ------  --------
100          Victoria    Williams   vwilliams               219-09-9999  13000   555-0100
200          Marvin      Anderson   manderson   vwilliams   457-55-5462  12030   555-0200
300          Chris       Evans      cevans      vwilliams   321-12-4567   6900   555-0300
400          Emma        Baker      ebaker      manderson   733-02-9821   8200   555-0400
500          Taylor      Mills      tmills      manderson   558-76-1243   9000   555-0500

Row-level security

Row-level security is enforced through data grants that restrict operations (such as SELECT, UPDATE, INSERT, or DELETE) to a specific set of rows, defined by a SQL predicate (WHERE clause). The predicate can reference the end-user security context or include subqueries for more complex logic. The database evaluates the predicate for each row: if it evaluates to TRUE, the row is accessible; if FALSE, the row is filtered out.

Example: Basic row security

The data grant in this example permits employees to view only their own record.

The following SQL statement creates a data grant named employees_own_record in the hr schema. This grant allows users with the employee_role data role to access their own record in the hr.employees table. In an IAM-managed environment, any end user whose application role maps to employee_role can view only the row that corresponds to their own identity.

-- Grant 1: Allow employees to see their own record
CREATE OR REPLACE DATA GRANT hr.employees_own_record
  AS SELECT
  ON hr.employees
  WHERE email = ORA_END_USER_CONTEXT.username
  TO employee_role;

When Emma, who is an application user and an employee, queries the table, she sees only her own record.

EMMA> SELECT * FROM hr.employees;

EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL   MANAGER    SSN         SALARY PHONE
----------- ---------- --------- ------- ---------- ----------- ------ --------
400         Emma       Baker     ebaker  manderson  733-02-9821  8200  555-0400

1 row selected.

Column- and cell-level security

While row security determines which records are visible, column security determines which attributes within those records are exposed. By specifying row predicates with column restrictions, you achieve cell-level security: rules that govern which column values a user may SELECT, INSERT, or UPDATE for a specific set of rows.

This enables scenarios where a user has access to a row but is restricted from viewing sensitive columns (such as social security number) or modifying critical columns (such as salary).

Example: Cell-level write restrictions

You can define data grants to limit UPDATE privileges to specific columns. If a user attempts to update an unauthorized column in an authorized row, the operation is silently ignored.

The data grant in this example allows employees to view their own record and update only the phone number.

-- Grant 2: Allow employees to see their own record and update phone number
CREATE OR REPLACE DATA GRANT hr.employees_own_record
  AS SELECT, UPDATE (phone)
  ON hr.employees
  WHERE email = ORA_END_USER_CONTEXT.username
  TO employee_role;

Example: Hierarchical access with column masking

You can grant access to rows while excluding sensitive columns (for example, social security number). The rows are returned, but the unauthorized columns appear as NULL.

The data grant (manager_direct_reports) in this example allows managers to view the records of their direct reports, with the social security number (SSN) column excluded. It also allows managers to update only the salary column for their direct reports. The grant is defined for the data role named manager_role.

-- Grant 3: Allow managers to see their direct reports (with SSN masked) and update their salaries
CREATE OR REPLACE DATA GRANT hr.manager_direct_reports
  AS SELECT (ALL COLUMNS EXCEPT ssn), UPDATE (salary)
  ON hr.employees
  WHERE manager = ORA_END_USER_CONTEXT.username
  TO manager_role;

Marvin, who is both a manager and an employee, holds both the employee_role and manager_role data roles. As an employee, he sees his own record, including his SSN. As a manager, he also sees the records of his direct reports (Emma and Taylor) but with their SSN values masked as NULL. The manager role additionally grants him the ability to edit the salaries of his direct reports.

MARVIN> SELECT * FROM hr.employees;

EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL      MANAGER    SSN         SALARY PHONE
----------- ---------- --------- ---------- ---------- ----------- ------ --------
200         Marvin     Anderson  manderson  vwilliams  457-55-5462 12030  555-0200
400         Emma       Baker     ebaker     manderson              8200   555-0400
500         Taylor     Mills     tmills     manderson              9000   555-0500

3 rows selected.

For advanced examples of data grants that propagate across table hierarchies, see Configure Data Grants.

Access Check Functions

Deep Sec provides SQL functions to detect unauthorized values for conditional masking and to evaluate user privileges at the row and column level.

Verify column access (ORA_IS_COLUMN_AUTHORIZED)

This function differentiates between a genuine NULL stored in the database and a NULL returned due to authorization restrictions. This allows developers to handle restricted data gracefully in the presentation layer.

Example:

Marvin can use this function in the SELECT list to display:

MARVIN> SELECT first_name, last_name,
               DECODE(ORA_IS_COLUMN_AUTHORIZED(ssn),
                       FALSE, '000-00-0000',
                       TRUE, ssn) AS ssn,
               email,
               manager
        FROM   hr.employees;

FIRST_NAME LAST_NAME  SSN          EMAIL       MANAGER
---------- ---------- ------------ ----------- ----------
Marvin     Anderson   457-55-5462  manderson   vwilliams
Emma       Baker      000-00-0000  ebaker      manderson
Taylor     Mills      000-00-0000  tmills      manderson

3 rows selected.

Validate operational privileges (ORA_CHECK_DATA_PRIVILEGE)

This function allows applications to check a user’s privileges at the row or column level. This is essential for enforcing security in APIs and controlling dynamic UI elements (such as enabling or disabling an Edit button) based on the user’s access rights.

Example:

The following query verifies which operations Marvin (who is both an employee and a manager) can perform. It checks whether he has SELECT privileges on each row and UPDATE privileges specifically on the phone column.

MARVIN> SELECT first_name, last_name,
              manager,
              ORA_CHECK_DATA_PRIVILEGE(emp, 'SELECT') AS can_view,
              ORA_CHECK_DATA_PRIVILEGE(emp, 'UPDATE', phone) AS can_update_phone
       FROM   hr.employees emp;

FIRST_NAME LAST_NAME  MANAGER    CAN_VIEW  CAN_UPDATE_PHONE
---------- ---------- ---------- --------- ----------------
Marvin     Anderson   vwilliams  TRUE      TRUE
Emma       Baker      manderson  TRUE      FALSE
Taylor     Mills      manderson  TRUE      FALSE

3 rows selected.

The output confirms that Marvin can view his own record and those of his direct reports, but can only update his own phone number.

Mandatory Access Control

Understand how adopting Mandatory Access Control (MAC) helps you enforce consistent security policies across all access paths to your data objects.

When your application handles sensitive data, like Personally Identifiable Information (PII) or Protected Health Information (PHI), authorization must remain consistent regardless of the access path. Whether a user queries a base table directly or accesses it indirectly through a view, the resulting data exposure must be identical.

The risk of inconsistent access

A security gap can arise when a user has access to both a base table and a view defined on that table. In standard configurations, views typically execute with the privileges of the view owner rather than the querying user. Consequently, a user restricted from certain rows in the base table may see all rows when querying the view.

The following example illustrates this scenario, using the same hr.employees table referenced earlier.

MAC enforcement

To resolve the inconsistent access behavior and enforce a Mandatory Access Control (MAC) model, Deep Sec provides the USE DATA GRANTS ONLY configuration setting.

When USE DATA GRANTS ONLY is enabled on a table:

Example: Enforce MAC on the hr.employees table

To ensure that access restrictions defined on the base table are not circumvented through views or alternative access paths, enable MAC on the table using the following command:

SET USE DATA GRANTS ONLY ON hr.employees ENABLED;

With MAC enabled, employees see only their row, whether they query the table or the view.

EMMA> SELECT first_name FROM hr.employees;

FIRST_NAME
----------
Emma

1 row selected.


EMMA> SELECT first_name FROM hr.employees_view;

FIRST_NAME
----------
Emma

1 row selected.