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
This guide is intended for developers who want to deeply understand the management of authentication within custom apps built with the App SDK. It covers both typical use cases for the App SDK (custom apps in the Sanity Dashboard), as well as more advanced or experimental implementations (such as using the App SDK within Studio).
In most cases, developers should not need to know the following information to successfully build with the App SDK. However, the curious among you are welcome to follow along!
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.oauthin 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.
In most cases, this is the best authentication method to rely on. It is intended for use when building a custom application running within the Sanity Dashboard.
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.
This flow presumes a Sanity user is already authenticated within the host Dashboard. If this is not the case, the Dashboard redirects to sanity.io/login in order to first authenticate the 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
The studioMode option was deprecated in 2.7.0 and removed in 3.0.0. You can still use the SDK within a Studio; no configuration is needed, since it's picked up automatically from the Studio context. You can still override this for programmatic control by setting the config.
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.
When this authentication method is used, only project-level endpoints work. Any calls made to global endpoints fail.
Was this page helpful?
Feedback submitted, thanks for helping us improve the docs. Have you tried these alternatives?