# Prerequisites

> The access, infrastructure, people, and decisions to settle before you start — so the setup runs without stalls.

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

Settle everything on this page before you begin. Most failed or half-finished
installs trace back to a missing prerequisite discovered mid-way — a scope that
cannot be added, a domain that is not final, or a device fleet with no management
tooling.

## People and access [#people-and-access]

<Cards>
  <Card title="A Canvas administrator" description="Someone who can create and manage Developer Keys, install external apps, edit account themes / JavaScript, and configure OAuth scopes at the root account." />

  <Card title="Cloud or host access" description="Owner/editor on a Google Cloud project (for Cloud Run), or root on a Linux host with Docker (for the self-hosted path)." />

  <Card title="A device-management owner" description="Whoever runs your MDM/device fleet, to install the SEB configuration-encryption identity onto exam devices." />
</Cards>

## Infrastructure [#infrastructure]

| Requirement                                   | Why                                                                                                                                                                            |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| A final, stable **HTTPS** origin (`TOOL_URL`) | Canvas registrations bind to it. The release bundle reserves or validates it before the Canvas handoffs. Changing it later is a Canvas re-registration, not a simple redeploy. |
| PostgreSQL 17 or newer                        | The durable store for settings, tokens, sessions, one-time state, and locks. Managed (Cloud SQL) or self-run.                                                                  |
| TLS termination                               | Cloud Run provides it; on a VPS you run a reverse proxy (Caddy, nginx, Traefik). Canvas will not launch a plain-HTTP tool.                                                     |
| Outbound access to Canvas                     | The service calls the Canvas REST and New Quiz APIs and Canvas's OAuth/JWKS endpoints.                                                                                         |

<Callout type="warn" title="Decide the URL first">
  The public origin flows into the LTI registration, the OAuth callback, the JWKS
  URL, and the detector script URL. Pick the final hostname (and, if you use one,
  finish the custom-domain mapping) **before** creating any Canvas keys. Both deploy
  guides reserve a stable URL as their first step for this reason.
</Callout>

## Safe Exam Browser and devices [#safe-exam-browser-and-devices]

* **Supported SEB clients** installed on exam devices (macOS and/or Windows).
  The generated configuration relies on client features such as Config Key proof
  and, on macOS, Automatic Assessment Configuration (AAC).
* **For the default certificate-encryption mode, a way to install a
  certificate/identity profile** on those devices — an MDM or equivalent. The
  private identity must be installed non-extractably and scoped to the SEB
  application; you cannot hand students a `.p12` file. If that is impossible,
  formally decide whether the lower-assurance plaintext compatibility mode is
  acceptable before deployment.
* Time to run a **setup check** on a representative device before any real exam.

<Callout title="Accessibility note">
  On macOS, AAC can block some third-party assistive technology. Plan
  accommodations that need such tools as a separately approved arrangement rather
  than by weakening the shared configuration. See
  [Certificate management](/docs/deploy/certificates) and
  [SEB configuration policy](/docs/reference/glossary#aac).
</Callout>

## Decisions to make now [#decisions-to-make-now]

### Deployment target [#deployment-target]

<Cards>
  <Card title="Google Cloud Run + Cloud SQL" href="/docs/deploy/google-cloud" description="Recommended managed path. A verified release bundle provisions or validates the infrastructure, uses numbered secret versions, and stages a no-traffic candidate before cutover." />

  <Card title="Docker Compose on a Linux host" href="/docs/deploy/docker" description="A verified release bundle with PostgreSQL, migrations, file secrets, optional Caddy, backup, and upgrade helpers. You operate the host and recovery process." />
</Cards>

The application runtime is provider-neutral. Cloud Build remains a maintained
source-based path for the repository's existing `canvas-seb-*` environments;
new public installations should use the matching release bundle instead.

### Canvas environment: cloud or self-hosted [#canvas-environment-cloud-or-self-hosted]

* **Canvas cloud** (`*.instructure.com`): the built-in defaults apply; no endpoint
  overrides needed.
* **Self-hosted Canvas**: you must override the authorization and JWKS endpoints
  and confirm the exact `iss` (issuer) Canvas sends. Read
  [Self-hosted Canvas](/docs/canvas/self-hosted-canvas) before you start — a
  self-hosted Canvas can still use `https://canvas.instructure.com` as its issuer,
  so do not infer it from the hostname.

### Deployment-ID policy [#deployment-id-policy]

By default the service accepts launches only from the specific installed
deployment ID you configure. A controlled self-service mode
(`LTI_DEPLOYMENT_ID_CHECKING_ENABLED=false`) accepts any signed launch from your
Canvas issuer and client ID — use it only if everyone who can install this app in
Canvas is trusted. See [Configuration](/docs/deploy/configuration#deployment-id-policy).

### Isolation [#isolation]

Confirm the list of **independent** environments you need. Each one gets its own
service URL, database, secrets, LTI deployment, and OAuth credentials. Never share
these across a test and a production Canvas.

## Values you will collect [#values-you-will-collect]

Keep a secure scratch document (not in version control, not in chat) for the
values that appear during setup. You will move them into your secret store:

| Value                                               | Source                                                                                                     |
| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `TOOL_URL`                                          | Your final HTTPS origin.                                                                                   |
| `CANVAS_DOMAIN`                                     | Your Canvas base origin.                                                                                   |
| `LTI_CLIENT_ID`                                     | LTI 1.3 Developer Key client ID.                                                                           |
| `LTI_DEPLOYMENT_ID`                                 | Assigned when you install the external app.                                                                |
| `CANVAS_API_CLIENT_ID` / `CANVAS_API_CLIENT_SECRET` | API OAuth Developer Key.                                                                                   |
| LTI signing key, session/state secrets, DB password | Generated during deploy.                                                                                   |
| SEB encryption certificate + private identity       | Required only for the default certificate-encryption mode; the private half goes to the device vault only. |

When these are ready, continue to the [Setup overview](/docs/setup-overview).