Security Transparency

Every Command We Run.
Nothing Hidden.

TuneVault's proxy executes only pre-approved commands on your Oracle server. Here's the complete list. If it's not on this page, we can't run it.

⬇ Download Lockdown Script ⬇ Plaintext Reference ⬇ Audit Verify Script
Read-only — zero writes to your database
No inbound firewall rules needed
No plaintext credentials stored — AES-256 encrypted at rest
Every action logged and auditable

How the Proxy Connects

The proxy runs on your server and talks outbound only. Your Oracle instance never touches the internet.

☁️
TuneVault Cloud
tunevault.app:443
HTTPS outbound
port 443 only
🖥️
Proxy Agent
your server · 127.0.0.1:3100
SQL over TCP
localhost:1521
🗄️
Oracle Database
localhost · never internet-exposed
🔒
No inbound rules
The proxy makes outbound HTTPS calls. Your firewall needs zero inbound rules from TuneVault.
🌐
Oracle stays offline
Oracle only talks to localhost:3100. The database port 1521 is never exposed to the internet.
📡
2 endpoints, that's it
Proxy contacts only tunevault.app:443 — to deliver results and check for updates. No third parties.
🔑
Local API key
A 64-hex API key is generated on your server at install time. TuneVault never holds Oracle credentials.
✅ TuneVault requires
Outbound HTTPS (443) from your server
Oracle service account with SELECT_CATALOG_ROLE
Proxy binary running on the Oracle host
❌ TuneVault does NOT need
Inbound SSH (22) to your server
Inbound DB port (1521) open to internet
SNMP (161) or WMI access
Root or SYSDBA privileges
VPN or tunneling software
00

Required Oracle Grants

Grant these privileges to the TuneVault service account before running health checks.

🔒 Minimum required grants

Run as SYS or SYSTEM. Replace tunevault_user with your service account name.

-- Core catalog access (covers DBA_* views, V$* views)
GRANT SELECT_CATALOG_ROLE TO tunevault_user;
GRANT CREATE SESSION TO tunevault_user;

-- Alert log access (not covered by SELECT_CATALOG_ROLE)
GRANT SELECT ON V_$DIAG_ALERT_EXT TO tunevault_user;
                
No write access needed. TuneVault never executes INSERT, UPDATE, DELETE, or DDL statements. All queries are SELECT-only against system catalog views (DBA_*, V$*, GV$*).
AWR / ADDM checks (optional on-demand panel) require Oracle Enterprise Edition with Diagnostics Pack (control_management_pack_access = DIAGNOSTIC+TUNING). TuneVault checks for this license and skips these queries gracefully on Standard Edition.
01

SQL Queries Executed Against Your Database

All queries are read-only SELECTs run during a health check. Click any row to see the literal SQL.

Instance & Version
Instance information
Identifies Oracle version, host, uptime, CPU count, SGA/PGA targets, and block size
V$DATABASEV$INSTANCEV$PARAMETER
SELECT
  d.NAME, i.INSTANCE_NAME, i.HOST_NAME, i.VERSION,
  d.PLATFORM_NAME,
  TO_CHAR(i.STARTUP_TIME, 'YYYY-MM-DD HH24:MI:SS'),
  ROUND(SYSDATE - i.STARTUP_TIME),
  (SELECT VALUE FROM v$parameter WHERE name = 'cpu_count'),
  ROUND((SELECT TO_NUMBER(VALUE)/1024/1024/1024 FROM v$parameter WHERE name = 'sga_target'), 1),
  ROUND((SELECT TO_NUMBER(VALUE)/1024/1024/1024 FROM v$parameter WHERE name = 'pga_aggregate_target'), 1),
  (SELECT TO_NUMBER(VALUE) FROM v$parameter WHERE name = 'db_block_size')
FROM v$database d, v$instance i
Database version banner
Detects Enterprise vs Standard Edition — gates AWR/ADDM queries
V$VERSION
SELECT BANNER FROM V$VERSION WHERE ROWNUM = 1
Storage
Tablespace usage
Used/total GB and % utilisation per tablespace; flags >80% warning, >90% critical
DBA_TABLESPACE_USAGE_METRICSDBA_TABLESPACESDBA_DATA_FILES
SELECT
  ts.TABLESPACE_NAME,
  ROUND(um.USED_SPACE * ts.BLOCK_SIZE / 1024/1024/1024, 1) AS used_gb,
  ROUND(um.TABLESPACE_SIZE * ts.BLOCK_SIZE / 1024/1024/1024, 1) AS total_gb,
  ROUND(um.USED_PERCENT, 1) AS pct_used,
  CASE WHEN df.autoext > 0 THEN 1 ELSE 0 END AS autoextend
FROM DBA_TABLESPACE_USAGE_METRICS um
JOIN DBA_TABLESPACES ts ON ts.TABLESPACE_NAME = um.TABLESPACE_NAME
LEFT JOIN (
  SELECT TABLESPACE_NAME,
    SUM(CASE WHEN AUTOEXTENSIBLE = 'YES' THEN 1 ELSE 0 END) AS autoext
  FROM DBA_DATA_FILES GROUP BY TABLESPACE_NAME
) df ON df.TABLESPACE_NAME = um.TABLESPACE_NAME
ORDER BY um.USED_PERCENT DESC
Undo tablespace health
Undo retention, block counts, concurrency
V$UNDOSTATDBA_DATA_FILESDBA_TABLESPACES
SELECT UNDOBLKS, TXNCOUNT, MAXQUERYLEN, MAXCONCURRENCY,
       TUNED_UNDORETENTION, EXPIREDBLKS, UNEXPIREDBLKS, ACTIVEBLKS
