Admin panel and CDN risk ======================== The admin panel is a JavaScript SPA served at /admin. Its JS contains the full structure of admin capabilities — endpoints, data shapes, what ops exist. That code should not be publicly accessible, even if the API correctly rejects unauthorized calls. Leaking it is an enumeration aid for attackers and a trust problem for customers who go looking. This rules out the common CDN-everything pattern for the admin route. A CDN in front of the origin would cache and serve the admin JS to anyone without an auth check. A client-side "requireAdmin" guard hides the UI but not the code; the JS bundle is still downloaded and inspectable. What we do ---------- - The /admin and /admin/* routes are served by the origin server, behind requireLogin, not a CDN. - Every response under /admin carries Cache-Control: no-store. Most CDNs respect this and won't cache the response even if the route is accidentally included in CDN config. The opt-out problem ------------------- CDN configs default to "cache everything from this origin." If someone adds a CDN later without explicitly excluding /admin/*, the admin JS will be cached and served publicly. Cache-Control: no-store is a signal that makes this less likely, but it only works if the CDN isn't configured to ignore origin headers (a common "performance optimization" that some teams apply blindly). The only guarantee is to exclude /admin/* from CDN routing at the CDN config level. Cache-Control: no-store is a belt; CDN exclusion is the suspenders. Document this requirement when adding any CDN or reverse proxy. If you need a harder guarantee (e.g. for compliance or high-risk deployments), serve the admin panel from a separate origin that is never behind a CDN, or restrict it to an internal network / VPN. That removes CDN misconfiguration from the threat model entirely.