Skip to content

Tenants & API keys

palumb has two kinds of caller. Machines — your backend — authenticate with a tenant API key, and that key resolves to exactly one tenant: the key is the machine identity. Humans — you and your team — sign in to the dashboard to create and manage those keys (and channels, subscribers, topics, and billing). The machine REST API is API-key-scoped end to end; the dashboard is where the keys come from.

A tenant is your account. It owns everything scoped to you:

Every table is tenant-scoped, and the tenant is taken from the API key — never from the request body or a path parameter — so one tenant can never read or write another’s data.

An API key is an opaque random token. Send it on every request:

Terminal window
curl -sS "$PALUMB_BASE_URL/v1/channels" \
-H "Authorization: Bearer $PALUMB_API_KEY"

Authorization: Bearer <key> is preferred; x-api-key: <key> also works.

palumb stores only the SHA-256 hash of a key, plus a short non-secret prefix for display. So:

  • the raw key is shown exactly once, at creation — store it then;
  • a leaked database never exposes a usable key (only hashes);
  • on each request palumb hashes the presented key and looks it up by hash, then loads the tenant. Controllers and use cases only ever see the resolved tenant, never the raw key.

A key can be revoked (it carries a revoked_at); a revoked or unknown key is a flat 401. palumb also records a best-effort last_used_at — observational, never blocking auth.

On managed palumb you manage keys yourself in the dashboard. Sign up with your email and password, verify your email, and log in. From there you can:

  • create an API key — the raw key is shown to you once, at creation; copy it then, because palumb only stores its hash;
  • revoke a key you no longer trust;
  • manage the rest of your tenant — channels, subscribers and topics, the delivery log, and billing.

Every key you create belongs to your tenant, so a key your backend presents always resolves to your account and only your data.

If you self-host, there is no managed dashboard — you provision a tenant and mint its first key with the seeder (npm run seed), as shown in Self-hosting.

The dashboard login is for humans; it never touches the machine REST API. Your backend authenticates every request the same way it always has — with an API key (or, on internal routes like the engine’s /v1/deliver, an internal service token that is never exposed to tenants). Either way, the system only ever depends on “which tenant is this”, so every use case and tenant-scoping check stays the same regardless of how the caller proved who they are.