Data Redaction (DBMS - REDACT) in Oracle Database 12c Release 1 (12.1)
Data Redaction (DBMS - REDACT) in Oracle Database 12c Release 1 (12.1)
Data Redaction (DBMS - REDACT) in Oracle Database 12c Release 1 (12.1)
Release 1 (12.1)
Oracle 10g gave us to ability to perform column masking to prevent sensitive data from being
displayed by applications. In Oracle 12c, and back-ported to 11.2.0.4, the data redaction feature uses
the DBMS_REDACT package to define redaction policies that give a greater level of control and
protection over sensitive data. The documentation for this feature is quite extensive, so this article will
provide a simple overview of the functionality.
Redaction is part of Oracle Advanced Security, which is a separately licensed Enterprise Edition
option.
Setup
Add a new Policy
Alter an Existing Policy
Drop an Existing Policy
Views
Additional Information
Related articles.
Setup
We need to make sure the test user has access to the DBMS_REDACT package.
The example code in this article requires the following test table.
CONN test/test@pdb1
SELECT *
FROM payment_details
ORDER BY id;
SQL>
Identify the object : The OBJECT_SCHEMA, OBJECT_NAME and COLUMN_NAME parameters identify the
column to be redacted.
Give it a name : The POLICY_NAME parameter assigns a name to the policy.
What should happen? : The FUNCTION_TYPE parameter determines the type of redaction that
should take place. The allowable values are listed here. Depending on the type of redaction
selected, you may be required to specify the FUNCTION_PARAMETERS or
various REGEXP_* parameters.
When should it happen? : The EXPRESSION parameter determines when the redaction should
take place. For example, an expression of "1=1" means the redaction will always take place.
Alternatively, situational expressions can be defined using the SYS_CONTEXT function.
The following example is about as simple as it gets. A full redaction policy is placed on
the CARD_NO column with an expression of "1=1".
CONN test/test@pdb1
BEGIN
DBMS_REDACT.add_policy(
object_schema => 'test',
object_name => 'payment_details',
column_name => 'card_no',
policy_name => 'redact_card_info',
function_type => DBMS_REDACT.full,
expression => '1=1'
);
END;
/
5 rows selected.
SQL>
We can see the CARD_NO column is now redacted to the number "0". The value displayed by full
redaction is based on the data type defaults for the DBMS_REDACT.FULL function type. You can see the
default values by querying the REDACTION_VALUES_FOR_TYPE_FULL view, shown by the
following example that uses the redaction_columns.sql script.
@redaction_value_defaults.sql
SQL>
@redaction_policies
1 row selected.
SQL>
@redaction_columns
1 row selected.
SQL>
Other variations on redaction policies are described in the following section. These are equally
applicable during redaction policy creation.
CONN test/test@pdb1
BEGIN
DBMS_REDACT.alter_policy (
object_schema => 'test',
object_name => 'payment_details',
policy_name => 'redact_card_info',
action => DBMS_REDACT.modify_column,
column_name => 'card_no',
function_type => DBMS_REDACT.partial,
function_parameters => '1,1,12'
);
END;
/
SELECT *
FROM payment_details
ORDER BY id;
5 rows selected.
SQL>
We can add another column to the redaction policy to protect the string representation of the card
number.
BEGIN
DBMS_REDACT.alter_policy (
object_schema => 'test',
object_name => 'payment_details',
policy_name => 'redact_card_info',
action => DBMS_REDACT.add_column,
column_name => 'card_string',
function_type => DBMS_REDACT.partial,
function_parameters => 'VVVVFVVVVFVVVVFVVVV,VVVV-VVVV-VVVV-VVVV,#,1,12'
);
END;
/
ALTER SESSION SET nls_date_format='DD-MON-YYYY';
COLUMN card_no FORMAT 9999999999999999
SELECT *
FROM payment_details
ORDER BY id;
5 rows selected.
SQL>
The following example redacts the expiry date using partial redaction, converting the day and month
values to 1st of January.
BEGIN
DBMS_REDACT.alter_policy (
object_schema => 'test',
object_name => 'payment_details',
policy_name => 'redact_card_info',
action => DBMS_REDACT.add_column,
column_name => 'expiry_Date',
function_type => DBMS_REDACT.partial,
function_parameters => 'm1d1Y'
);
END;
/
SELECT *
FROM payment_details
ORDER BY id;
5 rows selected.
SQL>
We can also amend the policy so it does not affect the schema owner. The following example uses
the SYS_CONTEXT function in the EXPRESSION parameter to determine the current user, making the
application of the redaction policy conditional.
CONN test/test@pdb1
BEGIN
DBMS_REDACT.alter_policy (
object_schema => 'test',
object_name => 'payment_details',
policy_name => 'redact_card_info',
action => DBMS_REDACT.modify_expression,
column_name => 'card_no',
expression => 'SYS_CONTEXT(''USERENV'',''SESSION_USER'') != ''TEST'''
);
END;
/
SELECT *
FROM payment_details
ORDER BY id;
5 rows selected.
SQL>
SELECT *
FROM test.payment_details
ORDER BY id;
5 rows selected.
SQL>
CONN test/test@pdb1
BEGIN
DBMS_REDACT.drop_policy (
object_schema => 'test',
object_name => 'payment_details',
policy_name => 'redact_card_info'
);
END;
/
SELECT *
FROM payment_details
ORDER BY id;
5 rows selected.
SQL>
Views
As mentioned previously, you can get information about redaction policies using the following views.
REDACTION_COLUMNS
REDACTION_POLICIES
REDACTION_VALUES_FOR_TYPE_FULL