FROM V$UNDOSTAT WHERE ROWNUM = 1 ORDER BY END_TIME DESC

-- Undo tablespace size
SELECT d.TABLESPACE_NAME, SUM(d.BYTES)/1073741824,
       SUM(d.BYTES - NVL(f.FREE_BYTES,0))/1073741824,
       ROUND(SUM(d.BYTES - NVL(f.FREE_BYTES,0))/SUM(d.BYTES)*100,1), t.RETENTION
FROM DBA_DATA_FILES d JOIN DBA_TABLESPACES t ON t.TABLESPACE_NAME=d.TABLESPACE_NAME
LEFT JOIN (SELECT FILE_ID, SUM(BYTES) AS FREE_BYTES FROM DBA_FREE_SPACE GROUP BY FILE_ID) f
  ON f.FILE_ID=d.FILE_ID
WHERE t.CONTENTS='UNDO' GROUP BY d.TABLESPACE_NAME, t.RETENTION
Temp tablespace usage
Temp space used/free; top sessions by temp usage to identify runaway sorts
DBA_TEMP_FREE_SPACEV$TEMPSEG_USAGE
SELECT TABLESPACE_NAME, ROUND(TABLESPACE_SIZE/1073741824,2),
       ROUND(FREE_SPACE/1073741824,2),
       ROUND((TABLESPACE_SIZE-FREE_SPACE)/NULLIF(TABLESPACE_SIZE,0)*100,1)
FROM DBA_TEMP_FREE_SPACE

-- Top temp-consuming sessions
SELECT s.SID, s.SERIAL#, s.USERNAME,
       ROUND(s.BLOCKS*8192/1048576,1), s.TABLESPACE
FROM V$TEMPSEG_USAGE s ORDER BY s.BLOCKS DESC FETCH FIRST 10 ROWS ONLY
Top segments by size
10 largest tables/indexes by GB to spot unexpected growth
DBA_SEGMENTS
SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE,
       ROUND(SUM(BYTES)/1073741824, 2) AS size_gb
FROM DBA_SEGMENTS
WHERE OWNER NOT IN ('SYS','SYSTEM','DBSNMP','SYSMAN','OUTLN','MDSYS',
  'ORDSYS','XDB','CTXSYS','WMSYS','EXFSYS')
GROUP BY OWNER, SEGMENT_NAME, SEGMENT_TYPE
ORDER BY size_gb DESC FETCH FIRST 10 ROWS ONLY
Datafile status & recycle bin
Offline/problem datafiles; wasted space from dropped-but-not-purged objects
DBA_DATA_FILESDBA_RECYCLEBIN
SELECT COUNT(*) AS problem_count,
       COUNT(CASE WHEN STATUS = 'OFFLINE' THEN 1 END) AS offline_count
FROM DBA_DATA_FILES WHERE STATUS NOT IN ('AVAILABLE','ONLINE')

SELECT COUNT(*) AS object_count,
       ROUND(SUM(SPACE)*8192/1073741824, 2) AS size_gb
FROM DBA_RECYCLEBIN
Memory (SGA / PGA)
SGA components & hit ratios
Buffer cache, library cache, dictionary cache hit ratios; shared pool free %
V$SGAV$SYSSTATV$LIBRARYCACHEV$ROWCACHEV$SGASTAT
SELECT ROUND(SUM(VALUE)/1024/1024/1024, 1) FROM V$SGA

-- Buffer cache hit ratio
SELECT ROUND((1 - (phys.VALUE / (db_gets.VALUE + con_gets.VALUE))) * 100, 1)
FROM (SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'physical reads') phys,
     (SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'db block gets') db_gets,
     (SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'consistent gets') con_gets

-- Library cache hit ratio
SELECT ROUND(SUM(PINS - RELOADS) / NULLIF(SUM(PINS), 0) * 100, 1) FROM V$LIBRARYCACHE

-- Dictionary cache hit ratio
SELECT ROUND(SUM(GETS - GETMISSES) / NULLIF(SUM(GETS), 0) * 100, 1) FROM V$ROWCACHE

-- Shared pool free %
SELECT ROUND(free_bytes.val / total_bytes.val * 100, 1)
FROM (SELECT SUM(BYTES) AS val FROM V$SGASTAT WHERE POOL='shared pool' AND NAME='free memory') free_bytes,
     (SELECT SUM(BYTES) AS val FROM V$SGASTAT WHERE POOL='shared pool') total_bytes
PGA statistics
PGA target vs allocated, over-allocation count, cache hit %, work area execution modes
V$PGASTATV$PARAMETERV$SQL_WORKAREA_HISTOGRAM
SELECT
  ROUND((SELECT TO_NUMBER(VALUE)/1024/1024/1024 FROM v$parameter WHERE name='pga_aggregate_target'),1),
  ROUND((SELECT VALUE/1024/1024/1024 FROM V$PGASTAT WHERE NAME='total PGA allocated'),1),
  ROUND((SELECT VALUE/1024/1024/1024 FROM V$PGASTAT WHERE NAME='maximum PGA allocated'),1),
  (SELECT VALUE FROM V$PGASTAT WHERE NAME='over allocation count'),
  ROUND((SELECT VALUE FROM V$PGASTAT WHERE NAME='cache hit percentage'),1)
