Oracle Data Redaction: Step-by-Step Guide to Protect Sensitive Data

In this step-by-step guide, we’ll walk you through everything you need to know about Oracle Data Redaction. You’ll learn what data redaction is, how redaction policies work, the different types of data redaction, and how to implement it practically using SQL examples. By the end of this guide, you’ll understand how Oracle Data Redaction helps protect sensitive data in real time, ensures compliance with privacy laws, and strengthens your database security all without affecting your applications or data integrity.

What is Oracle Data Redaction?

Oracle Data Redaction is a built-in security feature in Oracle Database that helps protect sensitive or confidential information from unauthorized access. It works by masking or hiding data in real time when users query the database without changing the actual data stored in the tables.

For example, an HR manager might see a full employee salary, while a normal user only sees a masked value like “XXXXXX”. This ensures that critical data such as salary, PAN, credit card numbers, or personal details are never exposed to users who shouldn’t see them.

Oracle Data Redaction policies can be defined using the DBMS_REDACT package, allowing administrators to set rules based on conditions such as user roles, application contexts, or environments.

By using Data Redaction, organizations can strengthen database security, meet compliance standards (like GDPR or PCI DSS), and protect sensitive data all without modifying existing applications or database structures.

What is a Redaction Policy?

A Redaction Policy is the main rule or instruction that tells Oracle which data to hide, how to hide it, and when to hide it.
It acts as the control point for applying data masking to specific tables and columns.

Each policy defines:
  • Table and Column: The data you want to protect (e.g., EMPLOYEE.SALARY).
  • Redaction Type: How the data should be masked (Full, Partial, Random, etc.).
  • Condition (Expression): When or for whom the masking should apply.
You create and manage redaction policies using the DBMS_REDACT package.

Oracle Data Redaction Types Explained (With Simple Examples)

1. FULL Redaction

Definition: Full redaction completely hides the original data and replaces it with a default masking value based on the data type.
Sample: 123-456-789 → XXXX
Best Use Case: When no part of the sensitive data should be visible.

2. PARTIAL Redaction

Definition: Partial redaction masks only a specific portion of the data and reveals the rest. You can customize which characters to expose.
Sample: 123456789 → 1234XXXX9
Best Use Case: Commonly used for masking credit card numbers, phone numbers, or showing only last 4 digits.

3. RANDOM Redaction

Definition: Random redaction replaces actual data with a random value each time. The output looks unpredictable and does not reveal real details.
Sample: 123456789 → 594837201
Best Use Case: When you want data to appear "changed" or obfuscated without showing the real value.

4. NULLIFY Redaction

Definition: NULLIFY replaces the actual data with NULL, making it appear blank to unauthorized users.
Sample: 123-456-789 → NULL
Best Use Case: When you want to completely hide data without showing any placeholder or masked text.

5. NONE

Definition: No redaction is applied. The data appears exactly as stored in the table.
Sample: 123456789 → 123456789
Best Use Case: For privileged users or when policy conditions evaluate to "no masking required."

6. REGEXP (Regular Expression) Redaction

Definition: REGEXP redaction masks data based on a regular expression pattern. Very useful for structured fields like email, PAN, Aadhaar, phone numbers, etc.
Sample: abc@gmail.com → ***@gmail.com
Best Use Case: Masking a specific format or pattern in a field.

Now we will explore how to create a data redaction policy and how to alter an existing policy for implementation on a database table.

Test Table:
SQL> select * from HR.INFO;

     SR_NO NAME            CARD_INFO       MAIL
---------- --------------- --------------- ---------------
         1 Rahul Sharma    123-654-876     rahul@gmail.com
         2 Amit Verma      987-321-654     amit@gmail.com
         3 Sneha Patel     543-789-210     sneha@gmail.com
         4 Karan Joshi     654-123-987     karan@gmail.com
         5 Neha Kapoor     321-567-894     neha@gmail.com

Policy creation and management for each redaction type.

Policy Creation:

SQL> show user
USER is "SYS"
SQL>
SQL> BEGIN
 DBMS_REDACT.ADD_POLICY  (
    object_schema => 'HR'
   ,object_name => 'INFO'
   ,policy_name => 'PROTECT_CARD'
   ,expression => '1=1');
END;
/  2    3    4    5    6    7    8

PL/SQL procedure successfully completed.

Altering Policies for Each Redaction Type:

