Skip to content

Authentication

The Centrali SDK supports three authentication methods. Choose the right one based on your use case.

Which method should I use?

Scenario Method SDK Option
Frontend app (React, Vue, public) Publishable key publishableKey
Frontend with user login (Clerk, Auth0) External token getToken
Server-side script or backend Service account clientId + clientSecret

Publishable Keys

Publishable keys are scoped, browser-safe credentials for frontend apps. They bypass workspace policies — only the key's scopes determine what it can access.

Create a publishable key in Console > ACCESS > Publishable Keys, select which collections, triggers, and files it can access, then use it in your app:

import { CentraliSDK } from '@centrali-io/centrali-sdk';

const centrali = new CentraliSDK({
  baseUrl: 'https://centrali.io',
  workspaceId: 'my-workspace',
  publishableKey: 'pk_live_a1b2c3d4e5f6g7h8',
});

// Read records (if scoped)
const posts = await centrali.queryRecords('posts');

// Submit a form (if scoped)
await centrali.createRecord('contact-submissions', {
  name: 'Jane',
  message: 'Hello!',
});

Key characteristics:

  • Sent as x-api-key header (not Bearer token)
  • No token refresh needed — the key is static
  • Scopes follow resource:action:target format (e.g., records:list:posts)
  • Wildcard targets (*) only allowed for read actions
  • Admin resources (users, groups, policies) are never accessible
  • Rate limited per key: 200 reads/min, 30 writes/min

Security: Publishable keys are safe to expose in client-side code. They are workspace-scoped and can only access the specific resources their scopes allow.

External Tokens (BYOT)

If your app has its own authentication (Clerk, Auth0, Okta, etc.), use the getToken callback to pass your provider's JWT to Centrali:

const centrali = new CentraliSDK({
  baseUrl: 'https://centrali.io',
  workspaceId: 'my-workspace',
  getToken: async () => {
    // Get a fresh token from your auth provider
    return await clerk.session.getToken();
  },
});

// Full access governed by ABAC policies
await centrali.updateRecord('posts', 'post-123', { title: 'Updated' });

Key characteristics:

  • Token is sent as Authorization: Bearer header
  • getToken is called before each request to ensure a fresh token
  • On 401, the SDK retries once with a new token from getToken
  • Access is governed by ABAC policies (workspace policies, roles, groups apply)
  • Requires an external auth provider configured in Console > ACCESS > Auth Providers

You can also pass a static token directly:

const centrali = new CentraliSDK({
  baseUrl: 'https://centrali.io',
  workspaceId: 'my-workspace',
  token: 'eyJhbGciOiJSUzI1NiIs...',
});

Service Accounts

Service accounts use OAuth2 client credentials for server-to-server authentication. Never use client secrets in browser code.

const centrali = new CentraliSDK({
  baseUrl: 'https://centrali.io',
  workspaceId: 'my-workspace',
  clientId: process.env.CENTRALI_CLIENT_ID,
  clientSecret: process.env.CENTRALI_CLIENT_SECRET,
});

// Full access governed by ABAC policies
await centrali.deleteRecord('posts', 'post-123');

Key characteristics:

  • Token is fetched automatically via client credentials grant on first request
  • On 401/403, the SDK refreshes the token and retries once
  • Access is governed by ABAC policies
  • Create service accounts in Console > ACCESS > Service Accounts

Mutual Exclusion

Only one auth method can be used at a time. The SDK throws an error if conflicting options are provided:

// This throws: "Cannot use publishableKey with clientId/clientSecret"
new CentraliSDK({
  publishableKey: 'pk_live_...',
  clientId: 'ci_...',
  clientSecret: 'sk_...',
});

Publishable Keys vs ABAC Policies

Publishable keys and ABAC policies are separate authorization systems:

Publishable Keys ABAC Policies
Used by publishableKey auth path token, getToken, clientId/clientSecret
Authorization Scopes embedded in the key Policies evaluated by IAM
Managed in Console > Publishable Keys Console > Permissions
Granularity resource:action:target Conditions (time, IP, claims, groups)
Admin access Never Policy-dependent

If you need conditional access (time-based, IP-restricted, group-based), use ABAC with user tokens or service accounts. If you need simple, scoped frontend access, use publishable keys.