Skip to Content
Using the client

Locking

Restore a saved session as locked until the user unlocks it, for example with biometrics, in native apps.

Locking is for native apps that ask a returning user to unlock, for example with biometrics, before the app opens. With the locking option, a saved session restores as locked: user and sessionId are set, so a "Welcome back" screen can greet the user, but the tokens wait for auth.unlock().

src/locked-auth.ts
import { , type  } from "@monarcode/session-kit";

import {  } from "./backend.js";

// Your app's own: a native secure store, and encryption with a key it holds
// in memory only while unlocked.
declare const : ;
declare const : ;
declare function (: , : string): <string>;
declare function (: , : string): <string>;

export const  = ({
  : "my-native-app",
  : ,
  ,
  : {
    // Runs whenever the tokens are saved.
    : () => (, ),
    // Runs only from `unlock()`.
    : () => (, ),
  },
});

/** Once the app has its key: resolves the session, now `authenticated`. */
export const  = () => .();

/** `locked` again. The saved session stays, and the tokens leave memory. */
export const  = () => .();
  • Sealing is yours. Session kit depends on no crypto or biometrics library. The user and session ID are saved beside the sealed tokens, readable while locked. locking: true stores the tokens as they are, for a lock screen in front of an otherwise ordinary session.
  • While locked, nothing waits. getSession, retry, refresh, updateUser, credentials.get, and credentials.renew reject with LOCKED instead of waiting for an unlock that may never come. Nothing refreshes, and timers are off. signIn replaces the session, which is the password path. After lock() resolves, signOut clears it without calling revoke, since no tokens are left in memory.
  • A failed unlock isn't always still locked. When open throws, unlock() rejects with UNLOCK_FAILED and the session stays locked. But a refresh that fails after the tokens were opened rejects with REFRESH_FAILED and leaves the session unlocked and unavailable until retry(). Check status after a rejection.
  • Keep the key until lock() settles. A refresh already running still saves its tokens, and saving seals them.
  • Native apps only. Locking is built for one JavaScript context. In a browser, tabs don't follow each other with locking, and the router adapters treat a locked session as signed out. It also needs a user schema: a user read from the access token can't be shown without its token.
  • Turning it on and off. A session saved before locking was added restores as locked too, and is sealed when unlocked. Turning locking off later makes sealed sessions unreadable, which signs those users out.

Next steps

The Expo guide has a worked example: a key behind the device's biometrics, AES-GCM sealing, and a welcome-back screen.

On this page