---
title: "@microsoft/rayfin-auth"
description: "The Auth client surface — signOut, session management, and the OpaqueSession shape — with exact signatures from the SDK."
url: https://rayfin.ai/docs/reference/sdk/rayfin-auth
markdown_url: https://rayfin.ai/docs/reference/sdk/rayfin-auth.md
section: reference
product: Rayfin
sdk_version: 1.34.0
cli_version: 1.33.2
last_updated: 2026-08-22T22:51:33-07:00
source: reference/sdk/rayfin-auth.mdx
---

# @microsoft/rayfin-auth

> The Auth client surface — signOut, session management, and the OpaqueSession shape — with exact signatures from the SDK.

`@microsoft/rayfin-auth` implements Rayfin's authentication client: session lifecycle
management, token refresh, and sign-out. You normally reach it through `client.auth` on a
[`RayfinClient`](/docs/reference/sdk/rayfin-client) rather than constructing it yourself.
Signing in happens through
[`@microsoft/rayfin-auth-provider-fabric`](/docs/reference/sdk/rayfin-auth-provider-fabric),
which operates on this same `Auth` instance — Fabric SSO (Entra ID) is the only supported
sign-in method.

## Installation [#installation]

```bash
npm install @microsoft/rayfin-auth
```

## The `Auth` class [#the-auth-class]

```typescript
class Auth {
  constructor(apiClient: ApiClient, options?: { storage?: AuthStorage | boolean; storageKeyPrefix?: string });
}

interface AuthStorage {
  getItem(key: string): string | null;
  setItem(key: string, value: string): void;
  removeItem(key: string): void;
  clear(): void;
}
```

Rayfin's own SDK auto-detects Node.js, React Native, and Electron, skipping browser-only
APIs (like `localStorage`) when `window` is undefined — the isomorphic design means the
same `Auth` code runs in any of these environments without crashing.

## Signing out [#signing-out]

| Method       | Signature                           | Description                                                                   |
| ------------ | ----------------------------------- | ----------------------------------------------------------------------------- |
| `signOut`    | `() => Promise<void>`               | Revokes the current access token and clears the local session.                |
| `signOutAll` | `() => Promise<SignOutAllResponse>` | Revokes every active session for the user (all devices). Returns `{ count }`. |

```typescript
await auth.signOut();
```

## Session management [#session-management]

| Method            | Signature                                                            | Description                                                                             |
| ----------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `getSession`      | `() => OpaqueSession`                                                | Returns the current session **synchronously** — not a `Promise`.                        |
| `onSessionChange` | `(callback: (session: OpaqueSession \| null) => void) => () => void` | Subscribes to session changes; returns an unsubscribe function.                         |
| `hasRefreshToken` | `() => boolean`                                                      | Whether a refresh token is available for `refreshSession()`.                            |
| `refreshSession`  | `() => Promise<TokenResponse>`                                       | Refreshes using the stored refresh token. Concurrent calls share one in-flight request. |

```typescript
const session = auth.getSession(); // no await — synchronous
if (session.isAuthenticated) {
  console.log(session.user?.email);
}

const unsubscribe = auth.onSessionChange((session) => {
  setCurrentSession(session);
});
// later: unsubscribe();
```

> [!WARNING]
> The session-change callback is &#x2A;*`onSessionChange`**. `onAuthStateChange` does not exist
> on the Rayfin auth client — see [Known limitations](/docs/reference/known-limitations).

### Session shape [#session-shape]

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

```typescript
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;
}
```

## Verifying tokens [#verifying-tokens]

| Method    | Signature                     | Description                                                                                 |
| --------- | ----------------------------- | ------------------------------------------------------------------------------------------- |
| `getJwks` | `() => Promise<JwksResponse>` | Public keys for verifying Rayfin-issued JWTs, for services that validate tokens themselves. |

## Events [#events]

`on(event, handler)` subscribes to a specific named `AuthEvent` (in addition to the
general `onSessionChange`), returning an unsubscribe function. Events relevant to session
lifecycle — independent of how the user signed in — include `'AUTH_LOGIN'`,
`'AUTH_LOGOUT'`, `'AUTH_REFRESH'`, and `'AUTH_SESSION_EXPIRED'`:

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

auth.on('AUTH_SESSION_EXPIRED', () => redirectToLogin());
```

## React usage [#react-usage]

```typescript
import { useState, useEffect } from 'react';
import { auth } from './lib/rayfin';
import type { OpaqueSession } from '@microsoft/rayfin-auth';

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 up sign-in separately with
[`ensureSignedInWithFabric`](/docs/reference/sdk/rayfin-auth-provider-fabric), which takes
this same `auth` instance.

## Configuration and restart behavior [#configuration-and-restart-behavior]

Auth is configured in `rayfin.yml` under `services.auth` (`enabled`, `allowedRedirectUris`,
`fabric.enabled`). After changing any of these values, restart the backend
(`npx rayfin up`) so the updated endpoints are exposed — the running server does not pick
up `rayfin.yml` changes on its own. See
[Known limitations](/docs/reference/known-limitations).
