Platform3 · Canonical architecture

Oneroster 1edtech Architecture

This page is rendered directly from the committed architecture decisions. Each stable section anchor is part of the public traceability contract.

Source-bound decision record

14 committed decisions · oneroster/1edtech

#oneroster_auth_shape

oneroster auth shape

Unspecified

Decision

SHIP: platform HS256 Bearer JWTs with role/scopes plus OneRoster relationship-scoped claims agentOf, schoolSourcedIds[], and classSourcedIds[] where the caller needs narrower visibility.

Alternatives and tradeoffs

  • role-only JWT
  • role+scopes without relationship claims
  • separate OneRoster auth system

Rationale and consequences

parent, student, teacher, and school views cannot be authorized safely with a single role-only token, and scoped claims refine rather than duplicate the platform JWT primitive

#oneroster_concurrency_model

oneroster concurrency model

Unspecified

Decision

SHIP: per-resource updates and deletes return ETag validators on reads and require If-Match on mutation; missing preconditions return 428 and stale validators return 412 or the documented conflict family.

Alternatives and tradeoffs

  • no concurrency control
  • bulk-only concurrency
  • last-write-wins

Rationale and consequences

a daily-use SIS can have simultaneous teacher/admin edits; If-Match prevents silent lost updates and inherits platform PITD-007

#oneroster_conformance_evidence

oneroster conformance evidence

Unspecified

Decision

SHIP: local executable spec-runner evidence for CSV schema, validation, dependency, API, auth, Problem, idempotency, concurrency, privacy, and route-shape contracts; DEFER official 1EdTech certification claims until external proof exists.

Alternatives and tradeoffs

  • no conformance evidence
  • imply official certification without proof
  • external certification now without a certificate or directory listing

Rationale and consequences

spec-runner evidence gives integrators reproducible trust without fabricating an official certification seal

#oneroster_error_envelope

oneroster error envelope

Unspecified

Decision

SHIP: typed RFC 7807 Problems with stable type URIs, requestId, traceId, fieldErrors[], and oneroster: branch codes including validation, dependency, score-scale, idempotency, precondition, not-found, rate-limit, and server errors.

Alternatives and tradeoffs

  • plain RFC 7807 without stable module codes
  • ad-hoc OneRoster error shapes
  • raw parser exceptions

Rationale and consequences

stable typed Problems let clients branch safely and keep source-linked OneRoster validation errors separate from free-text details

#oneroster_eventing_model

oneroster eventing model

Unspecified

Decision

SHIP: poll-based synchronization using list endpoints plus modifiedSince; DEFER webhooks and event streams until the documented OITD-107 trigger is met.

Alternatives and tradeoffs

  • full polling only
  • webhooks now
  • event stream now

Rationale and consequences

modifiedSince removes expensive full polling while webhooks would duplicate first-release change discovery and add delivery/replay/subscription semantics before demand proves them necessary

#oneroster_idempotency_model

oneroster idempotency model

Unspecified

Decision

SHIP: retryable writes require Idempotency-Key and store replay state in platform.idempotency_key scoped by tenant, module, surface, method, route template, operation id, key, and request hash.

Alternatives and tradeoffs

  • no idempotency
  • package hash only
  • make reads idempotency-keyed

Rationale and consequences

school admin clients need safe retries for imports, exports, and per-resource writes without duplicate records or custom duplicate-detection logic

#oneroster_list_endpoints

oneroster list endpoints

Unspecified

Decision

SHIP: one documented list endpoint per supported OneRoster collection, including academicSessions, categories, classes, classResources, courseResources, courses, demographics, enrollments, gradingPeriods, lineItemLearningObjectiveIds, lineItems, lineItemScoreScales, orgs, resources, resultLearningObjectiveIds, results, resultScoreScales, roles, scoreScales, userProfiles, userResources, and users.

Alternatives and tradeoffs

  • write-and-remember only
  • CSV export only
  • only the collections already exposed by the prior implementation

Rationale and consequences

one-per-collection matches the source surface and lets a cold SIS client discover dashboards, gradebooks, rosters, and admin search without private remembered IDs

