This page is Anni Planner's written information security program, published so teachers and school IT staff can evaluate it. It describes real, running controls, not aspirations; when the program changes materially, this page changes with it.
Responsibility
Jon Hegreness, the operator, is the designated security coordinator: accountable for this program, for reviewing it at least annually against the data the service holds, and for breach response. Contact for security matters, including vulnerability reports: security@anniplanner.com. Good-faith security research against your own account's data is welcome; we ask that you report what you find privately and give us time to fix it before publishing.
Architecture in one paragraph
Anni runs entirely on Cloudflare: static application, serverless API, SQL database (D1), and file storage (R2), all in the United States. There are no servers of ours to patch, we include no third-party JavaScript or ad and analytics trackers, and the browser is told to run only our own first-party scripts (a strict Content Security Policy without inline script). Encrypted backups go nightly to Backblaze B2, a separate company, so no single vendor account controls the data's survival.
Controls
| Layer | What is in place |
|---|---|
| Transport | HTTPS everywhere, HSTS (1 year, including subdomains); no unencrypted access path |
| Storage | Encryption at rest on the database and file store (provider-managed keys); backups additionally encrypted by us (AES-256-GCM) before leaving Cloudflare, with the key held outside the database |
| Passwords | Salted PBKDF2-SHA256 hashing combined with a separate server-held secret key, designed so that a stolen database copy alone is not crackable offline; passwords are never stored or logged in readable form |
| Login | Optional two-step verification (texted or emailed one-time codes, 10-minute expiry, attempt limits); 30-day remembered devices; rate limiting on login and password reset; neutral error messages that do not reveal whether an email has an account |
| Sessions | 256-bit random tokens, HttpOnly/Secure cookies, 30-day expiry, server-side revocation on logout, password change, and account disable (immediate kill switch) |
| Application | Every database query parameterized; all output escaped with an allow-list rich-text sanitizer; strict Content Security Policy (scripts from our own origin only, no inline script, no framing); uploaded files served with type protections designed to prevent a stored file from running as code; cross-site write requests refused |
| Access control | Every data route requires the teacher's session and reads only that teacher's records; administrative routes additionally require the admin flag; share pages expose only the limited, time-boxed content the teacher chose, via unguessable high-entropy links that send no referrer information |
| Audit | Append-only security log of logins and failures, verification codes, password changes, share links created and opened, roster changes, admin actions, and deletions; network addresses stored only as salted hashes; the application is designed with no route that edits or removes log entries, and entries are purged only by the published 1-year retention schedule |
| Backups | Nightly full database export, compressed and AES-256-GCM encrypted, shipped off-platform to Backblaze B2 with a file manifest and incremental file mirroring; 90-day archive retention; database point-in-time recovery (30 days) additionally available at the provider layer |
| Secrets | API keys and cryptographic secrets live in the platform secret store, never in code, the database, or version control; credentials are rotated when exposure is suspected |
| Data minimization | The student game portals collect no contact information from children; IP addresses are hashed in logs; expired sessions, codes, links, and throttle records are swept continuously |
Risk review and testing
The program is reviewed at least annually, and after any material feature touching student data, against the current threat model: account takeover, stolen database copy, cross-site scripting, share-link leakage, and vendor account loss. Changes ship through a locked build-test-verify process with security checks (syntax and review passes on changes, live verification of deployed behavior, and end-to-end tests of authentication flows, including destructive paths like account deletion, run with disposable test accounts).
Vendors (subprocessors)
Cloudflare (hosting, database, files), Backblaze (encrypted backups), Twilio (login code texts), Resend (service email), and, only when a teacher connects it, Google (the teacher's own Gmail/Calendar/Docs). Each handles data under terms restricting it to serving us, barring onward disclosure, and requiring reasonable security. The full table, with what each can see, is in the Privacy Policy.
Incident response
On discovering a security incident we investigate promptly, contain it, and determine whether a breach of security occurred. If personal information as A.R.S. § 18-551 defines it was acquired while unencrypted or unredacted (or encrypted information together with its key), we notify affected individuals without unreasonable delay and within 45 days (A.R.S. § 18-552), tell affected schools what student information was involved, and notify the Arizona Attorney General and the national consumer reporting agencies when more than 1,000 Arizona residents are affected. We also tell affected users plainly what happened and what changed, in the notice itself. Arizona's breach law treats a business that maintains and follows its own written notification procedures as compliant; this page, followed, is that procedure.