Wednesday, April 22, 2026

Automated Database Security: DBSAT 3.1 meets Oracle EM


What DBSAT is: the Database Security Assessment Tool is a free Oracle utility that interrogates a running database's configuration, users, privileges, and audit settings — producing a scored risk report without requiring DBA-level access or taking the system offline.

The OEM integration adds four key capabilities:

The plug-in agent deploys DBSAT as a managed OEM target, so assessments can be scheduled (daily, weekly, on-demand) from the central console rather than run manually on each host.

The analyzer engine classifies every finding into a severity tier — critical, high, medium, or low — and groups them by domain: basic security controls, privilege analysis, fine-grained auditing, encryption, and database vault.

The compliance framework mapping automatically aligns findings to regulatory and hardening standards: CIS Oracle Benchmarks, DISA STIGs, GDPR, PCI-DSS, and HIPAA. This eliminates the manual cross-referencing that normally consumes audit preparation time.

The output layer surfaces results in three directions: detailed HTML/JSON reports for security teams, the OEM compliance dashboard for executive visibility and trend lines over time, and automated remediation jobs that can trigger corrective SQL scripts or escalation workflows directly from OEM.

Practical benefit: instead of point-in-time assessments run before audits, organizations get a continuous risk baseline across their entire Oracle fleet — with drift detection that alerts when a previously-passing control regresses. Click any component above to ask more about it.




Architecture: how the OEM plug-in works

Before touching a keyboard, internalize this data flow. It determines where credentials need to live and what firewall ports must be open.

OEM 13.5 ServerEM Repository (OMS)Compliance EngineEM Agent + DBSATHost A · DB19ccollector.jarEM Agent + DBSATHost B · DB21ccollector.jarEM Agent + DBSATHost C · DB23aicollector.jarOracle DB 19c:1521Oracle DB 21c:1521Oracle DB 23ai:1521dispatch taskupload resultsJDBC :1521JDBC :1521JDBC :1521ComplianceFrameworkCIS · STIG · PCI · GDPR

Key data-flow facts every DBA should memorize:

  • The OEM agent on each host runs dbsat collect locally — no separate DBSAT binary to maintain.
  • The collector output ZIP is uploaded back to the OMS over the standard HTTPS agent channel (port 4900). No new firewall rules needed in most environments.
  • The analyzer step runs inside the OMS, not on the DB host, so CPU impact on production is negligible.
  • Credentials for dbsat collect are stored in the OEM Named Credential store — not in clear-text config files.

Prerequisites and installation

Required privileges — the minimum viable user

The biggest DBA mistake I see is running DBSAT with a SYS or DBA account. DBSAT 3.1 ships with a dedicated privilege script. Use it.

SQL — run as SYSDBA on each target DBdbsat_user_setup.sql
-- Create a dedicated, locked-down collector account
CREATE USER c##dbsat_coll IDENTIFIED BY "<VaultSecret_01>"
  DEFAULT TABLESPACE users
  TEMPORARY TABLESPACE temp
  ACCOUNT LOCK;   -- unlock only during assessment windows

-- Minimum grants for collector (CDB-wide)
GRANT CREATE SESSION               TO c##dbsat_coll CONTAINER=ALL;
GRANT SELECT_CATALOG_ROLE           TO c##dbsat_coll CONTAINER=ALL;
GRANT SELECT ON sys.registry$        TO c##dbsat_coll CONTAINER=ALL;
GRANT SELECT ON sys.dba_users_with_defpwd
                                     TO c##dbsat_coll CONTAINER=ALL;

-- DBSAT 3.1 new: SQL Firewall and Data Redaction views
GRANT SELECT ON sys.dbms_sql_firewall$   TO c##dbsat_coll CONTAINER=ALL;
GRANT SELECT ON dvsys.dba_dv_status        TO c##dbsat_coll CONTAINER=ALL;

-- Optional: privilege analysis (adds ~15% more findings)
EXEC dbms_privilege_capture.create_capture(
  name        => 'DBSAT_PA_CAP',
  type        => dbms_privilege_capture.g_database,
  roles       => role_name_list()
);
Warning
Never grant DBA to the collector account. DBSAT only needs read access to data dictionary views. The privilege script above covers all 3.1 checks. If you see "ORA-01031 insufficient privileges" in the log, see the extended grants section in MOS Note 2710440.1.

Deploying the OEM plug-in

