# Safe Online Exam documentation

> The operator guide for the public Safe Online Exam 1.x release line: what you install, who owns each part, and how to set it up safely.

[Canonical HTML page](https://safeonlineexam.com/docs)

Safe Online Exam is a public, source-available Canvas LTI 1.3 integration for
[Safe Exam Browser (SEB)](https://safeexambrowser.org/). It supports Canvas
Classic Quizzes and New Quizzes. Instructors decide which assessments require
SEB; students receive a purpose-built configuration; and the Canvas access code
is released only after SEB proves it is running the current configuration.

Version 1 is a stable public release line. Install a versioned GitHub Release,
verify its checksum and image attestation, and pin the exact published container
digest. The project, releases, changelog, security reporting path, and license are
at [JSB2010/safe-online-exam](https://github.com/JSB2010/safe-online-exam).

This documentation is the **setup and operations guide for the people who stand
the service up and keep it running** — Canvas administrators, institutional IT,
and system administrators. It is not the developer reference for the codebase. It
takes you from nothing to a fully working, verified integration, in order.

<Callout title="What you are installing">
  Three things work together, and you own all three:

  1. **The application** — a published Node.js container with PostgreSQL 17 or
     newer, installed through a Cloud Run or Docker Compose release bundle.
  2. **The Canvas registration** — LTI and OAuth developer keys, an installed app,
     and a small theme script, all pointing at your deployed service.
  3. **The SEB client identity** — normally, an encryption certificate whose
     private half lives only on managed exam devices, so only approved devices can
     open a configuration. A documented plaintext compatibility mode exists for
     fleets that cannot distribute that identity; it is not equivalent protection.
</Callout>

## Who this is for [#who-this-is-for]

<Cards>
  <Card title="Canvas administrators" description="You manage Developer Keys, external apps, account themes, and OAuth scopes. Sections on connecting Canvas and rolling out are written for you." />

  <Card title="Institutional IT / sysadmins" description="You run the service, the database, backups, and the device fleet. The deploy, operate, and troubleshooting sections are yours." />

  <Card title="Assessment / academic-integrity leads" description="You decide policy — which quizzes are locked down, which tools are allowed. The rollout and usage pages explain the day-to-day surfaces." />
</Cards>

## How to read this guide [#how-to-read-this-guide]

The left navigation is ordered as a path. If you are installing for the first
time, follow it top to bottom:

<Steps>
  <Step>
    ### Understand the model [#understand-the-model]

    [How it works](/docs/how-it-works) explains the trust and proof model in plain
    terms, so the configuration choices later make sense.
  </Step>

  <Step>
    ### Plan [#plan]

    [Prerequisites](/docs/prerequisites) is the checklist of access, infrastructure,
    and decisions to settle before you touch anything. [Setup overview](/docs/setup-overview)
    is the whole journey on one page.
  </Step>

  <Step>
    ### Install the release [#install-the-release]

    Choose [Google Cloud Run](/docs/deploy/google-cloud) or
    [Docker Compose](/docs/deploy/docker). Both release bundles use a verified,
    immutable image, generate or collect protected values, run migrations before
    traffic, and guide the two Canvas handoffs. Then review
    [configuration](/docs/deploy/configuration) and, where applicable,
    [certificate management](/docs/deploy/certificates).
  </Step>

  <Step>
    ### Connect Canvas [#connect-canvas]

    Create the [OAuth](/docs/canvas/api-oauth-key) and
    [LTI](/docs/canvas/lti-key) developer keys,
    [install the app](/docs/canvas/install-app), and load the
    [detector script](/docs/canvas/detector-script).
  </Step>

  <Step>
    ### Validate and operate [#validate-and-operate]

    [Verify the integration](/docs/operate) end to end, deploy the certificate to
    devices when encryption is enabled, and establish
    [operations](/docs/operate/operations).
  </Step>
</Steps>

<Callout type="warn" title="One deployment per Canvas">
  A single deployment connects to exactly &#x2A;*one Canvas tenant and environment.**
  Keep separate service URLs, databases, secrets, LTI registrations, and OAuth
  credentials for any environments that must stay isolated (for example a test
  Canvas and a production Canvas). This is the most common source of confusing
  launch failures — see [How it works](/docs/how-it-works#one-deployment-per-canvas).
</Callout>

## When something breaks [#when-something-breaks]

The [Troubleshooting](/docs/troubleshooting) section is organized by symptom —
what you see in Canvas, the browser console, or SEB — and maps each to the check
that resolves it. The reference pages hold the full
[configuration-variable table](/docs/reference/configuration), the
[public endpoint list](/docs/reference/routes), and a
[glossary](/docs/reference/glossary).