Safe Online Exam 1.0.1 is a backward-compatible security, deployment, and
release-engineering update. It closes a privileged OAuth callback-resume path,
returns users to an existing signed LTI session through a constrained popup
handshake, and completes the supported Cloud Run and Docker Compose operator
bundles.
This release adds no database migration and does not change the Canvas LTI
registration URLs, OAuth callback URL, required Canvas scopes, or public SEB
compatibility endpoints.
Canvas authorization and security
- Require instructor, student, and administrator Canvas authorization to start
from the application's own origin, rejecting explicitly cross-site
navigation attempts. - Stop OAuth callbacks from resuming or rendering privileged instructor and
administrator views. Successful callbacks now end on a non-privileged
completion screen, and management access still requires the original signed
LTI launch. - Open Canvas authorization in a popup while preserving the signed LTI page,
then return that page to its role-appropriate workspace only after an
exact-origin, exact-window completion message and two-way acknowledgement. - Sanitize OAuth and student-session navigation targets to same-origin paths,
reject network-path and cross-origin values, and retain a safe completion
screen when popups or opener acknowledgement are unavailable. - Harden root-account course query parsing so repeated, malformed, or
non-scalar search, pagination, term, and limit values fall back safely.
Deployment and upgrades
- Add checksum-protected, source-free Cloud Run and Docker Compose release
bundles, each with a guided top-level installer and an explicit unattended
file-based interface. - Add Cloud Run preflight, preparation, secret bootstrap, first-install,
two-pass Canvas registration, finalization, upgrade, and guarded rollback
commands using plaingcloud,docker,jq,openssl, andcurl. - Pin exact Secret Manager versions, run migrations before application traffic
changes, schedule bounded cleanup, verify Cloud SQL backups, stage
zero-traffic revisions, and require an explicit verified traffic cutover. - Add an interactive Cloud SQL profile chooser with a cost-conscious dedicated
zonal default, optional high-availability and capacity profiles, connector
enforcement, backups, point-in-time recovery, deletion protection, and
opt-in resource creation. - Add verified Compose backup and upgrade helpers that preserve protected
secret files and the PostgreSQL volume before pulling or restarting the
application. - Document and propagate the per-instance
SEB_CONFIG_ENCRYPTION_ENABLED=falsecompatibility mode while retaining
start-password wrapping, Config Key proof, grants, lockdown behavior, and
certificate encryption as the secure default.
Release engineering and supply chain
- Replace manual publication with a one-tag workflow that first proves the
tagged commit is onmainusing read-only permissions, waits for that exact
commit's application, PostgreSQL, Compose, and CodeQL checks, and only then
grants publication credentials. - Build and smoke the exact staged
linux/amd64andlinux/arm64image before
promoting the1.0.1,1.0,1, andlatestaliases to one verified
digest. - Publish the completed GitHub Release as immutable only after generating the
final digest-specific notes, provenance, SBOM, GitHub attestation, Compose
and Cloud Run archives, and SHA-256 checksum files. - Add idempotent draft recovery, final-tag and image-label verification,
persistent BuildKit caching, immutable action SHA pins, and the
npm run release:checkmetadata-consistency gate. - Verify immutability from the final published release record instead of
requiring the read-only workflow token to call GitHub's administration-only
repository-settings endpoint. - Add a reproducible protected-
mainruleset with pull requests, signed final
commits, required application/PostgreSQL/Compose/CodeQL checks, dependency
review, and narrowly scoped automatic merging for eligible Dependabot npm
patch updates. - Pin the Node.js 24 build/runtime, PostgreSQL 17, and Caddy base images by
digest while retaining reviewable automated update coverage for npm,
GitHub Actions, Dockerfiles, and Compose.
Documentation
- Reorganized the public documentation around evaluators, deployers, Canvas
administrators, instructors, students, support staff, contributors, and
release maintainers. - Added a documentation hub, role-based user guide, and symptom-driven
troubleshooting guide. - Replaced the duplicated deployment monolith with a mode-selection and
operations guide while keeping the Compose and Cloud Run bundle manuals
self-contained. - Revalidated public routes, OAuth scopes, runtime variables, PostgreSQL
schema, certificate behavior, deployment workflows, test gates, and release
behavior against the implementation. - Clarified that
/lti/configis Canvas’s JSON configuration URL rather than
the separate OpenID Dynamic Registration protocol, and documented the
Compose two-pass Canvas bootstrap.
Dependency maintenance
- Update React and React DOM to 19.2.8,
joseto 6.2.4,lucide-reactto
1.25.0,@vitejs/plugin-reactto 6.0.4, Prettier to 3.9.6, and Caddy to the
2.11 release line.
See the v1.0.1 changelog for the canonical release record.
Published container image
ghcr.io/jsb2010/safe-online-exam@sha256:54873dc3d08c2f72c225637ac2973ed8fedf395fc503d259c386636f5a7ed264
Production deployments must use this immutable digest. The 1.0.1,
major/minor, major, and latest tags are discovery and notification aliases,
not deployment pins.
Verify provenance
Install Docker, the GitHub CLI (gh), and jq, then authenticate gh.
Verify the image against the exact release workflow, source commit, and tag:
gh attestation verify \
oci://ghcr.io/jsb2010/safe-online-exam@sha256:54873dc3d08c2f72c225637ac2973ed8fedf395fc503d259c386636f5a7ed264 \
--repo JSB2010/safe-online-exam \
--signer-workflow JSB2010/safe-online-exam/.github/workflows/publish-release-image.yml \
--source-digest d4dbd722b4e60fbb9f11afb4eec69a3b7b80166b \
--source-ref refs/tags/v1.0.1Cloud Run install or upgrade
The Cloud Run bundle uses plain gcloud, docker, jq, openssl, and
curl. It pins exact Secret Manager versions, runs the database migration
before application traffic changes, verifies a tagged no-traffic revision, and
then performs an explicit 100% cutover.
VERSION=1.0.1
curl -fLO "https://github.com/JSB2010/safe-online-exam/releases/download/v${VERSION}/safe-online-exam-${VERSION}-cloud-run.tar.gz"
curl -fLO "https://github.com/JSB2010/safe-online-exam/releases/download/v${VERSION}/safe-online-exam-${VERSION}-cloud-run.tar.gz.sha256"
sha256sum --check "safe-online-exam-${VERSION}-cloud-run.tar.gz.sha256"
tar -xzf "safe-online-exam-${VERSION}-cloud-run.tar.gz"
cd "safe-online-exam-${VERSION}-cloud-run"
./setup.shThe guided setup walks through configuration, Cloud SQL cost selection,
protected secret generation, the Canvas Developer Key handoff, installation,
LTI registration, and finalization. Use ./setup.sh --help for resumable
stages and the fully unattended file-based interface. The lower-level phase
commands remain available for explicit orchestration.
For an existing installation, merge new keys from cloudrun.env.example into
the protected prior cloudrun.env, set the new digest, and run:
./upgrade.sh cloudrun.envThe upgrade creates and verifies a backup of the configured
SQL_INSTANCE. Application rollback does not reverse database migrations.
Docker Compose install or upgrade
VERSION=1.0.1
curl -fLO "https://github.com/JSB2010/safe-online-exam/releases/download/v${VERSION}/safe-online-exam-${VERSION}-compose.tar.gz"
curl -fLO "https://github.com/JSB2010/safe-online-exam/releases/download/v${VERSION}/safe-online-exam-${VERSION}-compose.tar.gz.sha256"
sha256sum --check "safe-online-exam-${VERSION}-compose.tar.gz.sha256"
tar -xzf "safe-online-exam-${VERSION}-compose.tar.gz"
cd "safe-online-exam-${VERSION}"
./setup.shThe guided setup covers HTTPS mode, Canvas values, protected secret
generation, validation, startup, and readiness. Use ./setup.sh --help for
the non-interactive configuration-and-secret-file interface.
On an upgrade, preserve the existing secret files and database volume, merge
new keys from the downloaded .env.compose.secrets.example into the protected
.env.secrets, and run ./upgrade.sh .env.secrets. The command creates a
validated PostgreSQL backup before pulling or restarting containers.
The published multi-architecture manifest contains linux/amd64 and
linux/arm64. The published digest in this section is
sha256:54873dc3d08c2f72c225637ac2973ed8fedf395fc503d259c386636f5a7ed264.