#oneroster_privacy_retention

oneroster privacy retention

Unspecified

Decision

SHIP: GDPR-style tenant-scoped export, audit, redaction from logs/Problems/evidence, OneRoster logical deletion where the standard defines status, and platform erasure/tombstone handling for student or family PII when policy requires it.

Alternatives and tradeoffs

  • no privacy/retention behavior
  • DELETE per spec only
  • unbounded retention in logs and evidence

Rationale and consequences

a daily-use SIS handles sensitive student and family data; explicit retention and redaction rules prevent hidden PII leaks and make audits deterministic

#oneroster_query_model

oneroster query model

Unspecified

Decision

SHIP: documented filtering, sorting, paging, cursor continuation, and modifiedSince on list endpoints; unsupported query parameters return typed 400 Problems rather than silent ignore.

Alternatives and tradeoffs

  • no query model
  • filter+sort only
  • filter+paging+cursor without modifiedSince
  • silent ignore of unsupported params

Rationale and consequences

real SIS tenants need scale and sync semantics, and failing loud on unsupported parameters is negative complexity compared with silently returning misleading data

#oneroster_read_shape

oneroster read shape

Unspecified

Decision

SHIP: list + detail + sub-collections; every collection has list and detail reads, plus documented relationship routes such as school classes, class students, class line items, user enrollments, and student results.

Alternatives and tradeoffs

  • list-only
  • list+detail without sub-collections
  • client-side relationship joins only

Rationale and consequences

profile, roster, and gradebook screens cannot require full-collection downloads and repeated client joins to render one student or class

#oneroster_score_scale_enforcement

oneroster score scale enforcement

Unspecified

Decision

SHIP: every persisted gradebook result with score or textScore must resolve to exactly one same-tenant effective scoreScale at write time; resultScoreScales can bind a result explicitly, otherwise exactly one lineItemScoreScales binding on the result lineItem is required. Gradebook reads expose effectiveScoreScaleSourcedId, and demo seed lineItems/results must include bound score scales.

Alternatives and tradeoffs

  • read-time hint only
  • accept missing bindings with warnings
  • require resultScoreScales for every result
  • allow multiple lineItemScoreScales without explicit result selection

Rationale and consequences

the SIS-clone persona cannot render numeric, letter, or GPA-style scores safely when the scale is missing or ambiguous; write-time validation removes ambiguity before invalid gradebook state reaches clients

#oneroster_served_audiences

oneroster served audiences

Unspecified

Decision

SIS developer building a minimum-useful clone of PowerSchool / Infinite Campus / Skyward on top of the OneRoster 1EdTech surface alone - a product that teachers, parents, students, and admins use every school day

Alternatives and tradeoffs

  • data-warehouse integrator
  • single-school CSV uploader
  • one-time roster migration tool

Rationale and consequences

the SIS-clone persona is what makes the persona-blocking test concrete; without it every integrator request looks deserving

#oneroster_tenant_routing

oneroster tenant routing

Unspecified

Decision

SHIP: tenant routing by the signed JWT tenant_id claim matched to platform.tenant; ordinary OneRoster routes stay flat with no /tenants/{id} prefix or duplicate tenant header.

Alternatives and tradeoffs

  • tenant in URL
  • tenant in header
  • tenant in both JWT and URL with precedence rules

Rationale and consequences

flat routes preserve OneRoster-shaped paths and token-bound tenants prevent cross-tenant mistakes without duplicate routing primitives

#oneroster_write_granularity

oneroster write granularity

Unspecified

Decision

SHIP: both CSV bulk import/export and per-resource POST, PUT or PATCH, and DELETE for every supported OneRoster collection the customer website documents.

Alternatives and tradeoffs

  • bulk-only CSV import/export
  • per-resource writes only
  • write-and-remember without documented write routes

Rationale and consequences

CSV bulk remains the standards exchange and evidence primitive, while per-resource writes are required for daily SIS edit workflows such as grades, enrollments, profile corrections, and admin changes