# Canvas setup overview

> What to register in Canvas, in what order, and the endpoints and values you will move between Canvas and your deployment.

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

With the service deployed and reachable, you now register it in Canvas. This
section creates two developer keys, installs the app, and loads the detector
script. Do it in order — each step produces a value the next one (or your
redeploy) needs.

<Callout type="warn" title="Deploy first">
  Your public `TOOL_URL` must be final before you create Canvas registrations, and
  the LTI registration document is served by the running service at
  `${TOOL_URL}/lti/config`. If you have not deployed yet, start with
  [Deploy the application](/docs/deploy).
</Callout>

## Before you touch Canvas [#before-you-touch-canvas]

Confirm these service endpoints respond on the deployed URL:

```bash
curl -fsS "${TOOL_URL}/health"
curl -fsS "${TOOL_URL}/lti/config"
curl -fsS "${TOOL_URL}/.well-known/jwks.json"
curl -fsS "${TOOL_URL}/js/canvas-seb-detector.js" | head
```

`${TOOL_URL}/setup` and `/setup/guide` provide a public, role-oriented checklist.
They confirm the service responds — not that Canvas has stored the intended
registration or loaded the detector.

## The order [#the-order]

<Steps>
  <Step>
    ### Create the API OAuth Developer Key [#create-the-api-oauth-developer-key]

    User-scoped Canvas OAuth for assessment discovery and access-code changes, with a
    specific scope set. → [API OAuth key](/docs/canvas/api-oauth-key)
  </Step>

  <Step>
    ### Create the LTI 1.3 Developer Key [#create-the-lti-13-developer-key]

    Registered from `${TOOL_URL}/lti/config` as Canvas's JSON configuration URL.
    This is not the separate OpenID Dynamic Registration protocol. →
    [LTI 1.3 key](/docs/canvas/lti-key)
  </Step>

  <Step>
    ### Install the external app [#install-the-external-app]

    Install by client ID at the intended account scope and record the deployment ID.
    → [Install the app](/docs/canvas/install-app)
  </Step>

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

    Add the theme JavaScript loader so the detector runs on quiz pages.
    → [Detector script](/docs/canvas/detector-script)
  </Step>
</Steps>

Then redeploy with the real LTI client and deployment IDs (pass 2), and
[verify the integration](/docs/operate).

## Values to record [#values-to-record]

| Value                      | Canvas source                                              | Runtime destination                            |
| -------------------------- | ---------------------------------------------------------- | ---------------------------------------------- |
| `CANVAS_DOMAIN`            | The Canvas base origin (e.g. `https://canvas.example.edu`) | `CANVAS_DOMAIN`                                |
| `LTI_CLIENT_ID`            | LTI 1.3 Developer Key client ID                            | `LTI_CLIENT_ID`                                |
| `LTI_DEPLOYMENT_ID`        | External App deployment ID after install                   | `LTI_DEPLOYMENT_ID` (when checking is enabled) |
| `CANVAS_API_CLIENT_ID`     | API OAuth Developer Key client ID                          | `CANVAS_API_CLIENT_ID`                         |
| `CANVAS_API_CLIENT_SECRET` | API OAuth Developer Key secret                             | `CANVAS_API_CLIENT_SECRET`                     |
| `CANVAS_REDIRECT_URI`      | OAuth callback registration                                | `${TOOL_URL}/api/oauth2callback`               |

<Callout type="warn" title="The two client IDs are different">
  The LTI client ID and the Canvas API OAuth client ID come from **different**
  registrations. Mixing them breaks either signed LTI launches or Canvas API
  authorization. Keep them clearly labeled.
</Callout>

## Self-hosted Canvas [#self-hosted-canvas]

If your Canvas is self-hosted (not `*.instructure.com`), read
[Self-hosted Canvas](/docs/canvas/self-hosted-canvas) **before** registering. You
will need to override authorization/JWKS endpoints, confirm the exact issuer, and
possibly rotate Canvas signing keys and use the hosted detector-loader workaround.

## Prerequisites for this section [#prerequisites-for-this-section]

You need a Canvas administrator who can manage Developer Keys, external apps,
account themes, and OAuth scopes — plus the deployed service URL and access to the
secret store that supplies its runtime values.