patternModerate
Column level security
Viewed 0 times
levelsecuritycolumn
Problem
I am in need of a solution to hide specific columns in a table. We have people who need to build reports against this database and specifically some of these tables with confidential information but aren't allowed to see items like salary or ssn. Is it possible to filter specific columns for users?
Solution
You can do this with a normal view, as long as the users involved haven't already got access to the base table.
EG:
If you revoke permissions on the tables in question & create the views, along with a synonym for each users view that has the same name as the original table, it should be transparent.
EG:
You can also do this with Virtual Private Database, but I think it's an expensive extra licensed option. You use DBMS_RLS to configure the relevant security policies that you require.
EG:
SQL> create user reportuser identified by reportuser;
User created.
SQL> grant create session to reportuser;
Grant succeeded.
SQL> grant create synonym to reportuser;
Grant succeeded.
SQL> select user from dual;
USER
------------------------------
PHIL
SQL> create table basetable
(
id number primary key,
viewable varchar2(30),
secret varchar2(30)
);
Table created.
SQL> insert into basetable values ( 1, 'hello world','this is secret' );
1 row created.
SQL> commit;
Commit complete.
SQL> create view reportview
as
select id, viewable
from basetable;
View created.
SQL> grant select on reportview to reportuser;
Grant succeeded.
SQL> conn reportuser/reportuser
Connected.
SQL> select * from phil.basetable;
select * from phil.basetable
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select secret from phil.basetable;
select secret from phil.basetable
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select * from phil.reportview;
ID VIEWABLE
---------- ------------------------------
1 hello world
SQL>If you revoke permissions on the tables in question & create the views, along with a synonym for each users view that has the same name as the original table, it should be transparent.
EG:
SQL> select user from dual;
USER
------------------------------
REPORTUSER
SQL> create synonym basetable for phil.reportview;
Synonym created.
SQL> select * from basetable;
ID VIEWABLE
---------- ------------------------------
1 hello world
SQL>You can also do this with Virtual Private Database, but I think it's an expensive extra licensed option. You use DBMS_RLS to configure the relevant security policies that you require.
Code Snippets
SQL> create user reportuser identified by reportuser;
User created.
SQL> grant create session to reportuser;
Grant succeeded.
SQL> grant create synonym to reportuser;
Grant succeeded.
SQL> select user from dual;
USER
------------------------------
PHIL
SQL> create table basetable
(
id number primary key,
viewable varchar2(30),
secret varchar2(30)
);
Table created.
SQL> insert into basetable values ( 1, 'hello world','this is secret' );
1 row created.
SQL> commit;
Commit complete.
SQL> create view reportview
as
select id, viewable
from basetable;
View created.
SQL> grant select on reportview to reportuser;
Grant succeeded.
SQL> conn reportuser/reportuser
Connected.
SQL> select * from phil.basetable;
select * from phil.basetable
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select secret from phil.basetable;
select secret from phil.basetable
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select * from phil.reportview;
ID VIEWABLE
---------- ------------------------------
1 hello world
SQL>SQL> select user from dual;
USER
------------------------------
REPORTUSER
SQL> create synonym basetable for phil.reportview;
Synonym created.
SQL> select * from basetable;
ID VIEWABLE
---------- ------------------------------
1 hello world
SQL>Context
StackExchange Database Administrators Q#24292, answer score: 13
Revisions (0)
No revisions yet.