Build1 publisher2 min readPublished
Oracle 26ai moves row and cell authorisation out of application code and into data grants
Deep Data Security declares in SQL who may read which rows, columns and cells, and the Oracle 26ai engine checks it on every query. A dev.to walkthrough shows the first end user failing to log in at all.
The Engineer · Build desk

What happened
- Oracle AI Database 26ai adds Deep Data Security, which declares which rows, columns and individual cells an identity may touch and has the database enforce that rule on every query, whatever sent it.
- It introduces a second kind of user alongside the standard database account: the local end user, created and managed inside the database but owning no schema and no objects.
- Data grants are the policy objects, stating in ordinary SQL who may SELECT, INSERT, UPDATE or DELETE which rows and which columns.
- Data roles carry those fine-grained privileges and can either be mapped to roles in Microsoft Entra ID or OCI IAM, or managed entirely inside the database.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Provisioning becomes a two-step operation: an unprovisioned identity does not get partial access, it gets a login failure, so every new agent or reporting tool needs a data role before it can open a session.
- capability What an agent is allowed to read can be inspected as a policy object a DBA can query, instead of being a property of whichever code path assembled the SQL.
- exposure An agent that keeps connecting through the pooled account that owns the tables gets none of this, because grants attach to end users, not to the schema owner.
- decision Shops with row filters already written in PL/SQL have to decide whether to re-declare them as data grants on the strength of a scaling claim the post asserts without a measurement.
`CREATE END USER vahid IDENTIFIED BY vahid` returns "End user created." [7]. The identity then shows up in a new dictionary view, DBA_END_USERS, with ACCOUNT_STATUS OPEN and PROFILE DEFAULT [10]. Connect as it and the database answers ORA-01045: Login denied. User VAHID does not have CREATE SESSION privilege [11]. The dev.to walkthrough is direct about the result: "This is expected, not a bug: an end user starts with no privileges at all." [12]
Deny by default is the design here. An end user cannot do anything, including log on, until a data role authorises it [17]. A data role can carry ordinary database roles such as CREATE SESSION alongside data grants, and one role can be assigned to several end users [5]. Every new application identity therefore costs a role assignment before it does any work.
The ID Oracle handed the new identity is 2147493788 [10], which is 10,140 past the 32-bit signed ceiling of 2,147,483,648 [14]. End users look to be numbered out of a range of their own. The same view carries MFA, START_TIME and END_TIME per identity [8], and START_TIME and END_TIME are declared VARCHAR2(37) [9], so the validity window is a string somebody has to parse.
The post's pitch is that "the same protection applies whether the request comes from a human user, a reporting tool, or an autonomous AI agent" [15]. For that to hold in a running system, the agent has to arrive as its own end user. An agent that borrows the pooled account owning the tables is outside the model, because data grants attach to end users through data roles [6][5]. Data roles can also be mapped to roles in Microsoft Entra ID or OCI IAM [4]. An identity minted outside the database reaches Deep Sec by that route.
The claim to check later is the one about scale: data grants are said to be a SQL-native form of fine-grained access that "scales far better than row-level security written in PL/SQL" [2]. No measurement accompanies it. The walkthrough stops mid-statement after creating its data role, before the first data grant [16], so the row and column syntax and the per-query cost of checking it are not in this instalment.
Deep Sec also runs alongside Oracle Label Security and Data Masking [2], which leaves an incremental path for a schema that already has policies in place. If you already filter rows in PL/SQL, the decision in front of you is whether to re-declare those filters as data grants, and the argument for moving currently rests on that single sentence about scale [2].
What to watch
- Whether Oracle documents how a pooled application or agent runtime asserts a specific end user identity per request.
- The data grant syntax itself, and whether row predicates can reference session or caller attributes.
- Any measured per-query overhead for cell-level checks against the equivalent PL/SQL row-level security.