Integrate Google Cloud CDN with Fraud Prevention JavaScript SDK
Google Cloud CDN is a fully managed service that distributes HTTP(S) traffic across backend services and can inspect and modify traffic at the edge. This allows it to act not only as a global entry point for applications but also as a point of control for injecting or filtering content in transit.
Mosaic provides a native integration with GCP Service Extensions that enables you to inject the Device Risk & Security (Fraud Prevention) JavaScript SDK into HTML responses automatically, without modifying your web application code.
This plugin intercepts HTML responses at the CDN level and injects the required <script>
tags for the Fraud Prevention SDK. As a result, every page served through the CDN includes the Fraud Prevention SDK, allowing Mosaic to capture risk signals from client devices transparently.
How it works
When a client requests an HTML page, the request passes through the GCP CDN (1).
The backend returns the response, which is intercepted by the Fraud Prevention plugin (2) at the CDN and modified to inject the SDK before being delivered to the browser. Once the page is loaded, the browser executes the injected Fraud Prevention SDK (formerly DRS) (3). The SDK collects device and risk signals client-side and forwards them to Mosaic for analysis (4).
The plugin uses the following injection strategy (fallback order):
-
After
<meta charset>
(preferred) -
After
<head>
-
Before
<body>
- At the beginning of the document
Before you start
Before you begin:
- A Google Cloud Platform account with billing enabled.
- A Global External HTTPS CDN (only HTTPS is supported).
-
gcloud
CLI installed and configured (version 534.0.0 or higher).
Step 1: Get client credentials
Client credentials are used to identify your app and generate access tokens for authorizing Mosaic requests. To obtain them, you'll need to create an application in the Admin Portal (if you don’t have one yet).
- From Applications , click Add application .
- Add the friendly application name to display in the Admin Portal.
-
Add a client display name, and your website URL as a redirect URI (e.g.,
https://your-domain.com
). These fields are required for all Mosaic apps, but won’t be used for Fraud Prevention. - Click Add to create your application. This will automatically generate your client credentials (you'll need your client ID in step 3 ).
Step 2: Set up your Google Cloud environment
Before deploying the plugin, you need to prepare your Google Cloud environment.
Define your project and enable the required API for Service Extensions.
Run the following commands from a terminal where the gcloud CLI is installed and authenticated (for example, in your local terminal or in the Google Cloud Shell).
Make sure you have the necessary permissions to run these commands; if not, contact your GCP administrator.
# Set your GCP project ID
gcloud config set project YOUR_PROJECT_ID
# Enable the Service Extensions API (required for deploying the plugin)
gcloud services enable serviceextensions.googleapis.com
Step 3: Deploy the HTML Injection WASM plugin
In this step you deploy the Fraud Prevention HTML Injection WASM plugin provided by Mosaic.
This plugin runs as a GCP Service Extension and is responsible for intercepting HTML responses at the CDN level and injecting the Fraud Prevention SDK automatically, without requiring changes to your application code.
The plugin accepts the following parameters:
Parameter | Description | Example |
---|---|---|
clientId |
Your Mosaic app client ID | XXXXXXXXXXXXXXX_XXX |
serverPath |
Fraud Prevention API server path | https://api.transmitsecurity.io/risk-collect/ |
Note
Never expose your clientId
in client-side code samples, public docs, or unsecured environments.
Common server paths by region:
-
US:
https://api.transmitsecurity.io/risk-collect/
-
EU:
https://api.eu.transmitsecurity.io/risk-collect/
-
Canada:
https://api.ca.transmitsecurity.io/risk-collect/
-
Australia:
https://api.au.transmitsecurity.io/risk-collect/
# Set variables for easy configuration
PLUGIN_VERSION="v1-3" # replace with the desired version (currently "v1-3")
PLUGIN_IMAGE="us-central1-docker.pkg.dev/dev-riskid/drs-plugins/drs-sdk-plugin-go:latest" # replace with the image URI (currently Transmit Security's public image)
CLIENT_ID="YOUR_CLIENT_ID" # replace with your DRS client ID (provided by Transmit Security)
SERVER_PATH="YOUR_SERVER_PATH" # replace with your DRS server path (see examples below)
# Create plugin configuration file
cat > plugin-config.txt << EOF
clientId=${CLIENT_ID},serverPath=${SERVER_PATH}
EOF
# Create the WASM plugin
gcloud service-extensions wasm-plugins create drs-html-injection-plugin \
--location=global \
--main-version="${PLUGIN_VERSION}" \
--image="${PLUGIN_IMAGE}" \
--plugin-config-file="plugin-config.txt" \
--log-config="enable=True,sample-rate=1.0,min-log-level=INFO" \
--description="DRS HTML Injection Plugin - Automatically injects DRS SDK into HTML responses"
# (Optional)Clean up config file
rm plugin-config.txt
You will receive a response similar to the one below:
Create request issued for: [drs-html-injection-plugin]
Waiting for operation [projects/dev-riskid/locations/global/operations/operation-1755779730683-63cdf5326b4c9-95d21107-9fd2f84e] to complete...done.
Created WasmPlugin [drs-html-injection-plugin] with WasmPluginVersion [PLUGIN_VERSION].
Example of injected code
When the plugin processes an HTML response, it automatically injects into the page a snippet similar to the one below. This happens at the CDN level — you do not need to add this code manually.
<script async src="https://platform-websdk.transmitsecurity.io/platform-websdk/1.x/ts-platform-websdk.js"></script>
<script>
window.addEventListener('load', function() {
if (window.tsPlatform) {
window.tsPlatform.initialize({
clientId: 'YOUR_CLIENT_ID',
drs: {
enabled: true,
serverPath: 'YOUR_SERVER_PATH'
}
});
console.log('DRS SDK initialized');
}
});
</script>
Note
The values YOUR_CLIENT_ID and YOUR_SERVER_PATH are automatically taken from the plugin configuration. You do not need to replace them manually in your application code.
Note
Use the Google Cloud CLI to check logs and monitor the status of your Service Extension and CDN.
Step 4: Configure the GCP CDN
Attach the plugin to your CDN so it can intercept traffic. This is done by creating a Service Extension that links the plugin to the forwarding rule of your HTTPS CDN.
- Identify the forwarding rule used by your CDN:
# Set your CDN name (replace with your CDN name)
LOAD_BALANCER_NAME="your-load-balancer-name"
# Get the target HTTPS proxy for your CDN
TARGET_PROXY_NAME=$(gcloud compute target-https-proxies list --filter="urlMap:${LOAD_BALANCER_NAME}" --format="value(name)")
# Find forwarding rules that use this target proxy
# (replace FORWARDING_RULE_NAME with your CDN's forwarding rule name)
gcloud compute forwarding-rules list --global --filter="target:${TARGET_PROXY_NAME}" --format="value(name)"
-
Create a Service Extension configuration file that attaches the previously deployed plugin (
drs-html-injection-plugin
) to your forwarding rule:
# Set variables for your GCP resources
PROJECT_ID="YOUR_PROJECT_ID" # replace with your GCP project ID
FORWARDING_RULE_NAME="YOUR_FORWARDING_RULE_NAME" # replace with your CDN's forwarding rule name
# Create service extension configuration
cat > drs-service-extension.yaml << EOF
name: projects/${PROJECT_ID}/locations/global/lbTrafficExtensions/drs-injection-service
description: "DRS HTML Injection Service Extension"
loadBalancingScheme: EXTERNAL_MANAGED
forwardingRules:
- https://www.googleapis.com/compute/v1/projects/${PROJECT_ID}/global/forwardingRules/${FORWARDING_RULE_NAME}
extensionChains:
- name: drs-injection-chain
matchCondition:
celExpression: "true"
extensions:
- name: drs-html-injection-plugin
service: projects/${PROJECT_ID}/locations/global/wasmPlugins/drs-html-injection-plugin
supportedEvents:
- RESPONSE_BODY
- RESPONSE_HEADERS
failOpen: true
EOF
- Apply the Service Extension so it becomes active on the CDN:
gcloud service-extensions import drs-service-extension.yaml
Step 5: Set user
A user identifier must be reported to Mosaic after the user is fully authenticated (including any required 2FA). This sets the user for all subsequent events in the current browser session.
The Web SDK is automatically injected and initialized by the CDN plugin after Steps 3–4.
You only need to call setAuthenticatedUser
once window.tsPlatform
is available.
Implement this in your web application code. The [USER_ID]
is an opaque identifier for the user in your system.
await window.tsPlatform.drs.setAuthenticatedUser('[USER_ID]');
Note
Do not include personal user identifiers (e.g., email) in plain text.
Step 6: Trigger actions
To obtain risk recommendations for sensitive actions, your application should report these actions from the web app using the Platform SDK. Add an event listener to the relevant form or button in your page and include the following code in your web application (after SDK initialization). Replace [ACTION_TYPE]
with an action from the list of actions. Optionally pass a correlation ID and a claimed user ID (for unauthenticated users).
// Trigger events for the action and get the actionToken
// (Optional) correlationId and claimedUserId help improve Fraud Prevention
const tsAccountProtectionLoginHandler = `
<script>
async function onSubmitLogin(event) {
event.preventDefault();
try {
const value = await window.tsPlatform.drs.triggerActionEvent("[ACTION_TYPE]", { correlationId: "[CORRELATION_ID]", claimedUserId: "[CLAIMED_USER_ID]" });
form.submit();
} catch (error) {
form.submit();
};
}
let form = document.getElementById("login");
if (form) {
form.addEventListener('submit', onSubmitLogin);
}
</script>
`;
Note (Backend handoff)
Make sure to pass the received actionToken
to your backend together with the actual action invocation so that your server can fetch the recommendation in the next step.
Step 7: Fetch recommendation
From your server, fetch recommendations for the reported action using the Recommendation API.
These APIs are authorized using an OAuth access token. Obtain a token with client credentials (from Step 1). The token should target the following resource: https://risk.identity.security
.
const { access_token } = await fetch(
`https://api.transmitsecurity.io/oidc/token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
body: new URLSearchParams({
grant_type: client_credentials,
client_id: [CLIENT_ID],
client_secret: [CLIENT_SECRET],
resource: 'https://risk.identity.security'
})
}
);
From your backend, invoke the Recommendation API. The [ACCESS_TOKEN]
is the token you obtained above and [ACTION_TOKEN]
is the actionToken
received from the SDK in Step 6.
const query = new URLSearchParams({
action_token: '[ACTION_TOKEN]',
}).toString();
const resp = await fetch(
`https://api.transmitsecurity.io/risk/v1/recommendation?${query}`,
{
method: 'GET',
headers: {
Authorization: 'Bearer [ACCESS_TOKEN]',
},
}
);
Note (Backend step)
This is a server-side (machine-to-machine) call and is not handled by the CDN plugin or the Web SDK.
Step 8: Clear user
When the user logs out or the session expires, clear the user so future actions aren’t associated with the previous user. Implement this in your web application (e.g., on logout).
const tsClearUserHandler = `
<script>
async function onUserLogout(event) {
await window.tsPlatform.drs.clearUser()
}
let button = document.getElementById("logout");
if (button) {
button.addEventListener('click', onUserLogout);
}
</script>
`;