Authentication with the App SDK

Learn about the mechanisms that enable authentication when building with the App SDK.

The App SDK has two authentication mechanisms and automatically uses the appropriate one based on the context in which it's running. This article provides technical information about each of these mechanisms.

Advanced/experimental usage ahead

Overview

Authentication in the SDK is primarily managed by an authStore, which tracks the user's authentication state (AuthStateType.LOGGED_IN, AuthStateType.LOGGED_OUT, AuthStateType.LOGGING_IN, AuthStateType.ERROR). It determines the initial state based on the environment the application is running in—that is, one of:

  • A Sanity Dashboard iframe
  • Sanity Studio
  • A standalone app, running outside the Sanity Dashboard and Sanity Studio
  • An app configured for OAuth (auth.oauth in the SDK config)

API client instances, managed by a clientStore, automatically use the current authentication token from the authStore for requests. The clientStore also handles differentiating between clients configured for 'global' endpoints (such as api.sanity.io) and 'default' (project-specific) endpoints (such as <projectId>.api.sanity.io).

Tokens

Several different types of authentication tokens are referred to in the course of this article:

Global tokens

Global tokens are not tied to a specific project, but instead to a Sanity user. They include access to all of the user’s organizations and projects. Global tokens are required for accessing global Sanity APIs (for example, project management), and are used when clientStore configures a client with scope: 'global' or without a projectId.

Project tokens

Project tokens are scoped to a single project (and any of a single project’s datasets). They are used in the Studio mode (described below), and can also be provided manually. These tokens only allow access to project-specific endpoints (for example, <projectId>.api.sanity.io).

Stamped tokens

Tokens obtained through the sanity.io/login authentication flow (and thus also from the Sanity Dashboard) are 'stamped' tokens (type=stampedToken). These tokens are refreshed by the App SDK’s refreshStampedToken function. Non-stamped tokens, however, are not refreshed by the App SDK.

Dashboard mode (default)

Dashboard mode at a glance

The Sanity Dashboard enables the default and preferred mode of authentication within custom applications, with the Dashboard providing an authentication token to custom applications built with the App SDK. This results in a seamless experience for the end-user.

This mechanism applies to both third-party custom apps and Sanity’s own applications built with the App SDK.

How Dashboard mode gets a token

In Dashboard mode, the Sanity Dashboard loads the custom app’s iframe with an authentication token hash (#token=…) in the iframe’s src URL. When the custom app is initialized, the getAuthCode function (invoked by the App SDK via the SanityApp component) retrieves and validates this token. If for some reason the token is invalid, the getAuthCode function requests a new token from the Dashboard, and this new token is used instead. Once a token is validated, it is stored in the authStore. No user interaction is required during this exchange—everything is handled automatically, and the process should be completely invisible to an end user.

With the token thus stored in the application’s authStore, it is used as part of all API client calls made through the App SDK’s hooks, effectively using the current user’s active Dashboard session. This token is a global, stamped token that is refreshed every 12 hours.

Studio mode

The studioMode option is removed

Studio mode at a glance

This authentication mode uses the studio’s own auth context (through a token or cookie). It’s used when the App SDK is used with the Sanity Studio codebase (not the Dashboard iframe)—for example, within custom input components, tools, or plugins integrated directly into the Studio application.

How Studio mode gets a token

Studio mode is enabled automatically. The Studio wraps its component tree in SDKStudioContext.Provider, and SanityApp reads the workspace handle from that context to derive the projectId, dataset, and a reactive auth token source. An explicit config prop takes precedence over the Studio context.

// Inside a Studio, SanityApp auto-configures from the workspace context
<SanityApp fallback={<Loading />}>
  <MyComponent />
</SanityApp>

In this mode, the authStore subscribes to the workspace's token source—the Studio stays the single authority for auth and handles token refresh. If the Studio doesn't expose a token source, the authStore falls back to token discovery. A token passed in the SDK config (auth.token) takes precedence. Without one, it tries one of two methods.

First, the getStudioTokenFromLocalStorage function looks for an authentication token specific to the Studio session, which is stored in local storage under the key __studio_auth_token_${projectId}. This token is project-specific.

If this token is not found, the function checkForCookieAuth is called. This function sends a request with credentials to the project's /users/me API endpoint to check if a valid HTTP-only session cookie exists. If it does, subsequent API requests managed by the App SDK client rely on this cookie for authentication.

Was this page helpful?

sanity.ioAll Systems Operational© Sanity 2026
Change site theme