What the Server Sends Back: The Response Headers of app.onepassapps.com
I work on OnePassApps, so this is our own site, and everything below is a measurement of the live responses from app.onepassapps.com taken on 4 November 2026 - plain HTTPS requests from outside the browser, no JavaScript
I work on OnePassApps, so this is our own site, and everything below is a measurement of the live responses from app.onepassapps.com taken on 4 November 2026 - plain HTTPS requests from outside the browser, no JavaScript, one build, one day.
The last few posts in this series looked at what a browser fetches (sitemap.xml, robots.txt, the web app manifest, the Open Graph tags, the route map and browser storage). This one looks at the other half of the conversation: the headers the server sends back before any of that arrives. It is the layer you never see in a screenshot, and it is where the caching, compression and browser-security policy of a site actually live.
One header set for every page
I fetched every URL in the site's sitemap.xml - the home page, the seven studios, the two hosted apps, /guides, /guides/newsflow, /guides/movie-tracker, /plans, /terms and /voting - plus /support and one URL that does not exist, /nonexistent-xyz. Eighteen responses in total.
All 18 responses carry exactly the same 21 header names. There is no per-page variation at all: no page adds a header, no page drops one, and the one 404 carries the same names as the home page. The full list:
access-control-allow-origin, alt-svc, cache-control, cf-cache-status, cf-ray, content-encoding, content-security-policy, content-type, cross-origin-opener-policy, cross-origin-resource-policy, date, nel, permissions-policy, referrer-policy, report-to, server, strict-transport-security, vary, x-content-type-options, x-frame-options, x-permitted-cross-domain-policies
Most of the values are also identical on every URL. Here is what is constant:
| Header | Value | On all 18 |
|---|---|---|
server |
cloudflare |
yes |
cf-cache-status |
DYNAMIC |
yes |
x-frame-options |
SAMEORIGIN |
yes |
strict-transport-security |
max-age=15552000; includeSubDomains |
yes |
referrer-policy |
no-referrer |
yes |
x-content-type-options |
nosniff |
yes |
cross-origin-opener-policy |
same-origin |
yes |
cross-origin-resource-policy |
same-origin |
yes |
x-permitted-cross-domain-policies |
none |
yes |
content-security-policy |
one 1,199-character policy, byte-identical everywhere | yes |
The only header whose value differs is cache-control: seventeen pages answer public, max-age=0, must-revalidate and the 404 answers no-store. That single difference is deliberate - a page that does not exist should not be remembered by anyone.
The compression is real, and it is Brotli
Every response was requested twice: once with Accept-Encoding: gzip, br, deflate and once with Accept-Encoding: identity, so the wire size and the uncompressed size could be compared on the same fetch.
- With the full offer, every one of the 18 responses comes back as
content-encoding: br- Brotli, not gzip. - If a client offers only gzip, the server answers
content-encoding: gzip, so the fallback is honoured. - If a client offers only
zstd, the server sends nocontent-encodingat all - there is no Zstandard support, and the body goes out uncompressed.
The savings are between 0.242 and 0.286 of the uncompressed size - so roughly a quarter of a byte in three. Concretely:
- Home page: 5,090 bytes on the wire, 18,624 bytes uncompressed.
-
/terms: 18,112 bytes on the wire, 74,746 bytes uncompressed - the largest HTML on the site, and still the best-compressed page, at 0.242. - A studio page such as
/studios/audio: 4,796 bytes compressed against 16,918 uncompressed.
None of the responses carries a Content-Length header, so the body arrives without a declared length in either mode.
Caching: nothing is cached, and nothing can be revalidated
Two headers tell the whole story.
cf-cache-status: DYNAMIC on all 18 responses means Cloudflare's edge is not serving any of these pages from cache - every request goes to the origin.
cache-control: public, max-age=0, must-revalidate means the browser may store the page, but must re-check with the server before reusing it. So a revisit revalidates rather than serving straight from disk.
And here is the part worth naming: the responses carry no ETag and no Last-Modified. I sent a conditional request with both If-None-Match and If-Modified-Since and got a fresh 200 with a full body, not a 304 Not Modified. There is no validator to revalidate against, so the browser re-checks, gets told nothing has changed that it can compare, and downloads the document again.
That is a deliberate, defensible choice for a site whose pages change without a URL changing - but it is also why the app shell is re-fetched rather than reused.
Transport
The connection is HTTP/2 to Cloudflare over IPv6, with alt-svc advertising h3 on port 443 for HTTP/3. Forcing HTTP/1.1 also works and answers 200, so there is a fallback for older clients.
The plaintext URL http://app.onepassapps.com/ answers 301 to the HTTPS URL. The www host does not resolve at all - no A or AAAA record - so https://www.app.onepassapps.com/ is not a live address rather than a redirect to one.
The security headers, in full
The site ships one Content-Security-Policy, and it is the same one on every URL. Read as a policy it is strict about where code may come from and explicit about the third parties it needs:
-
default-src 'self'andbase-uri 'self';object-src 'none';frame-ancestors 'self';form-action 'self';manifest-src 'self'. -
script-src 'self'plus one SHA-256 hash (sha256-Uk96zwJ2Cg3zp4L5PIIPtLI/vzkWqOvaXew7SqyYAsE=),'wasm-unsafe-eval'for the WebAssembly image models, the Clerk hosts andchallenges.cloudflare.com.script-src-attr 'none'- no inline event handlers at all. -
style-src 'self' 'unsafe-inline';font-src 'self' data:;img-src 'self' data: blob:plus the Clerk image host and the media hosts the two hosted apps read from (TMDB, Wikimedia, Kinocheck, TVMaze). -
media-src 'self' blob: data:andworker-src 'self' blob:- the studio workers run from the page's own origin. -
connect-src 'self'plusapi.onepassapps.com, the Clerk hosts and the Sentry ingest endpoints. -
upgrade-insecure-requests.
Three more worth naming separately:
-
referrer-policy: no-referrer- a link from the site to anywhere else sends no URL at all. That is the privacy-maximal setting, and it is the right one for a tool site whose URLs are plain paths. -
permissions-policydisables the hardware APIs the app has no use for:accelerometer=(),camera=(),geolocation=(),gyroscope=(),magnetometer=(),payment=(),usb=(), withautoplay=(self)andmicrophone=(self)kept for the NewsFlow player. -
access-control-allow-origin: *on the HTML responses. The document body of these pages is public app-shell markup - the same bytes a crawler gets - so this does not expose anything private, but it does mean a page on another origin can read our HTML withfetch. It is worth stating plainly rather than hiding: the API is where data lives, and the API does not behave this way.
Also present on every response: report-to and nel pointing at Cloudflare's cf-nel reporting group, and a per-request cf-ray identifier.
No cookies come with the page
None of the 18 HTML responses carries a Set-Cookie header. That matches what the browser-side measurement found earlier: the two cookies on the site (__client_uat and __client_uat_CLGjHovd, both 0, which is what a signed-out Clerk session looks like) are written by the sign-in script in the page, not by the document response.
The API answers a different contract
api.onepassapps.com is where the app's real behaviour lives, and its headers are deliberately not the same set. GET /api/config/feature-flags, signed out, over plain HTTPS:
-
cache-control: private, no-store, max-age=0andcdn-cache-control: no-store- a config response is never stored by anything. -
x-robots-tag: noindex- a header rather than a meta tag, so it applies to any client that reads headers and not only to crawlers that parse HTML. -
origin-agent-cluster: ?1,x-dns-prefetch-control: off,x-download-options: noopen,x-xss-protection: 0. -
vary: Accept-Encoding, Origin, withaccess-control-expose-headerslistingX-Request-Id,X-RateLimit-Limit,X-RateLimit-Remaining,X-Concurrency-Limit,X-Concurrency-Remaining,Retry-After,X-ToolPass-Credits-ChangedandX-ToolPass-Impersonating- the rate-limit and credit headers are readable by the browser that made the call.
The rate-limit headers are live numbers, not decoration. x-ratelimit-limit: 120 and x-concurrency-limit: 64 came back on every call, and x-ratelimit-remaining counted down across three consecutive requests - 119, then 118, then 117 - with x-concurrency-remaining: 63.
The CORS behaviour is the sharpest difference between the two hosts. Send Origin: https://app.onepassapps.com and the API answers access-control-allow-origin: https://app.onepassapps.com. Send Origin: https://example.com and the response carries no access-control-allow-origin header at all - the browser blocks the read. Send no Origin and there is none either. The API is origin-scoped to our own site; the HTML pages are open to everyone.
The honest limits
- One build, one day (4 November 2026), plain HTTPS from one network, no JavaScript. These are the headers a crawler or a script receives, not what a browser renders after hydration.
- The status codes and sizes are what this network's edge returned; a different point of presence could answer differently, and Cloudflare's own layer is in front of the origin in every measurement here.
- HTTP/3 was advertised by
alt-svcbut not exercised: the installed curl has no HTTP/3 support, so I cannot claim an HTTP/3 request was made. - I did not test a signed-in session, so no claim is made about headers that might differ behind a sign-in.
- The CSP is quoted as served; I did not attempt to find a page or input that gets past it.
- The compression ratios are single-shot measurements of one response per URL, not averages over repeated fetches.
Why it is worth looking at
Three of these headers decide how your tool behaves for the user, and none of them are visible in a screenshot: strict-transport-security decides whether the connection can be downgraded, content-security-policy decides what code is allowed to run at all, and cache-control plus the missing validators decide whether the page costs the user a full re-download on every visit.
For OnePassApps the answers are: one security policy applied identically everywhere, Brotli on every response, no third-party or analytics cookies, no edge caching, and an API that is origin-scoped, non-cacheable, rate-limited and self-describing in its headers.
If you want to see the same thing yourself, run curl -sI https://app.onepassapps.com/studios/image and read the header block, or open the Data Studio and check what the response carried before the page appeared. The app guides explain what each studio does with the file you give it.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.