[Developer] #567 expose VPD effective SQL trace

This commit is contained in:
devmrko
2026-06-30 11:40:02 +09:00
parent 5c40a9aa33
commit 3a07788e5c
17 changed files with 675 additions and 5 deletions

View File

@@ -477,6 +477,7 @@ GRANT CREATE SESSION TO cb_ords;
GRANT CREATE PROCEDURE TO cb_ords;
GRANT SELECT ON cb_v_search_documents TO cb_ords;
GRANT EXECUTE ON cb_agent_ctx_pkg TO cb_ords;
GRANT EXECUTE ON cb_agent_doc_vpd_filter TO cb_ords;
GRANT EXECUTE ON cb_agent_can_read_column TO cb_ords;
PROMPT === Local VPD setup complete ===

View File

@@ -90,9 +90,24 @@ BEGIN
p_source => q'!
DECLARE
v_rows SYS_REFCURSOR;
v_vpd_predicate VARCHAR2(32767);
v_effective_sql VARCHAR2(32767);
BEGIN
cb_ords_handler_pkg.set_vpd_context(:auth_header);
-- The predicate below is the value returned by the same DBMS_RLS policy
-- function that protects ADMIN.CB_V_SEARCH_DOCUMENTS.
BEGIN
v_vpd_predicate := admin.cb_agent_doc_vpd_filter('ADMIN', 'CB_V_SEARCH_DOCUMENTS');
v_effective_sql := 'SELECT d.doc_id, d.title, d.owner_emp_no, d.dept_code, d.contents '
|| 'FROM admin.cb_v_search_documents d WHERE (' || v_vpd_predicate || ') '
|| 'AND ROWNUM <= LEAST(GREATEST(NVL(:row_limit, 50), 1), 500)';
EXCEPTION
WHEN OTHERS THEN
v_vpd_predicate := NULL;
v_effective_sql := NULL;
END;
OPEN v_rows FOR
SELECT d.doc_id,
d.title,
@@ -108,6 +123,10 @@ BEGIN
OWA_UTIL.HTTP_HEADER_CLOSE;
APEX_JSON.OPEN_OBJECT;
IF v_effective_sql IS NOT NULL THEN
APEX_JSON.WRITE('vpd_predicate', v_vpd_predicate);
APEX_JSON.WRITE('effective_sql', v_effective_sql);
END IF;
APEX_JSON.WRITE('items', v_rows);
APEX_JSON.CLOSE_OBJECT;

View File

@@ -200,4 +200,9 @@ END;
SHOW ERRORS FUNCTION cb_agent_doc_vpd_filter
-- ORDS SQL tracing calls the same policy function after set_vpd_context so
-- the response can expose the token-specific VPD predicate. This is
-- diagnostic metadata only; the SELECT remains protected by DBMS_RLS.
GRANT EXECUTE ON cb_agent_doc_vpd_filter TO cb_ords;
PROMPT === Dynamic whitelist VPD filter ready ===

View File

@@ -50,9 +50,24 @@ DECLARE
v_rows SYS_REFCURSOR;
v_body_text CLOB;
v_embedding_text VARCHAR2(32767);
v_vpd_predicate VARCHAR2(32767);
v_effective_sql VARCHAR2(32767);
BEGIN
cb_ords_handler_pkg.set_vpd_context(:auth_header);
BEGIN
v_vpd_predicate := admin.cb_agent_doc_vpd_filter('ADMIN', 'CB_VECTOR_SEARCH_DOCUMENTS');
v_effective_sql := 'SELECT chunk_id, document_id, chunk_no, title, chunk_text, source_uri, tech_tag, score '
|| 'FROM (SELECT ... FROM admin.cb_vector_search_documents d '
|| 'WHERE d.embedding IS NOT NULL /* VPD: ' || v_vpd_predicate || ' */ '
|| 'ORDER BY score) ranked_chunks '
|| 'WHERE ROWNUM <= LEAST(GREATEST(NVL(:row_limit, 10), 1), 100)';
EXCEPTION
WHEN OTHERS THEN
v_vpd_predicate := NULL;
v_effective_sql := NULL;
END;
-- ORDS exposes :body_text as a stream bind. Read it exactly once; referring
-- to the stream bind twice causes ORA-17270 (Duplicate stream parameter).
v_body_text := :body_text;
@@ -108,6 +123,10 @@ BEGIN
OWA_UTIL.HTTP_HEADER_CLOSE;
APEX_JSON.OPEN_OBJECT;
IF v_effective_sql IS NOT NULL THEN
APEX_JSON.WRITE('vpd_predicate', v_vpd_predicate);
APEX_JSON.WRITE('effective_sql', v_effective_sql);
END IF;
APEX_JSON.WRITE('items', v_rows);
APEX_JSON.CLOSE_OBJECT;

View File

@@ -0,0 +1,21 @@
-- ============================================================
-- 33_agent_ords_sql_trace_grant.sql
-- Enable the optional VPD predicate trace for an existing ORDS install.
--
-- Run as ADMIN after 26_agent_ords_security_dynamic_vpd_filter.sql.
-- Then run 22_agent_ords_security_ords_handler_setup.sql as CB_ORDS, or
-- save the trace-enabled Handler source from the backoffice UI.
--
-- The grant exposes only the existing predicate function to the ORDS
-- runtime. It does not weaken DBMS_RLS enforcement or expose bearer values.
-- ============================================================
WHENEVER SQLERROR EXIT SQL.SQLCODE
SET ECHO ON
SET FEEDBACK ON
PROMPT === Enabling ORDS VPD predicate trace ===
GRANT EXECUTE ON cb_agent_doc_vpd_filter TO cb_ords;
PROMPT === ORDS VPD predicate trace grant ready ===
PROMPT Next: run 22_agent_ords_security_ords_handler_setup.sql as CB_ORDS
EXIT;