BASH — OEM admin on OMS hostplug-in deployment
# 1. Download plug-in archive from MOS (Patch 36500021)
cd /u01/app/oracle/product/13.5.0/em_home/bin

# 2. Import plug-in into OMS software library
./emcli import_update \
  -omslocal \
  -file="/tmp/oracle.dbsat_3.1.0.0.0_2000_0.opar"

# 3. Deploy to OMS
./emcli deploy_plugin_on_server \
  -plugin="oracle.dbsat:3.1.0.0.0" \
  -sys_password="<oms_sys_pw>"

# 4. Deploy to all managed agents (parallel, 10 at a time)
./emcli deploy_plugin_on_agent \
  -plugin="oracle.dbsat:3.1.0.0.0" \
  -agent_names="*:3872" \
  -async_operation

# 5. Verify deployment status
./emcli get_plugin_deployment_status \
  -plugin_id="oracle.dbsat" | grep -E "AGENT|STATUS"
BASH — verify plug-in on agentagent verification
# On the target agent host
$AGENT_HOME/bin/emctl listplugins agent \
  -type all | grep dbsat

# Expected output:
# oracle.dbsat    3.1.0.0.0    DEPLOYED

# Confirm dbsat binary is accessible
ls -lh $AGENT_HOME/plugins/oracle.dbsat_3.1.0.0.0/bin/dbsat

Running your first assessment

Option A — from the OEM console (recommended)

Navigate to the target database in OEM → Security → DBSAT Assessment

EM 13.5 adds a "DBSAT Assessment" menu item under the Database Security menu for any target that has the plug-in deployed. Click Run Assessment.

Select a Named Credential for the collector

Choose the credential that resolves to c##dbsat_coll. If it's not listed, create it first under Setup → Security → Named Credentials.

Choose assessment scope

Select Full Assessment for the first run. For CDB targets, enable Include all open PDBs. The Privilege Analysis option adds ~4 minutes per database.

Submit and monitor

The job appears in the EM Jobs page with real-time step progress. A typical 19c database completes in 6–9 minutes.

Option B — command-line (scripted / headless)

BASH — on DB host via EM agentmanual collect + report
DBSAT=$AGENT_HOME/plugins/oracle.dbsat_3.1.0.0.0/bin/dbsat
OUTPUT_DIR=/u01/dbsat_output/$(date +%Y%m%d)
mkdir -p $OUTPUT_DIR

# ── Step 1: Collect ──────────────────────────────────────────
$DBSAT collect \
  c##dbsat_coll/"<password>"@"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=dbhost01.example.com)(PORT=2484))(CONNECT_DATA=(SERVICE_NAME=PROD19C)))" \
  -n                       # suppress interactive password prompt
  -o $OUTPUT_DIR/prod19c   # output prefix

# Output: prod19c.zip (encrypted, requires reporter password)

# ── Step 2: Report ───────────────────────────────────────────
$DBSAT report \
  -n                       # no password on report zip
  -a                       # all checks
  -f html,json             # DBSAT 3.1: dual format output
  -o $OUTPUT_DIR/prod19c_report \
  $OUTPUT_DIR/prod19c.zip

# Output files:
#   prod19c_report.html  — human-readable
#   prod19c_report.json  — machine-readable (SIEM/ticketing)

CDB / multi-PDB sweep

BASH — CDB with all PDBsmulti-tenant assessment
# Connect to CDB$ROOT with the common user
$DBSAT collect \
  c##dbsat_coll@"(DESCRIPTION=...CDB_SERVICE...)" \
  -n \
  --pdb-scope ALL \        # DBSAT 3.1 flag: enumerate all open PDBs
  -o $OUTPUT_DIR/cdb01

# Report will include a top-level CDB summary + per-PDB sections
$DBSAT report \
  -n -a \
  -f html,json \
  --pdb-rollup \           # DBSAT 3.1: consolidated risk matrix
  -o $OUTPUT_DIR/cdb01_report \
  $OUTPUT_DIR/cdb01.zip
pro tip
Use --pdb-scope OPEN instead of ALL to skip PDBs in MOUNT or RESTRICTED state during scheduled jobs — avoids false-negative errors in the log.

Decoding the findings report

DBSAT categorizes every finding into one of five domains. Here's what a real output header looks like for a typical 19c production database, followed by what the score means:

