Keys, auth, and scopes
ThinkingRoot Cloud authenticates every request at the gateway. There are three kinds
ThinkingRoot Cloud authenticates every request at the gateway. There are three kinds of credentials, each for a different audience.
Secret project keys — tr_sk_…
The key machines use: SDKs, backends, AI tools, CI. A tr_sk_… key is full-scope
— it can read, write, compile, deploy functions, and manage the workspace. Treat it
like a password: keep it server-side, never ship it to a browser.
curl https://api.thinkingroot.com/engine/api/v1/ws/main/ask \
-H "authorization: Bearer tr_sk_..." \
-d '{"question":"how does billing work?"}'Publishable keys — tr_pk_…
The key safe to embed in client code (a website, a widget), the way a Stripe pk_ or
a Supabase anon key is. A tr_pk_… key is restricted:
- scope-limited — it can only reach ask/recall/search endpoints, never write, compile, or deploy. The gateway enforces this by request path, so the key physically cannot perform a write.
- domain-locked — it only works from origins you allow-list. A request from any
other site is rejected. This is enforced by the browser
Originheader at the gateway.
That combination is why a publishable key is safe to put in a public page: it can ask one brain, only from your domain, and nothing else.
Session JWTs
The credential humans use in the Console. After signing in, a short-lived JWT (delivered as an httpOnly cookie) authorizes Console actions, scoped by organization membership. The browser never holds a project key directly — the Console proxies engine calls through a same-origin backend.
How the gateway routes
The gateway reads the key prefix and routes accordingly: tr_sk_/tr_pk_ →
hash-lookup → project → that project's engine; JWT → identity verification → org
membership. A restricted key is checked against the required scope (and origin, if
domain-locked) on every call. A Console JWT can never reach a project the user isn't a
member of.
Picking the right key
- Building a backend, agent, or script →
tr_sk_…(secret, server-side). - Embedding ask/recall in a public page or widget →
tr_pk_…(publishable, domain-locked). - Acting as a signed-in human in the Console → handled for you via the session JWT.