Skip to content

Tech-debt batch 9: typed app.state accessors; demo read-only on the resolved principal (#609 #611) - #614

Merged
antosubash merged 4 commits into
mainfrom
fix/debt-batch-9
Oct 23, 2026
Merged

antosubash merged 4 commits into
mainfrom
fix/debt-batch-9

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Summary

  • framework: typed app.state accessors instead of getattr(app.state, ...) strings #609: simple_module_core.app_state adds 19 typed accessors (get_public_routes, get_tenant_resolver, get_principal_serializer, get_auth_provider, …), each documenting what installs it. Framework code now reads app.state through them instead of getattr(app.state, "<name>", None), and so do module reads of framework-level state. Behaviour is unchanged and the defaults match the old fallbacks.
  • users: demo read-only guard keys on the session, not the resolved identity #611: read-only demo mode now applies to the signed-in account, whatever the credential. A new AuthState.principal_guards hook runs in AuthMiddleware after any credential resolves (session, bearer access token, personal API token). Users registers a guard that refuses unsafe methods from a demo account with the same allow-list and the same 403 DEMO_READ_ONLY / Inertia 409 response. The existing session guard stays.
  • users: demo read-only guard keys on the session, not the resolved identity #611: demo accounts can no longer mint tokens while demo_read_only is on. POST /api/users/auth/token and /token/refresh return 403. A refused refresh does not consume the token, and a refresh token for a deactivated account is still burned on 401, as before.

Closes #609
Closes #611

Residual risk

A demo account's bearer or refresh token that was issued before this change, or while demo_read_only was off, can still write once demo_mode is switched off. At that point the configured demo-account list is empty. With this change, demo accounts can no longer get such tokens while read-only is on.

Verification

  • Local CI:
    • make lint passed.
    • make test-py: 5975 passed.
    • Postgres (users, auth, core): 1424 passed.
    • make test-js: 770 passed.
    • e2e: 49 passed.
  • Code review: 3 Sonnet passes (fixes in 2) plus an independent Codex review with no findings.
  • Verification report: https://claude.ai/artifact/EdhpdSPKWbJoXodmjNQrhZ

QA Report

  • One QA iteration, 22 tests: browser regression across admin pages, plus every demo credential path over HTTP, including attempts to bypass the allow-list and method checks.
  • 0 bugs found. 3 P3 observations that predate this work, such as the generic "Saving failed" toast on a refused demo write.
  • Full QA report: https://claude.ai/artifact/BuC4xjaU3C59zUyE5G9ZDd

Report links are Claude Artifacts and start private; the author can share them if reviewers need access.

Test plan

  • With demo mode on, POST /api/users/auth/token for a demo account returns 403 DEMO_READ_ONLY.
  • CI is green.

https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Deploying simple-module-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 41ae074
Status: ✅  Deploy successful!
Preview URL: https://954770f4.simple-module-python.pages.dev
Branch Preview URL: https://fix-debt-batch-9.simple-module-python.pages.dev

View logs

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review 🔄 Running since 2026-10-23T17:59:11.023971Z 41ae074 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@antosubash
antosubash merged commit f73d3d9 into main Oct 23, 2026
17 checks passed
@antosubash
antosubash deleted the fix/debt-batch-9 branch October 23, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant