Skip to content

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.

Access in ADM is decided in two independent steps.

  1. The role — one per user, ADMIN, CONTRIBUTOR or VIEWER. It is the ceiling on what that person can do anywhere in the application.
  2. 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.

RoleIn the session contextIntended for
ADMINADMINFull access, including the administration section and every file in the system.
CONTRIBUTOREDITThe normal user: create, upload, edit and share within their own rights.
VIEWERVIEWRead-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.

For a given user and a given document or folder, rights come from the first of these that applies:

  • Administrator. An ADMIN sees 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 VIEW or EDIT level. 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.

→ Sharing · Embedding

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:

AttributeHolds
ADM_USERNAMEThe ADM user acting.
ADM_ROLETheir context role: ADMIN, EDIT or VIEW.
ADM_ACCESS_SOURCEHow they got here: DB, APEX, REST or EMBED. Audit rows record it.
ADM_EMBED_TOKENSet 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.

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.

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
-- refuse
end if;

Every function defaults p_username to the user in the current context, so in the normal case you pass only the object id.

FunctionAnswers
user_is_allowed_to_view_documentMay the user open this document? Accepts a share-URL or embed token.
user_has_edit_rights_on_documentMay they change it? Returns Y/N.
user_has_owner_rights_on_documentDo they own it — may they delete it, share it, change its retention?
is_allowed_to_view_folderMay they open this folder? Also available as ..._yn.
user_has_edit_rights_on_folderMay they create in it, or move things into it? Returns Y/N.
user_is_adminIs the current context an administrator?
assert_adminRaise unless it is. First statement of an administrative operation.
documents_in_shared_folders / folders_in_shared_foldersPipelined 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 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.