Skip to content

Embedding ADM into other applications

If you want to embed ADM into another application that lives in a different schema, you need to grant execute privileges on the adm_embed_api package to the schema of the application where you want to embed ADM.

GRANT EXECUTE ON adm_embed_api TO <target_schema>;

We recommend creating tokens dynamically from the document or folder ID. The get_or_create_ functions in the adm_embed_api package create an expiring token when none exists yet.

:P1_TOKEN := adm_embed_api.get_or_create_document_token (
p_document_id => :P1_DOCUMENT_ID
);
:P1_TOKEN := adm_embed_api.get_or_create_folder_token (
p_folder_id => :P1_FOLDER_ID
);
-- both have optional parameters:
-- p_description in adm_embed_tokens.description%type default null,
-- p_expires_at in adm_embed_tokens.expires_at%type default systimestamp + 1
-- p_is_readonly in adm_embed_tokens.is_read_only%type default 'Y'
-- p_permissions in clob default null -- see "What the embed may do" below

p_is_readonly is the coarse switch: 'Y' lets a visitor browse and download, 'N' lets them do everything the embed exposes. A token can instead name exactly the operations it permits.

Pass p_permissions as JSON. Every operation not listed is refused.

:P1_TOKEN := adm_embed_api.get_or_create_folder_token (
p_folder_id => :P1_FOLDER_ID
, p_permissions => '{"grants": ["UPLOAD"], "maxUploadBytes": 26214400,
"allowedMimeTypes": ["application/pdf"], "visibility": "OWN"}'
);

The result is a submission portal: visitors may drop PDFs of up to 25 MB into the folder, they may not rename, move, replace or delete anything, and they only see their own uploads.

GrantLets a visitor
DOWNLOADtake a copy of a file. Leave it out for a preview-only embed — people can open and read, but not save
UPLOADadd a new file
UPLOAD_VERSIONadd a new version of a file that is already there. Separate from UPLOAD: on an intake box, granting both lets one entrant overwrite another’s submission
CREATE_FOLDERcreate sub-folders, including when dropping a whole directory
RENAME_FILErename a file. Folders can never be renamed from an embed — a folder rename rewrites the path the token is defined by
MOVEmove things around inside the embedded folder. Moving anything out is impossible either way
ZIP / UNZIPcreate a zip in the folder, or extract one
DELETEdelete a file — see the warning below

Omitting p_permissions keeps the old behaviour exactly: a read-only token gets DOWNLOAD, a writable one gets DOWNLOAD plus everything except DELETE. Existing tokens are untouched.

KeyMeaning
maxUploadByteslargest single file. Only ever tightens the instance-wide upload limit, never raises it
allowedMimeTypesan allowlist, e.g. ["application/pdf"]. Checked against the file’s actual content, not the type the browser claims
maxDepth0 confines the visitor to the embedded folder itself, with no sub-folders
visibility"ALL" (default) or "OWN". "OWN" shows a visitor only what they uploaded themselves
uploadQuotaat most this many files may accumulate in the folder through this token

One key in p_permissions is not about what the session may do, but about who it is:

KeyMeaning
identity"CALLER" (default) or "HOST". "HOST" lets your application name the user the embed acts as

By default get_item_values will only sign a URL for the user who calls it — you may mint embed parameters for yourself, and an ADM administrator may mint them for anybody. That rule holds when your users are ADM users, and it stops one embed token becoming a way to browse as somebody else.

It is the wrong rule when your application has its own users. If “Jens” exists only in your app and has no ADM account, there is nobody for ADM to recognise, and the call is refused with you do not have permission to generate embed parameters for another user. A token minted with "identity": "HOST" says the host application is trusted to name the user:

:P1_TOKEN := adm_embed_api.get_or_create_folder_token(
p_folder_id => :P1_FOLDER_ID
, p_permissions => '{"grants": ["DOWNLOAD", "UPLOAD"], "identity": "HOST"}'
);
-- and then, for each of your own users, whoever they are:
:P1_URL := adm_embed_api.get_item_values(:P1_TOKEN, :APP_USER);

Jens now acts as Jens inside the embed: his uploads are recorded under his name, visibility: "OWN" shows him his own files and nobody else’s, and a DELETE grant applies to what he put there. He still needs no ADM account.

Sharing, restoring from the trash, permanently deleting and searching are refused for every embed, whatever the token says, and asking for them is an error rather than being ignored. A share is standing access to your repository granted to a named person, and it outlives the URL that suggested it; the trash is private to one user, so an embed cannot name anything in it; and search would answer for the identity signed into the URL rather than for the folder.

You can also set all of this in the ADM administration interface, under Embed Tokens. The read-only flag there is shown for information: it is derived from the grants, so a token granting any write is writable by definition.

Alternatively you can manually create an embed token using the ADM interface. Log-in to the ADM application as administrator and go to the administration page. Click the menu entry Embed Tokens and create a new embed token.

You need to choose whether you want to embed a file or a folder and then enter the path to the asset. When done copy the generated embed token to your clipboard.

You need to import the UC Nested Pages Pro plug-in into the application where you want to embed ADM. This plug-in is essential for the integration process.

Also compile the uc_dynamic_dashboard package in the schema of the application where you want to embed ADM.

Go to a page where you want to embed ADM and create a new region of type UC Nested Pages Pro.

As a source for the region, select SQL Query and enter the following SQL query:

SELECT
'https://your-domain/ords/r/ws/acm/embed-folder-view?' || adm.adm_embed_api.get_item_values('{EMBED_TOKEN}', :APP_USER)
as iframe_url
FROM
dual

Make sure to replace the url with the correct URL of your ADM instance and the embed token with the one you copied earlier.

In the Attributes section of the region plug-in, set the following attributes:

  • Page URL Column: iframe_url
  • Loading template: <div>Loading...</div>

Now when you run the page, you should see the ADM interface embedded within your application.

The embeds open a portal into the ADM application. Because of that, you should be cautious about which users have access to the embedded content. When you embed from another workspace there is no authentication taking place.

The security model relies on parameter validation instead. The get_item_values function in the adm_embed_api package generates a URL whose parameters carry checksums computed with a secret key, so a tampered parameter is rejected.

Keep the default expiration settings in the get_or_create_document_token and get_or_create_folder_token functions, so a token expires rather than lasting indefinitely.

What a read-only token guarantees, and to whom

Section titled “What a read-only token guarantees, and to whom”

A read-only embed token (p_is_readonly => 'Y', the default) bounds an anonymous viewer completely. The token is the ceiling: the session is confined to the embedded folder and its subtree, cannot write anything, and never acquires administrator rights even if the username signed into the URL belongs to an administrator. The same holds for a token with a narrow grant set — an upload-only token cannot rename.

It does not bound a viewer who is separately logged in to ADM itself. When the host application lives in the same workspace, the embed shares its APEX session — that is why the iframe URL appends &session=, and it is also what keeps the host application logged in. If that same session has also authenticated against the ADM application, ADM recognises its own user and the request runs with that person’s own rights rather than the token’s.

It is not an escalation path:

  • It requires the viewer to already hold an ADM account and to have logged in to ADM in the same browser session. Merely being logged in to the host application is not enough — ADM’s role is established by ADM’s own login.
  • Such a viewer can reach the same documents by opening ADM directly. Confining the iframe would not remove any access they do not already have.

Embedding from another workspace has no such caveat: those sessions never authenticate against ADM, so the token is always the only authority.