> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tybritelabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Learn how to secure your Tybrite commerce integrations using API keys and HMAC signing.

Tybrite uses a dual-key architecture to ensure maximum security without sacrificing developer experience. Depending on where your code runs, you will use different keys and authentication patterns.

## API Key Types

We support two distinct key types for every store. You can manage these in your [Dashboard](https://gc.tybritelabs.com/integrations) under **Integrations → Developer**.

### Publishable Keys (`tybrite_pk_...`)

Publishable keys are intended for use in frontend applications, such as React websites, mobile apps, or headless storefronts.

* **Scope:** Read-only access to non-sensitive data (Products, Categories, Search).
* **Security:** Safe to include in client-side bundles or public repositories.
* **Usage:**
  ```typescript theme={null}
  const client = new Tybrite({ apiKey: 'tybrite_pk_live_...' });
  ```

### Secret Keys (`tybrite_sk_...`)

Secret keys are for server-side environments and provide full administrative access to your commerce data.

* **Scope:** Full Read/Write access (Orders, Customers, Payments, Settings).
* **Security:** **Must never be exposed to the client.** Keep them in environment variables (`TYBRITE_SECRET_KEY`).
* **Usage:**
  ```typescript theme={null}
  const client = new Tybrite({ apiKey: process.env.TYBRITE_SECRET_KEY });
  ```

***

## Environments & Sandbox

The key prefix determines which environment your requests target — there is no separate sandbox base URL.

| Prefix                                  | Environment    | Data scope                                       |
| :-------------------------------------- | :------------- | :----------------------------------------------- |
| `tybrite_sk_live_` / `tybrite_pk_live_` | **Production** | Live customer, order, and inventory data         |
| `tybrite_sk_test_` / `tybrite_pk_test_` | **Sandbox**    | Isolated test data — never mixed with production |

**What sandbox isolation means in practice:**

* Orders, customers, cart items, wishlist entries, product reviews, and messaging conversations created with a `test` key are stored in the sandbox partition and are never returned to `live` key requests.
* Payment providers switch to test mode automatically when a `test` key is used — Stripe test mode, PayPal sandbox, Paystack test keys, M-Pesa sandbox — regardless of what your store's payment settings show.
* Every authenticated response includes a `Tybrite-Environment: production | sandbox` header so you can confirm which partition resolved.

<Tip>
  Build and test your entire integration with `tybrite_sk_test_*` keys. When you're ready for production, swap to `tybrite_sk_live_*` and the right environment follows automatically — no code changes needed.
</Tip>

***

## Authorization Header

For direct REST API calls, provide your key in the `Authorization` header using the `Bearer` scheme:

```bash theme={null}
Authorization: Bearer tybrite_sk_live_YOUR_KEY
```

***

## Advanced Security: HMAC Signing

Sensitive operations, such as order creation or payment initialization, require an additional layer of security to prevent request tampering and replay attacks. For these requests, you must provide verified headers.

### Generating the Signature

The signature is a **SHA-256 HMAC** hash of the payload, where the payload is the current Unix timestamp concatenated with the JSON request body.

```typescript theme={null}
import { createHmac } from 'crypto';

// 1. Prepare Payload
const timestamp = Math.floor(Date.now() / 1000);
const body = JSON.stringify(requestData);
const payload = `${timestamp}.${body}`;

// 2. Generate Signature
const signature = createHmac('sha256', process.env.TYBRITE_HMAC_SECRET)
  .update(payload)
  .digest('base64');

// 3. Include in your request:
// xTimestamp: timestamp
// xSignature: signature
```

Endpoints requiring HMAC signing:

* `POST /v1/payments/initialize`
* `POST /v1/orders`
* `PATCH /v1/orders/:id`

***

## 🔄 Idempotency Protection

To prevent duplicate charges and orders—especially during network retries—all state-changing financial operations require a mandatory `Idempotency-Key` header.

* **Mechanism**: The server tracks these keys. If a request is retried with the same key, the server returns the original response with an `idempotent: true` flag.
* **Best Practice**: Generate a unique UUID or a hash of the transaction details (e.g., `payment-order_123-ts_456`).

Endpoints requiring an Idempotency Key:

* `POST /v1/payments/initialize`
* `POST /v1/orders`
* `PATCH /v1/orders/:id`

***

## Customer Session Tokens (`xAuthToken`)

While API keys authenticate **your application** to Galactic Core, **customer session tokens** authenticate **end customers** to their own data within your store. They are required *on top of* an API key for endpoints that access or modify a specific customer's records (cart, wishlist, profile, gift cards, messaging).

**Why both?** A leaked publishable key alone gives an attacker no way to read or modify any specific customer's data — they would also need that customer's JWT, which only the [AuthenticationService](/sdk/api-reference/classes/AuthenticationService) can issue, and only after a successful login / OTP verification / magic link redemption.

### Affected endpoints

| Endpoint                                       | `xAuthToken` requirement                                                       |
| ---------------------------------------------- | ------------------------------------------------------------------------------ |
| `GET` / `PATCH /v1/customers/{id}`             | **Required.** Token's subject must match path `id`.                            |
| `GET` / `POST` / `PATCH` / `DELETE /v1/cart/*` | **Required** when `customer_id` is supplied (anonymous session carts omit it). |
| `GET` / `POST` / `DELETE /v1/wishlist/*`       | **Required** — wishlist always requires `customer_id`.                         |
| `GET /v1/gift-cards?customer_id=...`           | **Required** when `customer_id` is supplied.                                   |
| `GET` / `POST` / `PATCH /v1/messaging/*`       | **Required**, gated by thread or message ownership.                            |

### Example flow

```typescript theme={null}
// 1. Customer logs in — mint the session JWT
const { customer, session } = await client.authentication.login({
  requestBody: { email: 'user@example.com', password: '...' }
});

const token = session.access_token;

// 2. Pass it on every customer-scoped call
await client.cartWishlist.addToCart({
  xAuthToken: token,
  requestBody: { customer_id: customer.id, product_id: 'prod_123', quantity: 1 }
});

await client.customers.getCustomer({
  xAuthToken: token,
  id: customer.id
});

// 3. Refresh before expiry (~1 hour)
const { session: fresh } = await client.authentication.refreshToken({
  requestBody: { refresh_token: session.refresh_token }
});
```

<Tip>
  **Recommended storage:** prefer **httpOnly, Secure, SameSite=Lax cookies** over `localStorage`. Cookies are immune to XSS-based token theft and the browser handles attachment automatically. Reach for `localStorage` only when your storefront is a native mobile WebView or a same-origin SPA without a backing server, and pair it with a strict CSP.
</Tip>

<Warning>
  Never log, persist server-side, or share customer access tokens between sessions. Each token is bound to a single customer and grants direct read/write access to their cart, wishlist, profile, and messages.
</Warning>

***

## Key Usage by Endpoint

Every endpoint accepts one (or a combination) of the credentials above. Use this table to pick the right key before you call. The legend:

* **`pk` or `sk`** — either a publishable or a secret key works.
* **`sk` only** — a secret key is required; a publishable key returns **`403 Forbidden`**.
* **`pk` (browser)** — a publishable key is enough; safe to call directly from the browser.
* **+ session** — *also* requires a [customer session token](#customer-session-tokens-xauthtoken) (`xAuthToken`, or `x-external-auth` for bring-your-own-auth).
* **+ HMAC** — *also* requires a [request signature](#advanced-security-hmac-signing).
* **Public** — no key required.
* **Operator** — a marketplace operator key (marketplace deployments only).

### Discovery & catalog (read)

| Endpoints                                                                             | Key                       |
| ------------------------------------------------------------------------------------- | ------------------------- |
| Products, collections, specifications (`client.products.*`)                           | `pk` or `sk`              |
| Categories & subcategories (`client.taxonomy.*`)                                      | `pk` or `sk`              |
| Prices (`client.pricing.*`)                                                           | `pk` or `sk`              |
| Search — text & semantic (`client.search.*`)                                          | `pk` or `sk`              |
| Tax preview (`client.tax.previewTax`)                                                 | `pk` or `sk` (browser)    |
| Recommendations (`client.recommendations.*`)                                          | **`sk` only**             |
| Discovery — most-viewed / most-added-to-cart / best-converting (`client.discovery.*`) | `pk` or `sk` (browser)    |
| Event capture (`client.events.recordEvent`)                                           | `pk` (browser)            |
| Blog posts & lookbooks (`client.cms.*`)                                               | `pk` or `sk`              |
| Store info (`client.system.getStoreInfo`)                                             | `pk` or `sk`              |
| API info `/`, health `/v1/health`                                                     | Public                    |
| Public catalog feed `/v1/feeds/{store}/products.json\|xml`                            | Public (per-store opt-in) |

### Cart & wishlist (storefront writes)

| Endpoints                                            | Key                                                                                       |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| Cart read/write (`client.cartWishlist` cart methods) | `pk` (browser) — anonymous via session id; **+ session** when a `customer_id` is supplied |
| Cart merge (`mergeCart`)                             | `pk` (browser) **+ session**                                                              |
| Wishlist (`getWishlist`, `addToWishlist`, …)         | `pk` (browser) **+ session**                                                              |

### Customers & authentication

| Endpoints                                                                                                     | Key                          |
| ------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| Auth — register / login / logout / magic-link / verify-otp / reset / refresh / me (`client.authentication.*`) | **`sk` only**                |
| Create customer (`client.customers.createCustomer`)                                                           | **`sk` only**                |
| Customer self — profile & addresses (`getCustomer`, `updateCustomer`, address methods)                        | `pk` (browser) **+ session** |

### Checkout — orders & payments

| Endpoints                                                  | Key                                                       |
| ---------------------------------------------------------- | --------------------------------------------------------- |
| List / get orders (`client.orders.listOrders`, `getOrder`) | **`sk` only**                                             |
| Create / update order (`createOrder`, `updateOrder`)       | **`sk` only + HMAC** (idempotency key required on create) |
| Payment methods (`client.payments.getPaymentMethods`)      | `pk` or `sk`                                              |
| Initialize payment (`initializePayment`)                   | **`sk` only + HMAC** (idempotency key required)           |
| Verify payment (`verifyPayment`)                           | **`sk` only**                                             |

### Engagement

| Endpoints                                                                                     | Key                                                                 |
| --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| List reviews (`client.reviews.listReviews`)                                                   | `pk` or `sk` (publishable sees approved only)                       |
| Submit / delete own review, mark helpful                                                      | `pk` (browser) **+ session** (helpful vote needs no session)        |
| Returns — lodge / list / track / accept-credit / request-refund (`client.returns.*`)          | `pk` (browser) **+ session** (`listReturnReasons` needs no session) |
| Messaging — threads, messages, realtime token (`client.messaging.*`)                          | `pk` (browser) **+ session**                                        |
| Gift card check by code (`checkGiftCard`)                                                     | `pk` or `sk`                                                        |
| List my gift cards (`listGiftCards`)                                                          | `pk` (browser) **+ session**                                        |
| Promotions — list & calculate (`client.promotions.*`)                                         | `pk` or `sk`                                                        |
| Shipping — zones, calculate, track (`getShippingZones`, `calculateShipping`, `trackShipment`) | `pk` or `sk`                                                        |

### Platform & integrations

| Endpoints                                                                 | Key                                                         |
| ------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Webhook endpoints & events (`client.webhooks.*`)                          | **`sk` only**                                               |
| Catalog ingestion — push (`client.ingestion.ingestProducts`)              | **`sk` only + HMAC** (idempotency key required)             |
| Ingestion sample / dry-run test (`getIngestSample`, `testIngest`)         | **`sk` only**                                               |
| Connect — authorize validate, token, revoke (`client.gcConnect.*`)        | Public (OAuth-style client credentials)                     |
| Connect — list sessions (`listConnectSessions`)                           | **`sk` only**                                               |
| Sandbox tools — reset / time-travel / webhook replay (`client.sandbox.*`) | **`sk` *test* key only** (`tybrite_sk_test_*`; sandbox env) |

### Marketplace (operator deployments)

| Endpoints                                                             | Key                                                           |
| --------------------------------------------------------------------- | ------------------------------------------------------------- |
| Unified split checkout (`/v1/cart/checkout`)                          | Operator                                                      |
| Unified shopper profile (`client.marketplace.getMarketplaceCustomer`) | Operator **+ `X-Customer-Token`**                             |
| Marketplace info (`client.marketplace.getMarketplaceInfo`)            | Operator                                                      |
| Any discovery endpoint with an operator key                           | Operator (aggregates across merchants; narrow with `storeId`) |

***

## Session Management

When building authenticated customer experiences (like "My Account" or "Quick Checkout"), the Tybrite SDK handles session persistence via `xAuthToken`.

1. **Login**: Call `client.authentication.login()` to receive a session and user object.
2. **Persistence**: Store the `session.access_token` securely (httpOnly cookies preferred).
3. **Requests**: Provide the token via the `xAuthToken` SDK parameter (or `x-auth-token` header for raw REST) on protected endpoints.
4. **Refresh**: Call `client.authentication.refreshToken()` \~60s before `expires_at` to rotate to a fresh session.

<Tip>
  Our TypeScript SDK exposes `refreshToken` so you can wire up a scheduled rotation. See the [Authentication Service](/sdk/api-reference/classes/AuthenticationService) for the full method reference and lifecycle diagram.
</Tip>
