Rayfin

@microsoft/rayfin-auth

Auth client reference for sessions, storage options, refresh, sign-out, events, and provider integration points in Rayfin apps.

@microsoft/rayfin-auth manages Rayfin session lifecycle, token refresh, event listeners, and sign-out. Most apps access it as client.auth on a RayfinClient rather than constructing it directly.

Microsoft Entra sign-in is provided by @microsoft/rayfin-auth-provider-fabric, which installs sessions on this same Auth instance.

Installation

npm install @microsoft/rayfin-auth @microsoft/rayfin-lib

Auth constructor

class Auth {
  constructor(apiClient: ApiClient, options?: AuthOptions);
}

Rayfin's auth SDK detects browser and non-browser runtimes. When window is unavailable, it skips browser-only APIs such as localStorage unless you supply custom storage. Use { storage: false } for Node.js scripts or server code where no browser storage should be touched.

scripts/createAuth.ts
import { Auth } from '@microsoft/rayfin-auth';
import { ApiClient } from '@microsoft/rayfin-lib';

const apiClient = new ApiClient({
  baseUrl: 'https://<workload-api-base-url>',
  publishableKey: '<publishable-key>',
});

const auth = new Auth(apiClient, { storage: false });
auth.attachToClient(apiClient);

AuthOptions

interface AuthOptions {
  storage?: AuthStorage | boolean;
  storageKeyPrefix?: string;
  persistSession?: boolean;
  autoRefreshToken?: boolean;
  multiTabSync?: boolean;
}

interface AuthStorage {
  getItem(key: string): string | null | Promise<string | null>;
  setItem(key: string, value: string): void | Promise<void>;
  removeItem(key: string): void | Promise<void>;
  clear?(): void | Promise<void>;
  keys?(prefix: string): string[] | Promise<string[]>;
}
OptionTypeDefaultDescription
storageAuthStorage | booleanBrowser localStorage when availableStorage implementation, true for default storage, or false for memory-only sessions.
storageKeyPrefixstringPackage defaultPrefix for stored auth keys.
persistSessionbooleantrueWhen false, skips all storage I/O and keeps sessions in memory.
autoRefreshTokenbooleantrueWhen false, disables refresh timers and automatic refresh on 401.
multiTabSyncbooleanAuto-detected in browsersWhen false, disables StorageEvent cross-tab session sync.

Session management

MethodSignatureDescription
getSession() => OpaqueSessionReturns the current public session synchronously.
onSessionChange(callback: (session: OpaqueSession | null) => void) => () => voidSubscribes to session changes and returns an unsubscribe function.
hasRefreshToken() => booleanReturns whether a refresh token is available.
refreshSession() => Promise<TokenResponse>Refreshes the session; concurrent refreshes share one in-flight request.
attachToClient(client: ApiClient) => voidAdds authorization injection and refresh handling to another ApiClient.
destroy() => voidRemoves timers and listeners used by the Auth instance.
startAutoRefresh() => Promise<void>Restarts scheduled refresh when autoRefreshToken: false is used.
stopAutoRefresh() => voidStops scheduled refresh when autoRefreshToken: false is used.
const session = auth.getSession();

const unsubscribe = auth.onSessionChange((nextSession) => {
  console.log(nextSession?.isAuthenticated ?? false);
});

unsubscribe();

Warning

The session-change callback is onSessionChange. onAuthStateChange is not part of this SDK.

OpaqueSession

Session objects are opaque by design. Gate UI logic on isAuthenticated or the presence of user, not on internal fields.

interface OpaqueSession {
  user: User | null;
  role?: string;
  expiresAt?: Date;
  isAuthenticated: boolean;
  isAnonymous: boolean;
}

interface User {
  id: string;
  email: string;
  role?: string;
  emailVerified?: boolean;
  emailVerifiedAt?: string | null;
}

TokenResponse

interface TokenResponse {
  accessToken: string;
  tokenType: string;
  expiresIn: number;
  refreshToken?: string | null;
  scope?: string | null;
}