FROM DUAL
OS memory & CPU stats (via Oracle)
Physical memory, free memory, CPU count, CPU utilisation, I/O wait — no shell access required
V$OSSTAT
SELECT STAT_NAME, VALUE FROM V$OSSTAT
WHERE STAT_NAME IN (
  'NUM_CPUS','IDLE_TIME','BUSY_TIME','USER_TIME',
  'SYS_TIME','IOWAIT_TIME',
  'PHYSICAL_MEMORY_BYTES','FREE_MEMORY_BYTES'
)
Performance
Top 10 SQL by elapsed time
Most resource-intensive SQL statements; excludes system schemas and internal metadata
V$SQL
SELECT SQL_ID, SUBSTR(SQL_TEXT, 1, 500), EXECUTIONS,
  ROUND(ELAPSED_TIME/1000000, 1), ROUND(CPU_TIME/1000000, 1),
  BUFFER_GETS, DISK_READS, ROWS_PROCESSED,
  CASE WHEN EXECUTIONS > 0 THEN ROUND(ELAPSED_TIME/EXECUTIONS/1000, 2) ELSE 0 END,
  CASE WHEN EXECUTIONS > 0 THEN ROUND(BUFFER_GETS/EXECUTIONS) ELSE 0 END,
  PLAN_HASH_VALUE
FROM V$SQL
WHERE EXECUTIONS > 0 AND ELAPSED_TIME > 0
  AND PARSING_SCHEMA_NAME NOT IN ('SYS','SYSTEM','DBSNMP','SYSMAN','OUTLN',
    'MDSYS','ORDSYS','EXFSYS','WMSYS','APPQOSSYS','DBSFWUSER')
  AND SQL_TEXT NOT LIKE '%v$%' AND SQL_TEXT NOT LIKE '%V$%'
  AND COMMAND_TYPE IN (2, 3, 6, 7, 189)
ORDER BY ELAPSED_TIME DESC FETCH FIRST 10 ROWS ONLY
Top 15 wait events
Leading wait events (excluding idle) consuming database time
V$SYSTEM_EVENT
SELECT EVENT, WAIT_CLASS, TOTAL_WAITS,
  ROUND(TIME_WAITED/100, 1) AS time_waited_s,
  CASE WHEN TOTAL_WAITS > 0
    THEN ROUND((TIME_WAITED/100/TOTAL_WAITS)*1000, 2) ELSE 0 END AS avg_wait_ms
FROM V$SYSTEM_EVENT
WHERE WAIT_CLASS NOT IN ('Idle') AND TOTAL_WAITS > 0
ORDER BY TIME_WAITED DESC FETCH FIRST 15 ROWS ONLY
Index health (top 20 fragmented)
Indexes with high B-tree depth (>3) or low direct access % — rebuild candidates
DBA_INDEXESDBA_IND_STATISTICSV$PARAMETER
SELECT i.OWNER, i.INDEX_NAME, i.TABLE_NAME,
  ROUND(s.LEAF_BLOCKS *
    (SELECT TO_NUMBER(VALUE) FROM v$parameter WHERE name='db_block_size')
    / 1024/1024) AS size_mb,
  i.BLEVEL, s.LEAF_BLOCKS, i.CLUSTERING_FACTOR,
  NVL(s.PCT_DIRECT_ACCESS,100), i.STATUS,
  CASE
    WHEN i.STATUS != 'VALID' THEN 'unusable'
    WHEN i.BLEVEL > 4 THEN 'critical'
    WHEN NVL(s.PCT_DIRECT_ACCESS,100) < 50 THEN 'critical'
    WHEN i.BLEVEL > 3 THEN 'fragmented'
    WHEN NVL(s.PCT_DIRECT_ACCESS,100) < 70 THEN 'fragmented'
    ELSE 'ok'
  END AS health_status
FROM DBA_INDEXES i
LEFT JOIN DBA_IND_STATISTICS s
  ON s.OWNER=i.OWNER AND s.INDEX_NAME=i.INDEX_NAME AND s.PARTITION_NAME IS NULL
WHERE i.OWNER NOT IN ('SYS','SYSTEM','DBSNMP','SYSMAN','OUTLN','MDSYS','ORDSYS',
  'EXFSYS','WMSYS','XDB','CTXSYS','APPQOSSYS','DBSFWUSER',
  'APEX_040000','APEX_040200','APEX_050000','FLOWS_FILES')
  AND i.INDEX_TYPE = 'NORMAL' AND NVL(s.LEAF_BLOCKS, 0) > 100
ORDER BY CASE WHEN i.STATUS != 'VALID' THEN 1 WHEN i.BLEVEL > 4 THEN 2
              WHEN i.BLEVEL > 3 THEN 3 ELSE 4 END,
         s.LEAF_BLOCKS DESC NULLS LAST
