[Developer] #567 record actual VPD execution with FGA
This commit is contained in:
@@ -19,7 +19,10 @@ SET FEEDBACK ON
|
||||
|
||||
PROMPT === Creating CB_ORDS handler package ===
|
||||
CREATE OR REPLACE PACKAGE cb_ords_handler_pkg AUTHID DEFINER AS
|
||||
PROCEDURE set_vpd_context(p_authorization IN VARCHAR2);
|
||||
PROCEDURE set_vpd_context(
|
||||
p_authorization IN VARCHAR2,
|
||||
p_probe_id IN VARCHAR2 DEFAULT NULL
|
||||
);
|
||||
FUNCTION set_vpd_context_sql(p_authorization IN VARCHAR2) RETURN NUMBER;
|
||||
PROCEDURE clear_vpd_context;
|
||||
END;
|
||||
@@ -38,12 +41,19 @@ CREATE OR REPLACE PACKAGE BODY cb_ords_handler_pkg AS
|
||||
RETURN TRIM(SUBSTR(v_auth, 8));
|
||||
END;
|
||||
|
||||
PROCEDURE set_vpd_context(p_authorization IN VARCHAR2) AS
|
||||
PROCEDURE set_vpd_context(
|
||||
p_authorization IN VARCHAR2,
|
||||
p_probe_id IN VARCHAR2 DEFAULT NULL
|
||||
) AS
|
||||
v_bearer_key VARCHAR2(4000);
|
||||
BEGIN
|
||||
DBMS_SESSION.CLEAR_IDENTIFIER;
|
||||
admin.cb_agent_ctx_pkg.clear_user;
|
||||
v_bearer_key := extract_bearer_key(p_authorization);
|
||||
admin.cb_agent_ctx_pkg.set_user_by_bearer(v_bearer_key);
|
||||
IF TRIM(p_probe_id) IS NOT NULL THEN
|
||||
DBMS_SESSION.SET_IDENTIFIER(SUBSTR(TRIM(p_probe_id), 1, 64));
|
||||
END IF;
|
||||
END;
|
||||
|
||||
FUNCTION set_vpd_context_sql(p_authorization IN VARCHAR2) RETURN NUMBER AS
|
||||
@@ -55,6 +65,7 @@ CREATE OR REPLACE PACKAGE BODY cb_ords_handler_pkg AS
|
||||
PROCEDURE clear_vpd_context AS
|
||||
BEGIN
|
||||
admin.cb_agent_ctx_pkg.clear_user;
|
||||
DBMS_SESSION.CLEAR_IDENTIFIER;
|
||||
END;
|
||||
END;
|
||||
/
|
||||
@@ -93,7 +104,7 @@ DECLARE
|
||||
v_vpd_predicate VARCHAR2(32767);
|
||||
v_effective_sql VARCHAR2(32767);
|
||||
BEGIN
|
||||
cb_ords_handler_pkg.set_vpd_context(:auth_header);
|
||||
cb_ords_handler_pkg.set_vpd_context(:auth_header, :probe_id);
|
||||
|
||||
-- The predicate below is the value returned by the same DBMS_RLS policy
|
||||
-- function that protects ADMIN.CB_V_SEARCH_DOCUMENTS.
|
||||
@@ -156,6 +167,16 @@ END;
|
||||
p_param_type => 'STRING',
|
||||
p_access_method => 'IN'
|
||||
);
|
||||
ORDS.DEFINE_PARAMETER(
|
||||
p_module_name => 'cb.agent.security',
|
||||
p_pattern => 'vpd/documents',
|
||||
p_method => 'POST',
|
||||
p_name => 'X-VPD-Probe-Id',
|
||||
p_bind_variable_name => 'probe_id',
|
||||
p_source_type => 'HEADER',
|
||||
p_param_type => 'STRING',
|
||||
p_access_method => 'IN'
|
||||
);
|
||||
ORDS.DEFINE_PARAMETER(
|
||||
p_module_name => 'cb.agent.security',
|
||||
p_pattern => 'vpd/documents',
|
||||
|
||||
@@ -53,7 +53,7 @@ DECLARE
|
||||
v_vpd_predicate VARCHAR2(32767);
|
||||
v_effective_sql VARCHAR2(32767);
|
||||
BEGIN
|
||||
cb_ords_handler_pkg.set_vpd_context(:auth_header);
|
||||
cb_ords_handler_pkg.set_vpd_context(:auth_header, :probe_id);
|
||||
|
||||
BEGIN
|
||||
v_vpd_predicate := admin.cb_agent_doc_vpd_filter('ADMIN', 'CB_VECTOR_SEARCH_DOCUMENTS');
|
||||
@@ -163,6 +163,17 @@ END;
|
||||
p_access_method => 'IN'
|
||||
);
|
||||
|
||||
ORDS.DEFINE_PARAMETER(
|
||||
p_module_name => 'cb.agent.vector',
|
||||
p_pattern => 'search',
|
||||
p_method => 'POST',
|
||||
p_name => 'X-VPD-Probe-Id',
|
||||
p_bind_variable_name => 'probe_id',
|
||||
p_source_type => 'HEADER',
|
||||
p_param_type => 'STRING',
|
||||
p_access_method => 'IN'
|
||||
);
|
||||
|
||||
ORDS.DEFINE_PARAMETER(
|
||||
p_module_name => 'cb.agent.vector',
|
||||
p_pattern => 'search',
|
||||
|
||||
70
sql/adb/42_agent_ords_fga_execution_audit.sql
Normal file
70
sql/adb/42_agent_ords_fga_execution_audit.sql
Normal file
@@ -0,0 +1,70 @@
|
||||
-- ============================================================
|
||||
-- 42_agent_ords_fga_execution_audit.sql
|
||||
-- Durable, request-correlated execution evidence for VPD probes.
|
||||
--
|
||||
-- Run as the protected-object owner (ADMIN in this PoC), after the
|
||||
-- VPD policies and CB_PROTECTED_OBJECT entries have been applied.
|
||||
--
|
||||
-- Each enabled protected object gets an FGA SELECT policy. Autonomous Oracle
|
||||
-- writes SQL_TEXT and RLS_INFO to UNIFIED_AUDIT_TRAIL (traditional databases
|
||||
-- can expose the same information through DBA_FGA_AUDIT_TRAIL). The ORDS handler puts the
|
||||
-- backoffice-generated X-VPD-Probe-Id into CLIENT_ID, so the UI can read
|
||||
-- exactly this request's audit row rather than guess from V$SQL.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET ECHO ON
|
||||
SET FEEDBACK ON
|
||||
|
||||
PROMPT === Applying FGA execution-audit policies ===
|
||||
DECLARE
|
||||
v_policy_name VARCHAR2(128);
|
||||
BEGIN
|
||||
FOR r IN (
|
||||
SELECT object_id, owner, object_name
|
||||
FROM cb_protected_object
|
||||
WHERE enabled_yn = 'Y'
|
||||
ORDER BY object_id
|
||||
) LOOP
|
||||
IF UPPER(r.owner) <> USER THEN
|
||||
RAISE_APPLICATION_ERROR(
|
||||
-20842,
|
||||
'Run this script as protected object owner ' || r.owner
|
||||
|| ' (current user: ' || USER || ')'
|
||||
);
|
||||
END IF;
|
||||
|
||||
v_policy_name := 'CB_VPD_EXEC_AUDIT_' || r.object_id;
|
||||
BEGIN
|
||||
DBMS_FGA.DROP_POLICY(
|
||||
object_schema => r.owner,
|
||||
object_name => r.object_name,
|
||||
policy_name => v_policy_name
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
-- ORA-28102: policy does not exist. Other errors must stop setup.
|
||||
IF SQLCODE <> -28102 THEN
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
DBMS_FGA.ADD_POLICY(
|
||||
object_schema => r.owner,
|
||||
object_name => r.object_name,
|
||||
policy_name => v_policy_name,
|
||||
audit_condition => NULL,
|
||||
audit_column => NULL,
|
||||
statement_types => 'SELECT',
|
||||
audit_trail => DBMS_FGA.DB + DBMS_FGA.EXTENDED,
|
||||
enable => TRUE
|
||||
);
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
COMMIT;
|
||||
|
||||
PROMPT === FGA policies are ready ===
|
||||
PROMPT Run 22, 29 and 43 as CB_ORDS, then run a new permission-result probe.
|
||||
PROMPT The resulting row is read from UNIFIED_AUDIT_TRAIL by CLIENT_IDENTIFIER.
|
||||
EXIT;
|
||||
59
sql/adb/43_agent_ords_probe_id_handler_patch.sql
Normal file
59
sql/adb/43_agent_ords_probe_id_handler_patch.sql
Normal file
@@ -0,0 +1,59 @@
|
||||
-- ============================================================
|
||||
-- 43_agent_ords_probe_id_handler_patch.sql
|
||||
-- Adds X-VPD-Probe-Id to existing generic cb.object.query handlers.
|
||||
--
|
||||
-- Run as CB_ORDS after 22_agent_ords_security_ords_handler_setup.sql.
|
||||
-- The dedicated document/vector handlers are updated by 22/29 themselves.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET ECHO ON
|
||||
SET FEEDBACK ON
|
||||
|
||||
PROMPT === Patching generic object-query handlers for FGA correlation ===
|
||||
DECLARE
|
||||
v_source CLOB;
|
||||
BEGIN
|
||||
FOR r IN (
|
||||
SELECT m.name AS module_name,
|
||||
t.uri_template,
|
||||
h.method,
|
||||
h.source
|
||||
FROM user_ords_handlers h
|
||||
JOIN user_ords_templates t ON t.id = h.template_id
|
||||
JOIN user_ords_modules m ON m.id = t.module_id
|
||||
WHERE m.name = 'cb.object.query'
|
||||
AND h.method = 'POST'
|
||||
AND INSTR(h.source, 'cb_ords_handler_pkg.set_vpd_context(:auth_header)') > 0
|
||||
) LOOP
|
||||
v_source := REPLACE(
|
||||
r.source,
|
||||
'cb_ords_handler_pkg.set_vpd_context(:auth_header)',
|
||||
'cb_ords_handler_pkg.set_vpd_context(:auth_header, :probe_id)'
|
||||
);
|
||||
|
||||
ORDS.DEFINE_HANDLER(
|
||||
p_module_name => r.module_name,
|
||||
p_pattern => r.uri_template,
|
||||
p_method => r.method,
|
||||
p_source_type => ORDS.source_type_plsql,
|
||||
p_source => v_source,
|
||||
p_items_per_page => 0
|
||||
);
|
||||
ORDS.DEFINE_PARAMETER(
|
||||
p_module_name => r.module_name,
|
||||
p_pattern => r.uri_template,
|
||||
p_method => r.method,
|
||||
p_name => 'X-VPD-Probe-Id',
|
||||
p_bind_variable_name => 'probe_id',
|
||||
p_source_type => 'HEADER',
|
||||
p_param_type => 'STRING',
|
||||
p_access_method => 'IN'
|
||||
);
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
COMMIT;
|
||||
|
||||
PROMPT === Generic handler patch complete ===
|
||||
EXIT;
|
||||
Reference in New Issue
Block a user