Authentication API

ProBeya uses Auth.js v5 (NextAuth) for session-based authentication and custom API keys for programmatic access. Authentication supports credentials (email/password), OIDC, and SAML providers (see SSO for per-tenant SSO setup).

Authentication Methods

API Key Format

probeya_sk_live_{40 random hex chars}
  • Prefix: probeya_sk_live_ identifies the key as a ProBeya API key
  • Entropy: 160 bits (20 random bytes), exceeding NIST 128-bit recommendation
  • Storage: Only the bcrypt hash is stored; the full key is returned once on creation
  • Lookup: First 8 hex chars stored as a cleartext prefix for efficient database lookup

Endpoints


GET /api/v1/auth/check-email

Check if an email address is already registered. Used by the signup form for real-time validation.

tRPC: auth.checkEmail Auth: None required (public)

Parameters:

NameTypeRequiredDescription
emailstringYesEmail address to check

Response (available):

{
  "available": true
}

Errors:

CodeDescription
409Email already registered

GET /api/v1/auth/me

Get the full profile of the currently authenticated user. Fetches from the database to include fields not available in the lightweight session context.

tRPC: auth.me Auth: Bearer token required or session cookie

Response:

{
  "id": "clx9us001",
  "name": "John Smith",
  "email": "[email protected]",
  "image": "https://cdn.probeya.com/avatars/john.jpg",
  "createdAt": "2026-01-15T10:00:00.000Z",
  "updatedAt": "2026-03-28T09:00:00.000Z"
}

Sensitive fields like passwordHash are explicitly excluded from the response.


PATCH /api/v1/auth/me

Update the current user’s profile (name and avatar image).

tRPC: auth.updateProfile Auth: Bearer token required or session cookie

Parameters:

NameTypeRequiredDescription
namestringNoDisplay name (2-100 chars)
imagestringNoAvatar image URL

Response:

Returns the updated user object.


API Key Management

API keys are managed via session-based authentication only (the settings UI). You cannot create or revoke API keys using another API key — this prevents privilege escalation.

POST /api/v1/auth/api-keys

Generate a new API key. The full key is returned once and cannot be retrieved later.

tRPC: apiKeys.create Auth: Session cookie only. Role: manage_settings permission required. Org context: Required

Parameters:

NameTypeRequiredDescription
namestringYesHuman-readable label for the key (max 100 chars)
scopesstring[]NoPermission scopes (empty array = full access)
expiresAtstringNoExpiration date (ISO 8601)

Response:

{
  "key": "probeya_sk_live_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0",
  "apiKey": {
    "id": "clx9ak001",
    "name": "CI Pipeline",
    "prefix": "a1b2c3d4",
    "scopes": ["read:items", "write:items"],
    "expiresAt": "2027-01-01T00:00:00.000Z"
  }
}

Store the API key securely immediately after creation. It will never be displayed again.


GET /api/v1/auth/api-keys

List all API keys for the current organization. The key hash is never returned — only the prefix is shown for identification.

tRPC: apiKeys.list Auth: Session cookie only. Role: manage_settings permission required. Org context: Required

Response:

{
  "data": [
    {
      "id": "clx9ak001",
      "name": "CI Pipeline",
      "prefix": "a1b2c3d4",
      "scopes": ["read:items", "write:items"],
      "status": "active",
      "lastUsedAt": "2026-04-01T10:00:00.000Z",
      "expiresAt": "2027-01-01T00:00:00.000Z",
      "createdAt": "2026-03-01T10:00:00.000Z"
    }
  ]
}

POST /api/v1/auth/api-keys/:id/revoke

Permanently revoke an API key. This is irreversible — once revoked, the key cannot be reactivated.

tRPC: apiKeys.revoke Auth: Session cookie only. Role: manage_settings permission required. Org context: Required


POST /api/v1/auth/api-keys/:id/rotate

Atomically revoke the current key and generate a new one. Returns the new full key once.

tRPC: apiKeys.rotate Auth: Session cookie only. Role: manage_settings permission required. Org context: Required


DELETE /api/v1/auth/api-keys/:id

Hard-delete an API key record from the database.

tRPC: apiKeys.delete Auth: Session cookie only. Role: manage_settings permission required. Org context: Required


OAuth / SSO Flows

Per-tenant SSO is configured via the Admin API. When SSO is active:

  1. The user navigates to {tenant}.probeya.com/login
  2. If SSO enforcement is enabled, the login page redirects directly to the IdP
  3. After IdP authentication, the user is redirected back with an authorization code
  4. ProBeya exchanges the code for tokens and creates a session
  5. The OIDC client secret is stored server-side and never exposed to the client

Permission Scopes

API keys support fine-grained permission scopes:

ScopeDescription
read:itemsRead boards, items, KPIs, actions, and related data
write:itemsCreate and modify boards, items, KPIs, and actions
read:actionsRead action items
write:actionsCreate and modify action items
read:kpisRead KPI definitions and values
write:kpisRecord KPI measurements
read:membersRead organization members
manage_settingsManage org settings, API keys, webhooks
manage_billingAccess billing and subscription management

An empty scopes array grants full access to all operations.

Security Notes

  • API key management requires session authentication (not API key auth) to prevent escalation
  • All CRUD operations on API keys are logged to the audit trail
  • Keys are hashed with bcrypt (10 salt rounds) before storage
  • The 8-character prefix enables efficient DB lookup without exposing the full key
  • Rate limiting applies to all authenticated endpoints (see Rate Limiting)

Error Codes

CodeDescription
401Missing or invalid authentication token
403Insufficient scope or role for the requested operation
404User or API key not found
409Email already registered