Oracle Database Vault (DBV) restricts highly privileged database accounts (DBA, SYSDBA) from accessing application data. On Exadata, this is particularly important: Exadata DBAs have elevated OS access (root on compute nodes, cellcli on storage cells), making privilege separation inside the database itself critical for compliance frameworks such as SOX, PCI-DSS, and HIPAA.
This guide implements DB Vault entirely via command line — no OEM Cloud Control. All steps apply to Oracle Database 19c on Exadata in both CDB and non-CDB deployments.
Understanding DB Vault Roles
Before implementing, understand the mandatory role separation:
| Role | Purpose | Best Practice |
|---|---|---|
DV_OWNER |
Creates/manages DB Vault configuration | Separate account, not DBA |
DV_ACCTMGR |
Manages database user accounts | Separate account, replaces DBA for account management |
DV_ADMIN |
Administers DB Vault after initial setup | Assigned to DV_OWNER initially |
DBA |
Standard DBA role — restricted by DB Vault | Cannot access application data in realms |
The key principle: the DV_OWNER (Vault administrator) and DV_ACCTMGR (account manager) must be different individuals from the DBA team. This enforces separation of duties.
Phase 1: Pre-Implementation Assessment
1.1 Verify Prerequisites
-- Verify Oracle Database Vault is installed (licence check)
SELECT * FROM dba_registry WHERE comp_name = 'Oracle Database Vault';
-- If not installed, verify the option is available
SELECT * FROM v$option WHERE parameter = 'Oracle Database Vault';
# On the Exadata compute node: verify DBV components are installed
$ORACLE_HOME/bin/dbv help # should return help output (not "command not found")
# Check if the DBV option is linked in the Oracle binary
$ORACLE_HOME/bin/oraversion -component ORACLE_DATABASE_VAULT
1.2 Identify Privileged Account Usage
Before enabling DB Vault, capture which accounts currently access application schemas using DBA privileges — DB Vault will block this access:
-- Identify DBA-privileged accounts with application schema access (last 30 days)
SELECT DISTINCT s.username,
a.owner,
a.action_name,
COUNT(*) AS access_count
FROM dba_audit_trail a
JOIN dba_users s ON a.username = s.username
WHERE a.timestamp >= SYSDATE - 30
AND a.owner IN (SELECT username FROM dba_users WHERE account_status = 'OPEN' AND default_tablespace NOT IN ('SYSTEM','SYSAUX'))
AND s.username IN (SELECT grantee FROM dba_role_privs WHERE granted_role = 'DBA')
GROUP BY s.username, a.owner, a.action_name
ORDER BY access_count DESC;
Document all legitimate DBA access to application schemas — these will need exceptions or alternative access paths after DB Vault is enabled.
Phase 2: Enable Oracle Database Vault
2.1 Create DB Vault Owner and Account Manager Accounts
Run as SYSDBA before enabling DB Vault:
-- Create DB Vault owner account (separate from DBA)
CREATE USER c##dv_owner_admin IDENTIFIED BY "DVOwner#2026!"
CONTAINER = ALL; -- for CDB: use c## prefix
-- Create DB Vault account manager
CREATE USER c##dv_acctmgr_admin IDENTIFIED BY "DVAcctMgr#2026!"
CONTAINER = ALL;
-- Required minimum grants (Oracle will complete the setup during configuration)
GRANT CREATE SESSION TO c##dv_owner_admin CONTAINER = ALL;
GRANT CREATE SESSION TO c##dv_acctmgr_admin CONTAINER = ALL;
For non-CDB or PDB-specific implementation:
-- PDB-level (connect to specific PDB first)
ALTER SESSION SET CONTAINER = PDB_PROD;
CREATE USER dv_owner_admin IDENTIFIED BY "DVOwner#2026!";
CREATE USER dv_acctmgr_admin IDENTIFIED BY "DVAcctMgr#2026!";
GRANT CREATE SESSION TO dv_owner_admin;
GRANT CREATE SESSION TO dv_acctmgr_admin;
2.2 Run the DB Vault Configuration Script
# Run the DB Vault configuration script (as oracle OS user)
cd $ORACLE_HOME/rdbms/lib
# For CDB:
sqlplus / as sysdba
SQL> @?/rdbms/admin/dbvca.sql
-- The script will prompt for:
-- DV owner username: c##dv_owner_admin
-- DV owner password: DVOwner#2026!
-- DV account manager: c##dv_acctmgr_admin
-- DV account manager password: DVAcctMgr#2026!
Alternatively, use dvcfg (pre-19c) or the PL/SQL API directly:
-- Configure DB Vault using the DVSYS API (19c+)
BEGIN
CONFIGURE_DV(
dvowner_uname => 'c##dv_owner_admin',
dvowner_passwd => 'DVOwner#2026!',
dvacctmgr_uname => 'c##dv_acctmgr_admin',
dvacctmgr_passwd => 'DVAcctMgr#2026!'
);
END;
/
2.3 Enable DB Vault (Requires Database Restart)
-- Enable DB Vault in the parameter file
ALTER SYSTEM SET enable_ddl_logging = TRUE SCOPE=BOTH;
-- Enable DB Vault (this step registers the option — requires restart)
EXEC DBMS_MACADM.ENABLE_DV;
# Restart the database to activate DB Vault
srvctl stop database -d ORCL
srvctl start database -d ORCL
2.4 Verify DB Vault Is Active
-- Connect as DV_OWNER to verify
CONNECT c##dv_owner_admin/DVOwner#2026!
SELECT * FROM DVSYS.DBA_DV_STATUS;
NAME STATUS
----------------------- -------
DATABASE VAULT ENABLED
DATABASE VAULT CONFIGURE ENABLED
Phase 3: Create Realms
A Realm defines a protected zone. Objects in a realm are inaccessible to users outside the realm’s authorization list, even if those users have DBA or SELECT ANY TABLE privileges.
3.1 Create a Realm for the Application Schema
-- Connect as DV_OWNER
CONNECT c##dv_owner_admin/DVOwner#2026!
-- Create realm for the HR application schema
BEGIN
DBMS_MACADM.CREATE_REALM(
realm_name => 'HR Application Realm',
description => 'Protects all HR schema objects from privileged user access',
enabled => DBMS_MACUTL.G_YES,
audit_options => DBMS_MACUTL.G_REALM_AUDIT_FAIL + DBMS_MACUTL.G_REALM_AUDIT_SUCCESS
);
END;
/
3.2 Add Objects to the Realm
-- Add all objects owned by HR schema to the realm
BEGIN
DBMS_MACADM.ADD_OBJECT_TO_REALM(
realm_name => 'HR Application Realm',
object_owner => 'HR',
object_name => '%', -- wildcard: all objects
object_type => '%' -- wildcard: all object types
);
END;
/
-- Add a specific sensitive table from a different schema
BEGIN
DBMS_MACADM.ADD_OBJECT_TO_REALM(
realm_name => 'HR Application Realm',
object_owner => 'PAYROLL',
object_name => 'SALARY_DETAILS',
object_type => 'TABLE'
);
END;
/
3.3 Authorise Realm Participants
Authorised participants can access realm objects. These are the legitimate application accounts and DBAs who specifically need access:
-- Authorise the application owner (participant: can access objects)
BEGIN
DBMS_MACADM.ADD_AUTH_TO_REALM(
realm_name => 'HR Application Realm',
grantee => 'HR',
rule_set_name => NULL,
auth_options => DBMS_MACUTL.G_REALM_AUTH_PARTICIPANT
);
END;
/
-- Authorise a specific application service account
BEGIN
DBMS_MACADM.ADD_AUTH_TO_REALM(
realm_name => 'HR Application Realm',
grantee => 'HR_APP_USER',
auth_options => DBMS_MACUTL.G_REALM_AUTH_PARTICIPANT
);
END;
/
-- Authorise a DBA for break-glass access (owner level: can manage realm objects)
BEGIN
DBMS_MACADM.ADD_AUTH_TO_REALM(
realm_name => 'HR Application Realm',
grantee => 'DBA_BREAKGLASS',
auth_options => DBMS_MACUTL.G_REALM_AUTH_OWNER
);
END;
/
3.4 Test Realm Enforcement
-- Test: connect as DBA (should be blocked from HR objects)
CONNECT dba_user/dba_password
-- This should raise ORA-01031: insufficient privileges (DB Vault block)
SELECT * FROM HR.EMPLOYEES FETCH FIRST 1 ROW ONLY;
Expected error:
ORA-01031: insufficient privileges
-- This should work (DBA can still access system objects)
SELECT COUNT(*) FROM dba_tables WHERE owner = 'HR'; -- metadata: allowed
Phase 4: Create Command Rules
Command Rules restrict SQL commands (SELECT, INSERT, UPDATE, DELETE, ALTER SYSTEM, CONNECT, etc.) based on Rule Sets — conditions that must be true for the command to be allowed.
4.1 Restrict CONNECT During Maintenance Hours
-- Create a Rule: only allow CONNECT during business hours (Mon-Fri, 08:00-18:00)
BEGIN
DBMS_MACADM.CREATE_RULE(
rule_name => 'Business Hours Only',
rule_expr => 'TO_CHAR(SYSDATE,''DY'') NOT IN (''SAT'',''SUN'')
AND TO_NUMBER(TO_CHAR(SYSDATE,''HH24'')) BETWEEN 8 AND 18'
);
END;
/
-- Create a Rule Set containing this rule
BEGIN
DBMS_MACADM.CREATE_RULE_SET(
rule_set_name => 'Business Hours Rule Set',
description => 'Allow connections only during business hours',
enabled => DBMS_MACUTL.G_YES,
eval_options => DBMS_MACUTL.G_RULESET_EVAL_ALL, -- ALL rules must pass
audit_options => DBMS_MACUTL.G_RULESET_AUDIT_FAIL,
fail_options => DBMS_MACUTL.G_RULESET_FAIL_SHOW, -- show error message
fail_message => 'Database access is restricted to business hours only',
fail_code => 20001,
handler_options => DBMS_MACUTL.G_RULESET_HANDLER_OFF
);
END;
/
-- Add the rule to the rule set
BEGIN
DBMS_MACADM.ADD_RULE_TO_RULE_SET(
rule_set_name => 'Business Hours Rule Set',
rule_name => 'Business Hours Only'
);
END;
/
-- Create Command Rule: CONNECT restricted to business hours for non-sys users
BEGIN
DBMS_MACADM.CREATE_COMMAND_RULE(
command => 'CONNECT',
rule_set_name => 'Business Hours Rule Set',
object_owner => '%',
object_name => '%',
enabled => DBMS_MACUTL.G_YES
);
END;
/
4.2 Prevent ALTER SYSTEM from Non-DBA Hosts
-- Create a Factor based on client IP address (network factor)
BEGIN
DBMS_MACADM.CREATE_FACTOR(
factor_name => 'DB Admin Subnet',
factor_type_name => 'Network',
description => 'Identifies whether the connection is from the DBA subnet',
rule_set_name => NULL,
get_expr => 'UTL_INADDR.GET_HOST_ADDRESS(SYS_CONTEXT(''USERENV'',''IP_ADDRESS''))',
validate_expr => NULL,
identify_by => DBMS_MACUTL.G_IDENTIFY_BY_CONTEXT,
labeled_by => DBMS_MACUTL.G_LABELED_BY_SELF,
eval_options => DBMS_MACUTL.G_RULESET_EVAL_ALL,
audit_options => DBMS_MACUTL.G_FACTOR_AUDIT_OFF,
fail_options => DBMS_MACUTL.G_RULESET_FAIL_SHOW
);
END;
/
-- Create a Rule: client IP must be in the DBA management subnet
BEGIN
DBMS_MACADM.CREATE_RULE(
rule_name => 'DBA Subnet Check',
rule_expr => 'SYS_CONTEXT(''USERENV'',''IP_ADDRESS'') LIKE ''10.10.10.%'''
);
END;
/
-- Rule Set for ALTER SYSTEM control
BEGIN
DBMS_MACADM.CREATE_RULE_SET(
rule_set_name => 'DBA Network Rule Set',
description => 'Allows ALTER SYSTEM only from DBA management network',
enabled => DBMS_MACUTL.G_YES,
eval_options => DBMS_MACUTL.G_RULESET_EVAL_ALL,
audit_options => DBMS_MACUTL.G_RULESET_AUDIT_FAIL,
fail_options => DBMS_MACUTL.G_RULESET_FAIL_SHOW,
fail_message => 'ALTER SYSTEM is restricted to DBA management subnet',
fail_code => 20002,
handler_options => DBMS_MACUTL.G_RULESET_HANDLER_OFF
);
END;
/
BEGIN
DBMS_MACADM.ADD_RULE_TO_RULE_SET(
rule_set_name => 'DBA Network Rule Set',
rule_name => 'DBA Subnet Check'
);
END;
/
-- Command Rule: ALTER SYSTEM restricted to DBA subnet
BEGIN
DBMS_MACADM.CREATE_COMMAND_RULE(
command => 'ALTER SYSTEM',
rule_set_name => 'DBA Network Rule Set',
object_owner => '%',
object_name => '%',
enabled => DBMS_MACUTL.G_YES
);
END;
/
Phase 5: Simulation Mode (Exadata 19c+)
Before enforcing DB Vault policies, test them in Simulation Mode — violations are logged but not blocked. This allows you to identify unintended access patterns before going live.
-- Enable Simulation Mode for a realm (logs violations, does not block)
BEGIN
DBMS_MACADM.UPDATE_REALM(
realm_name => 'HR Application Realm',
description => 'HR realm in simulation mode for 2 weeks',
enabled => DBMS_MACUTL.G_SIMULATION
);
END;
/
-- Review simulation violations after 1 week
SELECT realm_name,
username,
machine,
module,
object_owner,
object_name,
command,
violation_type,
TO_CHAR(event_time, 'YYYY-MM-DD HH24:MI:SS') AS event_time
FROM dvsys.dba_dv_simulation_log
WHERE realm_name = 'HR Application Realm'
ORDER BY event_time DESC
FETCH FIRST 50 ROWS ONLY;
Review violations, add necessary realm authorisations for legitimate access, then switch from simulation to enforcement:
-- Switch realm from simulation to enforcement
BEGIN
DBMS_MACADM.UPDATE_REALM(
realm_name => 'HR Application Realm',
enabled => DBMS_MACUTL.G_YES
);
END;
/
Phase 6: DB Vault on Exadata — Specific Considerations
Exadata Storage Cell Access
DB Vault operates at the database layer — it does not directly control OS-level access to Exadata storage cells. However:
- DB Vault prevents DBAs from
SELECT-ing application data even when they have OS access to the compute nodes. - For full separation, combine DB Vault with Exadata Security (
cellcliaccess control) and OS-level auditing.
cellcli and DB Vault Integration
# On Exadata cells: restrict cellcli to specific OS users only
# (OS-level control, independent of DB Vault but complementary)
usermod -G celladmin restricted_dba_user
Auditing DB Vault Events on Exadata
DB Vault events are written to the Unified Audit Trail (Oracle 12c+):
-- View DB Vault audit records
SELECT event_timestamp,
dbusername,
os_username,
ip_address,
object_schema,
object_name,
sql_text,
action_name,
return_code
FROM unified_audit_trail
WHERE component = 'Database Vault'
AND event_timestamp >= SYSDATE - 7
ORDER BY event_timestamp DESC
FETCH FIRST 100 ROWS ONLY;
Integrate these audit records with Oracle Audit Vault and Database Firewall (AVDF) for centralised, tamper-proof audit retention — the standard approach for SOX and PCI compliance on Exadata.
Phase 7: Verifying the Full Configuration
-- Connect as DV_OWNER: full status report
CONNECT c##dv_owner_admin/DVOwner#2026!
-- List all realms and their status
SELECT realm_name, description, enabled, audit_options
FROM dvsys.dba_dv_realm
ORDER BY realm_name;
-- List all realm authorisations
SELECT r.realm_name, a.grantee, a.auth_option
FROM dvsys.dba_dv_realm r
JOIN dvsys.dba_dv_realm_auth a ON r.realm_name = a.realm_name
ORDER BY r.realm_name, a.grantee;
-- List all command rules
SELECT command, rule_set_name, object_owner, object_name, enabled
FROM dvsys.dba_dv_command_rule
ORDER BY command;
-- List all rule sets
SELECT rule_set_name, enabled, eval_options, fail_message
FROM dvsys.dba_dv_rule_set
ORDER BY rule_set_name;
Disabling DB Vault (Break-Glass Procedure)
In an emergency requiring full DBA access to application data:
-- As DV_OWNER: temporarily disable a realm
BEGIN
DBMS_MACADM.UPDATE_REALM(
realm_name => 'HR Application Realm',
enabled => DBMS_MACUTL.G_NO
);
END;
/
To fully disable DB Vault (requires database restart):
-- Disable DB Vault (DV_OWNER only)
EXEC DBMS_MACADM.DISABLE_DV;
srvctl stop database -d ORCL
srvctl start database -d ORCL
All disabling actions are audited. Ensure your audit policy captures DVSYS.DBMS_MACADM procedure calls so any break-glass usage is recorded and alerted.