Provider packages consume TokenResponse internally to install a public OpaqueSession. Application code should not copy Rayfin tokens between clients.

Sign-out methods

MethodSignatureDescription
signOut() => Promise<void>Revokes the current access token and clears the local session.
signOutAll() => Promise<SignOutAllResponse>Revokes every active session for the user and returns { count }.
await auth.signOut();

const result = await auth.signOutAll();
console.log(`Revoked ${result.count} sessions`);

Verification and settings methods

MethodSignatureDescription
getJwks() => Promise<JwksResponse>Fetches public signing keys for services that validate Rayfin-issued JWTs themselves.
getAuthSettings() => Promise<AuthSettingsConfig>Fetches public auth settings from the backend.

Events

Use onSessionChange for UI state. For narrower lifecycle handling, subscribe to session events with on(event, handler). The signature uses the exported AuthEvent union:

import type { AuthEvent, OpaqueSession } from '@microsoft/rayfin-auth';

function on(event: AuthEvent, handler: (session: OpaqueSession) => void): () => void;

The exported union contains every auth event emitted by the SDK. Fabric apps usually care about these session lifecycle events:

EventFires when
AUTH_LOGINA session is established.
AUTH_LOGOUTThe user signs out.
AUTH_REFRESHThe session refreshes.
AUTH_SESSION_EXPIREDThe access token expires and no refresh token can recover the session.
auth.on('AUTH_SESSION_EXPIRED', () => redirectToSignIn());

React usage

src/hooks/useAuth.ts
import { useEffect, useState } from 'react';
import type { OpaqueSession } from '@microsoft/rayfin-auth';
import { auth } from './lib/rayfin';

export function useAuth() {
  const [session, setSession] = useState<OpaqueSession | null>(null);

  useEffect(() => {
    setSession(auth.getSession());
    return auth.onSessionChange(setSession);
  }, []);

  return {
    session,
    isAuthenticated: session?.isAuthenticated ?? false,
    signOut: auth.signOut.bind(auth),
  };
}

Wire sign-in separately with ensureSignedInWithFabric, signInWithEntraToken, or the local development helper that installs a brokered token.

AuthApi provider integration

auth.getAuthApi() returns the lower-level AuthApi used by companion provider packages. Rayfin 1.36 adds getBrokeredAuthorizeExternalUrl() so the external embed flow can tell the parent host which endpoint to call. New in 1.36

class AuthApi {
  getBrokeredAuthorizeExternalUrl(): string;
  exchangeVerificationCode(request: VerificationCodeExchangeRequest): Promise<TokenResponse>;
  getAuthSettings(): Promise<AuthSettingsConfig>;
}

Builders using ensureSignedInWithFabric() or createEmbedHost() do not call getBrokeredAuthorizeExternalUrl() directly. The provider SDK includes it in the external-embed handshake.

Internal provider exports

The package also exposes @microsoft/rayfin-auth/_internal for first-party provider packages. Do not use these helpers in application code:

function getAuthProviderClient(auth: Auth): ApiClient;
function runProviderSignIn<T>(auth: Auth, operation: () => Promise<T>): Promise<T>;
function createSessionFromTokenResponse(
  auth: Auth,
  tokenResponse: TokenResponse,
  options?: { persistBeforeCommit?: boolean }
): Promise<OpaqueSession>;

PKCE helper exports

The root package exports PKCE utilities used by auth providers:

function generateCodeVerifier(): string;
function generateCodeChallenge(verifier: string): Promise<string>;
function generateState(): string;

Configuration and restart behavior

Auth is configured in rayfin.yml under services.auth. After changing values such as enabled, allowedRedirectUris, fabric.enabled, or fabric.externalEntraExchange, apply the updated runtime settings with npm run dev or npx rayfin up. A running backend does not infer local config changes until they are applied.

Something wrong on this page?Report an issueEdit this page

On this page