The security model
Almost nothing in ADM is protected by database privileges; it is protected by a session context that says who you are, and by per-object checks that consult it. Code that sets up no context is nobody, and gets nothing.
Two layers
Section titled “Two layers”Access in ADM is decided in two independent steps.
- The role — one per user,
ADMIN,CONTRIBUTORorVIEWER. It is the ceiling on what that person can do anywhere in the application. - Access to the individual object — whether this user may see or change this document or folder. It comes from ownership, group membership, an explicit share, a share link, or an embed token.
Both have to say yes. A CONTRIBUTOR may upload, but not into a folder they have no rights on. A
user with edit rights on a shared folder still cannot upload if their role is VIEWER.
| Role | In the session context | Intended for |
|---|---|---|
ADMIN | ADMIN | Full access, including the administration section and every file in the system. |
CONTRIBUTOR | EDIT | The normal user: create, upload, edit and share within their own rights. |
VIEWER | VIEW | Read-only. Can open and download what they have access to, and nothing else. |
The database role names and the context role names differ because the context maps them —
CONTRIBUTOR becomes EDIT and VIEWER becomes VIEW. Roles live in adm_roles and are assigned
per user in adm_users; see Users and groups.
Where access to an object comes from
Section titled “Where access to an object comes from”For a given user and a given document or folder, rights come from the first of these that applies:
- Administrator. An
ADMINsees and may change everything, which is why admin actions are audited. - Ownership. Whatever sits in your home folder is yours.
- Group membership. Everything in a group folder is accessible to every member of that group.
- An explicit share. A document or folder shared with you, or with a group you are in, at
VIEWorEDITlevel. A folder share carries down the whole subtree — sharing a folder shares everything currently in it and everything added to it later. - A share-link token. An unauthenticated visitor holding a valid share URL, which may also require a password. Scoped to one document.
- An embed token. A scoped window onto one document or one folder, used when another application embeds ADM. Capped at the token’s own permissions — which may be a single operation such as “upload, and nothing else” — and never granted admin rights even if the identity on the URL belongs to an administrator. See Embedding.
The session context
Section titled “The session context”Every check above reads the current identity out of an Oracle application context in the namespace
ADM_CONTEXT, managed by
adm_context_api. It holds:
| Attribute | Holds |
|---|---|
ADM_USERNAME | The ADM user acting. |
ADM_ROLE | Their context role: ADMIN, EDIT or VIEW. |
ADM_ACCESS_SOURCE | How they got here: DB, APEX, REST or EMBED. Audit rows record it. |
ADM_EMBED_TOKEN | Set only in an embed session, and the ceiling on what that session may do. |
The context is session scoped, and an APEX or ORDS session comes from a connection pool. Every entry point therefore clears the context before establishing its own: without that, a request whose login fails silently would inherit whoever used the connection last — possibly an administrator.
Establishing a context from your own code
Section titled “Establishing a context from your own code”Two entry points are meant for you. Both are for code running outside the APEX application — a SQL*Plus script, a scheduled job, an ORDS handler, a package of your own.
-- Full privileges, acting as the system user `_UC_SYSTEM_`.-- For installation, migration and administrative scripts.begin adm_context_api.system_login; -- ... administrative work ... commit;end;/-- Act as a specific user, with exactly that user's permissions.-- This is the right choice for anything acting on a user's behalf: the checks-- apply as they would in the app, and the audit log names the real user.begin adm_context_api.system_user_login('JDOE'); -- ... work as JDOE ... commit;end;/system_login takes an optional debug level, which turns on apex_debug output for the script:
adm_context_api.system_login(p_debug_level => apex_debug.c_log_level_info);The two remaining entry points, apex_login and embed_login, are @private: the application’s
initialization code calls them on every request. Do not call them yourself.
If you elevate a session and then hand it back — a job that runs administrative work inside a user’s
session, for example — capture the previous username and role and put them back with
restore_context, or clear the context with clear_context. Leaving an elevated role behind
mis-attributes every audit row written afterwards.
Checking rights in your own code
Section titled “Checking rights in your own code”Never decide access by querying adm_folder_shares, adm_document_shares or the folder hierarchy
yourself. Access depends on subtree inheritance, group membership, trashed ancestors and tokens, and
a query of your own has to reproduce all four. Go through
adm_access_control_api:
if not adm_access_control_api.user_is_allowed_to_view_document( p_document_id => l_document_id )then -- refuseend if;Every function defaults p_username to the user in the current context, so in the normal case you
pass only the object id.
| Function | Answers |
|---|---|
user_is_allowed_to_view_document | May the user open this document? Accepts a share-URL or embed token. |
user_has_edit_rights_on_document | May they change it? Returns Y/N. |
user_has_owner_rights_on_document | Do they own it — may they delete it, share it, change its retention? |
is_allowed_to_view_folder | May they open this folder? Also available as ..._yn. |
user_has_edit_rights_on_folder | May they create in it, or move things into it? Returns Y/N. |
user_is_admin | Is the current context an administrator? |
assert_admin | Raise unless it is. First statement of an administrative operation. |
documents_in_shared_folders / folders_in_shared_folders | Pipelined id lists, for joining in your own queries. |
The return types are mixed: some return boolean (usable only in PL/SQL), the _yn and
edit_rights variants return 'Y'/'N' so they can be used in SQL.
The APEX access control list
Section titled “The APEX access control list”The application also ships APEX’s own access control feature, with an application setting
ACCESS_CONTROL_SCOPE that is either ALL_USERS or ACL_ONLY. It governs who may sign in to the
application at all, one layer above everything on this page. It is not ADM’s role model, and
adding somebody to the APEX ACL does not create an ADM user or give them a home folder — that is
adm_user_api.add_user.