API keys
How api_key, api_secret, and user JWTs differ — and where each one belongs.
Cariosan uses three different credential types. Mixing them up is the most common integration mistake — this page maps each to where it belongs.
The three credentials
| Credential | Prefix | Lifetime | Where it goes |
|---|---|---|---|
api_key | pk_live_… or pk_test_… | Until workspace deleted | Server-side env var; safe to log |
api_secret | sk_live_… or sk_test_… | Until rotated | Server-side secret manager only; never in logs, frontend, or repos |
| User JWT | eyJ… | Default 24h | Issued per end-user, passed to client SDKs |
api_key (pk_*)
The public key. Safe to put in env vars, your CI configuration, and your docker-compose.yml.
Where you use it:
- Server SDK constructor — your backend calling Cariosan's REST API to upsert users, create channels, send webhooks.
- Cariosan Cloud dashboard — visible in the Overview page with copy-to-clipboard.
- Headers — sent alongside
api_secretasAuthorization: Bearer <api_key>:<api_secret>.
Where it does NOT go:
- Your frontend JavaScript bundle (use a user JWT instead).
- A public Git repo (although disclosure is recoverable via rotation — see below).
api_secret (sk_*)
The signing secret. Treated like a database password.
Where you use it:
- Server SDK constructor — paired with
api_key. - Webhook signature verification (
X-Cariosan-SignatureHMAC uses this secret).
Where it does NOT go:
- ANY frontend code.
- Logs, error reports, or analytics events.
- Cariosan Cloud's dashboard does not store the plaintext — once you close the modal showing it, the only way to retrieve it is to rotate.
One-time reveal
Cariosan Cloud shows the plaintext api_secret exactly once: right after workspace creation, and right after a manual rotation. We hash it server-side and discard the plaintext. Copy it to your secret manager immediately.
User JWTs
Short-lived tokens you issue from your backend, scoped to a single end-user.
Where you use them:
- Client SDKs (
@cariosan/client,@cariosan/react) on the browser / mobile. - The user JWT lets that ONE user read their messages and send new ones — they can't read other users' data.
How to issue:
- Backend calls the Go SDK's
IssueUserToken(userID)(or its TypeScript equivalent) with yourapi_key+api_secret. - Hand the JWT to your frontend through your existing auth flow (alongside your own session, typically).
JWTs default to 24h. Tune via CARIOS_JWT_TTL_HOURS if you self-host; on Cariosan Cloud the default is fixed at 24h.
Rotation
Rotation invalidates the current api_secret immediately. Any server using the old secret receives 401 until you redeploy with the new one.
Cariosan Cloud — dashboard rotation
- Open the workspace in dashboard.cariosan.com.
- Click Regenerate secret in the Overview page.
- The new
api_secretdisplays once. Copy it. - Update your secret manager. Redeploy your backend.
Self-host — CLI rotation
Same one-time reveal applies.
Plan rotation around redeploy
The old secret stops working the moment rotation completes. If your backend is mid-deploy, requests using the old secret error during the window. Best practice: rotate immediately after you've already published the new secret to your runtime config.
Lost the secret?
If you no longer have the secret AND no way to recover from your own secret manager:
- Cariosan Cloud — click Regenerate secret. The replacement is shown once.
- Self-host — run
/cariosan workspace rotate-secret.
There's no recovery path that returns the original. The hashed value on the server can't be reversed.
Test mode keys (pk_test_ / sk_test_)
Not implemented in Phase A. Today every workspace's keys are live (pk_live_ / sk_live_). Test-mode workspaces — separate ID space, no quota counting against billing — ship with the paid tier.
Next steps
- Webhooks guide — verify signatures using your
api_secret - Go server SDK —
IssueUserTokenand other backend operations - TypeScript client SDK — consume user JWTs in the browser
Was this page helpful?