FETCH FIRST 20 ROWS ONLY
Resource limits & sessions
Session/process counts, blocked sessions, long-running SQL, resource utilisation vs. configured limits
V$RESOURCE_LIMITV$SESSION
-- Resource limits
SELECT RESOURCE_NAME, CURRENT_UTILIZATION, MAX_UTILIZATION, INITIAL_ALLOCATION, LIMIT_VALUE
FROM V$RESOURCE_LIMIT
WHERE RESOURCE_NAME IN (
  'sessions','processes','enqueue_locks','enqueue_resources',
  'dml_locks','temporary_table_locks','transactions','max_rollback_segments'
)

-- Session counts
SELECT COUNT(*), COUNT(CASE WHEN STATUS='ACTIVE' AND TYPE='USER' THEN 1 END),
       COUNT(CASE WHEN TYPE='USER' THEN 1 END) FROM V$SESSION

-- Blocked sessions
SELECT COUNT(*) FROM V$SESSION WHERE BLOCKING_SESSION IS NOT NULL AND STATUS='ACTIVE'

-- Long-running SQL
SELECT COUNT(*), ROUND(MAX((SYSDATE - SQL_EXEC_START)*1440), 1)
FROM V$SESSION WHERE STATUS='ACTIVE' AND TYPE='USER'
  AND SQL_EXEC_START IS NOT NULL AND (SYSDATE - SQL_EXEC_START)*1440 > 5
Disk sort & full table scan ratios
Disk vs in-memory sort ratio; full table scan vs index lookup ratio
V$SYSSTAT
SELECT d.VALUE AS disk_sorts, m.VALUE AS mem_sorts
FROM (SELECT VALUE FROM V$SYSSTAT WHERE NAME='sorts (disk)') d,
     (SELECT VALUE FROM V$SYSSTAT WHERE NAME='sorts (memory)') m

SELECT s.VALUE AS long_scans, i.VALUE AS index_lookups
FROM (SELECT VALUE FROM V$SYSSTAT WHERE NAME='table scans (long tables)') s,
     (SELECT VALUE FROM V$SYSSTAT WHERE NAME='table fetch by rowid') i
Invalid objects, stale statistics, SCN headroom
Invalid PL/SQL objects, stale optimizer stats, and days until SCN exhaustion
DBA_OBJECTSDBA_TAB_STATISTICSV$DATABASE
SELECT COUNT(*),
  COUNT(CASE WHEN OBJECT_TYPE IN ('PACKAGE BODY','PACKAGE') THEN 1 END),
  COUNT(CASE WHEN OBJECT_TYPE='PROCEDURE' THEN 1 END),
  COUNT(CASE WHEN OBJECT_TYPE='VIEW' THEN 1 END),
  COUNT(CASE WHEN OBJECT_TYPE='TRIGGER' THEN 1 END)
FROM DBA_OBJECTS WHERE STATUS='INVALID'
  AND OWNER NOT IN ('SYS','SYSTEM','DBSNMP','SYSMAN','OUTLN','MDSYS','ORDSYS',
    'XDB','CTXSYS','WMSYS','EXFSYS','APPQOSSYS','DBSFWUSER','OJVMSYS','DVSYS','LBACSYS')

SELECT COUNT(*), COUNT(CASE WHEN LAST_ANALYZED IS NULL THEN 1 END)
FROM DBA_TAB_STATISTICS WHERE STALE_STATS='YES'
  AND OWNER NOT IN ('SYS','SYSTEM','DBSNMP','SYSMAN','OUTLN','MDSYS','ORDSYS','XDB','CTXSYS','WMSYS','EXFSYS')

-- SCN headroom
SELECT CURRENT_SCN,
  ROUND((TO_NUMBER(SYSDATE-TO_DATE('01-01-1988','DD-MM-YYYY'))*24*3600*16384*1024-CURRENT_SCN)/(24*3600*16384),0)
FROM V$DATABASE
Alert log errors (last 24h)
ORA- errors, checkpoints, corruption warnings, TNS errors from the in-memory alert log view
V$DIAG_ALERT_EXT
SELECT TO_CHAR(ORIGINATING_TIMESTAMP,'YYYY-MM-DD HH24:MI:SS'), MESSAGE_TEXT
FROM V$DIAG_ALERT_EXT
WHERE ORIGINATING_TIMESTAMP > SYSDATE-1
  AND (MESSAGE_TEXT LIKE 'ORA-%' OR MESSAGE_TEXT LIKE '%checkpoint%'
       OR MESSAGE_TEXT LIKE '%corruption%' OR MESSAGE_TEXT LIKE '%recovery%'
       OR MESSAGE_TEXT LIKE '%error%' OR MESSAGE_TEXT LIKE '%warning%'
       OR MESSAGE_TEXT LIKE '%TNS-%' OR MESSAGE_TEXT LIKE '%instance%'
       OR MESSAGE_TEXT LIKE 'Thread%')
ORDER BY ORIGINATING_TIMESTAMP DESC FETCH FIRST 200 ROWS ONLY
-- Note: requires GRANT SELECT ON V_$DIAG_ALERT_EXT (not in SELECT_CATALOG_ROLE)
Backup & Recovery
RMAN backup freshness
Last full/incremental/archivelog backup time and size; flags >48h since last full as critical
V$RMAN_BACKUP_JOB_DETAILS
SELECT INPUT_TYPE, STATUS,
  TO_CHAR(START_TIME,'YYYY-MM-DD HH24:MI:SS'),
  TO_CHAR(END_TIME,'YYYY-MM-DD HH24:MI:SS'),
  ROUND((SYSDATE - END_TIME)*24, 1) AS hours_ago,
  ROUND(OUTPUT_BYTES/1073741824, 2) AS size_gb, ELAPSED_SECONDS
