Skip to content

feat(auth): method-aware public-route extension point (closes #191) - #193

Merged
antosubash merged 2 commits into
mainfrom
worktree-fix-auth-public-routes
Jun 5, 2026
Merged

feat(auth): method-aware public-route extension point (closes #191)#193
antosubash merged 2 commits into
mainfrom
worktree-fix-auth-public-routes

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Summary

Closes #191. Adds a first-class, method-aware extension point for declaring
anonymous/public routes, so modules (and the host) can expose read-only APIs
(STAC / OGC API / TileJSON, webhooks, status pages) without monkeypatching.

Before this, AuthMiddleware gated every request and the only exemption hook was
AuthProvider.get_public_paths() — which only the auth provider could
contribute to and matched prefix-only, method-agnostically. That blocked
sibling modules from exposing anonymous reads, and couldn't isolate
GET .../tilejson from sibling PATCH .../visibility under a shared prefix.

What's added

  • simple_module_core.public_routes: PublicRoute (method-aware; prefix / exact / suffix / regex) + PublicRouteRegistry.
  • ModuleBase.register_public_routes(registry) lifecycle hook (no-op default; recognized by the SM007 diagnostic).
  • Host wiring in create_app: aggregates every module's rules plus the SM_AUTH_PUBLIC_PATHS host escape hatch; publishes at app.state.public_routes (and app.state.sm.public_routes).
  • AuthMiddleware consults the registry method-aware (via scope["method"]), in addition to framework defaults and the legacy provider paths (kept intact — zero breakage for users/keycloak).
  • Docs: docs/framework/public-routes.md.

A GET read route nested under a mutation-bearing prefix can now be exempted
without opening the mutations.

Verification

Local CI (fresh): ruff format + check, ty, file-size cap, hardcoded-strings — all green. 1313 tests passed (incl. a full-stack ASGI test exercising AuthMiddleware end-to-end with anonymous + gated requests).

Browser QA (/qa, 9/9 passed, 0 bugs): scoped to the auth-gating surface this change governs.

Public routes load anonymously Protected routes redirect when logged out
landing redirect
Authenticated access works New mechanism, live (302 → 404 once declared public)
dashboard mechanism
  • /, /users/login, /health200 (anonymous); /dashboard302 → /users/login; /api/users/admin401.
  • Live: declaring /zzz-demo-public via SM_AUTH_PUBLIC_PATHS flipped it 302 → 404 (gate lifted), while an unlisted control path stayed 302 — no over-matching. Boot log confirmed 1 public routes.
  • Full QA report: .verify/qa-report.md.

Test plan

  • Reviewer confirms a module's register_public_routes rule exempts a GET read route while sibling POST/PATCH stay gated.
  • CI is green.

AuthMiddleware gated every request and offered no supported way for a
module to declare anonymous/read-only routes — the only exemption hook
was AuthProvider.get_public_paths(), which (a) only the auth provider can
contribute to and (b) matches prefix-only, method-agnostic. That blocks
modules like gis from exposing a STAC/OGC/TileJSON read API anonymously,
and can't isolate `GET .../tilejson` from sibling `PATCH .../visibility`
under a shared prefix.

Add a first-class extension point:

- `simple_module_core.public_routes`: `PublicRoute` (method-aware;
  prefix/exact/suffix/regex) + `PublicRouteRegistry`.
- `ModuleBase.register_public_routes(registry)` lifecycle hook (no-op by
  default; recognized by the SM007 diagnostic).
- Host wires it in `create_app`: aggregates every module's rules plus the
  `SM_AUTH_PUBLIC_PATHS` host escape hatch, publishes at
  `app.state.public_routes` (and `app.state.sm.public_routes`).
- AuthMiddleware consults the registry method-aware (via `scope["method"]`),
  in addition to framework defaults and the legacy provider paths
  (unchanged, back-compat).

A GET read route nested under a mutation-bearing prefix can now be exempted
without opening the mutations. Docs: docs/framework/public-routes.md.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying simple-module-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 32045fb
Status: ✅  Deploy successful!
Preview URL: https://f4461cf6.simple-module-python.pages.dev
Branch Preview URL: https://worktree-fix-auth-public-rou.simple-module-python.pages.dev

View logs

@antosubash
antosubash merged commit 88f5be6 into main Jun 5, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AuthMiddleware has no hook for modules to declare public/anonymous routes (matcher is method-agnostic prefix-only)

1 participant