1. Redaction Type FULL:
SQL> BEGIN
 DBMS_REDACT.ALTER_POLICY(
    object_schema  => 'HR',
    object_name    => 'INFO',
    policy_name    => 'PROTECT_CARD',
    action         => DBMS_REDACT.ADD_COLUMN,
    column_name    => 'CARD_INFO',
    function_type  => DBMS_REDACT.FULL
 );
END;
/
  2    3    4    5    6    7    8    9   10   11
PL/SQL procedure successfully completed.
How the Table Appears to Users:
SQL> show user
USER is "TEST"
SQL> select * from HR.INFO;

     SR_NO NAME            CARD_INFO       MAIL
---------- --------------- --------------- ---------------
         1 Rahul Sharma                    rahul@gmail.com
         2 Amit Verma                      amit@gmail.com
         3 Sneha Patel                     sneha@gmail.com
         4 Karan Joshi                     karan@gmail.com
         5 Neha Kapoor                     neha@gmail.com
2. Redaction Type PARTIAL:
SQL> BEGIN
 DBMS_REDACT.ALTER_POLICY  (
    OBJECT_SCHEMA => 'HR'
   ,object_name => 'INFO'
   ,policy_name => 'PROTECT_CARD'
   ,action => DBMS_REDACT.MODIFY_COLUMN
   ,column_name => 'CARD_INFO'
   ,function_type => DBMS_REDACT.PARTIAL,
   function_parameters => 'vvvfvvvfvvv,vvv-vvv-vvv,#,4,6'
   );
END;
/  2    3    4    5    6    7    8    9   10   11   12

PL/SQL procedure successfully completed.
How the Table Appears to Users:
SQL> show user
USER is "TEST"
SQL> select * from HR.INFO;

     SR_NO NAME            CARD_INFO       MAIL
---------- --------------- --------------- ---------------
         1 Rahul Sharma    123-###-876     rahul@gmail.com
         2 Amit Verma      987-###-654     amit@gmail.com
         3 Sneha Patel     543-###-210     sneha@gmail.com
         4 Karan Joshi     654-###-987     karan@gmail.com
         5 Neha Kapoor     321-###-894     neha@gmail.com
3. Redaction Type RANDOM:
SQL> BEGIN
 DBMS_REDACT.ALTER_POLICY(
    object_schema  => 'HR',
    object_name    => 'INFO',
    policy_name    => 'PROTECT_CARD',
    action         => DBMS_REDACT.MODIFY_COLUMN,
    column_name    => 'CARD_INFO',
    function_type  => DBMS_REDACT.RANDOM
 );
END;
/  2    3    4    5    6    7    8    9   10   11

PL/SQL procedure successfully completed.
How the Table Appears to Users:
SQL> show user
USER is "TEST"
SQL> select * from HR.INFO;

     SR_NO NAME            CARD_INFO       MAIL