FROM (
  SELECT INPUT_TYPE, STATUS, START_TIME, END_TIME, OUTPUT_BYTES, ELAPSED_SECONDS,
         ROW_NUMBER() OVER (PARTITION BY INPUT_TYPE ORDER BY END_TIME DESC) AS RN
  FROM V$RMAN_BACKUP_JOB_DETAILS WHERE STATUS='COMPLETED'
) WHERE RN=1
Fast Recovery Area (FRA) usage
FRA size, used/reclaimable space, and breakdown by file type
V$RECOVERY_FILE_DESTV$FLASH_RECOVERY_AREA_USAGEV$ARCHIVED_LOG
SELECT NAME, ROUND(SPACE_LIMIT/1073741824,2), ROUND(SPACE_USED/1073741824,2),
  ROUND(SPACE_RECLAIMABLE/1073741824,2), NUMBER_OF_FILES
FROM V$RECOVERY_FILE_DEST

SELECT FILE_TYPE, ROUND(PERCENT_SPACE_USED,1),
       ROUND(PERCENT_SPACE_RECLAIMABLE,1), NUMBER_OF_FILES
FROM V$FLASH_RECOVERY_AREA_USAGE ORDER BY PERCENT_SPACE_USED DESC

SELECT ROUND(SUM(BLOCKS * BLOCK_SIZE)/1073741824, 2)
FROM V$ARCHIVED_LOG WHERE COMPLETION_TIME > SYSDATE-1 AND STANDBY_DEST='NO'
Archivelog mode & log switch rate
Confirms ARCHIVELOG mode; measures log switch frequency (alert if >20/hour)
V$DATABASEV$INSTANCEV$ARCHIVED_LOGV$LOG_HISTORY
SELECT LOG_MODE, ROUND((SYSDATE - STARTUP_TIME)*24) FROM V$DATABASE, V$INSTANCE

SELECT TO_CHAR(COMPLETION_TIME,'YYYY-MM-DD HH24'), COUNT(*),
       ROUND(SUM(BLOCKS*BLOCK_SIZE)/1048576, 1)
FROM V$ARCHIVED_LOG WHERE COMPLETION_TIME > SYSDATE-1 AND STANDBY_DEST='NO'
GROUP BY TO_CHAR(COMPLETION_TIME,'YYYY-MM-DD HH24') ORDER BY 1 DESC

