# Setup overview

> The entire installation on one page — the order of operations, why each step precedes the next, and a checklist you can track against.

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

This is the whole journey in order. Each deep-dive page has the exact commands;
this page is the map, so you always know where you are and what has to be true
before the next step.

## The order, and why [#the-order-and-why]

<Callout title="The dependency that shapes everything">
  Canvas registrations bind to your final `TOOL_URL`, and the LTI configuration is
  served **by the running service** at `${TOOL_URL}/lti/config`. A first install
  therefore has two deliberate Canvas handoffs: first the API OAuth key after the
  stable URL is known, then the LTI key and app deployment after the service is
  ready. The release bundles record `bootstrap-pending` only until the real LTI
  client and deployment IDs are available.
</Callout>

<Steps>
  <Step>
    ### Download, verify, and begin the release install [#download-verify-and-begin-the-release-install]

    Download the versioned GitHub Release, verify the adjacent SHA-256 checksum and
    the release attestation, then run the matching guided installer. It creates or
    validates the database and protected values, reserves or validates the HTTPS
    origin, pauses for the API OAuth key, and deploys a first service revision.
    Confirm `/health`, `/ready`, `/lti/config`, and JWKS respond.

    → [Google Cloud](/docs/deploy/google-cloud) · [Docker](/docs/deploy/docker) ·
    [Configuration](/docs/deploy/configuration)
  </Step>

  <Step>
    ### Create the SEB encryption identity (default mode) [#create-the-seb-encryption-identity-default-mode]

    Generate the certificate/identity pair. The **public** certificate goes to the
    service; the **private** identity goes only to your device vault. This can be done
    alongside pass 1. If the institution has explicitly approved plaintext
    compatibility mode, record that decision instead and skip this device-identity
    workflow.

    → [Certificate management](/docs/deploy/certificates)
  </Step>

  <Step>
    ### Create the Canvas API OAuth key [#create-the-canvas-api-oauth-key]

    Create the **API OAuth** Developer Key with the exact application and
    administrator scope sets. The release install records its client ID and secret
    through protected input.

    → [API OAuth key](/docs/canvas/api-oauth-key)
  </Step>

  <Step>
    ### Create and install the LTI app [#create-and-install-the-lti-app]

    Use `${TOOL_URL}/lti/config` as Canvas's JSON configuration URL, enable the LTI
    Developer Key, then install the external app by client ID. Canvas assigns the
    deployment ID; record both values.

    → [Install the app](/docs/canvas/install-app)
  </Step>

  <Step>
    ### Finalize the LTI IDs (pass 2) [#finalize-the-lti-ids-pass-2]

    The installer creates new versions for the real `LTI_CLIENT_ID` and
    `LTI_DEPLOYMENT_ID`, stages a verified revision, and explicitly cuts traffic over.
    The service now accepts real launches.
  </Step>

  <Step>
    ### Load the detector script [#load-the-detector-script]

    Add the small theme loader so the detector runs on quiz pages. Self-hosted Canvas
    may need the hosted-loader workaround.

    → [Detector script](/docs/canvas/detector-script)
  </Step>

  <Step>
    ### Deploy the certificate to devices (certificate mode) [#deploy-the-certificate-to-devices-certificate-mode]

    Install the private identity onto exam devices via your MDM, non-extractable and
    SEB-scoped. Validate on a test device with the setup check.

    For an explicitly approved plaintext compatibility deployment, document the
    exception and validate its Config Key, session-handoff, URL-filter, and lockdown
    controls instead.

    → [Device deployment](/docs/operate/devices)
  </Step>

  <Step>
    ### Verify end to end [#verify-end-to-end]

    Run the administrator, instructor, student, and in-SEB acceptance sequence before
    any real exam.

    → [Verify the integration](/docs/operate)
  </Step>

  <Step>
    ### Schedule operations [#schedule-operations]

    Turn on scheduled cleanup, backups, and monitoring; document your rotation and
    incident procedures.

    → [Operations](/docs/operate/operations)
  </Step>
</Steps>

## Checklist [#checklist]

Copy this into your rollout ticket.

```text
PLAN
[ ] Final HTTPS TOOL_URL decided (and custom domain mapped, if any)
[ ] Canvas cloud vs self-hosted determined; issuer/endpoints confirmed
[ ] Deployment-ID policy decided
[ ] SEB clients + MDM ready for device identity install (or plaintext compatibility mode formally approved)

DEPLOY (pass 1)
[ ] Database provisioned (PostgreSQL 17+)
[ ] Secrets created (LTI key, session/state secrets, DB password)
[ ] Stable URL reserved; service reachable without auth challenge
[ ] Service deployed with bootstrap-pending LTI IDs
[ ] /health, /ready, /lti/config, /.well-known/jwks.json all respond

CERTIFICATE
[ ] Certificate mode: identity generated; public cert in the service secret
[ ] Certificate mode: private .p12 + passphrase moved to device vault; workstation copies removed

CANVAS
[ ] API OAuth key created with full application + admin scopes
[ ] LTI 1.3 key created from /lti/config and enabled
[ ] App installed; deployment ID recorded

DEPLOY (pass 2)
[ ] Real LTI_CLIENT_ID and LTI_DEPLOYMENT_ID deployed
[ ] Detector theme loader installed and loading on quiz pages

ROLL OUT
[ ] Certificate mode: profile installed on test device; setup check passes
[ ] Admin / instructor / student / in-SEB acceptance sequence passed

OPERATE
[ ] Cleanup scheduled (daily)
[ ] Backups running + one restore drill completed
[ ] Monitoring/alerts configured
[ ] Rotation + incident procedures documented
```

Start with [Deploy the application](/docs/deploy).