# School roster integrations

ClassGuard includes read-only roster connectors for Google Classroom / Workspace, Clever Secure Sync (API v3.1), the ClassLink OAuth2 roster proxy, Canvas LMS, and compatible OneRoster 1.1/1.2 services using OAuth2 client credentials. CSV remains a fallback. These connectors import students and class memberships; they do not create staff accounts, assign staff privileges, sync grades, or configure school sign-in. [School SSO](sso-setup.md) is configured separately for staff and students.

## School setup

1. School IT obtains approved, least-privilege access from the provider and limits sharing to the intended district, students and classes. Clever and ClassLink require their own application/partner setup and district authorization. Connector code alone does not register ClassGuard in either app directory or establish an official partnership.
2. On the school server, run `npm run configure:integrations`. Choose a provider. Enter its non-secret settings and paste its credential into the hidden terminal prompt. Keep keys out of chat, Chrome policy and browser storage. Google continues to use [the Google setup guide](google-workspace-setup.md).
3. The helper saves a versioned JSON configuration in `classguard-server/private/integrations.json` with mode 0600 in a private folder. Only `CLASSGUARD_INTEGRATIONS_FILE` is added to the school `.env`. Other provider configurations and school settings are preserved. Restart the school service.
4. Sign in as a ClassGuard administrator. Open **Student lists → School connections → Review students**. Review new/updated students, linked CSV identities, class memberships and students losing access. **Save [provider] student list** applies that exact review. A failed or empty response never replaces the saved list.
5. In **Staff & classrooms**, assign imported class groups to existing staff accounts and create saved classrooms. Student devices still require the Chrome extension and enrollment; use personal setup codes or separately configured [school SSO](sso-setup.md).

Configuration check: `npm run configure:integrations -- --check` validates the local file without contacting a provider. A connection is only verified when a real provider review succeeds. The dashboard distinguishes “IT setup needed” from “Ready to review” and displays the last saved sync.

## Provider access

### Google Classroom / Workspace

The existing connector uses district-approved read-only directory delegation, configured student OUs and explicit Classroom course IDs. It includes a preview/apply flow, periodic sync, student Google enrollment and safeguards for failed, empty and unusually destructive syncs. See [Google setup](google-workspace-setup.md).

### Clever Secure Sync

Obtain a district-app Secure Sync token and its district ID through the approved Clever integration. An SSO user token cannot replace the district roster token. The connector verifies `GET /v3.1/districts/{districtId}`, pages `GET /v3.1/users?role=student`, then pages `GET /v3.1/sections` and reads their student IDs. It retains only student identity, optional email and class membership. No contact, guardian, demographic or grade data is retained.

Clever setup/agreements and any certification requirements must be completed with Clever before production access. References: [API overview](https://dev.clever.com/me/docs/api-overview), [v3.x upgrade guide](https://dev.clever.com/docs/api-v3-upgrade-guide), [pagination](https://dev.clever.com/me/docs/paging-and-limits), [teacher roster workflow](https://dev.clever.com/docs/build-teacher-facing-roster-app).

### ClassLink

Use the exact **app-scoped OAuth2 Proxy roster API base URL** and **application access token** from ClassLink Partner Portal / its API reference after the district shares data. The base must be on `oneroster-proxy.apis.classlink.com`. Do not use the partner-wide applications-list key or append a guessed tenant/application path. The connector reads the app’s OneRoster `students`, `classes` and `enrollments` collections with limit/offset pagination. Direct legacy OAuth1-signature connections are not implemented; use ClassLink’s documented OAuth2 Proxy route.

References: [partner setup](https://help.classlink.com/s/article/pp-about-oc-rs), [approved roster access methods](https://help.classlink.com/articles/Knowledge/pp-access-rs-data).

### Canvas LMS

Use the school’s HTTPS Canvas origin, a school-approved read-only API token and an explicit list of course IDs (up to 5,000). Required GET scopes: `/api/v1/courses/:course_id`, `/api/v1/courses/:course_id/sections`, and `/api/v1/courses/:course_id/enrollments`. The connector accepts published (`available`) courses and active `StudentEnrollment` records, follows Link-header pagination and separates course sections into roster groups. Configure an account with access to every selected course and its student enrollment records.

Canvas email may be unavailable to the token; those students retain their stable Canvas identity and use setup codes. The connector does not call assignment, submission, message or grade endpoints and discards all fields outside identity and section membership from provider responses. It does not write to Canvas.

References: [course/enrollment API](https://developerdocs.instructure.com/services/canvas/resources/enrollments), [pagination](https://developerdocs.instructure.com/services/canvas/basics/file.pagination).

### OneRoster and other SIS/LMS systems

Provide the exact HTTPS rostering service base URL, OAuth token URL, client ID, client secret and provider-approved read-only scope. OneRoster 1.2 commonly uses `https://purl.imsglobal.org/spec/or/v1p2/scope/roster-core.readonly`; use the provider’s corresponding 1.1 scope for a 1.1 service. The client reads `students`, `classes` and `enrollments`, follows supplied pagination links or 500-record offsets, excludes disabled/deleted users and inactive memberships, and preserves unrelated manual groups. This is a tested subset client, not a claim of 1EdTech certification or compatibility with every SIS configuration.

Reference: [OneRoster 1.1 specification and OAuth2 requirements](https://www.imsglobal.org/oneroster-v11-final-specification).

## Identity and change review

- Provider identities are namespaced by provider and district/API connection, so identical IDs from different systems cannot collide.
- Default imports do not automatically merge existing email identities. An administrator may select **Link existing CSV students by matching email**, then review and save the matching preview. Existing CSV IDs and device enrollment hashes are preserved. Records already owned by another integration cannot be taken over through that option; choose an authoritative roster source or plan an explicit migration.
- Manual groups are retained. Provider-managed memberships refresh from the source. Stable source class IDs preserve existing group labels across provider title changes, so saved classroom assignments are retained; rename/reassign a group separately when desired.
- Removed source students are disabled and their personal enrollment codes revoked when the administrator saves that review. Other sources’ records remain intact. Live students whose source was disabled or whose class membership ended are removed from the affected live class.
- Reviews are bound to the administrator session, expire after 15 minutes, and cannot be applied after any roster revision change. Failed, empty, expired and partial requests never commit.
- Saved identities and last-sync timestamps persist in the private roster and school backup. Provider tokens remain in the separate private config; include that file only in a separately encrypted IT recovery process. Browser responses and generated school packages exclude tokens and client secrets.

## Automatic sync and limits

Choose an optional 15–1,440-minute interval in the server setup helper. A first import always needs manual review. Automatic updates that would disable more than 20% of that source’s previously active students require administrator review. Only one external-provider review runs at a time. Google has its existing separate sync schedule.

The shared roster supports 100,000 records. Reviews retain a bounded preview of 25 students. API requests use public HTTPS, pinned public DNS results, no credential-bearing redirects, response/time bounds and API-scoped pagination. The client rejects paging loops and cross-origin links. Provider request errors are sanitized.

Live classrooms still have separate capacity limits: 30 students per class and 50 rooms per school-server instance. Larger rosters do not establish concurrent screenshot capacity. Test district credentials, representative provider data, course sharing, removals, device enrollment and load before production rollout. Automated connector tests use synthetic API fixtures; real provider tenant credentials are required for a live compatibility check.
