Even with smart use of roles to manage privileges, one of the frustrations for DBAs with security privileges has been the disconnect between privileges and typical usage hierarchy. Object privileges have always worked on two tiers only, namely, you get access a single object (eg GRANT SELECT), or you get access to every object (GRANT SELECT ANY).

However, in the real world of database usage, we generally work in three tiers not two. Live the tiers above, some people need access to objects on an individual basis, or people (most likely with some sort administrative level of authority) will have access to all objects. But there is a common third tier that sits between these two, namely, the role (no pun intended) of schemas in our database. The schema often is indicative of an access tier, eg, “All the Human Resources staff can access anything in the HR schema” and so forth.

Historically, because object level grants had no concept of this third tier, we had to manage this ourselves. For example, if I have a new user “JANE_DOE” who should have rights to the HR schema, I would need to do something like the following:


SQL> create user jane_doe identified by jane_doe;

User created.

SQL> select table_name
  2  from   dba_tables
  3  where  owner = 'HR'
  4  order by 1;

TABLE_NAME
-----------------------------
COUNTRIES
DEPARTMENTS
EMPLOYEES
JOBS
JOB_HISTORY
LOCATIONS
REGIONS

7 rows selected.


SQL> grant select on HR.COUNTRIES   to jane_doe;

Grant succeeded.

SQL> grant select on HR.REGIONS     to jane_doe;

Grant succeeded.

SQL> grant select on HR.LOCATIONS   to jane_doe;

Grant succeeded.

SQL> grant select on HR.DEPARTMENTS to jane_doe;

Grant succeeded.

SQL> grant select on HR.JOBS        to jane_doe;

Grant succeeded.

SQL> grant select on HR.EMPLOYEES   to jane_doe;

Grant succeeded.

SQL> grant select on HR.JOB_HISTORY to jane_doe;

Grant succeeded.

Obviously this is both cumbersome (if you’ve ever seen the number of objects in an eBiz schema you’ll know this acutely), and creates an ongoing maintenance nuisance because as objects are created in the HR schema, the privileges must be continuously revisited. You can see my post “How to a grant on an entire schema” for details on how this can be managed in current versions of the database.

Luckily, in 23ai, all this becomes a thing of the past with the new schema level privileges. Finally the tiering system in security reflects the three tier logical concepts we use for objects, schemas and databases. Now when I wish to let JANE_DOE have SELECT access to the anything in the HR schema, it is a single DDL


SQL> grant select any table
  2    on schema hr
  3    to jane_doe;

Grant succeeded.

Don’t let the “ANY” frighten you. We have retained the use of “ANY” because it is indeed true that we are allowing JANE_DOE access to ANY-thing in the HR schema.

The great thing with this new feature is that it removes the hassles of ongoing maintenance. Now, for example, when I create a new table in the HR schema


SQL> create table hr.new_table as
  2  select * from scott.emp;

Table created.

JANE_DOE will automatically be able to see that table due to the schema level privilege.


SQL> conn jane_doe/jane_doe@db23
Connected.

SQL> select * from hr.new_table;

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
      7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
      7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
      7788 SCOTT      ANALYST         7566 09-DEC-82       3000                    20
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
      7844 TURNER     SALESMAN        7698 08-SEP-81       1500                    30
      7876 ADAMS      CLERK           7788 12-JAN-83       1100                    20
      7900 JAMES      CLERK           7698 03-DEC-81        950                    30
      7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
      7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

14 rows selected.

Note that the schema level privilege is not “additive/subtractive” from individual object level privileges. For example, if you want JANE_DOE to have access to all object except the EMPLOYEES table in the HR schema, then doing the following REVOKE statement


SQL> revoke select on hr.employees from jane_doe;

Revoke succeeded.

will not have the desired effect. The schema level privilege is still in place, and thus JANE_DOE still have access to the EMPLOYEES table.


SQL> conn jane_doe/jane_doe@db23
Connected.
SQL> select count(*) from hr.employees;

  COUNT(*)
----------
       107
       

Image credit https://en.wikipedia.org/wiki/User:Yskyflyer

7 responses to “Schema level grant in 23ai”

  1. Brilliant! But I need it in 19c.

  2. iudithd5bf8e4d8d Avatar
    iudithd5bf8e4d8d

    Hi Connor,

    Your last remark regarding the “non-additive/subtractive” behavior of this new feature triggered me to look into the documentation,
    and found that the new schema-level privilege is documented in the dictionary in the new DBS_SYS_PRIVS_ALL view,
    so it is still kind of a “more detailed” system privilege and not just a “summary level” object privilege meant to shorten the need to issue several
    DDL statements.

    Nice to always learn something new 🙂

    If Oracle had used a “layered” approach while checking privileges, that is, if during DLL it would have looked first for an object privilege,
    afterwards for a schema privilege and lastly for a system privilege, then a REVOKE of a privilege on the specific object would have already denied the access, before looking further up in the hierarchy.
    But this is not how Oracle works, the REVOKE-s are in fact NOT stored in the dictionary for allowing such behavior.

    Cheers & Best Regards,
    Iudith Mentzel

  3. Nice! Can you have “create/drop” privilege?

  4. SQL> grant create any table on schema hr to demo;

    Grant succeeded.

  5. Greetings,

    What if we only want to grant access to the views in a schema? We use EBR and typically refrain from giving access to the underlying tables of the editioning views.

    Thanks,

    Chad

    1. Unfortunately not, but I like that use case. I’ll log an enhancement request

Got some thoughts? Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Trending