SQLMentor // learn pl/sql

Invoker vs Definer Rights (AUTHID)

Every stored PL/SQL unit runs under one of two privilege models: definer's rights (the default) or invoker's rights. The AUTHID clause chooses which — and it determines whose privileges the code uses and whose schema unqualified object names resolve in.

Definer's Rights (the Default)

By default, a stored procedure, function, package, or type runs with AUTHID DEFINER. It executes with the owner's privileges, and any unqualified reference to a table or view resolves in the owner's schema — regardless of who calls it.

CREATE OR REPLACE PROCEDURE hr.raise_all_salaries(p_pct IN NUMBER)
    AUTHID DEFINER   -- the default; can be omitted
IS
BEGIN
    -- "employees" resolves to HR.EMPLOYEES no matter who calls this
    UPDATE employees SET salary = salary * (1 + p_pct/100);
    COMMIT;
END raise_all_salaries;
/

-- Grant EXECUTE to a user who has NO direct access to HR.EMPLOYEES
GRANT EXECUTE ON hr.raise_all_salaries TO app_user;

This is the classic encapsulation pattern: app_user can run the procedure without ever being granted UPDATE on the table. The procedure is a controlled gateway to the data.

Under definer's rights, roles are disabled during execution. Any privilege the unit needs must be granted directly to the owner, not through a role. A procedure that works interactively can fail once compiled if its owner only holds the privilege via a role.

Invoker's Rights (AUTHID CURRENT_USER)

AUTHID CURRENT_USER makes the unit run with the caller's privileges. Unqualified object names in the unit's SQL statements resolve at runtime in the invoker's schema, and enabled roles apply. This is what you want for generic utilities that should operate on whichever user is running them.

CREATE OR REPLACE PROCEDURE count_my_rows(p_table IN VARCHAR2)
    AUTHID CURRENT_USER
IS
    v_count  NUMBER;
BEGIN
    -- Resolves p_table in the CALLER's schema, with the CALLER's privileges
    EXECUTE IMMEDIATE
        'SELECT COUNT(*) FROM ' || DBMS_ASSERT.SQL_OBJECT_NAME(p_table)
        INTO v_count;

    DBMS_OUTPUT.PUT_LINE(p_table || ': ' || v_count || ' rows');
END count_my_rows;
/

If SCOTT and HR both call count_my_rows('EMPLOYEES'), each counts the EMPLOYEES table in their own schema — because name resolution follows the invoker, not the owner.

Definer vs Invoker at a Glance

Aspect Definer's rights (default) Invoker's rights (CURRENT_USER)
Runs with privileges of Owner (definer) Caller (invoker)
Unqualified names resolve in Owner's schema Invoker's schema (SQL statements)
Roles during execution Disabled Enabled
Typical use Controlled, encapsulated access to the owner's data Generic utilities acting on the caller's own objects
Name resolution differs by statement type. In an invoker's rights unit, references inside SQL statements (and dynamic SQL) resolve in the invoker's schema at run time, but calls to other PL/SQL subprograms are resolved at compile time in the owner's schema. Qualify names (hr.employees) whenever you need to remove all ambiguity.

Packages, Types, and Granularity

AUTHID is set on the package specification (it applies to the whole package body) and on the object type specification — not on individual subprograms inside them:

CREATE OR REPLACE PACKAGE admin_utils
    AUTHID CURRENT_USER   -- applies to every subprogram in the package
AS
    PROCEDURE truncate_my_table(p_table IN VARCHAR2);
    FUNCTION  my_row_count(p_table IN VARCHAR2) RETURN NUMBER;
END admin_utils;
/

From Oracle 12c onward you can also grant roles to a PL/SQL unit (code-based access control), letting an invoker's rights unit carry exactly the privileges it needs without over-privileging the caller:

GRANT reporting_role TO PROCEDURE count_my_rows;

The Invoker's Rights Security Consideration

Because an invoker's rights unit runs with the caller's privileges, a low-privileged owner could write one that, when run by a DBA, performs privileged actions on the owner's behalf. Oracle 12c closes this hole with the INHERIT PRIVILEGES privilege: by default a unit's owner must have INHERIT PRIVILEGES on the invoking user (or PUBLIC) for the invoker's rights call to use the invoker's privileges. Revoke it from PUBLIC and grant it selectively to harden a schema.

-- A cautious user prevents untrusted schemas from borrowing their privileges
REVOKE INHERIT PRIVILEGES ON USER dba_user FROM PUBLIC;
GRANT  INHERIT PRIVILEGES ON USER dba_user TO trusted_owner;
Default to definer's rights for business logic that guards a fixed set of tables — it is the safest, most predictable choice. Reach for invoker's rights only for genuinely generic tooling that must act on the caller's own schema, and always validate object names with DBMS_ASSERT.

Checking the Setting

SELECT object_name, object_type, authid          -- CURRENT_USER or DEFINER
FROM   user_procedures
WHERE  authid IS NOT NULL;

-- Also visible per object in USER_PROCEDURES / ALL_PROCEDURES

Summary

  • AUTHID DEFINER (the default) runs a unit with the owner's privileges; unqualified names resolve in the owner's schema. Roles are disabled — grant privileges directly.
  • AUTHID CURRENT_USER runs a unit with the caller's privileges; SQL-statement names resolve in the caller's schema and roles are enabled.
  • Definer's rights power the encapsulation pattern: GRANT EXECUTE without granting table access.
  • Invoker's rights suit generic utilities that operate on whichever user runs them.
  • AUTHID is declared on the package/type spec, applying to all members.
  • Oracle 12c adds INHERIT PRIVILEGES (protects invokers) and roles granted to PL/SQL units (code-based access control).