Skip to content

Authentication Options

How to set up authentication between your site and Sesamy. The right choice depends on your infrastructure and security requirements.

The BFF (Backend for Frontend) pattern stores tokens in HttpOnly cookies that JavaScript can never read, eliminating XSS token theft entirely. Your server or CDN proxies /sesamy-auth/* and /sesamy-api/* to Sesamy so that cookies are first-party.

text
Browser            Your Server / CDN Edge         Sesamy API
  |                        |                          |
  |-- GET /sesamy-auth/login -> proxy -------------> |
  |<- Set-Cookie ---------- |<----------------------- |
  |                        |                          |
  |-- GET /sesamy-api/...  |-- proxy --------------> |
  |   (cookie attached)     |                          |
  |<- data --------------- |<----------------------- |

Setup: Configure your server or CDN to proxy two paths. You can choose any path prefix -- /sesamy-auth and /sesamy-api are recommended to avoid conflicts with your own routes.

PathDestination
/sesamy-auth/*https://api2.sesamy.com/auth/*
/sesamy-api/*https://api2.sesamy.com/*

Then configure sesamy-js:

json
{
  "clientId": "your-vendor-id",
  "vendorId": "your-vendor-id",
  "api": { "endpoint": "/sesamy-api" },
  "auth": {
    "useHttpCookies": true,
    "baseUrl": "/sesamy-auth"
  }
}

auth.baseUrl is the prefix the BFF plugin prepends before its /auth/* routes, so the runtime requests are {auth.baseUrl}/auth/userinfo, {auth.baseUrl}/auth/{vendorId}/login, and {auth.baseUrl}/auth/logout. Omit it if you forward /auth/* directly without a prefix.

Since all requests go to your own origin, cookies are first-party automatically. No custom domain or CNAME required.

See proxy setup for CDN-specific configuration guides.

Why first-party cookies matter

Safari's Intelligent Tracking Prevention (ITP) limits third-party cookies to seven days, and in some cases blocks them entirely. By proxying through your own domain, all cookies are first-party and unaffected by these restrictions. Apple is also increasingly restrictive about requests to different IP addresses, making same-origin proxying the most future-proof approach.

Option 2: Custom API Domain

If you cannot set up a reverse proxy, point a subdomain (e.g. api.yoursite.com) at the Sesamy API proxy via CNAME. The page and the API domain must share a top-level domain so the cookie is first-party.

text
DNS:  api.yoursite.com  CNAME  api2.sesamy.com
json
{
  "clientId": "your-vendor-id",
  "vendorId": "your-vendor-id",
  "api": { "endpoint": "https://api.yoursite.com" },
  "auth": { "useHttpCookies": true }
}

The session cookie is set as HttpOnly; SameSite=Lax by the server. Contact Sesamy to enable the Token Handler for your custom domain.

Option 3: OIDC Integration

If you manage your own authentication and want to connect it to Sesamy, you can integrate via OpenID Connect. Your server acts as an OIDC client to Sesamy's auth server and manages its own session cookies.

This approach gives you full control over the auth flow while still using Sesamy for entitlements and content access. If you also want to use Sesamy's client-side components and APIs, you need to proxy API requests with the Sesamy access tokens your server obtained during the OIDC exchange.

When to use this: You already have a login system and want to add Sesamy content access without changing how your readers authenticate.

Option 4: SPA Auth (Auth0 Plugin) -- Legacy

For publishers who already use Auth0 or need popup/redirect login flows. Tokens are managed by @auth0/auth0-spa-js in the browser. This is simpler to set up but stores tokens in localStorage, which is accessible to any JavaScript on the page.

Via Scripts Host (no code change needed):

When your vendor has no custom apiDomain configured, the Scripts Host bundle automatically includes the Auth0 plugin. This is the default for existing integrations.

Via npm:

typescript
import { init } from '@sesamy/sesamy-js';
import { createAuth0Plugin } from '@sesamy/sesamy-js/auth0-plugin';

const sesamy = await init(
  {
    clientId: 'your-client-id',
    auth: {
      domain: 'login.yoursite.com',
    },
  },
  { authPlugin: createAuth0Plugin() },
);

Via script tags:

html
<script src="https://cdn.sesamy.com/sesamy-js/latest/auth0-plugin.iife.js"></script>
<script src="https://cdn.sesamy.com/sesamy-js/latest/sesamy-js.iife.js"></script>
<script type="application/json" id="sesamy-js">
  {
    "clientId": "your-client-id",
    "auth": { "domain": "login.yoursite.com" }
  }
</script>

Legacy approach

The Auth0 SPA plugin stores tokens in localStorage, making them accessible to any JavaScript running on the page. For new integrations, use the reverse proxy approach instead.

Comparison

CriteriaReverse ProxyCustom DomainOIDCSPA (Auth0)
SecurityBest -- tokens never in JSBest -- tokens never in JSBest -- your server controls tokensGood -- tokens in localStorage
Setup complexityMedium -- proxy configLow -- DNS CNAMEHigh -- OIDC client setupLowest -- no infra changes
Custom domain requiredNoYesNoOptional
Third-party cookie issuesNoneNoneNonePossible in Safari/Firefox
Sesamy components workYesYesYes (with API proxy)Yes
Recommended forNew integrationsSites without proxy capabilitySites with existing authExisting Auth0 integrations

When using Options 1 or 2, the Token Handler sets these cookies:

CookiePurposeFlags
atEncrypted access tokenHttpOnly; Secure; SameSite=Lax
__Host-rtEncrypted refresh tokenHttpOnly; Secure; SameSite=Strict
sesamy_is_authenticatedSession hint for sesamy-jsSecure; SameSite=Lax (readable by JS)
sesamy_vidVendor identifierSecure; SameSite=Lax

The sesamy_is_authenticated cookie is the only one readable by JavaScript. It tells sesamy-js whether to attempt a userinfo call on page load, avoiding unnecessary network requests for anonymous readers.

Next Steps

Released under the MIT License.