THIS FEATURE IS IN BETA AND SUBJECT TO CHANGE. TO JOIN THE BETA PLEASE CONTACT YOUR CUSTOMER SUCCESS MANAGER
Embed our features directly in your own PAM or CMS
Console Remote Control enables you to render most of our bank data and risk analysis content within your own player account management tools with a very simple but secure integration.
There are three steps:
- Configure remote control in the DoTrust Console
- Secure your access by requesting an authentication token from your server to ours
- Include a JS script tag and individual placeholders for the content within your PAM
The content rendered in your system is exactly the same as you would see if you were logged in to the DoTrust console.
INFO
The API base used throughout this guide is https://complete.dotrust.co. This is where /embeddedWidgets and /embedded/widget/* are served. If you have been given a different base URL for your environment, use that instead.
Concepts
| Term | Meaning |
|---|---|
| Embed key | Public identifier for your embed configuration (the key). Safe to put in the page. |
| Secret key | Used only by your server to mint session tokens. Never put it in a page. |
| Session token | Short-lived (24hr) token scoped to your platform — it is not tied to a customer. One token serves the whole page whilst it is valid. |
| customerId | Your own id for the customer. You do not have to pre-enrol the customer with DoTrust for this to work. |
| IP allowlist | Required. One or more IP addresses permitted to request session tokens — your server's egress IPs. Minting from any other IP is refused. |
Configure your embed
In Console → Service admin → Remote Control set:
Permitted domains — the domain your PAM is hosted on. If set, content will only be rendered if the window matches. Optional, as security is primarily protected by the session tokens
Allowed IPs — the server egress IPs allowed to mint session tokens. Required.
Allowed widgets — which of the available widgets may be embedded on your PAM.
Status — a 'kill switch' for the feature if you want to disable it everywhere all at once.
Keys — an embed key (public id) and a secret key (server-side only). Both are generated for you and can be copied or regenerated. You need these to implenent the integration.
INFO
At least one allowed IP is mandatory. Session-token minting is refused from any IP not in the allowlist — this is the primary control on who can mint tokens, so configure it carefully.
Quick start
Your backend mints a session token with the secret key, from one of your allowlisted IPs, and you put it on the script tag as data-session. The token is operator-scoped (not customer-specific) and lasts 24 hours. The secret key never goes in the page, and there is no in-page minting.
1. Your server mints a session token:
POST https://complete.dotrust.co/embedded/widget/session_token
Headers: x-widget-embed-key: <SECRET_KEY>
content-type: application/json
Body: { "key": "<EMBED_KEY>" }
→ { "widgetSessionToken": "<AUTH_TOKEN>" }The mint is only honoured when the request reaches DoTrust from an IP in your IP allowlist. Because the call is made from your server, the allowlisted IP is your server's egress IP, not the end user's browser.
2. Render the page. Put the token on the script tag, and data-customer-id (plus optional data-brand) on each div — data-dot-widget is the widget name:
html
<div data-dot-widget="income" data-customer-id="<CUST_A>"></div>
<div data-dot-widget="accounts" data-customer-id="<CUST_A>"></div>
<div data-dot-widget="affordability" data-customer-id="<CUST_B>"></div>
<script
src="https://complete.dotrust.co/embeddedWidgets/<EMBED_KEY>"
data-session="<AUTH_TOKEN>"
></script>data-customer-id is set per <div>, so a single page can show widgets for different customers — you control placement on your side. Each div is replaced with an iframe for that widget, and the embed auto-enrols each distinct customer before loading it.
Server-side token minting
The token must be minted by your backend, using the secret key, from an allowlisted IP. Examples in TypeScript, JavaScript (Node) and Python:
ts
/**
* Mint a DoTrust embedded-widget session token (server tier, TypeScript).
*
* The SECRET key must stay on your server, and you must call this from one of
* your allowlisted IPs. Returns a short-lived (24h) token that you inject into
* the page on each widget div as `data-session`.
*
* Env:
* DOTRUST_API_BASE e.g. https://complete.dotrust.co
* DOTRUST_EMBED_KEY your embed key
* DOTRUST_SECRET_KEY your secret key (server only)
*/
export async function mintWidgetSessionToken(): Promise<string> {
const base = process.env.DOTRUST_API_BASE;
const key = process.env.DOTRUST_EMBED_KEY;
const secretKey = process.env.DOTRUST_SECRET_KEY;
if (!base || !key || !secretKey) {
throw new Error('Missing DOTRUST_API_BASE / DOTRUST_EMBED_KEY / DOTRUST_SECRET_KEY');
}
const res = await fetch(`${base}/embedded/widget/session_token`, {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-widget-embed-key': secretKey,
},
body: JSON.stringify({ key }),
});
const data = (await res.json()) as { widgetSessionToken?: string; error?: string };
if (!res.ok || data.error || !data.widgetSessionToken) {
throw new Error(`Failed to mint session token: ${data.error ?? res.statusText}`);
}
return data.widgetSessionToken;
}js
/**
* Mint a DoTrust embedded-widget session token (server tier, Node.js).
*
* The SECRET key must stay on your server, and you must call this from one of
* your allowlisted IPs. Returns a short-lived (24h) token that you inject into
* the page on each widget div as `data-session`.
*
* Env:
* DOTRUST_API_BASE e.g. https://complete.dotrust.co
* DOTRUST_EMBED_KEY your embed key
* DOTRUST_SECRET_KEY your secret key (server only)
*/
// Node 18+ has global fetch. On older Node: const fetch = require('node-fetch');
async function mintWidgetSessionToken() {
const base = process.env.DOTRUST_API_BASE;
const key = process.env.DOTRUST_EMBED_KEY;
const secretKey = process.env.DOTRUST_SECRET_KEY;
if (!base || !key || !secretKey) {
throw new Error('Missing DOTRUST_API_BASE / DOTRUST_EMBED_KEY / DOTRUST_SECRET_KEY');
}
const res = await fetch(`${base}/embedded/widget/session_token`, {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-widget-embed-key': secretKey,
},
body: JSON.stringify({ key }),
});
const data = await res.json();
if (!res.ok || data.error || !data.widgetSessionToken) {
throw new Error(`Failed to mint session token: ${data.error || res.statusText}`);
}
return data.widgetSessionToken;
}
module.exports = { mintWidgetSessionToken };python
"""
Mint a DoTrust embedded-widget session token (server tier, Python).
The SECRET key must stay on your server, and you must call this from one of your
allowlisted IPs. Returns a short-lived (24h) token that you inject into the page
on each widget div as `data-session`.
Env:
DOTRUST_API_BASE e.g. https://complete.dotrust.co
DOTRUST_EMBED_KEY your embed key
DOTRUST_SECRET_KEY your secret key (server only)
Requires: requests (pip install requests)
"""
import os
import requests
def mint_widget_session_token() -> str:
base = os.environ.get("DOTRUST_API_BASE")
key = os.environ.get("DOTRUST_EMBED_KEY")
secret_key = os.environ.get("DOTRUST_SECRET_KEY")
if not base or not key or not secret_key:
raise RuntimeError(
"Missing DOTRUST_API_BASE / DOTRUST_EMBED_KEY / DOTRUST_SECRET_KEY"
)
res = requests.post(
f"{base}/embedded/widget/session_token",
json={"key": key},
headers={"x-widget-embed-key": secret_key},
timeout=15,
)
data = res.json()
token = data.get("widgetSessionToken")
if not res.ok or data.get("error") or not token:
raise RuntimeError(
f"Failed to mint session token: {data.get('error') or res.reason}"
)
return tokenINFO
A personalised version of these examples — pre-filled with your keys and allowed widgets — can be downloaded from the Embedded widgets admin tab.
Available widgets
Your allowed widgets are listed in the admin tab, and data-dot-widget must be one of them. Examples include demographics, income, affordability, accounts, peps, vrs, creditActive, customerRisk, and disclosureRequest (the inline bank-data disclosure-requests manager). The list in the admin tab is authoritative — a div naming a widget you have not allowed will not render. Ask your CSM for information and assistance.
Behaviour notes
Automatic enrolment. The embed resolves each div's
data-customer-idto a customer record and locks that customer's widgets to it. If the customer ID isn't known yet on the DoTrust platform it is created automatically across all your brands.Customer PII management If a widget has a risk check such as Light Touch vulnerability which hasn't run yet, it is run on demand when there is enough PII for the customer available in the DoT platform. You can integrate the PII admin widget to add or edit customer details shared with DoT within your PAM, or use our API.
Bank and document disclosure requests. The
disclosureRequestwidget renders the bank-data disclosure manager (create / send / revoke disclosure requests). If you are using embedded journeys this is not required.Sizing. Each iframe fills its div; size the div container as you like. They are expecting full width or at least 50vw.
Auditing
When you use Remote Control all views and actions are assigned to a Service Account. We have no visibility of which member of your team is logged in to your PAM. Please let us know if you require us to integrate this information; it may be possible depending upon your security model.
Security
WARNING
Never expose the secret key in a browser. Use it server-side only — session tokens must be minted by your backend, never in the page.
| Control | Detail |
|---|---|
| Server-minted only | A single secret key, held only on your backend, mints session tokens. There is no page-visible key and no in-page minting. |
| Mandatory IP allowlist | Session tokens can only be minted from an IP in the embed's allowlist (at least one required) — your server's egress IPs. This is the primary control on who can mint. |
| Short-lived, operator-scoped tokens | The session token is valid 24h and bound to one operator (not a customer or domain). The customerId travels per request. |
| Server-resolved identity | customerId (your op_uid) is resolved to an internal customer record server-side; the client can never substitute another customer. |
| Auto-enrolment boundary | An unknown customerId is enrolled for your operator, so a token can reach any of your customers. Treat the secret key and the IP allowlist as the security boundary. |
| Least-PII per iframe | Each widget receives only the data slices it actually renders, not the full customer record. |
| Framing | Your permitted-domains list is enforced as the CSP frame-ancestors allowlist — it controls which origins may frame your widgets. It is not a minting control. |
