Roadie has two authenticated surfaces:
  • The control plane () manages your account: organizations, projects, environments, keys, provider credentials, limits, budgets, and logs. It is authenticated by your dashboard session or a management key (rd_mk_…) for CI and automation.
  • The data plane () serves model traffic — POST /v1/chat, POST /v1/embeddings, and the client-token mint routes. It is authenticated by a project-and-environment credential: a secret key, a publishable key, or a client token.
Every credential is scoped as narrowly as its job allows, and every data-plane credential resolves to exactly one project and environment.

The six credentials

The first three are keys you create in the dashboard; the last three are minted or presented at runtime by client apps. The rest of this page covers each in turn.

Secret keys

A secret key (rd_sk_{env}_…, where {env} is dev or prod) is the server-side credential. It can call every data-plane endpoint and can mint client tokens. It grants full access to its project and environment, so it must never ship in a browser or mobile binary. Only the SHA-256 hash of a key is stored; the plaintext is shown once at creation, and the display form keeps just a masked prefix and the last four characters (e.g. rd_sk_prod_…x4Fq).
A secret key grants full project access. The SDK throws if it detects a rd_sk_… key in a browser-like environment. Client apps must use a client token via a tokenProvider, never a secret key.

Publishable keys

A publishable key (rd_pk_{env}_…) is client-safe: it is designed to be embedded in a web or mobile app. Its only power is minting a client token — either by exchanging a federated identity token (Path B) or by completing the device-attestation flow, both covered in Client tokens. It cannot call model or embeddings endpoints. A leaked publishable key alone mints nothing: minting still requires a valid identity token or a genuine device attestation. Because it is not a secret, the plaintext may be re-displayed in the dashboard — but it is still stored and looked up by hash, exactly like a secret key, so it flows through the same lifecycle (rotation, revocation, restrictions).

Management keys

A management key (rd_mk_…) authenticates the control plane for automation — the non-interactive counterpart to a signed-in owner session. Unlike secret and publishable keys, it is org-scoped, not environment-scoped, so it carries no {env} segment.
  • It carries a role that plugs into control-plane authorization, capped at admin — it can never grant owner-level actions, and a management key can never mint another management key.
  • Only an org owner can issue one.
  • It is verified only by the control-plane API — the gateway has no knowledge of rd_mk_, so a management key can never call the data plane.
  • Revocation is immediate: the control plane reads Postgres live, so a revoked_at timestamp takes effect on the next request with no propagation window.
See Automating with management keys for usage.

Client tokens

A client token is a short-lived ES256 JWT that lets a browser or mobile app call the data plane as one end user, without embedding a secret. It is scoped to a single end user, carries that user’s limits, and lives for at most an hour (15 minutes by default). Its scopes gate which endpoints it may call: ai.chat, ai.embed, ai.images, and feedback. Client tokens are the subject of their own page — see Client tokens for how they are minted (from a backend or via federated identity) and why they are safe.

Device attestation

For iOS apps with no backend and no user accounts, Apple App Attest proves that a request comes from a genuine, unmodified build of your app on a real device — using a hardware-backed key in the Secure Enclave. The gateway turns that proof into a per-device end user (device:<hash>) and mints a client token for it. The device routes (POST /v1/device/{challenge,attest,assert}) are publishable-key-only and are off by default per project. An optional Apple DeviceCheck token can travel alongside the attestation as an anti-farming signal: Apple persists two bits per device that survive reinstalls and device erase, which Roadie uses to stop a device from farming a fresh free tier by reinstalling. It is auxiliary — omitting it simply grants the normal free tier — and it is never a bearer credential on its own. See the mobile device auth guide and the App Attest tutorial for the full flow.

Environments

Every project has separate development and production environments, created automatically (see Tenancy & isolation). Each is isolated, with its own keys, provider credentials, limits, and log-privacy default. A secret or publishable key belongs to exactly one environment — choosing which environment to call is simply a matter of which key you send. Development keys default to higher log capture; production defaults to metadata-only (see Privacy modes).

Sending a credential

Send the credential as a bearer token on every data-plane request:
With the SDK you pass a secret key once at construction:
Client apps pass a tokenProvider instead of a key — see Client tokens.

Key lifecycle

  • Create — the full key is shown once; only its hash and masked display prefix are stored.
  • Roll — issue a replacement while keeping the old key valid for a configurable overlap window (0–72 h, default 1 h) so you can rotate without downtime.
  • Revoke — takes effect immediately: the gateway keeps a Redis denylist plus a config-dirty push, so revocation propagates in well under a second across gateway instances. (Management-key revocation is immediate too, via a live Postgres read.)
Revoked or expired keys fail with an authentication_error (key_revoked / key_expired).

Restricted keys

A secret or publishable key can carry optional allowlists, enforced in the gateway from the config snapshot:
  • allowed_models — the only provider/model ids (or aliases) this key may request. Anything else fails permission_error / model_not_allowed.
  • allowed_endpoints — the only endpoints this key may call (e.g. chat but not embeddings). A disallowed endpoint fails permission_error / endpoint_not_allowed.
  • Max request cost — an upper bound (USD) on a single request’s estimated cost.
Restrictions are ideal for scoping a key to exactly what a given service or integration needs. A client token inherits the restrictions of the key that minted it.

Authorization order

For every data-plane request the gateway evaluates, deny-by-default at each step:
  1. Credential → tenant context (project, environment, key scopes, end user).
  2. Key restrictions (model / endpoint allowlists, max cost).
  3. Environment + project policy (allowed models, privacy mode).
  4. Plan entitlements (platform subscription gates).
  5. The limits engine.
Every denial has a typed error code and appears in your request logs. For the full request path, see Architecture.