Browse documentation→
Docs/Security
Best practices

Security

API tokens are bearer credentials with billing authority. Treat them as production secrets and keep them out of every client environment.

Server-side only

Always call the inference API from a trusted server process. Never embed an API token in browser JavaScript, a mobile binary, a public build variable, or an app-store bundle. Anyone who can read the client can extract a bearer credential.

Safe

Server process, background worker, backend route, or trusted CI job reading the token from a secret manager.

Never

Browser bundles, mobile clients, public repositories, support tickets, analytics tools, or NEXT_PUBLIC_* variables.

server-environment
# Server-side environment only. Never expose this to a client bundle.
INFERENCE_API_KEY=sk_live_xxxxxxxx

Console sessions are separate

The web console authenticates with an HttpOnly session cookie and accesses a private management API. That cookie is not an inference credential and should not be forwarded to arbitrary third parties.

Proxy pattern

Keep the token in a server route and let the browser call that route. This example forwards a chat request without revealing the credential or accepting an arbitrary remote URL from the client.

app/api/chat/route.ts
import { NextResponse } from "next/server";

const API_BASE = process.env.INFERENCE_API_BASE_URL!;
const API_KEY = process.env.INFERENCE_API_KEY!;

export async function POST(request: Request) {
  const body = await request.json();

  const upstream = await fetch(`${API_BASE}/v1/chat/completions`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": crypto.randomUUID(),
    },
    body: JSON.stringify({
      model: body.model,
      messages: body.messages,
      stream: false,
    }),
  });

  const data = await upstream.json();

  if (!upstream.ok) {
    return NextResponse.json(
      { error: "inference_failed" },
      { status: upstream.status },
    );
  }

  return NextResponse.json({
    content: data.choices?.[0]?.message?.content ?? "",
  });
}
  • Validate and constrain the request body. Do not forward arbitrary fields or URLs supplied by the browser.
  • Authenticate and authorize your own users before spending inference balance on their behalf.
  • Apply your own rate limiting and abuse controls in addition to the platform's limits.
  • Add the Idempotency-Key header when retries are possible.

Credential hygiene

  • Use a separate token per environment and service. Name tokens by consumer, not by person.
  • Store tokens in a managed secret store or server environment configuration. Do not commit them to source control.
  • Rotate on a schedule and whenever a consumer is decommissioned. Rotation invalidates the old secret immediately.
  • Revoke a token rather than letting it linger when you are unsure whether it is still in use. Side effects are preferable to an uncontrolled credential.
  • Never send credentials in URLs, query strings, screenshots, or error reports.

Logging & redaction

Redact authorization headers and any value beginning with sk_live_xxxxxxxx before logging request metadata. Prefer logging the token ID, prefix, and last four characters, which the console exposes for identification.

redact.ts
export function redactAuth(headers: Headers): string {
  const raw =
    headers.get("authorization") ?? headers.get("x-api-key") ?? "missing";
  if (raw.startsWith("Bearer ")) return "Bearer sk_live_xxxxxxxx";
  return raw === "missing" ? raw : "sk_live_xxxxxxxx";
}

// Prefer identifying the credential without the secret:
// token.id, token.prefix, token.last4

Include error.requestId in structured logs to correlate failures with platform-side traces.

If a key leaks

  1. Revoke immediately from Dashboard → Tokens. Revocation is immediate.
  2. Rotate the consumer to a fresh token and redeploy only after the old token is invalid.
  3. Review usage for unexpected requests, models, or spend in the affected window.
  4. Remove the exposure from code, build settings, logs, and artifacts, then rotate any other credentials that shared the leak path.

No browser fallback

There is no secure way to call the inference API directly from a public browser application with a bearer token. If an integration currently exposes one, treat that token as compromised and move the call behind a server immediately.