CORS & allowed origins
Publishable keys (kld_pk_live_…) carry an allowed-origins list — the
browser origins permitted to use the key. Set it when you mint the key (e.g.
https://acme.com, https://app.acme.com); a live publishable key requires at
least one. Server keys (kld_sk_live_…) get no CORS grant, so a page can
never read a response made with one. Note what that does and doesn't cover:
CORS blocks the response, not the request — a server key embedded in page
source has already been exposed regardless. The SDK therefore refuses
kld_sk_… at mount; server keys are server-to-server only.
How it's enforced
- Preflight (
OPTIONS) is permissive — it reflects the requested origin so the browser proceeds (the key isn't presented on a preflight). - The real request only gets an
Access-Control-Allow-Originheader back when the requestOriginis in the key's allowed list. A non-allowlisted origin gets no ACAO header, so the browser blocks the response.
No cookies are involved — the platform API is bearer-token auth, so there is no
Access-Control-Allow-Credentials.
Publishable keys travel in URLs to the tile CDN
tile.kaleidr.com takes your publishable key as a ?key= query parameter. That
is by design, and it has a consequence worth stating plainly: query strings are
recorded in CDN access logs, browser history, and any proxy in between.
This is acceptable because a publishable key is public by construction — it
already ships in your page source. The control that makes it safe is the
per-key origin allowlist, which the edge enforces on every tile request, plus
the key being restricted to the maps scope.
It is not acceptable for a server key. Never put kld_sk_… in a URL, and note
that a leaked server key is already exposed by the time the API refuses it.
Everywhere else — the SDK session exchange, the platform API — the key travels as a header, never a query parameter.
Tips
- Use bare origins (
scheme://host[:port]) — no path, no trailing slash — so they match the browser'sOriginheader exactly. httpsis required except forlocalhost/127.0.0.1(local testing).- Server-to-server calls with a server key (no browser
Origin) aren't CORS-gated, but still authenticate + scope-check normally.