The first thing to remember is a user with DBA privileges can do basically anything in the database. Given enough time it's always possible to bypass whatever measures you put in place.
So whatever steps you put in place to limit access to the secure code, you should also:
Audit executions of the procedure in question. While this won't stop people executing the procedure in question, you will be able to track down who did.
Avoid granting DBA to users! Create custom roles which only have the privileges people need to do their job.
That said, there are steps you can take to make it harder for privileged users to execute secure code.
12.1 introduced accessor lists. These define a comma-separated list of program units that can execute the target procedure. It's then only possible to execute the procedure via one of those in the list.
So you can create a wrapper around the secure package/procedures. These can check which roles are enabled in the current session. If this includes DBA or any others you want to restrict access, raise an error to stop execution.
Here's a quick demo. My current user (Chris) has the DBA role. Despite owning the procedure and having this role, the accessible by clause prevents me calling protect_me directly.
The only way to call it is via privileged_proc. This checks session_roles to see if DBA is enabled. If it is, it raises an exception. So CHRIS & DBAU can't run protect_me. Just U - which has only create session and execute on privileged_proc - can call it:
grant dba
to dbau identified by dbau;
grant create session, create procedure
to u identified by u;
create or replace procedure protect_me
accessible by ( privileged_proc )
authid current_user
as
begin
dbms_output.put_line ( 'Executed' );
end protect_me;
/
create or replace procedure privileged_proc
authid current_user
as
begin
for r in (
select * from session_roles
where role = 'DBA'
) loop
raise_application_error ( -20001, 'Stop doing this DBA!' );
end loop;
chris.protect_me ();
end privileged_proc;
/
exec protect_me();
ORA-06550: line 1, column 7:
PLS-00904: insufficient privilege to access object PROTECT_ME
exec privileged_proc();
ORA-20001: Stop doing this DBA!
grant execute on privileged_proc to u;
conn u/u
exec chris.protect_me ();
ORA-06550: line 1, column 7:
PLS-00201: identifier 'CHRIS.PROTECT_ME' must be declared
exec chris.privileged_proc();
Executed
conn dbau/dbau
exec chris.protect_me ();
ORA-06550: line 1, column 7:
PLS-00904: insufficient privilege to access object PROTECT_ME
exec chris.privileged_proc();
ORA-20001: Stop doing this DBA!