═══════════════════════════════════════════════════════════════════ Oracle Database Security Assessment Report Database: PROD19C · Version: 19.21.0.0 · OS: Linux x86-64 Assessed: 2025-04-22 14:03:11 UTC | DBSAT 3.1.0.0.0 ═══════════════════════════════════════════════════════════════════ SUMMARY ─────────────────────────────────────────────────── Domain Critical High Medium Low Advisory ─────────────────────────────────────────────────── Basic Security Configuration User Accounts Privilege and Role Analysis Auditing and Logging Encryption and Data Protection 1 ─────────────────────────────────────────────────── TOTAL 16 22 14 20 Overall Risk Score: MEDIUM-HIGH (68/100)

The risk score algorithm in DBSAT 3.1 weights findings as: Critical × 20, High × 6, Medium × 2, Low × 1 — normalized to 100. A score above 70 triggers an automatic OEM compliance alert.

Critical
4
Immediate action required
High
16
Address within sprint
Medium
22
Schedule remediation
Low
14
Harden in next cycle

Top findings to always check first

DBV.0001 — Database Vault not enabled
Basic Security Configuration · Critical
AUDIT.0003 — Unified Auditing not enforced (Mixed mode)
Auditing and Logging · Critical
PRIV.0012 — 23 users with excessive system privileges never logged in for > 90 days
Privilege and Role Analysis · High
ENC.0007 — Transparent Data Encryption not active on USERS and SYSAUX tablespaces
Encryption and Data Protection · High
USER.0004 — 4 accounts using default Oracle passwords (SCOTT, OUTLN, DBSNMP…)
User Accounts · High
CONF.0019 — SEC_CASE_SENSITIVE_LOGON = FALSE (allows case-insensitive passwords)
Basic Security Configuration · Medium

Compliance framework mapping

DBSAT 3.1 ships with five built-in compliance mappings. OEM's compliance framework picks these up automatically and folds them into enterprise-level compliance dashboards.

DBSAT Check IDDescriptionFrameworksSeverity
AUDIT.0001Audit trail secureCIS 4.1 STIG V-236 PCI 10.2Critical
ENC.0001TDE on sensitive tablespacesPCI 3.4 GDPR Art.32 HIPAA §164High
USER.0002Default passwords changedCIS 5.1 STIG V-219 PCI 2.1 GDPR Art.25High
PRIV.0001PUBLIC has no dangerous grantsCIS 6.2 STIG V-225Medium
NET.0003sqlnet.ora encryption enforcedPCI 4.1 GDPR Art.32 STIG V-241High
CONF.0011Remote_OS_Authent = FALSECIS 2.2 STIG V-220Critical
OEM tip
In OEM, navigate to Compliance → Library → Oracle Database Security Baseline to see all 147 DBSAT checks mapped to standards. You can customize the baseline — suppress checks that don't apply to your environment and it persists across future assessments.

Scheduling and automation in OEM

Set up a weekly fleet-wide assessment job

BASH — emcli job schedulingautomated weekly sweep
# Create a multi-target DBSAT job via emcli
./emcli create_job \
  -name="WEEKLY_DBSAT_FLEET" \
  -type="DBSATAssessment" \
  -target_type="oracle_database" \
  -target_list="PROD19C:oracle_database,PROD21C:oracle_database,DEVPDB:oracle_database" \
  -credential_set_name="DBCredsDBSAT" \
  -start_time="2025-04-27 02:00:00" \
  -repeat_units="Weeks" \
  -repeat_value="1" \
  -input_file="dbsat_job_params.properties"

# dbsat_job_params.properties:
#   assessment_scope=FULL
#   include_privilege_analysis=true
#   pdb_scope=OPEN
#   report_formats=html,json
#   upload_to_compliance=true
#   alert_on_score_delta=10   # alert if score worsens by ≥10 pts

Drift detection alert rule

SQL — OEM repository (run as SYSMAN)custom drift alert
-- Query the DBSAT results table to find databases where score
-- worsened by more than 5 points since last assessment
SELECT
    t.target_name,
    r.assessment_date,
    r.overall_score,
    r.overall_score - LAG(r.overall_score)
        OVER (PARTITION BY t.target_name ORDER BY r.assessment_date) AS score_delta,
    r.critical_count,
    r.high_count
FROM
    mgmt$dbsat_assessments r
    JOIN mgmt$target t ON t.target_guid = r.target_guid
WHERE
    r.assessment_date >= SYSDATE - 14
    AND (r.overall_score - LAG(r.overall_score)
        OVER (PARTITION BY t.target_name ORDER BY r.assessment_date)) > 5