SELECT ROUND(COUNT(*)/24.0, 1), COUNT(*) FROM V$LOG_HISTORY WHERE FIRST_TIME > SYSDATE-1
Backup corruption check
Corruption markers in RMAN backup sets and image copies
V$BACKUP_CORRUPTIONV$COPY_CORRUPTION
SELECT COUNT(*), SUM(BLOCKS) FROM V$BACKUP_CORRUPTION
SELECT COUNT(*), SUM(BLOCKS) FROM V$COPY_CORRUPTION
Security
Default-password accounts
OPEN accounts using well-known default passwords (Oracle's advisory view)
DBA_USERS_WITH_DEFPWD
SELECT COUNT(*) FROM DBA_USERS_WITH_DEFPWD WHERE ACCOUNT_STATUS = 'OPEN'
Dangerous PUBLIC grants & DBA users
PUBLIC privilege escalation risk; non-system accounts with DBA privilege
DBA_SYS_PRIVS
-- Dangerous PUBLIC grants
SELECT COUNT(*) FROM DBA_SYS_PRIVS WHERE GRANTEE = 'PUBLIC'
  AND PRIVILEGE IN ('CREATE PROCEDURE','CREATE ANY PROCEDURE',
    'CREATE ANY TRIGGER','ALTER SYSTEM','ALTER DATABASE',
    'DROP ANY TABLE','EXECUTE ANY PROCEDURE')

-- DBA-privileged user count
SELECT COUNT(DISTINCT GRANTEE) FROM DBA_SYS_PRIVS
WHERE PRIVILEGE='DBA' AND GRANTEE NOT IN ('SYS','SYSTEM','DBA','SYSMAN')
Password policy & audit settings
Password complexity function and audit trail configuration
DBA_PROFILESV$PARAMETERDBA_USERS
SELECT LIMIT FROM DBA_PROFILES WHERE PROFILE='DEFAULT' AND RESOURCE_NAME='PASSWORD_VERIFY_FUNCTION'
SELECT VALUE FROM V$PARAMETER WHERE NAME='audit_trail'

-- Schema-only (no-auth) open accounts
SELECT COUNT(*) FROM DBA_USERS
WHERE ACCOUNT_STATUS='OPEN' AND AUTHENTICATION_TYPE='NONE'
  AND USERNAME NOT IN ('SYS','SYSTEM')
Oracle Applications (EBS) — executes only when EBS detected
Conditional. TuneVault probes APPS.DUAL at connection time to detect EBS. These queries only run if the probe succeeds. On non-EBS Oracle databases, this entire section is skipped. The EBS detection result is passed to the AI Summary only.
EBS detection probe
Single-row probe to check if APPS schema exists; gates all EBS-specific checks
APPS.DUALEBS only
SELECT 1 FROM APPS.DUAL WHERE ROWNUM = 1
-- If this query fails (ORA-00942), EBS is not present. All APPS.* queries are skipped.
Concurrent Manager health
Running vs max processes for each Concurrent Manager queue
APPS.FND_CONCURRENT_QUEUESAPPS.FND_CONCURRENT_QUEUES_VLEBS only
SELECT b.user_concurrent_queue_name, b.node_name,
       a.running_processes, a.max_processes
FROM apps.fnd_concurrent_queues a, apps.fnd_concurrent_queues_vl b
WHERE a.concurrent_queue_id = b.concurrent_queue_id
Pending request count & WF components
Queued/running concurrent requests; Workflow service component statuses
APPS.FND_CONCURRENT_REQUESTSAPPS.FND_SVC_COMPONENTSEBS only
SELECT phase_code, COUNT(*) FROM APPS.FND_CONCURRENT_REQUESTS
WHERE phase_code IN ('P','R') GROUP BY phase_code

SELECT component_type, component_name, component_status, startup_mode
FROM apps.fnd_svc_components WHERE component_type LIKE 'WF%' ORDER BY 1, 2
Workflow notification & error queues
Stuck notifications (open >1 hour); WF error queue depth
APPS.WF_NOTIFICATIONSAPPS.WF_ERROREBS only
SELECT COUNT(*) FROM APPS.WF_NOTIFICATIONS
WHERE STATUS='OPEN' AND MAIL_STATUS='MAIL' AND BEGIN_DATE < SYSDATE - 1/24

SELECT COUNT(*) FROM APPS.WF_ERROR
ADDM (on-demand panel — Enterprise Edition + Diagnostics Pack only)
License gate. TuneVault checks V$VERSION for 'ENTERPRISE' and DBA_FEATURE_USAGE_STATISTICS for Diagnostics Pack before running any AWR/ADDM queries. Skipped silently on Standard Edition.
ADDM findings (AWR-backed)
Automatic Database Diagnostic Monitor findings for a configurable lookback window
DBA_HIST_SNAPSHOTDBA_HIST_ADDM_TASKSDBA_ADVISOR_FINDINGSDBA_ADVISOR_RECOMMENDATIONS
SELECT MIN(SNAP_ID), MAX(SNAP_ID), MIN(BEGIN_INTERVAL_TIME), MAX(END_INTERVAL_TIME)
FROM DBA_HIST_SNAPSHOT WHERE END_INTERVAL_TIME > SYSDATE - :lookback_hours/24

SELECT TASK_ID, TASK_NAME FROM DBA_HIST_ADDM_TASKS
WHERE BEGIN_SNAP_ID = :begin_snap AND END_SNAP_ID = :end_snap
  AND STATUS = 'COMPLETED' FETCH FIRST 1 ROWS ONLY

SELECT f.FINDING_ID, f.TYPE, f.MESSAGE, f.BENEFIT,
       d.ATTR1 AS recommendation, d.TYPE AS rec_type
FROM DBA_ADVISOR_FINDINGS f
LEFT JOIN DBA_ADVISOR_RECOMMENDATIONS d ON d.TASK_ID=f.TASK_ID AND d.FINDING_ID=f.FINDING_ID
WHERE f.TASK_ID = :task_id ORDER BY f.BENEFIT DESC NULLS LAST FETCH FIRST 20 ROWS ONLY
02

Shell Commands

The complete whitelist of OS commands the proxy may execute on your server. All are read-only status checks. No commands modify files, change configuration, or write to disk.

Core health checks use zero shell commands. CPU, memory, and I/O wait metrics are read from V$OSSTAT via Oracle SQL. Shell commands only run on EBS 12.2.x environments to check application-tier service status — and only the exact commands below are permitted.
Core Health Checks (200+ checks)
Command Purpose Condition Writes?
— none — All core OS metrics (CPU, memory, I/O wait) are read via V$OSSTAT through the Oracle connection. No shell commands required for any of the 200+ core health checks. always NO
EBS 12.2.x Application-Tier Commands — conditional (complete whitelist)

All commands use $ADMIN_SCRIPTS_HOME — no hardcoded paths. Only status subcommands are whitelisted. admanagedsrvctl.sh is the unified controller for all managed servers in EBS 12.2.x.

Command Purpose Condition Writes?
adcmctl.sh status Concurrent Manager status. Reports running/max processes per queue. EBS detected NO
adalnctl.sh status APPS TNS Listener status. Checks if the application-tier listener is running. EBS detected NO
admanagedsrvctl.sh status oacore_server1 OACore managed server status. Hosts Oracle Applications Framework pages. EBS detected NO
admanagedsrvctl.sh status forms_server1 Forms managed server status. Required for EBS forms-based modules. EBS detected NO
admanagedsrvctl.sh status oafm_server1 OA Framework managed server status. Hosts OAF-based Oracle Applications pages. EBS detected NO
admanagedsrvctl.sh status wfmlrsvc Workflow Mailer managed service status. Reports if outbound workflow notifications are processing. EBS detected NO
admanagedsrvctl.sh status opp Output Post Processor status. Handles PDF/EXCEL output for concurrent requests. EBS detected NO
adadminsrvctl.sh status Admin Server status. The WLS administration server managing all managed servers. EBS detected NO
adnodemgrctl.sh status Node Manager status. Controls WebLogic managed server lifecycle on this node. EBS detected NO
adopmnctl.sh status OPMN status. Oracle Process Manager and Notification Server for OHS/Apache. EBS detected NO
mwactl.sh status Middleware Agent status. Monitors and reports on WLS middleware component health. EBS detected NO
adapcctl.sh status Apache/OHS status. Reports if the Oracle HTTP Server is running and accepting requests. EBS detected NO
Hard whitelist enforcement. The proxy validates the exact script filename and argument list against a compiled whitelist before execution. Any command not in this table — including start/stop/restart variants — is rejected with a 403. Scripts are resolved via $ADMIN_SCRIPTS_HOME at runtime; the path itself is never accepted from the caller. Execution is logged with timestamp, requester IP, exit code, and a SHA-256 hash of the output.
03

What TuneVault Never Does

Explicit guarantees. These are enforced in the proxy binary — not policy statements.

Never modifies your data
Zero INSERT, UPDATE, DELETE, or MERGE statements. All SQL is SELECT-only against system catalog views.
Never executes DDL
No CREATE, ALTER, DROP, or TRUNCATE. Can't create objects, can't destroy them.
Never runs as SYS or SYSDBA
Only the service account you create is used. SYSDBA privilege is not needed and not requested.
Never changes passwords
No ALTER USER statements. No password reads beyond what Oracle reports via DBA_USERS_WITH_DEFPWD (which stores no plaintext).
Never stores Oracle credentials
Credentials live only in the proxy's local environment on your server. TuneVault never transmits or stores them.
Never opens inbound ports
The proxy binds to 127.0.0.1:3100 only. No external inbound ports. No VPN. No SSH tunnel.
Never sends data to third parties
Metrics go only to tunevault.app. No analytics SDKs, no third-party telemetry, no external tracking.
Never reads user data rows
All queries target system catalog views (DBA_*, V$*, GV$*). No SELECT against application tables.
04

Customer Lockdown Script

Run this before installing the proxy. It creates a restricted OS user, sets filesystem permissions, and configures sudoers with a command whitelist.

🔐
tunevault-lockdown.sh
Creates a hardened environment for the TuneVault proxy on your Oracle server. Principle of least privilege throughout — the proxy user can only do exactly what's needed.
  1. Creates restricted OS user tunevault with no login shell
  2. Sets tunevault as owner of the proxy install directory
  3. Configures sudoers with explicit command whitelist (NOPASSWD for allowed commands only)
  4. Prints a verification summary — inspect before running proxy

Full script — read every line before running:

tunevault-lockdown.sh
⬇ Download
#!/bin/bash
# tunevault-lockdown.sh
# ==================================================
# Run this on your Oracle server BEFORE installing
# the TuneVault proxy. It creates a restricted OS
# user and configures minimal sudo privileges.
#
# Usage:
#   chmod +x tunevault-lockdown.sh
#   sudo ./tunevault-lockdown.sh [--install-dir /opt/tunevault]
#
# Requirements: bash, sudo, useradd/adduser
# Tested on: Oracle Linux 7/8/9, RHEL 7/8/9, Ubuntu 20/22
# ==================================================

set -euo pipefail

INSTALL_DIR=${1:-/opt/tunevault}
PROXY_USER=tunevault
PROXY_GROUP=tunevault
LOG_FILE=/var/log/tunevault-lockdown.log

# Must run as root
if [ "$(id -u)" != "0" ]; then
  echo "ERROR: Must run as root (sudo ./tunevault-lockdown.sh)"
  exit 1
fi

echo "========================================"
echo " TuneVault Lockdown Script"
echo " $(date)"
echo " Install dir: $INSTALL_DIR"
echo "========================================"
echo ""

# --- Create restricted group and user ---
if ! getent group "$PROXY_GROUP" &>/dev/null; then
  echo "[1/4] Creating group: $PROXY_GROUP"
  groupadd --system "$PROXY_GROUP"
else
  echo "[1/4] Group $PROXY_GROUP already exists — skipping"
fi

if ! id "$PROXY_USER" &>/dev/null; then
  echo "[2/4] Creating user: $PROXY_USER (no login shell, system account)"
  useradd \
    --system \
    --gid "$PROXY_GROUP" \
    --shell /sbin/nologin \
    --no-create-home \
    --comment "TuneVault proxy service account" \
    "$PROXY_USER"
else
  echo "[2/4] User $PROXY_USER already exists — skipping"
fi

# --- Create and lock down install directory ---
echo "[3/4] Setting up install directory: $INSTALL_DIR"
mkdir -p "$INSTALL_DIR"
chown "$PROXY_USER:$PROXY_GROUP" "$INSTALL_DIR"
chmod 750 "$INSTALL_DIR"

# Log directory (writable by proxy user only)
mkdir -p "$INSTALL_DIR/logs"
chown "$PROXY_USER:$PROXY_GROUP" "$INSTALL_DIR/logs"
chmod 700 "$INSTALL_DIR/logs"

# --- Configure sudoers whitelist ---
echo "[4/4] Writing sudoers whitelist..."
SUDOERS_FILE=/etc/sudoers.d/tunevault

# Remove existing file if present
[ -f "$SUDOERS_FILE" ] && rm -f "$SUDOERS_FILE"

cat > "$SUDOERS_FILE" << 'SUDOERS_EOF'
# TuneVault proxy — minimal sudo whitelist (EBS 12.2.x application tier)
# Generated by tunevault-lockdown.sh
# DO NOT edit manually — re-run lockdown.sh to update
#
# All paths use $ADMIN_SCRIPTS_HOME set in the oracle user environment.
# Only "status" subcommands are listed — start/stop/restart are NOT granted.

Defaults:tunevault env_keep += "ADMIN_SCRIPTS_HOME"

# Non-managed services
Cmnd_Alias TUNEVAULT_NON_MANAGED = \
  $ADMIN_SCRIPTS_HOME/adcmctl.sh status, \
  $ADMIN_SCRIPTS_HOME/adalnctl.sh status, \
  $ADMIN_SCRIPTS_HOME/adadminsrvctl.sh status, \
  $ADMIN_SCRIPTS_HOME/adnodemgrctl.sh status, \
  $ADMIN_SCRIPTS_HOME/adopmnctl.sh status, \
  $ADMIN_SCRIPTS_HOME/mwactl.sh status, \
  $ADMIN_SCRIPTS_HOME/adapcctl.sh status

# Managed servers (unified admanagedsrvctl.sh controller)
Cmnd_Alias TUNEVAULT_MANAGED = \
  $ADMIN_SCRIPTS_HOME/admanagedsrvctl.sh status oacore_server1, \
  $ADMIN_SCRIPTS_HOME/admanagedsrvctl.sh status forms_server1, \
  $ADMIN_SCRIPTS_HOME/admanagedsrvctl.sh status oafm_server1, \
  $ADMIN_SCRIPTS_HOME/admanagedsrvctl.sh status wfmlrsvc, \
  $ADMIN_SCRIPTS_HOME/admanagedsrvctl.sh status opp

tunevault ALL=(oracle) NOPASSWD: TUNEVAULT_NON_MANAGED, TUNEVAULT_MANAGED

# No other commands are permitted
SUDOERS_EOF

# Validate sudoers file syntax
if command -v visudo &>/dev/null; then
  if visudo -c -f "$SUDOERS_FILE" &>/dev/null; then
    echo "    sudoers syntax OK: $SUDOERS_FILE"
  else
    echo "ERROR: sudoers validation failed — removing $SUDOERS_FILE"
    rm -f "$SUDOERS_FILE"
    exit 1
  fi
fi
chmod 440 "$SUDOERS_FILE"

# --- Print verification summary ---
echo ""
echo "========================================"
echo " Lockdown complete. Verify before use:"
echo "========================================"
echo ""
echo "OS user:"
id tunevault 2>/dev/null || echo "  ERROR: user not found"
echo ""
echo "Install directory:"
ls -la "$INSTALL_DIR" 2>/dev/null | head -5
echo ""
echo "Sudoers whitelist:"
cat "$SUDOERS_FILE" 2>/dev/null
echo ""
echo "Shell (should be /sbin/nologin or /bin/false):"
getent passwd tunevault | cut -d: -f7
echo ""
echo "========================================"
echo " Next: install the proxy as user 'tunevault'"
echo " See: https://tunevault.app/docs/oracle-setup"
echo "========================================"
05

Audit & Logging

Every action TuneVault takes on your infrastructure is recorded. Your security team can audit the complete history at any time.

📋
TuneVault Dashboard
Every health check run appears in your dashboard with timestamp, duration, score, and a complete record of which checks were executed. Filterable by date range and connection.
🖥️
Local Proxy Logs
The proxy writes structured JSON logs to /opt/tunevault/logs/. Each entry records: timestamp, command or query type, execution duration, success/failure, and a result hash (not the data itself).
🔎
Verification Script
Download lockdown-verify.sh to capture a live 30-second syscall trace of the proxy using strace or auditd. See every file open, network connection, and process execution in real time.
🔒
Immutable Log Format
Proxy logs are append-only. The log file is owned by tunevault:tunevault and not writable by other accounts. Hash chaining detects any post-hoc modification.
Questions from your security team? We're happy to do a live walkthrough — screen share, walk through the proxy source, answer specific concerns. Email security@tunevault.app to schedule.
06

Network Egress from the Proxy

Exactly two outbound HTTPS connections. No inbound ports. No third parties.

Destination
tunevault.app (US region) — port 443 / HTTPS / TLS 1.2+
Purpose
Delivers health check results to your TuneVault account. JSON payload of Oracle metrics collected during the run.
Authentication
64-hex API key in X-API-Key header — generated locally on your server at install time. TuneVault never holds Oracle credentials.
Data sent
Oracle metrics (tablespace usage, wait events, SQL stats). NOT sent: Oracle credentials, schema objects, user data rows.
Destination
tunevault.app/api/proxy/version (same host)
Purpose
Auto-update check every 6 hours. Downloads new binary, validates SHA-256 checksum, replaces in-place. No restart of PM2/systemd required.
Data sent
Current proxy version string only. No credentials, no metrics.
No tunnel software. No inbound connections. The proxy uses standard outbound HTTPS. Your firewall only needs to allow outbound 443 from the Oracle server to tunevault.app. No inbound rules, no VPN, no NAT punching.