---------- --------------- --------------- ---------------
         1 Rahul Sharma    XG;8(aZ;`OC     rahul@gmail.com
         2 Amit Verma      5U^5VkjO=]f     amit@gmail.com
         3 Sneha Patel     )<"#8~m$1D*     sneha@gmail.com
         4 Karan Joshi     sVT*GA&/{^\     karan@gmail.com
         5 Neha Kapoor     #XW3:MQp+`_     neha@gmail.com
4. Redaction Type NULLIFY:
SQL> BEGIN
 DBMS_REDACT.ALTER_POLICY(
    object_schema  => 'HR',
    object_name    => 'INFO',
    policy_name    => 'PROTECT_CARD',
    action         => DBMS_REDACT.MODIFY_COLUMN,
    column_name    => 'CARD_INFO',
    function_type  => DBMS_REDACT.NULLIFY
 );
END;
/  2    3    4    5    6    7    8    9   10   11

PL/SQL procedure successfully completed.
How the Table Appears to Users:
SQL> show user
USER is "TEST"
SQL> select * from HR.INFO;

     SR_NO NAME            CARD_INFO       MAIL
---------- --------------- --------------- ---------------
         1 Rahul Sharma                    rahul@gmail.com
         2 Amit Verma                      amit@gmail.com
         3 Sneha Patel                     sneha@gmail.com
         4 Karan Joshi                     karan@gmail.com
         5 Neha Kapoor                     neha@gmail.com
5. Redaction Type NONE:
SQL> BEGIN
 DBMS_REDACT.ALTER_POLICY(
    object_schema  => 'HR',
    object_name    => 'INFO',
    policy_name    => 'PROTECT_CARD',
    action         => DBMS_REDACT.MODIFY_COLUMN,
    column_name    => 'CARD_INFO',
    function_type  => DBMS_REDACT.NONE
 );
END;
/  2    3    4    5    6    7    8    9   10   11

PL/SQL procedure successfully completed.
How the Table Appears to Users:
SQL> show user
USER is "TEST"
SQL> select * from HR.INFO;

     SR_NO NAME            CARD_INFO       MAIL
---------- --------------- --------------- ---------------
         1 Rahul Sharma    123-654-876     rahul@gmail.com
         2 Amit Verma      987-321-654     amit@gmail.com
         3 Sneha Patel     543-789-210     sneha@gmail.com
         4 Karan Joshi     654-123-987     karan@gmail.com
         5 Neha Kapoor     321-567-894     neha@gmail.com
6. Redaction Type REGEXP:
SQL> BEGIN
 DBMS_REDACT.ALTER_POLICY(
    object_schema         => 'HR',
    object_name           => 'INFO',
    policy_name           => 'PROTECT_CARD',
    action                => DBMS_REDACT.ADD_COLUMN,
    column_name           => 'MAIL',
    function_type         => DBMS_REDACT.REGEXP,
    regexp_pattern        => '^[^@]+',
    regexp_replace_string => '***'
 );
END;
/
  2    3    4    5    6    7    8    9   10   11   12   13
PL/SQL procedure successfully completed.
How the Table Appears to Users:
SQL> show user
USER is "TEST"
SQL> select * from HR.INFO;

     SR_NO NAME            CARD_INFO       MAIL
---------- --------------- --------------- ---------------
         1 Rahul Sharma    123-654-876     ***@gmail.com
         2 Amit Verma      987-321-654     ***@gmail.com
         3 Sneha Patel     543-789-210     ***@gmail.com
         4 Karan Joshi     654-123-987     ***@gmail.com
         5 Neha Kapoor     321-567-894     ***@gmail.com
Note: Once a redaction policy is applied to a table, even the table owner cannot view the original data in the redacted column.

Next, we will learn how to grant access so a specific user can view the original data in a redacted column.

SQL> show user
USER is "HR"
SQL>
SQL> select * from HR.INFO;

     SR_NO NAME            CARD_INFO       MAIL
---------- --------------- --------------- ---------------
         1 Rahul Sharma    123-654-876     ***@gmail.com
         2 Amit Verma      987-321-654     ***@gmail.com
         3 Sneha Patel     543-789-210     ***@gmail.com
         4 Karan Joshi     654-123-987     ***@gmail.com
         5 Neha Kapoor     321-567-894     ***@gmail.com
As you can see, even the HR schema cannot view the 'MAIL' column in its own 'INFO' table. Now, we will grant access to the HR schema to view this redacted column by altering the existing policy.
SQL> show user
USER is "SYS"
SQL>
SQL> BEGIN
  DBMS_REDACT.ALTER_POLICY  (
    OBJECT_SCHEMA => 'HR',
    object_name => 'INFO',
    policy_name => 'PROTECT_CARD',
    action => DBMS_REDACT.MODIFY_EXPRESSION,
    expression => 'sys_context(''userenv'',''session_user'') != ''HR'''
    );
END;
/  2    3    4    5    6    7    8    9   10

PL/SQL procedure successfully completed.
After altering the policy, the HR schema can now view the original values in the column.
SQL> show user
USER is "HR"
SQL>
SQL> select * from HR.INFO;

     SR_NO NAME            CARD_INFO       MAIL
---------- --------------- --------------- ---------------
         1 Rahul Sharma    123-654-876     rahul@gmail.com
         2 Amit Verma      987-321-654     amit@gmail.com
         3 Sneha Patel     543-789-210     sneha@gmail.com
         4 Karan Joshi     654-123-987     karan@gmail.com
         5 Neha Kapoor     321-567-894     neha@gmail.com

How to Delete an Existing Redaction Policy

SQL> show user
USER is "SYS"
SQL>
SQL> BEGIN
 DBMS_REDACT.DROP_POLICY  (
   OBJECT_SCHEMA => 'HR',
   object_name => 'INFO',
   policy_name => 'PROTECT_CARD');
END;
/  2    3    4    5    6    7

PL/SQL procedure successfully completed.
Conclusion: With the right redaction policies in place, Oracle Data Redaction offers a powerful and flexible way to secure sensitive columns, mask confidential information, and control data exposure for different users across your database.

Post a Comment

© Ayaan Israr - All rights reserved. Premium By Ayaan Israr