For IT administrators
Exactly what we ask for and exactly what we do.
The technical detail your security team will want before tenant-wide consent. Multi-tenant Microsoft 365 app, delegated scopes only, no data retention, no third parties.
Architecture in one paragraph
mydocs.school is a multi-tenant Microsoft 365 application registered to the Muon Works tenant. Schools opt in by their IT admin granting tenant-wide consent — there is no per-school app registration, no agent, no device-side install. The student signs in via OAuth, our backend calls Microsoft Graph with the student's delegated token, and bytes stream from Graph through our backend to the student's browser as a single zip. We do not retain file content.
The Entra app
- Single multi-tenant registration in the Muon Works tenant, supporting Accounts in any organizational directory. We deliberately exclude personal Microsoft accounts.
- Verified publisher domain (Muon Works Ltd). The consent screen shows the verified publisher mark.
- Web platform redirect URI
https://mydocs.school/auth/callback. Tokens flow over the standard authorization-code-with-PKCE flow. - Front-channel logout URL
https://mydocs.school/auth/logout.
Scopes we request
All scopes are delegated — we can only act on behalf of the signed-in user, never tenant-wide. There are no Application-permission scopes.
User.Read— display name, UPN, oid, for the dashboard.Files.Read— read the signed-in student's OneDrive (their own files only).Files.Read.All— read the underlying SharePoint folders backing class notebooks (M365 group drives). Required because OneNote class notebooks live in the class's group library, not the student's OneDrive. SharePoint enforces ACLs server-side, so the student still only sees folders they have permission on; we re-assert this in code.Notes.Read/Notes.Read.All— list personal and class notebooks via the OneNote API. Read only.EduRoster.ReadBasic— list the student's class memberships, used to enumerate which class notebooks they can access.offline_access— refresh tokens, so the student doesn't re-authenticate every hour during a long download.openid,profile,email— standard OIDC claims.
We do not request: Mail.*, Calendars.*, Chat.*, Sites.FullControl, any .Writescope, or any tenant-wide application permission.
Data flow
- Student visits
mydocs.schooland clicks Sign in. Browser redirects to Microsoft. - Standard OAuth authorization-code flow with the scopes above. Tokens come back to our backend, never the browser.
- Tokens are stored in a Fernet-encrypted session cookie (HttpOnly, Secure, SameSite=Lax). Optionally backed by Redis when sessions exceed cookie size; the Redis value is encrypted with the same key.
- When the student clicks Download, our backend calls Microsoft Graph with their delegated token, walks their OneDrive (and the relevant class-notebook folders in M365 group drives), and streams the bytes through to the browser as a zip — assembled in memory, no disk persistence.
- When the response completes (or is cancelled), the streaming generator is garbage-collected. Nothing remains.
What we store, what we don't
We don't store: file contents, page text, filenames, sizes-by-name, file metadata, OneNote page bodies, download history beyond an aggregated audit row, OneDrive listings, search indexes.
We do store:
- The encrypted session for the duration of the browser session.
- A “seat” row per student, holding the Entra OID and a 60-day expiry. PII (display name, UPN) is encrypted at rest. Used for licensing.
- An audit log line per download (kind, oid, notebook id where applicable, timestamp, byte count). No file content. Retained 12 months, then aggregated and deleted.
- For school admins only: tenant id, school name, billing contacts, subscription state.
Full text in the privacy policy.
Privacy boundary on class notebooks
Two independent layers prevent a student's zip from containing another student's work:
- SharePoint ACLs (Microsoft). OneNote Class Notebook applies per-folder permissions: each student has read on their own section group plus the two shared folders (
_Content Library,_Collaboration Space). When our backend walks the group drive with the student's delegated token, SharePoint filters out folders they cannot read. Other students' section groups do not appear in the listing we receive. - Application-level scoping. Even with that, our walker only descends into the child folder whose name matches the resolved section group for the student.
_Content Libraryand_Collaboration Spaceare explicitly skipped, and any other student's section group is skipped by name.
The relevant code paths are routes/notebooks.py::_resolve_student_section_group and exporters/onenote_raw.py::_find_child_folder.
Hosting
- DigitalOcean App Platform, London region (LON1).
- DigitalOcean Managed Postgres for school admin / billing metadata, with PII fields encrypted at rest using a key the DB server never sees.
- DigitalOcean Managed Redis for session storage when needed, values encrypted with the same key.
- TLS termination via Let's Encrypt at the App Platform edge.
- No CDN inspecting traffic, no analytics provider, no third-party SaaS in the data path.
Onboarding (the actual click path)
Open mydocs.school/onboard in a browser, signed out. The button there assembles the admin-consent URL with our client id and the requested scopes, and redirects you to login.microsoftonline.com/{your-tid}/adminconsent. You sign in with a Cloud Application Administrator (or higher) account, review the scopes, and click Accept. Microsoft records an enterprise application in your tenant; from that moment your users can sign in to mydocs.school normally.
To revoke: Entra → Enterprise applications → mydocs.school → Permissions → Remove. Existing tokens stop working within an hour.
Modern authentication & MFA
mydocs.school sign-in is built entirely on Microsoft Modern Authentication — OAuth 2.0 with OpenID Connect, the authorization-code flow with PKCE. There is no fallback to legacy protocols. We never see, store, or proxy a username or password for any account in your tenant; the credential entry happens on Microsoft's own login page, not ours.
Multi-factor authentication is enforced by your tenant's sign-in policies, not by us. If a user's policy requires MFA — Microsoft Authenticator, FIDO2 keys, conditional MFA based on risk — they will be challenged exactly as they would for any first-party Microsoft app. We respect every step Microsoft adds to the sign-in: number-matching prompts, sign-in frequency constraints, device-compliance checks, named-location rules.
Because we receive a regular delegated access token at the end of the flow, your tenant can revoke it at any time (Entra → Users → the user → Sign-in logs / Revoke sessions) and the next call we make to Microsoft on that user's behalf fails immediately.
Conditional Access
mydocs.school works with Conditional Access policies that target sign-in risk, MFA, trusted networks, and device compliance. We don't require any specific CA exemption. If your CA blocks third-party multi-tenant apps by default, you'll need to allow the mydocs.school enterprise app explicitly.
Data Processing Agreement
For UK GDPR purposes the school is the data controller and Muon Works Ltd is the processor. We sign a DPA on request — email [email protected] with your school's registered name and your DPO's contact.
Things we will tell you straight
- We are a small UK company (Muon Works Ltd). If your procurement requires SOC 2, ISO 27001, or similar formal certifications we don't yet hold, we'll tell you so rather than dance around it.
- The student-facing service streams files through our infrastructure. If the legal regime your tenant operates under requires data not to leave Microsoft's direct control, we aren't a fit for you.
- We don't use student data for AI training, advertising, benchmarking, or any purpose other than serving the student's download. There's no fine print.
Talk to us
For technical or security questions: [email protected]. For procurement and DPA: [email protected].