Racing Championship: Deep Data Security
The Racing Championship shows how the AI Optimizer augments a model with live racing data. Oracle Deep Data Security (DDS) adds the next constraint: the assistant should use only the data the person asking is allowed to see.
In this extension, TALENT_SCOUT can assess Team 1's drivers but cannot see their confidential SKILL_PROFILE notes.
Create that policy in the AI Optimizer, then compare direct SQL and NL2SQL results. Both respect the same policy because
the database enforces it.
What you'll build
A single scenario you can demo in a few minutes:
| Object | Name (suggested) | Purpose |
|---|---|---|
| Data role | TALENT_SCOUT_ROLE | The principal the policy authorizes. |
| Data grant | DG_TALENT_SCOUT_DRIVERS | On DRIVERS: SELECT on all columns except SKILL_PROFILE (column masking), filtered to a single team with a row predicate (team_id = 1). |
| End user | TALENT_SCOUT | A talent scout who needs to assess a team's drivers without seeing their confidential skill profiles. |
Net effect: TALENT_SCOUT can assess only Team 1's drivers and never sees SKILL_PROFILE. The schema owner still
sees everything (owners are not subject to their own data grants — that is exactly why you test as the end user).
If you have already completed this DDS demo in the same clean environment, creating TALENT_SCOUT_ROLE,
DG_TALENT_SCOUT_DRIVERS, or TALENT_SCOUT again may show an "already exists" error. That is fine... you can skip the creation step and continue to the next step. The policy is still in effect.
Prerequisites
-
Oracle AI Database 26ai. DDS is only available in 26ai. If the connected database does not support it, the Deep Data Security tab shows a "not available" notice instead of the management UI.
-
The racing schema is loaded. Complete Setup so
DRIVERS,RACE_RESULTS, etc. exist in the AI Optimizer's configured database user (referred to below as<SCHEMA>). -
DDS privileges on
<SCHEMA>. As a DBA, grant the configured user the Deep Data Security privileges below. In the commands, replace<DATABASE_USER>with<SCHEMA>.To use all Deep Data Security management actions, grant the following privileges to the configured database user. Replace
<DATABASE_USER>with that username. The privileges are optional: unsupported databases show an availability warning, and a missing privilege disables only its related action.GRANT CREATE DATA ROLE TO "<DATABASE_USER>";GRANT DROP DATA ROLE TO "<DATABASE_USER>";GRANT CREATE END USER TO "<DATABASE_USER>";GRANT DROP END USER TO "<DATABASE_USER>";GRANT CREATE DATA GRANT TO "<DATABASE_USER>";GRANT CREATE END USER CONTEXT TO "<DATABASE_USER>";GRANT CREATE END USER SECURITY CONTEXT TO "<DATABASE_USER>";GRANT ADMINISTER ANY DATA GRANT TO "<DATABASE_USER>";GRANT GRANT ANY DATA ROLE TO "<DATABASE_USER>";-- Read access so the tool can list data roles, role grants, and end usersGRANT SELECT ON DBA_DATA_ROLES TO "<DATABASE_USER>";GRANT SELECT ON DBA_DATA_ROLE_GRANTS TO "<DATABASE_USER>";GRANT SELECT ON DBA_END_USERS TO "<DATABASE_USER>";To let Vector Search and NL2SQL connect as a Deep Data Security end user, the end user must be able to log in.
CREATE SESSIONcannot be granted directly to an end user; a standard database role carries it through a data role. As a privileged user, create that role once and let<DATABASE_USER>grant it:CREATE ROLE AIO_DDS_ROLE;GRANT CREATE SESSION TO AIO_DDS_ROLE;GRANT AIO_DDS_ROLE TO "<DATABASE_USER>" WITH ADMIN OPTION;The tool grants
AIO_DDS_ROLEto each locally managed data role it creates, so an end user assigned that data role can be connected as.
Step 1 — Confirm DDS is available (UI)
- In the AI Optimizer, open Tools > Deep Data Security.
- The page renders three stacked sections: Data Roles, End Users, and Data Grants.
- If you instead see "Deep Data Security is not available on the
<database>database. It requires Oracle AI Database 26ai," your database build does not support DDS — switch the Configuration > Databases connection to a 26ai database. - If an action is disabled, the page shows an inline hint with the exact
GRANT … TO <user>;it needs (for example, "Assigning data roles requires:GRANT ANY DATA ROLE to <user>;"). A missing privilege disables only its related action; the rest of the demo still works. Revisit the grants in Prerequisites.
- If you instead see "Deep Data Security is not available on the
Step 2 — Create the data role (UI)
- Go to the Data Roles section.
- Click Create Data Role. In the dialog, set:
- Data role name:
TALENT_SCOUT_ROLE - Mapped to: leave blank (a local role; you would fill this in only to map to an external identity-provider application role).
- Data role name:
- Click Create.
- The new role appears with Enabled by Default = Yes. It becomes active when assigned to
TALENT_SCOUTin Step 4.
Step 3 — Create the data grant: column + row policy (UI)
This is where the actual access policy is written.
-
Go to the Data Grants section.
-
Fill in the grant builder:
- Data grant name:
DG_TALENT_SCOUT_DRIVERS - Object (table/view):
DRIVERS - Privileges:
SELECT - Columns: choose All columns except, then in the column picker select
SKILL_PROFILE. This authorizes every column onDRIVERSexceptSKILL_PROFILE, so that column is masked for the grantee. - Row predicate:
team_id = 1A SQLWHEREexpression evaluated per row; only Team 1's drivers are visible. - Grant to data role:
TALENT_SCOUT_ROLE
- Data grant name:
-
Review the generated statement shown in the preview block. It should read close to:
CREATE DATA GRANT DG_TALENT_SCOUT_DRIVERSAS SELECT (ALL COLUMNS EXCEPT "SKILL_PROFILE") ON DRIVERSWHERE team_id = 1TO TALENT_SCOUT_ROLE;Review the statement before creating the grant.
-
Click Create Data Grant. It now appears (expanded per column) in the data-grants list.
Tip — pick columns that show well.
SKILL_PROFILEis the scouting attribute, so masking it is the clearest "before/after."VEHICLE_SETUPandDRIVING_STYLEare good secondary choices.
Step 4 — Create the end user (UI)
- Go to the End Users section.
- Click Create End User. In the dialog, set:
- End user name:
TALENT_SCOUT - Schema (for name resolution): leave the default (
<SCHEMA>, the connected user). This is the schema thatTALENT_SCOUT's unqualified object names resolve against. - No password field: the end user is provisioned server-side with the same password as the connected
database user (
<SCHEMA>). You will use that password when you connect asTALENT_SCOUTin Step 5. - Assigned data roles: select
TALENT_SCOUT_ROLE. This grants the role to the end user and requiresGRANT ANY DATA ROLEfrom Prerequisites. If the multiselect is disabled, you are missing that privilege.
- End user name:
- Click Create.
TALENT_SCOUTappears in the list with its account status.
Step 5 — Test that the policy is enforced
The schema owner (<SCHEMA>) is not subject to its own data grants, so the comparison must use TALENT_SCOUT.
First compare direct SQL, then ask the same questions through the Chatbot.
5a — Compare direct SQL
Connect as the owner and look at Driver 1's row in full:
-- As <SCHEMA>: owner bypasses data grants, sees everything
SELECT driver_code, team_id, skill_profile
FROM drivers
WHERE driver_id = 1;
Now connect as the end user and run the equivalent query against the owner's table:
-- As TALENT_SCOUT (for example: sqlplus 'TALENT_SCOUT/<password>@<dsn>')
SELECT driver_code, team_id, skill_profile
FROM <SCHEMA>.drivers
ORDER BY driver_id;
What to look for:
- Only Team 1 drivers are returned (the
team_id = 1row predicate). SKILL_PROFILEcomes back masked (NULL) for those rows (theALL COLUMNS EXCEPTcolumn policy).- The owner query, by contrast, returned every team and the real
SKILL_PROFILEtext.
That difference, owner vs. end user against the same table, is the policy working.
5b — Ask through Chatbot
Now ask the same questions through the Chatbot. The prompt does not change; only the database identity does.
-
Keep the active database set to
<SCHEMA>. -
In the Chatbot sidebar, select NL2SQL under Tool Selection.
-
In Tools > Deep Data Security, set Connect tools as to
TALENT_SCOUT. -
Return to the Chatbot and enable Deep Data Security in the sidebar. The NL2SQL tool now connects as
TALENT_SCOUT. -
Ask:
List the drivers and their skill profiles.How many drivers are there in total, and which teams are they on?What to look for: the agent's answers cover only Team 1's drivers, and skill-profile values come back empty or "not available" — the same masking and row filter you saw in SQL, now enforced on the agent's generated query.
-
Turn Deep Data Security off in the Chatbot sidebar and ask the same questions. The agent now sees all teams and the real skill profiles because it is using the owner connection again.
Step 6 — More policies to try
Each is built the same way in the Data Grants section; only the highlighted fields change.
| Goal | Object | Privileges | Columns | Row predicate |
|---|---|---|---|---|
| Hide penalties from talent scouts | RACE_RESULTS | SELECT | All columns except PENALTIES | (none) |
| Show one team's results only | RACE_RESULTS | SELECT | All columns | driver_id IN (SELECT driver_id FROM <SCHEMA>.drivers WHERE team_id = 1) |
| Expose only published team points | TEAM_RACE_POINTS | SELECT | All columns except RACE_CONTROL_NOTE | publication_status = 'PUBLISHED' |
Re-run the Step 5 checks as TALENT_SCOUT after each to see the effect. The "published team points" policy pairs
nicely with the use case's Final Reveal: a talent scout sees a team's points only once publication_status flips to
published.
Troubleshooting
- Deep Data Security shows "not available": the active database is not 26ai. Switch connections in Configuration > Databases.
- Buttons / fields are greyed out: the configured user is missing a DDS privilege. The disabled control shows the
exact
GRANT … TO <user>;it needs (e.g. the Assigned data roles multiselect needsGRANT ANY DATA ROLE). Grant it (Prerequisites) and reload. TALENT_SCOUTsees all rows / unmasked columns: the data role is not reaching the end user. Check that Deep Data Security is enabled in the Chatbot sidebar,TALENT_SCOUT_ROLEwas granted toTALENT_SCOUT(Step 4 → Assigned data roles, or Edit next to the end user), andDG_TALENT_SCOUT_DRIVERSwas granted toTALENT_SCOUT_ROLE.TALENT_SCOUTsees no rows at all: DDS is deny-by-default — without a matching data grant the end user sees nothing. Confirm the grant exists and that your row predicate matches real data (Team 1 has drivers in the seed).