Keys and security
Understanding public and secret API keys, where to use each, and how to keep your application secure.
Every SimpleAuth application has two API keys. Using the right key in the right place is critical for security.
Public key
- Prefix:
sa_live_… - Where to use: Browsers, mobile apps, any client-side code.
- How it's sent:
Authorization: Bearer sa_live_…(default) orX-API-Key: sa_live_…. - What it can do: Register users, log in, verify email, reset passwords.
The public key identifies your application but does not grant any admin privileges. It's safe to ship in client bundles.
const auth = createSimpleAuthClient({
apiKey: "sa_live_…",
})Secret key
- Prefix:
sa_secret_… - Where to use: Your backend servers only. Never in client-side code.
- How it's sent: Same headers as the public key, but only from server environments.
- What it can do: Everything the public key can, plus admin operations — create users, ban/unban, delete users, revoke sessions.
import { createServerSimpleAuthClient } from "@simpleauthjs/core/server"
const adminAuth = createServerSimpleAuthClient({
secretKey: "sa_secret_…",
})Key rotation
If a key is compromised, rotate it from the dashboard. Rotation takes effect immediately — the old key stops working the moment you rotate. Update your application configuration right after rotating.
Security best practices
- Never commit keys to version control. Use environment variables (
SIMPLEAUTH_SECRET_KEY). - Never expose the secret key in client bundles. The server SDK throws an error if imported in a browser environment.
- Use HTTPS in production. The SDK warns if
baseUrluseshttp://while the page is served overhttps://. - Configure CORS correctly. Since sessions use HTTP-only cookies with
credentials: "include", your server must allow credentials from your frontend origin. - Allowlist your app origins. OAuth and cookie-based flows require your real app URLs (and local dev URLs) to be configured in the dashboard so redirects work with
credentials: "include".