core-service · dev-navaratri · 5fb3968

Datta Vani Core API Inventory

Every HTTP route in the navaratri backend, and what a caller needs to reach it. I read the FastAPI routers in wt-be-navaratri/core-service/app/routers and followed each route's Depends() chain to the auth check it ends in. Routes with no login dependency I checked by hand.

135 routes in 29 routersStatic code analysis, 28 Oct 2026Staging not probed: TLS handshake to staging.dattavani.ai failed
Who can call what
Reachable without login

Routes that don't need a JWT

None of these is open by accident. They're login steps, health checks, redirect pages, or webhooks and internal tools behind a shared secret. Every secret-gated route refuses requests when its secret isn't configured.

RouteAccessHow it's protected
Worth a look

Findings

public

API docs are on by default

FastAPI(...) in main.py:83 doesn't set docs_url, redoc_url or openapi_url. So /docs, /redoc and /openapi.json publish the full schema in every environment, unless a proxy blocks them. Seven internal routes are hidden from it with include_in_schema=False.

secret

Secrets compared with !=

The cache-invalidate, Tataji internal and RevenueCat webhook checks compare secrets with plain !=. hmac.compare_digest would avoid timing leaks. The Swamiji webhook already uses a proper HMAC check.

secret

Cache invalidation is reachable in production

The Tataji /internal/ routes return 404 outside dev and local. POST /api/learnings/internal/cache/invalidate has no such environment check: in production it relies only on [redacted].

auth

“Protected routers” comment is misleading

main.py:321 labels a block of routers as protected, but only rag is mounted with protected_dependencies. The others are protected because each route declares its own auth dependency. A new route that forgets one would be public.

Full list

All routes

RouteAccessWhat it doesHandler