Safe OnlineExam
Connect Canvas

Load the detector script

Add the detector via a Canvas theme JavaScript loader so it runs on quiz pages, and handle the self-hosted Canvas local-file (HTTP 422) case.

The detector runs on Canvas quiz-taking pages. It launches the protected SEB flow, fills the access code only after Config Key proof, shows approved web tools, and detects Canvas-confirmed completion. It reaches those pages by being loaded through your Canvas account theme JavaScript.

The stable script URL is:

${TOOL_URL}/js/canvas-seb-detector.js

Create the loader

Upload a small loader (not the detector itself) as the theme's desktop JavaScript. Replace ${TOOL_URL} before uploading.

(function () {
  "use strict";

  const detectorUrl = "${TOOL_URL}/js/canvas-seb-detector.js";
  const assessmentPath = /^\/courses\/\d+\/(?:quizzes\/\d+\/take|assignments\/\d+)(?:\/|$)/;

  if (!assessmentPath.test(window.location.pathname)) {
    return;
  }
  if (document.querySelector('script[data-canvas-seb-detector="true"]')) {
    return;
  }

  const script = document.createElement("script");
  script.src = detectorUrl;
  script.async = true;
  script.dataset.canvasSebDetector = "true";
  document.head.appendChild(script);
})();

The pattern matches Classic Quiz /take pages and New Quiz assignment routes (including their Canvas-generated descendants). script.src must be a plain JavaScript URL string — not a Markdown link.

Upload as theme JavaScript

Upload the loader as the account theme's desktop JavaScript and apply the theme at the intended account scope.

Confirm it applies at the right scope

Theme upload capability and inherited-theme behavior vary by Canvas configuration. If the upload control is unavailable, resolve that account setting before treating the detector as installed.

Retest after Canvas changes

Retest the loader after significant Canvas theme, CSP, or quiz-rendering changes.

Self-hosted Canvas: the local-file (HTTP 422) case

Some self-hosted Canvas deployments store an uploaded theme JavaScript file as a local /accounts/:accountId/files/:fileId/download attachment. Rails can reject that response with ActionController::InvalidCrossOriginRequest (HTTP 422), so the loader never reaches the service. This is a Canvas attachment-serving limitation — not an LTI, detector, or deployment-ID failure.

Do not disable CSRF protection

When the browser console shows that 422, do not disable Canvas CSRF protection globally. Instead, point the account theme's js_overrides value at the externally hosted loader:

${TOOL_URL}/js/canvas-seb-theme-loader.js

The hosted loader keeps the same quiz-route scope and loads the full detector only on Classic Quiz /take pages and New Quiz assignment routes. Canvas's Theme Editor has no direct URL field, so set this through your provisioning/administration path and preserve it on future theme saves. For a one-off root-account recovery, run this inside the Canvas web container (replace the account ID and URL):

bundle exec rails runner '
account = Account.find(1)
current = account.brand_config || BrandConfig.default
attrs = current.attributes.slice(*BrandConfig::ATTRS_TO_INCLUDE_IN_MD5.map(&:to_s))
attrs["js_overrides"] = "https://seb.example.edu/js/canvas-seb-theme-loader.js"
replacement = BrandConfig.for(attrs.symbolize_keys)
replacement.save_unless_dup!
replacement.sync_to_s3_and_save_to_account!(nil, account)
'

For a broader deployment, configure S3-compatible attachment storage and re-upload the theme file — Canvas then serves uploaded theme assets from object storage instead of the local files controller. That is the durable fix for arbitrary uploaded theme JavaScript; the hosted loader is the smallest safe fix for this integration.

The service also exposes /api/seb/canvas-detector.js as a compatibility alias for an existing installation that uses that path. New loaders should use /js/canvas-seb-detector.js.

Verify the detector loaded

In a normal browser, open a Classic Quiz /take page and a New Quiz assignment route and confirm the detector script loads without console errors, and that ${TOOL_URL}/js/canvas-seb-detector.js returns JavaScript. If it never loads, see Troubleshooting → Detector.

Next: verify everything end to end in Roll out & operate.

On this page