ORDER BY score_delta DESC;

Remediation playbook

Here are the exact fixes for the most common Critical and High findings DBSAT surfaces.

Switch to Pure Unified Auditing

SQL + BASH — Oracle 19c/21c/23aiAUDIT.0003 fix
-- 1. Check current audit mode
SELECT value FROM v$option WHERE parameter = 'Unified Auditing';
-- If FALSE → mixed mode. If TRUE → pure unified (already good).

-- 2. Stop the instance and relink (mixed → pure unified)
-- On the OS, as oracle user:
BASHrelink for pure unified auditing
cd $ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk uniaud_on ioracle ORACLE_HOME=$ORACLE_HOME

# Restart the instance
sqlplus / as sysdba <<EOF
SHUTDOWN IMMEDIATE;
STARTUP;
SELECT value FROM v\$option WHERE parameter = 'Unified Auditing';
EOF
# Verify output: TRUE

Enable TDE on user tablespaces

SQL — as SYSDBAENC.0007 fix
-- 1. Create or open the wallet
ADMINISTER KEY MANAGEMENT
  SET KEYSTORE OPEN
  IDENTIFIED BY "<wallet_pw>"
  CONTAINER = ALL;

-- 2. Set master encryption key (first time only)
ADMINISTER KEY MANAGEMENT
  SET KEY
  USING TAG 'PROD19C_MEK_2025'
  IDENTIFIED BY "<wallet_pw>"
  WITH BACKUP
  CONTAINER = ALL;

-- 3. Encrypt existing tablespaces (online, no downtime on 12.2+)
ALTER TABLESPACE users     ENCRYPTION ONLINE USING 'AES256' ENCRYPT;
ALTER TABLESPACE app_data  ENCRYPTION ONLINE USING 'AES256' ENCRYPT;
ALTER TABLESPACE sysaux    ENCRYPTION ONLINE USING 'AES256' ENCRYPT;

-- 4. Verify
SELECT tablespace_name, encrypted
FROM   dba_tablespaces
WHERE  encrypted = 'YES';

Revoke dangerous PUBLIC grants

SQL — PRIV.0001 fixtighten PUBLIC
-- Find and revoke dangerous grants on PUBLIC
BEGIN
  FOR r IN (
    SELECT 'REVOKE ' || privilege || ' ON '
           || owner || '.' || table_name
           || ' FROM PUBLIC' AS stmt
    FROM   dba_tab_privs
    WHERE  grantee  = 'PUBLIC'
    AND    owner    = 'SYS'
    AND    privilege IN ('EXECUTE','SELECT')
    AND    table_name IN (
             'UTL_FILE', 'UTL_TCP', 'UTL_HTTP', 'UTL_SMTP',
             'DBMS_ADVISOR', 'DBMS_BACKUP_RESTORE',
             'DBMS_JAVA', 'DBMS_SYS_ERROR')
  ) LOOP
    EXECUTE IMMEDIATE r.stmt;
    DBMS_OUTPUT.PUT_LINE('Revoked: ' || r.stmt);
  END LOOP;
END;
/
 caution
Always test PUBLIC revokes in a lower environment first. Applications that relied on these implicit grants will throw ORA-01031 errors. Build a regression test for each UTL_* package before touching production.

Performance and operational impact

The most common DBA pushback: "Will this affect my production database?" Short answer — minimal if you follow the guidelines.

── DBSAT 3.1 Performance Profile (19c, 500GB, 200 active sessions) ── Phase Duration CPU% Active Sessions Impact ────────────────────────────────────────────────────────────── Collect (no PA) 4m 12s 0.3% None (reads dict only) Collect (with PA) 9m 55s 1.8% Minor (PA session sampling) Report 1m 06s 0.1% None (runs off-DB) ────────────────────────────────────────────────────────────── Recommended window: 02:00–04:00 local | Off-peak batch window

The collector only reads data dictionary views — no DML, no DDL. The most I/O-intensive check is Privilege Analysis, which joins DBA_SYS_PRIVS and SESSION_PRIVS across all grantees. On a busy database, schedule this outside peak hours.


No comments:

Post a Comment

MLOps on OCI: Applying a DBA Mindset to Machine Learning

MLOps is the discipline of treating machine learning systems the way seasoned DBAs treat database pipelines: with version control, monitorin...