Skip to main content

API reference

New to blueprint-auth?

Check out our getting started guides:

Upgrading from an older version?

See the migration guides for version-specific breaking changes and upgrade instructions.

Public entry points​

Import each runtime export from the entry point in this table.

Entry pointRuntime exports
@krakentech/blueprint-authAUTH_COOKIE, AuthError, BlueprintAuthErrorCode, createAuthCacheProfiles, createAuthConfig, getErrorType, getKrakenErrorDetails, ignoredQueryParams, isKrakenErrorResponse, isMappedKrakenErrorCode, krakenAuthTokenOverrideHeader, krakenErrorTypeToCodeMap, nextPageParam, sessionQueryKey, xClientIpAuthorizationHeader, xClientIpHeader, xErrorPolicyHeader
@krakentech/blueprint-auth/cache/global-configcreateGlobalConfigCacheAdapter
@krakentech/blueprint-auth/cache/memorycreateMemoryCacheAdapter
@krakentech/blueprint-auth/clientcreateClientSideAuth, redirectToNextPage
@krakentech/blueprint-auth/middlewarecreateAuthCookieUtils, createAuthMiddleware, forwardHeaders
@krakentech/blueprint-auth/servercreateAppRouterAuth, createAuthCookieUtils, createGraphQLHandler, createKrakenOAuthHandler, createLoginHandler, createLogoutHandler, createServerSideAuth, createSessionHandler, createUpdateOrgTokenHandler, generateKrakenOAuthURI, getAuth, getGraphQLClient, getRequestPathname, getSession, login, logout, prefetchSession, redirectToLogin, validateGraphQLRequest
@krakentech/blueprint-auth/utilsconvertIterableToRecord, convertRecordToIterable, getErrorCode, isBlueprintAuthErrorCode, isUnauthenticatedError, setKrakenAuthTokenOverrideHeader, setNextPageSearchParam

Configuration​

The utility functions of the package all extend the same interface for static configuration options. This enables the use of a centralized configuration object that can be reused throughout the project.

The package provides a configuration factory, enabling auto-completion and type-checking of the configuration object.


createAuthConfig​

Create a config object reusable throughout the project, and set compatible options with environment variables.

Configuration​

Required options

Required options with an environment variable alternatives must be provided either via environment variables or directly in the config object.

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.authEndpointAuth endpoint for OAuth and verification keysstringKRAKEN_AUTH_ENDPOINT✅
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT❌ Defaults to krakenConfig.graphqlEndpoint
krakenConfig.graphqlEndpointTarget GraphQL endpointstringKRAKEN_GRAPHQL_ENDPOINT✅
krakenConfig.oauthClientIdKraken OAuth client IDstringKRAKEN_OAUTH_CLIENT_ID⚠️ Required to enable Kraken OAuth
krakenConfig.organizationSecretKeyKraken organization secret keystringKRAKEN_ORGANIZATION_KEY⚠️ Required to enable organization-scoped auth
krakenConfig.xClientIpOverrideOverride the client IP sent to Krakenstring❌
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY✅
Rate-limiting prevention

When Blueprint Auth resolves a client IP, it adds the x-kraken-client-ip-authorization and x-kraken-client-ip headers. The first header contains the base 64 encoded value of krakenConfig.xClientIpSecretKey. The second header contains the resolved client IP. krakenConfig.xClientIpOverride takes precedence. Otherwise, Blueprint Auth uses the first address in x-forwarded-for.

These headers are used by Kraken to attribute requests made from a limited number of IP addresses, e.g. server-side requests, to the actual user IP address, preventing erroneous rate-limiting. More information can be found on this Kraken announcement.

Route matching​

The pathname and allowList options accept three route formats:

FormatExampleDescription
Static path/dashboardMatches the configured route and its subroutes
Next.js dynamic segment/dashboard/[accountNumber]Converts the dynamic segment to a glob
Glob pattern/dashboard/*Uses picomatch

A route pathname includes its subroutes. An allowList entry does not add subroutes. Add /** when an allowlist entry must include descendant routes.

appRoutes.dashboard.customSuccessResponse runs only after middleware successfully refreshes and verifies an access token. It does not run when an existing credential grants access. Blueprint Auth preserves the callback response body, status, destination, headers, and cookies when it adds auth headers and refreshed cookies.

You can use all three formats in one configuration. Blueprint Auth converts Next.js dynamic segments to glob patterns before it matches a route:

PatternGlob equivalentMatches
/dashboard/[accountNumber]/dashboard/*/dashboard/A-12345
/join/[...steps]/join/**/join/energy/signup
/join/[[...steps]]/join/**/join or /join/energy/signup
tip

Use Next.js dynamic segment syntax to make the configured routes match your file structure. You do not need to convert these segments to glob patterns. See the i18n guide for information about localized dynamic routes.

Prefix matching

appRoutes.dashboard.pathname, appRoutes.anon.pathname, and appRoutes.masquerade.pathname use prefix matching, so all routes that start with the configured path are guarded. For example, appRoutes.dashboard.pathname: "/dashboard" protects /dashboard, /dashboard/settings, /dashboard/account/123, and so on. Use allowList to exempt specific sub-routes from authentication.

Redirect target routes

appRoutes.dashboard.pathname, appRoutes.login.pathname, and appRoutes.home.pathname must use static paths. The middleware redirects users to these routes (e.g. unauthenticated users to login, authenticated users to dashboard), and a redirect requires a concrete URL. Dynamic segments and glob patterns cannot be resolved for redirects because the middleware has no way to determine the params.

This does not affect allowList entries or routes used only for matching (appRoutes.anon.pathname, appRoutes.masquerade.pathname), which support all three formats.

Security

Make sure your secrets are kept secure and available server-side only:

  • Do not hardcode them in your codebase.
  • Do not use environment variables starting with NEXT_PUBLIC_.

Usage​

Somewhere in your project, export the config object returned by createAuthConfig.

lib/auth/config.ts
import { createAuthConfig } from "@krakentech/blueprint-auth";

export const authConfig = createAuthConfig({ ... });

Middleware​

createAuthMiddleware​

The middleware protects routes that require authentication. It redirects unauthenticated users to the login page and refreshes eligible, missing, or expired access tokens. It also handles masquerade and anonymous authentication. It returns 503 Service Unavailable when verification keys are unavailable.

Edge Runtime compatibility

We expose this function separately to avoid bundling code that is unsupported in Edge Runtime. Learn More.

Post-auth middleware mutations

If you change headers or cookies after authMiddleware, finalize the response with forwardHeaders.

Configuration​

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.authEndpointAuth endpoint for OAuth and the public JSON Web Key Set (JWKS)stringKRAKEN_AUTH_ENDPOINT✅
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT❌ Defaults to krakenConfig.graphqlEndpoint
krakenConfig.graphqlEndpointTarget GraphQL endpointstringKRAKEN_GRAPHQL_ENDPOINT✅
krakenConfig.oauthClientIdKraken OAuth client IDstringKRAKEN_OAUTH_CLIENT_ID⚠️ Required to enable Kraken OAuth
krakenConfig.xClientIpOverrideOverride the client IP sent to Krakenstring❌
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY✅

Parameters​

ParameterTypeDescription
configAuthMiddlewareConfigRoute, Kraken, and verification configuration

Usage​

If your Next.js middleware only handles authentication, the function returned by createAuthMiddleware can be exported directly as middleware:

middleware.ts
import { createAuthMiddleware } from "@krakentech/blueprint-auth/middleware";
import { authConfig } from "@/lib/auth/config";

export const middleware = createAuthMiddleware(authConfig);

export const config = {
matcher: ["/", "/((?!api|_next|_vercel|.*\\..*).*)"],
};

forwardHeaders​

Forwards request headers to Server Components and getServerSideProps while preserving response headers and cookies. Redirect and error responses are returned unchanged.

When is this needed?

The auth middleware calls this internally, you only need to use it if you mutate headers or cookies after the auth middleware.

ParameterTypeDescription
requestNextRequestThe incoming request
responseNextResponseThe middleware response to finalize

Returns: The finalized NextResponse.

Usage​

Call forwardHeaders after your post-auth changes. To set a request header for downstream handlers, use x-middleware-request-<name> as shown below. Setting an ordinary response header does not change the downstream request:

middleware.ts
import type { NextRequest, NextResponse } from "next/server";
import { createAuthMiddleware, forwardHeaders } from "@krakentech/blueprint-auth/middleware";
import createIntlMiddleware from "next-intl/middleware";
import { authConfig } from "@/lib/auth/config";
import { routing } from "@/i18n/routing";

const intlMiddleware = createIntlMiddleware(routing);
const authMiddleware = createAuthMiddleware(authConfig);

function setCustomCookie({ res }: { res: NextResponse }) {
res.cookies.set("my-custom-cookie", "value");
return res;
}

export async function middleware(request: NextRequest) {
let response = await intlMiddleware(request);
if (!response.ok) return response;

response = await authMiddleware(request, response);
if (!response.ok) return response;

// Set the downstream request header, including any existing override.
response.headers.set("x-middleware-request-x-custom-header", "updated-value");
response = setCustomCookie({ res: response });

return forwardHeaders(request, response);
}

export const config = {
matcher: ["/", "/((?!api|_next|_vercel|.*\\..*).*)"],
};

Server Functions​

The package exports Server Functions, which can be used in Next.js server-side execution contexts.

Direct usage or factories

These functions can either be used directly, passing all required configuration and context parameters on each call, or via factories.

Server Function Parameters

Server functions typically accept two separate parameter objects:

  1. Static Configuration: Application settings that rarely change (endpoints, secrets, routes). Pass your authConfig object directly.
  2. Runtime Parameters: Dynamic values for each call (context, user input, etc.)
// Direct call: pass configuration and request values.
await login(authConfig, {
context,
input: { email, password },
});

// Factory call: pass only request values.
await login({ context, input: { email, password } });

A factory function adds the configuration for you.

Execution environment​

Compatibility

Not all functions work in all environments. Use the table below to check compatibility.

FunctionSSGSSRAPI HandlerRoute HandlerServer ComponentServer ActionMiddleware
createAuthCookieUtils✅✅✅✅✅✅✅
generateKrakenOAuthURI❌✅✅✅❌✅✅
getAuth✅✅✅✅✅✅✅
getGraphQLClient✅✅✅✅✅✅✅
getRequestPathname❌✅✅✅✅✅✅
getSession❌✅✅✅✅✅✅
login❌❌✅✅❌✅❌
logout❌❌✅✅❌✅❌
prefetchSession✅✅❌❌✅❌❌
redirectToLogin❌✅✅✅✅✅❌

The context object​

Request-bound Server Functions expect a context object in Pages Router code. Its shape varies with the execution context. getGraphQLClient.* accepts a resolved auth context instead.

type StaticPropsContext = GetStaticPropsContext;
import type { GetStaticPropsContext } from "next";

export async function getStaticProps(context: GetStaticPropsContext) {
// Pass context to supported server functions.
}
Server Actions and Server Components

At the TypeScript level, Server Actions and Server Components share the same context type since they use the same Next.js APIs (cookies() and headers()). However, we distinguish them with separate type names:

  • ServerComponentContext is used for React Server Components (RSC).
  • ServerActionContext is used for Server Actions.

This distinction helps clarify where each function can be used, even though the underlying type is identical.


Server cache dependency​

AuthConfig does not contain cache credentials. If you use organization auth, create the cache adapter in a module that browser code cannot import. Pass it to direct organization auth functions and handlers, or bind it with a server factory. Blueprint Auth uses the adapter for encrypted organization credentials. User and viewer auth, sessions, login, logout, and OAuth do not require an adapter, including when accessed through a server factory.

In an App Router application, add import "server-only"; as the first line of the cache module. Pages Router does not support this marker. In a Pages Router application, import the cache module only from getServerSideProps, API Routes, and other server modules. Do not import it from a component or client module.

createGlobalConfigCacheAdapter​

Blueprint Auth provides an optional Vercel Global Config adapter. Install its peer dependency, then create one adapter at module scope:

pnpm add @vercel/global-config
lib/auth/cache.ts
import { createGlobalConfigCacheAdapter } from "@krakentech/blueprint-auth/cache/global-config";

export const cacheAdapter = createGlobalConfigCacheAdapter();

The adapter reads GLOBAL_CONFIG, VERCEL_AUTH_TOKEN, and VERCEL_TEAM_ID when it is created. It falls back to the legacy EDGE_CONFIG variable when GLOBAL_CONFIG is absent. Creation synchronously checks that all values are present. It also parses the store ID and creates the Global Config client. The provider checks authentication and access when the adapter reads or writes data. You can override individual values:

const cacheAdapter = createGlobalConfigCacheAdapter({
authToken: process.env.CUSTOM_VERCEL_AUTH_TOKEN,
});
OptionDefaultPurpose
authTokenprocess.env.VERCEL_AUTH_TOKENVercel API token for writes
envVarprocess.env.GLOBAL_CONFIG ?? process.env.EDGE_CONFIGGlobal Config connection string and read token
teamIdprocess.env.VERCEL_TEAM_IDTeam that owns the Global Config store

All reads use the connection credentials from envVar. Writes require authToken and teamId.

createMemoryCacheAdapter​

Use the memory adapter for local development and isolated tests:

import { createMemoryCacheAdapter } from "@krakentech/blueprint-auth/cache/memory";

const cacheAdapter = createMemoryCacheAdapter();

Each call creates an isolated process-local store. The adapter accepts and ignores bypassCache because every read reaches the same store.

Not for cloud production

Values do not survive a process restart and are not shared with other application instances. In cloud environments, each instance and cold start begins with an empty cache. This can repeat network requests that a shared cache avoids.

Use the memory adapter only for local development and isolated tests.

Custom adapter contract​

Import AuthCacheAdapter and AuthCacheValue from the package root:

import type { AuthCacheAdapter, AuthCacheValue } from "@krakentech/blueprint-auth";

An AuthCacheAdapter stores authentication data on the server. get(key) can use the provider's normal read cache. get(key, { bypassCache: true }) asks the adapter to bypass an additional cache layer when it has one. An adapter can ignore the hint when every read already reaches its backing store, such as with a direct Redis adapter.

Both read modes return undefined when the key does not exist. null is a valid stored value. Read failures must reject. set(key, value) must resolve only after the adapter accepts the write. Write failures must reject.

AuthCacheValue supports strings, finite numbers, booleans, null, arrays of supported values, and objects whose values are supported. Do not store undefined, functions, symbols, bigint, class instances, or other non-JSON data.

Production adapters must use a backing store shared by application instances that use the same organization credentials. Use a process-local store only for local development and isolated tests.

Server Function Factories​

Server Functions can be used in three different ways, depending on your particular needs.

createServerSideAuth(config, params = {}) accepts an optional cacheAdapter. createAppRouterAuth(config, { cache, cookies, headers, cacheAdapter }) requires cache, cookies, and headers, but cacheAdapter is optional.

Without an adapter, both factories support user and viewer auth, sessions, login, logout, and OAuth. Calling a factory's getAuth.org without an adapter fails with AuthMissingPropertiesError for cacheAdapter. Direct getAuth.org calls and organization token handlers still require an adapter.

MethodDescriptionRecommendationNeeds configurationNeeds context
DirectImport each function from the packageOne call or advanced use✅✅
Server-sideBind configuration and the cache adapterPages Router❌✅
App RouterBind configuration, the cache adapter, and contextApp Router❌❌
Full API

Pass configuration and request values to each direct function. Pass the cache adapter to direct organization auth functions. Pass resolved auth contexts directly to GraphQL clients.

Usage
import {
createAuthCookieUtils,
generateKrakenOAuthURI,
getAuth,
getGraphQLClient,
getRequestPathname,
getSession,
login,
logout,
prefetchSession,
} from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

const {
getAuthCookie,
getAuthCookies,
getAuthTokenOverride,
removeAllCookies,
removeAuthCookies,
removeAuthTokenCookies,
setAuthCookie,
} = createAuthCookieUtils(authConfig, { context });
await generateKrakenOAuthURI(authConfig, { context });
await getRequestPathname({ context });
await getSession(authConfig, { context });
await login(authConfig, {
context,
input: { email, password },
});
await logout(authConfig, { context });
await prefetchSession(authConfig, { context, queryClient });
const auth = await getAuth.user(authConfig, { context });
if (auth) getGraphQLClient.user(authConfig, { auth });

generateKrakenOAuthURI​

Set the code verifier cookie, and generate a unique URI to initiate the Kraken OAuth flow.

Configuration​

OptionDescriptionTypeRequired
apiRoutes.krakenOAuthOAuth callback API routestring✅
krakenConfig.authEndpointKraken auth endpointstring✅
krakenConfig.oauthClientIdKraken OAuth client IDstring✅

Parameters​

ParameterDescriptionTypeRequired
contextRequest contextServerSidePropsContext | ApiRouteHandlerContext | RouteHandlerContext | ServerActionContext | MiddlewareContext✅

Output​

TypeDescription
Promise<string>The generated Kraken OAuth URI

Usage​

Usage
import { generateKrakenOAuthURI } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

const krakenOAuthURI = await generateKrakenOAuthURI(authConfig, { context });

getSession​

Select and verify one user token. Return session data from the verified token fields. See Session management for a session lifecycle overview.

Configuration​

OptionDescriptionTypeEnvironment variableRequired
customization.accessTokenRefreshThresholdSecondsProactive access token refresh thresholdnumber❌ Defaults to 60
customization.getCookieOptionsCookie options used when writing a replacement access tokenfunction❌
customization.headersToForwardIncoming headers to include in authentication refresh requestsstring[]❌
customization.setCustomHeadersAdd headers to authentication refresh requestsfunction❌
krakenConfig.authEndpointAuth endpoint for verification keys and OAuth refreshstringKRAKEN_AUTH_ENDPOINT✅
krakenConfig.graphqlAuthEndpointGraphQL endpoint for email and mobile refreshstringKRAKEN_GRAPHQL_AUTH_ENDPOINT❌ Defaults to krakenConfig.graphqlEndpoint
krakenConfig.oauthClientIdOAuth client ID used for OAuth refreshstringKRAKEN_OAUTH_CLIENT_ID⚠️ Required for OAuth refresh
krakenConfig.xClientIpOverrideOverride the client IP sent during email and mobile refreshstring❌
krakenConfig.xClientIpSecretKeySecret key used to sign the client IP during email/mobile refreshstringKRAKEN_X_CLIENT_IP_SECRET_KEY✅
validation.accessTokenIssuersExact trusted access token issuersstring[]KRAKEN_ACCESS_TOKEN_ISSUERS✅

Parameters​

ParameterDescriptionTypeRequired
params.contextRequest contextServerSidePropsContext | ApiRouteHandlerContext | RouteHandlerContext | ServerComponentContext | ServerActionContext | MiddlewareContext✅

Output​

Returns a SessionState object:

FieldDescriptionType
authMethodMethod from the verified gty fieldAuthMethod | null
authSourceLocation of the selected tokenAuthSource | null
isAuthenticatedThe request has a verified user tokenboolean
subUser ID from the verified sub fieldstring | null

Usage​

import { getSession } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

const session = await getSession(authConfig, { context });

login​

Authenticate a user with an email address and password. Redirect the user after successful authentication unless you disable the redirect.

Configuration​

OptionDescriptionTypeRequired
krakenConfig.authEndpointAuth endpoint for verification keysstring✅
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstring✅
krakenConfig.xClientIpOverrideOverride the client IP sent to Krakenstring❌
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstring✅

Parameters​

ParameterDescriptionTypeRequired
contextRequest contextApiRouteHandlerContext | RouteHandlerContext | ServerActionContext✅
inputLogin credentials{ email: string; password: string; captchaResponse?: string }✅
nextPageRedirect pathnamestring | null❌
enableRedirectEnable redirectboolean❌ Only available in API Handlers and Route Handlers
searchParamsURL search parametersSearchParams | Promise<SearchParams>✅ Only available in Server Actions

Output​

Context dependent output

The return type of this function varies depending on the execution context.

TypeCondition
Promise<undefined>Always

Usage​

Usage
import { login } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

await login(authConfig, {
context,
input: { email: "test@example.com", password: "****" },
nextPage: "/dashboard/settings",
searchParams, // available as props in Next.js App Router page components
});
Redirect behavior

After a successful login, if you do not set nextPage, the function uses the nextPage URL search parameter. It uses appRoutes.dashboard.pathname as the fallback. To disable the success redirect, set nextPage to null. This does not suppress a failure redirect when enableRedirect is true.

API Handlers

Redirection is disabled by default in API Handlers and Route Handlers. To enable redirects, set the enableRedirect option to true.

Learn more

A Pages Router fetch does not start a client navigation from a redirect response. The browser follows the redirect and can lose client state. By default, the handler returns the redirect URL in JSON. The caller controls the navigation.

However, this behavior does not fit all use cases. For instance, a redirect response is desirable when the API endpoint is used as the action attribute of the HTML <form> element. To enable redirects, set the enableRedirect option. Use the login function in an App Router Server Action. For the Pages Router, see the login form guide.

Error handling

Authentication failures throw by default. In API routes and Route Handlers, enableRedirect: true redirects handled login failures to the referring page with an error query parameter. Other failures, such as unavailable verification keys, still throw. createLoginHandler returns HTTP error responses for thrown errors.

Learn more

Since Next.js 15, calling redirect in a Server Action results in a 303 See Other status response. The App Router handles this error code with a client-side navigation, preserving the state of layout components. However, redirecting to the same page triggers a full page reload, losing client-side page state in the process.

Handling errors client-side prevents the progressive enhancements enabled by Server Actions. If you're using the App Router, consider storing form errors and validation errors as action state using React's useActionState hook. Check out the Next.js documentation to learn more.


logout​

Remove authentication cookies. Redirect the user to the home page unless you disable the redirect.

For an OAuth session, Blueprint Auth first tries the upstream logout and token revocation requests. It logs an upstream failure and continues to remove local cookies. A local cookie removal failure still fails the logout operation.

Configuration​

OptionDescriptionTypeRequired
appRoutes.home.pathnameHome pathnamestring✅

Parameters​

ParameterDescriptionTypeRequired
contextRequest contextApiRouteHandlerContext | RouteHandlerContext | ServerActionContext✅
nextPageRedirect pathnamestring | null❌
enableRedirectEnable redirectboolean❌ Only available in API Handlers and Route Handlers

Output​

Context dependent output

The return type of this function varies depending on the execution context.

TypeCondition
Promise<undefined>Always

Usage​

Usage
import { logout } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

await logout(authConfig, { context, nextPage: "/goodbye" });
Redirect behavior

If the nextPage option is not set, appRoutes.home.pathname is used as the default redirect. To disable redirection, set the nextPage option to null.

API Handlers

Redirection is disabled by default in API Handlers and Route Handlers. To enable redirects, set the enableRedirect option to true.

Learn more

A Pages Router fetch does not start a client navigation from a redirect response. The browser follows the redirect and can lose client state. By default, the handler returns the redirect URL in JSON. The caller controls the navigation.

However, this behavior does not fit all use cases. For instance, a redirect response is desirable when the API endpoint is used as the action attribute of the HTML <form> element. To enable redirects, set the enableRedirect option.


prefetchSession​

Selects and verifies one user token. Stores the resulting session in a QueryClient.

HydrationBoundary required

prefetchSession must be used in combination with the HydrationBoundary component from @tanstack/react-query. To set it up with the Pages Router, check out the Server Rendering and Hydration guide. To learn more about the App Router setup, check out the Advanced Server Rendering guide.

Configuration​

This function uses krakenConfig.authEndpoint and validation.accessTokenIssuers for token verification.

Parameters​

ParameterDescriptionTypeRequired
contextRequest contextServerComponentContext | ServerSidePropsContext | StaticPropsContext✅
queryClient@tanstack/react-query client instanceQueryClient✅

Output​

TypeDescription
Promise<void>No return value

Usage​

Usage
import { prefetchSession } from "@krakentech/blueprint-auth/server";
import { QueryClient } from "@tanstack/react-query";
import { authConfig } from "@/lib/auth/config";

const queryClient = new QueryClient();
await prefetchSession(authConfig, { context, queryClient });

getRequestPathname​

Get the page pathname associated with a request.

Configuration​

This function does not require static configuration.

Parameters​

ParameterDescriptionTypeRequired
contextRequest contextServerSidePropsContext | ApiRouteHandlerContext | RouteHandlerContext | ServerComponentContext | ServerActionContext | MiddlewareContext✅

Output​

TypeDescription
Promise<string | null>Page pathname, or null when no referring page is available

In API routes and Route Handlers, this is the referring page's pathname, not the endpoint's. Server rendering and Server Actions require auth middleware to run for the route; otherwise, the function throws.

Usage​

Usage
import { getRequestPathname } from "@krakentech/blueprint-auth/server";

const pathname = await getRequestPathname({ context });

redirectToLogin​

Redirect to the configured login route from a server context. The function adds errorCode as the error search parameter. It uses the current request pathname as nextPage by default. Pass nextPage: null to omit that parameter.

ContextResult
API RouteCalls res.redirect() and resolves to undefined
Route HandlerReturns NextResponse.redirect()
Server Component or Server ActionCalls redirect() and does not return
getServerSidePropsReturns a nonpermanent redirect object

The function supports API Routes, Route Handlers, Server Components, Server Actions, and getServerSideProps. It does not support SSG or Middleware.

InputTypeMeaning
appRoutes.login.pathnamestringConfigured login route
i18nAuth i18n configurationOptional localized login route support
contextSupported server contextRequest and response APIs
errorCodestringRequired error search parameter
nextPagestring | null | undefinedExplicit destination, no destination, or current pathname
import { BlueprintAuthErrorCode } from "@krakentech/blueprint-auth";
import { redirectToLogin } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

return redirectToLogin(authConfig, {
context,
errorCode: BlueprintAuthErrorCode.AuthenticationRequired,
});

Factories bind configuration. The App Router factory also binds context. redirectToLogin reads request state. Call it outside a "use cache" scope.


getAuth​

Resolve request-specific credentials and headers into a server-only auth context. Call these asynchronous functions outside "use cache" scopes.

FunctionReturn typeUse when
getAuth.viewerPromise<AuthContext.Viewer>Authentication is optional
getAuth.userPromise<AuthContext.User | null>A local user credential is required
getAuth.orgPromise<AuthContext.Org | null>Organization credentials are required

Session resolution​

getAuth.viewer and getAuth.user select one authentication source in this order:

  1. Request access token override
  2. Mobile session from MWAuthToken and its optional MWRefreshToken
  3. Web session from accessToken and its optional refreshToken
  4. Mobile session recovery from MWRefreshToken
  5. Web session recovery from refreshToken

Blueprint Auth sends refresh tokens to Kraken only to obtain replacement access tokens.

The functions verify the replacement before use. The selected authentication source is final for the request. The functions do not try a lower priority source if the selected source cannot produce a valid session.

Eligible user sessions support proactive refresh. Blueprint Auth refreshes a valid token at the configured threshold. After a recoverable proactive failure, it tries again during each later auth resolution while the current token is valid. A rejected refresh token ends the local session. See Session management for the eligibility rules.

Blueprint Auth uses reactive refresh when an access token is missing or expired. Invalid signatures, issuers, claims, and grants end the selected local session.

getAuth.viewer always returns a context. Its session is null when the request has no verified user. getAuth.user returns null in the same case. Both functions get identity and authMethod from verified token fields. Kraken can still reject a verified token because of permissions, revocation, or account state.

getAuth.org checks a request override first. The override must be a verified API-KEY token. Without an override, the function checks the shared cache. It then checks the latest stored value. If needed, it requests a token from Kraken. It verifies each value before use or storage.

See Session management for a session lifecycle overview.

The direct namespace exports getAuth.ViewerConfig, getAuth.ViewerParams, getAuth.UserConfig, getAuth.UserParams, getAuth.OrgConfig, and getAuth.OrgParams.

Parameters​

ParameterDescriptionTypeRequired
cacheAdapterShared cache for organization tokensAuthCacheAdaptergetAuth.org only
contextRequest contextServerSideContext✅

Resolved request values​

Each context can contain the client IP, custom headers, and selected incoming headers. getAuth.* resolves these values for the current request. It awaits customization.setCustomHeaders. It also reads names in customization.headersToForward.

The client later removes reserved auth headers. It applies the resolved values to GraphQL requests. When the context is an argument to a cached function, all of these values participate in the cache key.

Usage​

Usage
import { getAuth } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

const auth = await getAuth.user(authConfig, { context });
if (!auth) throw new Error("Authentication required.");
Server-only credentials

Auth contexts contain access tokens and can contain forwarded headers. Keep every context on the server and out of Client Components, browser code, logs, and public props.

Removed getUserScopedGraphQLClient​

Use getAuth.user and then getGraphQLClient.user.

Removed getOrganizationScopedGraphQLClient​

Use getAuth.org and then getGraphQLClient.org.

getGraphQLClient​

Create a BlueprintGraphQLClient from a resolved auth context. Client creation is synchronous. It does not read request APIs, so it can run inside "use cache" scopes.

FunctionRequired auth typeBehavior
getGraphQLClient.viewerAuthContext.ViewerUses user credentials when present and supports an unauthenticated viewer
getGraphQLClient.userAuthContext.UserRequires an authenticated user context at type and runtime boundaries
getGraphQLClient.orgAuthContext.OrgRequires organization credentials

Request behavior​

Direct calls use (config, { auth, errorPolicy? }). Factory calls use ({ auth, errorPolicy? }). errorPolicy defaults to "none". The selected policy changes the return type of client.request().

Each client operation sends one GraphQL request. The client applies the selected error policy to the response. Resolve auth before you create the client.

An operation can provide x-kraken-auth-token-override in its request headers. The client converts that value to the outgoing authorization header. It does not forward the override header itself.

Other operation headers are limited to names in customization.headersToForward. The client removes reserved auth headers. The auth context supplies the token, client IP, and resolved headers.

The direct namespace exports getGraphQLClient.Config and these parameter types: getGraphQLClient.ViewerParams<Policy>, getGraphQLClient.UserParams<Policy>, and getGraphQLClient.OrgParams<Policy>.

Parameters​

ParameterDescriptionTypeRequired
authContext from the matching getAuth.* scopeAuthContext.Viewer | AuthContext.User | AuthContext.Org✅
errorPolicyGraphQL error handling policy"none" | "ignore" | "all"❌

Output​

TypeDescription
BlueprintGraphQLClient<Policy>A GraphQL client for the selected auth scope. A viewer client can be unauthenticated. Policy is inferred from errorPolicy.

Usage​

Usage
import { getAuth, getGraphQLClient } from "@krakentech/blueprint-auth/server";
import { cacheAdapter } from "@/lib/auth/cache";
import { authConfig } from "@/lib/auth/config";

const auth = await getAuth.org(authConfig, { cacheAdapter, context });
if (!auth) throw new Error("Organization authentication is unavailable.");

const graphQLClient = getGraphQLClient.org(authConfig, { auth });
const thirdPartyViewer = await graphQLClient.request(ThirdPartyViewerQuery);
Authentication failures

Kraken can reject a locally verified token after revocation or an account change. The GraphQL client returns that authentication failure to the application. Applications can use isUnauthenticatedError for an optional local session policy.

createAuthCookieUtils​

Create helpers to manage authentication cookies.

Signature​

function createAuthCookieUtils(
config: CreateAuthCookieUtilsConfig,
params: { context: ServerSideContext },
): AuthCookieUtils;

Configuration​

OptionDescriptionTypeRequired
customization.getCookieOptionsCustomize cookie options(cookieName: [CookieName](#cookiename)) => SerializeOptions | undefined❌

Output​

Returns an object with the following fields:

FieldDescriptionType
getAuthCookieGet one auth cookie(name: [CookieName](#cookiename)) => Promise<string | undefined>
getAuthCookiesGet all managed auth cookies() => Promise<[CookieMap](#cookiemap)>
getAuthTokenOverrideGet the request token override header() => Promise<{ token: string, type: "override" } | null>
removeAllCookiesRemove all managed session cookies() => Promise<void>
removeAuthCookiesRemove named auth cookies(cookies: [CookieName](#cookiename)[]) => Promise<void>
removeAuthTokenCookiesRemove accessToken and MWAuthToken() => Promise<void>
setAuthCookieSet one auth cookie({ name, value, expires? }: { name: [CookieName](#cookiename), value: string, expires?: Date }) => Promise<void>

See CookieName and CookieMap in the Types section for type definitions.

setAuthCookie stores cookies without verifying tokens. For accessToken and MWAuthToken, the supplied expires takes precedence over custom cookie options; for other cookies, the custom expires wins. Avoid maxAge on access cookies; see Access token expiry.

Usage​

Usage
import { createAuthCookieUtils } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

const {
getAuthCookie,
getAuthCookies,
getAuthTokenOverride,
removeAllCookies,
removeAuthCookies,
removeAuthTokenCookies,
setAuthCookie,
} = createAuthCookieUtils(authConfig, { context });

API Handlers​

The package exports factories for API Routes and Route Handlers. In the output tables, Data is the response union for that factory.

AspectAPI RouteRoute Handler
ExportDefault handler exportNamed HTTP method export
ArgumentsNextApiRequest, NextApiResponseNextRequest
ReturnMutates NextApiResponse and resolves to undefinedReturns NextResponse
BodyUses req.bodyReads and parses the request body
OAuth queryUses req.queryUses URL search parameters
RedirectCalls res.redirect(url)Returns NextResponse.redirect(url)
JSON response caching

The handler factories set Cache-Control to no-cache, no-store, max-age=0, must-revalidate on JSON responses. Redirect responses do not receive this header from Blueprint Auth.

createLoginHandler​

The login handler authenticates the user with an email address and password. It verifies the returned access token before it sets cookies.

Configuration​

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.authEndpointAuth endpoint for verification keysstringKRAKEN_AUTH_ENDPOINT✅
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT✅
krakenConfig.xClientIpOverrideOverride the client IP sent to Krakenstring❌
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY✅

Output​

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<undefined>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<Data>>Handler function for App Router

Usage​

src/pages/api/auth/login.ts
import { createLoginHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createLoginHandler(authConfig);

Request​

The login handler expects a POST request with a JSON body containing the following fields:

FieldDescriptionTypeRequired
captchaResponseCAPTCHA responsestring❌
emailUser emailstring✅
enableRedirectReturn a redirect responseboolean❌
nextPageRedirect pathname or no redirectstring | null❌
passwordUser passwordstring✅

Response​

When enableRedirect is false or omitted, the success response body contains:

FieldDescriptionType
data.redirectUrlURL to use after login, or null when no URL is selectedstring | null

The error response body contains:

FieldDescriptionType
error.errorCodeError codeErrorCode
error.messageError messagestring
error.sourceSource of the error"blueprint-auth"
Status Codes​
Status CodeCondition
200 OKLogin succeeds and enableRedirect is false or omitted
307 Temporary RedirectLogin succeeds and enableRedirect is true
307 Temporary RedirectAuthentication fails and enableRedirect is true. The destination is the request pathname with an error parameter
400 Bad RequestThe body or credentials are invalid and the handler returns JSON
401 UnauthorizedKraken returns an unauthorized error and the handler returns JSON
403 ForbiddenOrigin evidence is untrusted or absent, or Content-Type is not JSON
405 Method Not AllowedThe request method is not POST
503 Service UnavailableVerification keys are not available

createLogoutHandler​

The logout handler removes auth cookies and provides a redirect URL in the response.

For an OAuth session, Blueprint Auth first tries the upstream logout and token revocation requests. It logs an upstream failure and continues to remove local cookies. A local cookie removal failure still fails the logout operation.

Configuration​

OptionDescriptionTypeRequired
appRoutes.home.pathnameDefault redirect after logoutstring✅

Output​

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<undefined>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<Data>>Handler function for App Router

Usage​

src/pages/api/auth/logout.ts
import { createLogoutHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createLogoutHandler(authConfig);

Request​

The logout handler expects a POST request with a JSON body containing the following fields:

FieldDescriptionTypeRequired
enableRedirectReturn a redirect responseboolean❌
nextPageRedirect pathname or no redirectstring | null❌

Response​

When enableRedirect is false or omitted, the success response body contains:

FieldDescriptionType
data.redirectUrlURL to use after logout, or null when no URL is selectedstring | null

The error response body contains:

FieldDescriptionType
error.errorCodeError codeErrorCode
error.messageError messagestring
error.sourceSource of the error"blueprint-auth"
Status Codes​
Status CodeCondition
200 OKLogout succeeds and enableRedirect is false or omitted
307 Temporary RedirectSuccessful logout, redirect to home or nextPage (when enableRedirect is true)
400 Bad RequestInvalid request body (validation error)
403 ForbiddenUntrusted Origin / Referer, missing both headers, or non-JSON Content-Type
405 Method Not AllowedRequest method is not POST
500 Internal Server ErrorUnknown logout operation error

createSessionHandler​

The session handler selects and verifies one user token. It returns session data from the verified token fields.

Configuration​

OptionDescriptionTypeEnvironment variableRequired
customization.accessTokenRefreshThresholdSecondsProactive access token refresh thresholdnumber❌ Defaults to 60
customization.getCookieOptionsCookie options used when writing a replacement access tokenfunction❌
customization.headersToForwardIncoming headers to include in authentication refresh requestsstring[]❌
customization.setCustomHeadersAdd headers to authentication refresh requestsfunction❌
krakenConfig.authEndpointAuth endpoint for verification keys and OAuth refreshstringKRAKEN_AUTH_ENDPOINT✅
krakenConfig.graphqlAuthEndpointGraphQL endpoint for email and mobile refreshstringKRAKEN_GRAPHQL_AUTH_ENDPOINT❌ Defaults to krakenConfig.graphqlEndpoint
krakenConfig.oauthClientIdOAuth client ID used for OAuth refreshstringKRAKEN_OAUTH_CLIENT_ID⚠️ Required for OAuth refresh
krakenConfig.xClientIpOverrideOverride the client IP sent during email and mobile refreshstring❌
krakenConfig.xClientIpSecretKeySecret key used to sign the client IP during email/mobile refreshstringKRAKEN_X_CLIENT_IP_SECRET_KEY✅
validation.accessTokenIssuersExact trusted access token issuersstring[]KRAKEN_ACCESS_TOKEN_ISSUERS✅

Output​

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<undefined>Handler for Pages Router
(req: NextRequest) => Promise<NextResponse<Data>>Handler for App Router

Usage​

src/pages/api/auth/session.ts
import { createSessionHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createSessionHandler(authConfig);

Request​

The session handler accepts a GET request.

Response​

The success response contains:

FieldDescriptionType
data.authMethodMethod from the verified gty fieldAuthMethod | null
data.authSourceLocation of the selected tokenAuthSource | null
data.isAuthenticatedThe request has a verified user tokenboolean
data.subUser ID from the verified sub fieldstring | null

The error response contains:

FieldDescriptionType
error.errorCodeError codeErrorCode
error.messageError messagestring
error.sourceError source"blueprint-auth"
Status Codes​
Status CodeCondition
200 OKThe handler returns session state
405 Method Not AllowedThe request method is not GET
500 Internal Server ErrorSession resolution fails
503 Service UnavailableVerification keys or access token refresh services are unavailable

createGraphQLHandler​

The GraphQL handler sends requests to krakenConfig.graphqlEndpoint. It selects and verifies one user token before it sets the Authorization header.

Configuration​

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.authEndpointAuth endpoint for verification keysstringKRAKEN_AUTH_ENDPOINT✅
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT✅
krakenConfig.graphqlEndpointTarget GraphQL endpointstringKRAKEN_GRAPHQL_ENDPOINT✅
krakenConfig.oauthClientIdOAuth client ID used for OAuth refreshstringKRAKEN_OAUTH_CLIENT_ID⚠️ Required for OAuth refresh
krakenConfig.xClientIpOverrideOverride for the user IP header (for tests)string❌
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY✅
Request size limits

maxRequestBodySize checks the declared Content-Length, not the actual body size. Configure a server or proxy limit if you need a hard cap. See validateGraphQLRequest for the available limits.

Headers sent to Kraken

If you omit customization.headersToForward (or pass an empty array), no request headers are forwarded to Kraken.

The authenticated client still sets Kraken headers such as authorization, x-kraken-client-ip, and x-kraken-client-ip-authorization. It also sets headers from customization.setCustomHeaders. This behavior does not depend on the forwarding list.

Output​

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<undefined>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<Data>>Handler function for App Router

Usage​

src/pages/api/graphql/kraken.ts
import { createGraphQLHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createGraphQLHandler(authConfig);

Request​

The GraphQL handler expects a POST request with a JSON body containing the following fields:

FieldDescriptionTypeRequired
queryGraphQL query/mutationstring✅
variablesVariables of the GraphQL query/mutationobject❌
x-error-policy header

Client-side requests made through useGraphQLClient are proxied through this handler. The x-error-policy header is set automatically based on the error policy you configure, whether at the client level or per-request through the object configuration. You do not need to set this header yourself.

Response​

With the "none" or "ignore" error policy, a successful response has this shape:

FieldDescriptionType
dataGraphQL response dataShape of the query or mutation result

A handled error response has this shape:

FieldDescriptionType
dataPartial data or nullShape of the operation result or null
errorsGraphQL errorsKrakenError[]

With the "all" error policy, the handler passes through the GraphQL response envelope. It can contain data, errors, extensions, and headers.

Authentication and request dispatch

The handler resolves authentication first. Authentication can send a separate token refresh request. The handler then submits the GraphQL operation once and handles that response according to errorPolicy.

Error handling

The GraphQL handler passes errors returned by the GraphQL API endpoint through.

In case an error occurs inside of the GraphQL handler, the error is converted to match the KrakenError interface, and includes the following fields:

FieldDescriptionType
messageError messagestring
extensions.errorCodeError codestring
extensions.errorDescriptionError descriptionstring
Status Codes​
Status CodeCondition
200 OKThe handler returns data or a handled GraphQL error
503 Service UnavailableVerification keys or access token refresh services are unavailable

createKrakenOAuthHandler​

The Kraken OAuth handler authenticates the user using the Kraken OAuth flow. It is meant to be used in combination with generateKrakenOAuthURI. It gets tokens from Kraken. It verifies both tokens before it sets cookies. On success, it redirects the user to the dashboard. On failure, it redirects the user to the login page with an error parameter.

Configuration​

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.authEndpointKraken auth endpointstringKRAKEN_AUTH_ENDPOINT✅
krakenConfig.oauthClientIdKraken OAuth client IDstringKRAKEN_OAUTH_CLIENT_ID✅
krakenConfig.xClientIpOverrideOverride the client IP sent to Krakenstring❌
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY✅

Output​

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<undefined>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<Data>>Handler function for App Router

Usage​

src/pages/api/auth/kraken-oauth.ts
import { createKrakenOAuthHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createKrakenOAuthHandler(authConfig);

Request​

The Kraken OAuth handler expects a GET request with the following URL search parameters:

URL search parameterDescriptionTypeRequired
codeKraken OAuth codestring⚠️ Required when error is absent
errorStandard OAuth error valuestring❌
PKCE Verifier

The Kraken OAuth handler requires a Proof Key for Code Exchange (PKCE) verifier in the incoming pkceVerifier cookie. generateKrakenOAuthURI creates the verifier and writes this cookie.

After a successful token exchange, the handler removes pkceVerifier. It then verifies both returned tokens. The identity token must use the OAuth client ID as its audience. Its issuer must be the auth token endpoint. The access token must be a verified OAuth token. Both tokens must have the same sub field.

Response​

A GET callback returns a redirect response. The Location header identifies the dashboard after success. It identifies the login page with an error code after authentication failure.

A request with another method returns the standard JSON error response. It does not redirect or process OAuth tokens.

Status Codes​
Status CodeCondition
307 Temporary Redirect (to Dashboard)Successful OAuth authentication
307 Temporary Redirect (to Login)The callback has an OAuth error, required value is missing, token exchange fails, or token verification fails
405 Method Not AllowedRequest method is not GET. The response is JSON and does not redirect
503 Service UnavailableVerification keys are not available

createUpdateOrgTokenHandler​

The organization token update handler is meant to be used as a Vercel cron job. It fetches a new organization token and stores the value in the configured cache.

Configuration​

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.authEndpointAuth endpoint for verification keysstringKRAKEN_AUTH_ENDPOINT✅
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT✅
krakenConfig.organizationSecretKeyKraken organization secret keystringKRAKEN_ORGANIZATION_KEY✅
krakenConfig.xClientIpOverrideOverride the client IP sent to Krakenstring❌
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY✅
Bearer secret

Set CRON_SECRET in the production environment. Vercel sends its value in the Authorization header when it invokes the cron job. The handler requires the exact value Bearer <CRON_SECRET>.

A match proves that the caller knows the secret. It does not prove that Vercel sent the request. The handler returns 401 Unauthorized when the value does not match.

See the Vercel documentation for more information.

Output​

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<undefined>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<Data>>Handler function for App Router

Usage​

src/pages/api/auth/update-org-token.ts
import { createUpdateOrgTokenHandler } from "@krakentech/blueprint-auth/server";
import { cacheAdapter } from "@/lib/auth/cache";
import { authConfig } from "@/lib/auth/config";

export default createUpdateOrgTokenHandler(authConfig, { cacheAdapter });

To set up the cron job, create a vercel.json at the root of your project with the following content:

vercel.json
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"crons": [
{
"path": "/api/auth/update-org-token",
"schedule": "*/30 * * * *"
}
]
}

Request​

The update organization token handler expects a GET request with the Authorization header set to Bearer {CRON_SECRET}.

Response​

The handler returns this JSON response after a successful update:

{
"data": "Success"
}
Status Codes​
Status CodeCondition
200 OKSuccessfully updated organization token
401 UnauthorizedMissing Authorization header or header does not match CRON_SECRET
405 Method Not AllowedRequest method is not GET
500 Internal Server ErrorError updating organization token, cache write failure, or any unknown error
503 Service UnavailableVerification keys are not available

Client Functions​

App Router

If you are using the Next.js App Router, you most likely do not need any of these helpers, use Server Functions instead.

createClientSideAuth​

Creates AuthProvider and the hooks depending on it, i.e. useAuth, useGraphQLClient, useKrakenAuthErrorHandler, useLogin, useLogout, and useSession.

Configuration​

OptionDescriptionTypeRequired
appRoutes.dashboard.pathnameDashboard pathnamestring✅
appRoutes.home.pathnameHome pathnamestring✅
appRoutes.login.pathnameLogin pathnamestring✅

Parameters​

ParamDescriptionTypeRequired
defaultTargetDefault GraphQL API endpointkeyof typeof apiRoutes.graphql✅
routerSpecifies which Next.js router the application uses."app-router" | "pages-router"✅
Multiple GraphQL endpoints

If your application uses multiple GraphQL endpoints relying on Kraken authentication, you can define them in the apiRoutes.graphql object.

{
apiRoutes: {
graphql: {
kraken: "/api/graphql/kraken",
custom: "/api/graphql/custom",
}
}
}
Default GraphQL target

The createClientSideAuth factory expects an options object as its second argument with two properties:

  • defaultTarget: The default GraphQL endpoint used by useGraphQLClient. The value must be a key of the apiRoutes.graphql object.
  • router: The Next.js router being used. Must be either "pages-router" or "app-router".

Usage​

Export the functions returned by createClientSideAuth.

import { createClientSideAuth } from "@krakentech/blueprint-auth/client";
import { authConfig } from "./config";

export const {
AuthProvider,
useAuth,
useGraphQLClient,
useKrakenAuthErrorHandler,
useLogin,
useLogout,
useSession,
} = createClientSideAuth(authConfig, {
defaultTarget: "kraken",
router: "pages-router",
});

AuthProvider​

Provides configuration to auth hooks.

Configuration​

OptionDescriptionTypeRequired
childrenChild React nodesReactNode✅
onLoginSuccessSuccessful login callback(defaultRedirect: () => void) => void | Promise<void>❌
onLoginErrorLogin error callback(errorCode: [ErrorCode](#errorcode), defaultRedirect: () => void) => void | Promise<void>❌
onLogoutSuccessSuccessful logout callback(defaultRedirect: () => void) => void | Promise<void>❌
onLogoutErrorLogout error callback(errorCode: [ErrorCode](#errorcode), defaultRedirect: () => void) => void | Promise<void>❌
Extend the default redirect behavior

Providing handlers overrides the default redirect behavior of the useLogin and useLogout hooks. In case you need to extend the default behavior, all callbacks are called with the defaultRedirect function.

Usage​

In your Next.js _app.tsx file, wrap the page component with AuthProvider, and optionally define custom handlers.

pages/_app.tsx
import type { AppProps } from "next/app";
import { useRouter } from "next/router";
import { useToast } from "@/hooks/useToast";
import { AuthProvider } from "@/lib/auth/client";

export default function App({ Component, pageProps }: AppProps) {
const router = useRouter();
const toast = useToast("auth");
return (
<AuthProvider
// extend default behavior
onLoginSuccess={(defaultRedirect) => {
defaultRedirect();
toast("login.success", { type: "success" });
}}
// override default behavior
onLoginError={(errorCode) => {
toast("login.error", { errorCode, type: "error" });
}}
// optionally extend default behavior
onLogoutSuccess={(defaultRedirect) => {
toast("logout.success", { type: "success" });
if (router.pathname.startsWith("/dashboard")) {
defaultRedirect();
}
}}
>
<Component {...pageProps} />
</AuthProvider>
);
}

useAuth​

This hook is used internally by other auth hooks to access the AuthProviderContext state.

Advanced use cases

This hook is exposed for convenience in advanced use cases, e.g. custom auth hooks. In most cases you should not use it directly.

Configuration​

No configuration needed.

Output​

FieldDescriptionTypeRequired
apiRoutes.graphqlGraphQL API endpointsRecord<string, string>✅
apiRoutes.loginLogin API endpointstring✅
apiRoutes.logoutLogout API endpointstring✅
apiRoutes.sessionSession API endpointstring✅
appRoutes.dashboard.pathnameDashboard pathnamestring✅
appRoutes.home.pathnameHome pathnamestring✅
appRoutes.login.pathnameLogin pathnamestring✅
defaultTargetDefault GraphQL endpointstring✅
handlers.onLoginSuccessSuccessful login callback(defaultRedirect: () => void) => void | Promise<void>❌
handlers.onLoginErrorLogin error callback(errorCode: ErrorCode, defaultRedirect: () => void) => void | Promise<void>❌
handlers.onLogoutSuccessSuccessful logout callback(defaultRedirect: () => void) => void | Promise<void>❌
handlers.onLogoutErrorLogout error callback(errorCode: ErrorCode, defaultRedirect: () => void) => void | Promise<void>❌
i18n.getLocalizedPathnameLocalized pathname callback(options: GetLocalizedPathnameOptions) => string❌
i18n.localeCookieLocale cookie namestring❌

Requirements​

RequirementNotes
Context providerUse inside AuthProvider.
Client-side authThe component must be wrapped with a client-side auth setup using createClientSideAuth.

Usage​

hooks/useCustomLogin.ts
import { useAuth } from "@/lib/auth/client";

function useCustomLogin() {
const { apiRoutes, appRoutes, defaultTarget, handlers } = useAuth();
...
}

useGraphQLClient​

Get a preconfigured GraphQL client to perform authenticated requests to the Kraken GraphQL API endpoint, or GraphQL API endpoint relying on Kraken for authentication.

Requirements​

RequirementNotes
API endpointCreate the GraphQL API endpoint at apiRoutes.graphql using createGraphQLHandler.
Context providerUse inside AuthProvider.

Configuration​

ParameterDescriptionTypeRequired
targetTarget GraphQL endpoint (must be a key of the apiRoutes.graphql object provided to createClientSideAuth)string❌ Defaults to the default target
errorPolicyHow the client handles GraphQL errors: "none" (default), "ignore", or "all". See Error policy."none" | "ignore" | "all"❌ Defaults to "none"

Returns​

A BlueprintGraphQLClient<Policy> instance.

Usage​

hooks/useAccount.ts
import { useQuery } from "@tanstack/react-query";
import { AccountQuery } from "@/graphql/AccountQuery";
import { useGraphQLClient } from "@/lib/auth/client";

export function useAccount(variables: { accountNumber: string }) {
const graphQLClient = useGraphQLClient();

return useQuery({
queryKey: ["account", variables.accountNumber],
queryFn: () => graphQLClient.request(AccountQuery, variables),
});
}

Use useGraphQLClient({ target: "custom" }) to select another configured target. Use useGraphQLClient({ errorPolicy: "ignore" }) to return data when a response also contains GraphQL errors.

useKrakenAuthErrorHandler​

The hook provides an error handler to be used with data fetching libraries. If the error is auth-related the handler redirects the user to the login page with error and nextPage search parameters.

Requirements​

RequirementNotes
Context providerUse inside AuthProvider.

Configuration​

OptionDescriptionTypeRequired
onErrorError callback(error: unknown, defaultRedirect: () => void) => void | Promise<void>❌
redirectTypeRedirect type"push" | "replace"❌ Defaults to "push"
Extend the default redirect behavior

Providing onError overrides the default redirect behavior of the useKrakenAuthErrorHandler hook. In case you need to extend the default behavior, the onError callback is called with the defaultRedirect function.

Output​

FieldDescriptionTypeRequired
handleKrakenErrorsError handler(error: unknown) => void | Promise<void>✅
i18n Support

When i18n is configured, this hook redirects to localized login pages based on the user's locale.

Usage​

Pass query errors to handleKrakenErrors inside queryFn, then rethrow them so React Query records the failure:

hooks/useAccount.ts
"use client";

import { useQuery } from "@tanstack/react-query";
import { AccountQuery } from "@/graphql/AccountQuery";
import { useGraphQLClient, useKrakenAuthErrorHandler } from "@/lib/auth/client";

export function useAccount(variables: { accountNumber: string }) {
const graphQLClient = useGraphQLClient();
const { handleKrakenErrors } = useKrakenAuthErrorHandler();

return useQuery({
queryKey: ["account", variables.accountNumber],
queryFn: async () => {
try {
return await graphQLClient.request(AccountQuery, variables);
} catch (error) {
await handleKrakenErrors(error);
throw error;
}
},
retry: false,
});
}

useLogin​

The useLogin hook can be used to authenticate the user, and handles redirection for both success and failure cases.

Learn more about the useLogin hook redirect behavior

Default success redirect​

  1. Redirect to the nextPage option if set.
  2. Redirect to the nextPage URL search parameter if set.
  3. Redirect to the appRoutes.dashboard.pathname otherwise.

Default failure redirect​

Set the error URL search parameter in the current URL.

Customizing redirects​

To replace the default redirects, provide handlers.onLoginSuccess and handlers.onLoginError to AuthProvider. Each callback must call its supplied defaultRedirect to retain the default navigation.

The onSuccess and onError callbacks passed to login.mutate or login.mutateAsync supplement the hook callbacks. They do not replace or suppress the hook's redirects.

Redirect callback behavior

If the handlers.onLoginSuccess callback set on the AuthProvider does not call the defaultRedirect function, the nextPage option and the nextPage URL search parameter have no effect.

Requirements​

RequirementNotes
API endpointCreate the login API endpoint at apiRoutes.login using createLoginHandler.
Context providerUse inside AuthProvider.
React QueryUse inside of <QueryClientProvider>, see the Pages Router or the App Router example.
Login API Handler​

The useLogin hook expects the login API handler created with createLoginHandler to be available on the apiRoutes.login endpoint.

QueryClientProvider​

The useLogin hook uses React Query's useMutation under the hood. It must be used inside of <QueryClientProvider>. Check out React Query's Pages Router example. or App Router example.

Configuration​

OptionDescriptionTypeRequired
nextPageRedirect pathnamestring | null❌

Output​

Returns a UseMutationResult object, see React Query's useMutation hook documentation.

Usage​

components/LoginForm.tsx
import type { FormEvent } from "react";
import { useLogin } from "@/lib/auth/client";

export function LoginForm() {
const login = useLogin();

function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const email = formData.get("email");
const password = formData.get("password");

if (typeof email !== "string" || typeof password !== "string") {
return;
}

login.mutate({ email, password });
}

return (
<form method="POST" onSubmit={handleSubmit}>
<input name="email" type="email" required />
<input name="password" type="password" required />
<button type="submit" disabled={login.isPending}>
Log in
</button>
</form>
);
}
Display errors

The error code can be read from the error URL search parameter. The UseMutationResult object returned by the useLogin hook also includes the error response accessible as login.error. The error code can be extracted from the error response using the getErrorCode utility function.

Form method

Set method="POST" on a form that contains credentials. This prevents the browser from adding credentials to the URL before hydration. See the Pages Router login form guide.

useLogout​

The useLogout hook can be used to log out the user, and handles redirection for both success and failure cases.

Learn more about the useLogout hook redirect behavior

Default success redirect​

  1. Redirect to the nextPage option if set.
  2. Redirect to appRoutes.home.pathname otherwise.

Default failure redirect​

Set the error URL search parameter in the current URL.

Customizing redirects​

To replace the default redirects, provide handlers.onLogoutSuccess and handlers.onLogoutError to AuthProvider. Each callback must call its supplied defaultRedirect to retain the default navigation.

The onSuccess and onError callbacks passed to logout.mutate or logout.mutateAsync supplement the hook callbacks. They do not replace or suppress the hook's redirects.

Redirect callback behavior

If the handlers.onLogoutSuccess callback set on the AuthProvider does not call the defaultRedirect function, the nextPage option has no effect.

Requirements​

RequirementNotes
API endpointCreate the logout API endpoint at apiRoutes.logout using createLogoutHandler.
Context providerUse inside AuthProvider.
React QueryUse inside of <QueryClientProvider>, see the Pages Router or the App Router example.
Logout API Handler​

The useLogout hook expects the logout API handler created with createLogoutHandler to be available on the apiRoutes.logout endpoint.

QueryClientProvider​

The useLogout hook uses React Query's useMutation under the hood. It must be used inside of <QueryClientProvider>. Check out React Query's Pages Router example. or App Router example.

Configuration​

OptionDescriptionTypeRequired
nextPageRedirect pathnamestring | null❌

Output​

TypeDescription
UseMutationResultReact Query mutation result, see useMutation docs

Usage​

components/LogoutButton.tsx
import { useLogout } from "@/lib/auth/client";

export function LogoutButton() {
const logout = useLogout();

return (
<button type="button" disabled={logout.isPending} onClick={() => logout.mutate()}>
Log out
</button>
);
}
Display errors

The error code can be read from the error URL search parameter. The UseMutationResult object returned by the useLogout hook also includes the error response accessible as logout.error. The error code can be extracted from the error response using the getErrorCode utility function.

useSession​

The useSession hook can be used to access information about the current user session.

Requirements​

RequirementNotes
API endpointCreate the session API endpoint at apiRoutes.session using createSessionHandler.
Context providerUse inside AuthProvider.
React QueryUse inside of <QueryClientProvider>, see the Pages Router or the App Router example.

Configuration​

No configuration needed.

Output​

Returns a DefinedUseQueryResult<SessionState, unknown> object.

The SessionState data includes:

FieldDescriptionType
authMethodMethod from the verified token grantAuthMethod | null
authSourceLocation of the selected tokenAuthSource | null
isAuthenticatedThe request has a verified user tokenboolean
subUser ID from the verified tokenstring | null

The initial data has isAuthenticated: false while the first request runs. Check isFetched before you render a signed-out state. Check isError before you use the session data.

components/SessionControls.tsx
import { useSession } from "@/lib/auth/client";

export function SessionControls() {
const { data: session, error, isError, isFetched } = useSession();

if (!isFetched) {
return <SessionSkeleton />;
}

if (isError) {
return <SessionError error={error} />;
}

return session.isAuthenticated ? <LogoutButton /> : <LoginButton />;
}

redirectToNextPage​

The redirectToNextPage function redirects the user to the relative URL found in the nextPage URL search parameter.

Fallback behavior

If nextPage is empty or contains an absolute URL, the fallback is used. If nextPage is invalid and the fallback is not provided, the function has no effect.

Requirements​

RequirementNotes
Pages RouterThis function requires a NextRouter instance from the Pages Router.

Configuration​

OptionDescriptionTypeRequired
routerThe NextRouter instanceNextRouter✅
fallbackThe fallback URL in case nextPage is empty or invalidstring❌
redirectTypeNavigation method"push" | "replace"❌ Defaults to "replace"

Output​

Returns Promise<boolean> when it starts a navigation. Returns undefined when it has no valid destination.

Usage​

import { useRouter } from "next/router";
import { redirectToNextPage } from "@krakentech/blueprint-auth/client";

const Page = () => {
const router = useRouter();

useEffect(() => {
redirectToNextPage({
router,
fallback: "/dashboard",
});
}, []);

return <p>Redirecting...</p>;
};

Testing​

createMockAuthTokenIssuer​

Creates a temporary RS256 key pair for server tests. It can create signed access tokens and return the matching JSON Web Key Set (JWKS).

Import it from the testing entry point:

import { createMockAuthTokenIssuer } from "@krakentech/blueprint-auth/testing";

const issuer = await createMockAuthTokenIssuer({
issuer: "https://api.kraken.test/v1/graphql/",
});

const accessToken = await issuer.createAccessToken({
authMethod: "email",
subject: "user-123",
});

const jwks = issuer.getJwks();
MethodDescription
createAccessToken(options)Create a signed access token for email, OAuth, scoped, masquerade, or organization auth
getJwks()Return the public keys that verify the created tokens

The helper keeps the private key in memory. Use it only in server test code. Add the test issuer to validation.accessTokenIssuers. Serve getJwks() from the JWKS URL for the test auth endpoint.

Utils​

validateGraphQLRequest​

Validate the Content-Length header and GraphQL query size. The GraphQL handler calls this utility automatically.

function validateGraphQLRequest(
context: ApiRouteHandlerContext | RouteHandlerContext,
query: string,
options?: {
maxQueryLength?: number;
maxRequestBodySize?: number;
},
): Promise<void>;
  • maxRequestBodySize: maximum declared Content-Length, defaulting to 102400 bytes. This is not a hard limit on the actual request body.
  • maxQueryLength: maximum query size in UTF-8 bytes, defaulting to 51200 bytes.

Import from @krakentech/blueprint-auth/server.

convertIterableToRecord​

Converts an Iterable (like an Iterator or generator) to a Record object.

function convertIterableToRecord<
T extends {
entries(): Iterable<readonly [string, string]>;
},
>(iterable: T): Record<string, string | string[]>;

Configuration​

ParameterDescriptionTypeRequired
iterableThe iterable to convertT extends { entries(): Iterable<readonly [string, string]>}✅

Output​

TypeDescription
Record<string, string | string[]>A record object created from the iterable

Usage​

const iterable = new Map([
["key1", "value1"],
["key2", "value2"],
]);
const record = convertIterableToRecord(iterable);
// { key1: "value1", key2: "value2" }

convertRecordToIterable​

Converts a Record object back to an Iterable.

function convertRecordToIterable<
Entry,
Target extends { append(key: string, value: string): void },
>(record: Record<string, Entry>, target: Target): Target;

Configuration​

ParameterDescriptionTypeRequired
recordThe record to convertRecord<string, Entry>✅
targetThe target iterable to append toTarget extends { append(key: string, value: string): void }✅

Output​

TypeDescription
TargetThe target iterable with appended entries

Usage​

const record = { key1: "value1", key2: "value2" };
const iterable = convertRecordToIterable(record, new URLSearchParams());
// URLSearchParams { "key1" => "value1", "key2" => "value2" }

getErrorCode​

Get an error code from a Blueprint Auth response or the first Kraken GraphQL error. Returns null for unrecognized errors. For an AuthError instance, read error.errorCode directly.

Configuration​

Expect an error of type unknown.

Output​

TypeCondition
ErrorCodeError code found
nullNo error code found

Usage​

queries/getAccount.ts
import { AuthError } from "@krakentech/blueprint-auth";
import { getErrorCode } from "@krakentech/blueprint-auth/utils";
import { AccountQuery } from "@/graphql/AccountQuery";
import { getAuth, getGraphQLClient } from "@/lib/auth/server";
import { reportGraphQLError, reportUnexpectedError } from "@/lib/error/reporting";

async function getAccount(variables: { accountNumber: string }) {
try {
const auth = await getAuth.user();
if (!auth) throw new Error("Authentication required.");

const graphQLClient = getGraphQLClient.user({ auth });
const { account } = await graphQLClient.request(AccountQuery, variables);
return account;
} catch (error) {
const errorCode = error instanceof AuthError ? error.errorCode : getErrorCode(error);
if (errorCode) {
return reportGraphQLError(error, { errorCode });
}
return reportUnexpectedError(error);
}
}

getErrorType​

Get extensions.errorType from a Kraken error. The function uses extensions.errorClass as a fallback.

function getErrorType(error: KrakenError): KrakenErrorType | undefined;

Import this function from @krakentech/blueprint-auth.

getKrakenErrorDetails​

Normalize a Kraken error into a KrakenErrorDetails object.

function getKrakenErrorDetails(error: KrakenError): KrakenErrorDetails;

Import this function from @krakentech/blueprint-auth.

isKrakenErrorResponse​

Check whether a value has a Kraken GraphQL error response.

function isKrakenErrorResponse(value: unknown): value is KrakenErrorResponse;

Import this function from @krakentech/blueprint-auth.

isMappedKrakenErrorCode​

Check whether a string is a value in krakenErrorTypeToCodeMap.

function isMappedKrakenErrorCode(errorCode: string): errorCode is MappedKrakenErrorCode;

Import this function from @krakentech/blueprint-auth.

isUnauthenticatedError​

Check whether an error code indicates that the local user session can no longer authenticate requests. The function accepts ErrorCode | null and narrows a matching value to ErrorCode.

GraphQL clients return authentication failures to the application. Use this helper for an optional policy that ends the local session.

Import it from @krakentech/blueprint-auth/utils.

isBlueprintAuthErrorCode​

Check if an error code is a valid BlueprintAuthErrorCode.

Configuration​

Expect an error code of type string.

Output​

TypeDescription
errorCode is BlueprintAuthErrorCodeNarrows a valid Blueprint Auth error code

Usage​

utils/getErrorMessage.ts
import { getTranslations } from "next-intl/server";
import { AuthError, isMappedKrakenErrorCode } from "@krakentech/blueprint-auth";
import { getErrorCode, isBlueprintAuthErrorCode } from "@krakentech/blueprint-auth/utils";

async function getErrorMessage(error: unknown) {
const t = await getTranslations("getErrorMessage");
const errorCode = error instanceof AuthError ? error.errorCode : getErrorCode(error);
if (errorCode) {
if (isBlueprintAuthErrorCode(errorCode)) {
return t(`blueprint-auth.${errorCode}`);
}
if (isMappedKrakenErrorCode(errorCode)) {
return t(`kraken.${errorCode}`);
}
}
return t("unknown");
}

signJwt​

Signs a JWT payload with a shared secret.

function signJwt(payload: JWTPayload, secret: string, options?: SignJwtOptions): Promise<string>;
OptionDefaultDescription
algorithmHS256HMAC signing algorithm
expiresIn5mAbsolute expiry time or duration from signing
issuedAttrueInclude the current time, omit the claim with false, or set an absolute time or duration from now

signJwt throws an AuthMissingPropertiesError when secret is empty.

Usage​

import { signJwt } from "@krakentech/blueprint-auth/utils";

const token = await signJwt({ ip: clientIp }, secret);

setNextPageSearchParam​

This function sets the nextPage URL search parameter. This is the URL search parameter that we are setting in the authMiddleware function when we redirect the user to the login page.

Configuration​

OptionDescriptionTypeRequired
nextPageRedirect page pathname or URLstring | URL✅
urlURL on which to set the nextPage parameterURL✅

Output​

Returns void.

Usage​

import { setNextPageSearchParam } from "@krakentech/blueprint-auth/utils";

const url = new URL("https://example.com/login");
setNextPageSearchParam({
nextPage: "/profile/settings?tab=update-password",
url,
});
// url.href → https://example.com/login?nextPage=%2Fprofile%2Fsettings%3Ftab%3Dupdate-password
Search parameters

If the nextPage URL includes search parameters, they are included in the encoded nextPage URL search parameter along with the URL pathname.

Automatic removal of auth parameters

setNextPageSearchParam removes existing nextPage and error parameters from the destination URL.

setKrakenAuthTokenOverrideHeader​

Manually set the Kraken auth token override header.

Configuration​

OptionDescriptionTypeRequired
headersHeaders objectHeaders✅
tokenOverride token valuestring✅

Output​

TypeDescription
voidNo return value

Usage​

app/subscribe/checkout/action.ts
"use server";

import { setKrakenAuthTokenOverrideHeader } from "@krakentech/blueprint-auth/utils";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
import { getAuth, getGraphQLClient } from "@/lib/auth/server";
import { CheckoutQuoteInput, CheckoutQuote } from "@/mutations/checkout-quote";
import {
handleRequestError,
handleSubmissionError,
parseSubmission,
type FormState,
} from "@/utils/form-actions";

export async function checkoutAction(token: string, _formState: FormState, formData: FormData) {
const submission = parseSubmission(formData, CheckoutQuoteInput);
if (!submission.success) {
return handleSubmissionError(submission);
}

const requestHeaders = new Headers(await headers());
setKrakenAuthTokenOverrideHeader({ headers: requestHeaders, token });

try {
const auth = await getAuth.viewer();
const graphQLClient = getGraphQLClient.viewer({ auth });
await graphQLClient.request(CheckoutQuote, submission.data, requestHeaders);
} catch (error) {
return handleRequestError(error, submission);
}

redirect("/subscribe/confirmation");
}

Interfaces​

BlueprintGraphQLClient<Policy>​

The BlueprintGraphQLClient<Policy> interface provides a GraphQL client with resolved authentication headers and a selected error policy. Each operation sends one GraphQL request. getGraphQLClient and useGraphQLClient return this interface.

Generic parameter

Policy extends ErrorPolicy and defaults to "none". It is inferred from the errorPolicy argument passed when creating the client. The value of Policy determines the return type of .request():

  • "none" or "ignore" → Promise<T> (data only)
  • "all" → Promise<GraphQLClientResponse<T>> (full response with data, errors, extensions, and headers)

Error policy​

The client supports an optional error policy that controls how GraphQL errors in responses are handled:

PolicyBehavior
"none"(default) GraphQL errors cause the request to throw.
"ignore"GraphQL errors are ignored; response data is returned even when the response contains errors.
"all"Response includes both data and errors (rawRequest-style), so the caller can handle errors explicitly.

The error policy is set when creating the client. See getGraphQLClient or useGraphQLClient for details.

const auth = await getAuth.user({ context });
if (!auth) throw new Error("Authentication required.");

// Client-level error policy: affects all requests from this client.
const graphQLClient = getGraphQLClient.user({
auth,
errorPolicy: "all",
});

const { data, errors } = await graphQLClient.request(MyQuery);
// Return type is GraphQLClientResponse<T> because errorPolicy is "all"
Per-request override

You can also override the error policy on individual requests using the object configuration style. See the Per-request Override tab in the Usage section below.

request<T, V>(document, ...args)​

Execute a GraphQL query or mutation with automatic authentication.

Parameters​

Pass up to three separate arguments to the request method.

ParameterTypeDescriptionRequired
documentRequestDocument | TypedDocumentNode | TypedDocumentStringGraphQL operation document✅
variablesVGraphQL variables. Inferred from the document type; required if the query defines variables.Conditional
requestHeadersHeadersInitRequest-level headers❌
const { account } = await graphQLClient.request(
AccountQuery,
{ accountNumber: "A-12345678" },
{ "x-custom-header": "my-value" },
);
Output​
TypeDescription
Promise<T>Returned when Policy is "none" or "ignore". Contains the GraphQL response data directly.
Promise<GraphQLClientResponse<T>>Returned when Policy is "all". Contains the full response object with data, errors, extensions, and headers.
Throws​
Error typeCondition
Kraken authentication errorKraken rejects the selected access token
AuthError with BlueprintAuthErrorCode.ForbiddenA mutation runs while preventGraphQLMutations returns true
Kraken API errorA GraphQL operation fails with error policy "none"
Usage​

Execute GraphQL queries and mutations with automatic authentication:

import { getAuth, getGraphQLClient } from "@/lib/auth/server";
import { graphql } from "@/gql-tada";

const AccountQuery = graphql(`
query Account($accountNumber: String!) {
account(accountNumber: $accountNumber) {
number
balance
status
}
}
`);

export async function getServerSideProps(context) {
const auth = await getAuth.user({ context });
if (!auth) throw new Error("Authentication required.");

const graphQLClient = getGraphQLClient.user({ auth });

// graphQLClient is BlueprintGraphQLClient<"none"> (default)
// request() returns Promise<T>
const { account } = await graphQLClient.request(AccountQuery, {
accountNumber: "A-12345678",
});

return {
props: { account },
};
}

Server-side request behavior​

A server GraphQL client submits each operation once. Resolve auth before you create the client. Authentication resolution can send a separate token refresh request. Handle authentication errors in application code. Use isUnauthenticatedError only if the application must end the local session.


AuthError​

AuthError represents an authentication failure created by Blueprint Auth. Public functions can also expose platform, network, validation, provider, and framework errors. For example, Next.js navigation functions throw redirect errors.

Constructor​

new AuthError(
message: string,
options?: {
cause?: unknown;
code?: ErrorCode;
logLevel?: "debug" | "error" | "info" | "warn" | AuthErrorLogLevelResolver;
},
)

Parameters:

ParameterTypeDescriptionRequired
messagestringError message✅
options.causeunknownUnderlying cause❌
options.codeErrorCodeBlueprint Auth or Kraken error code❌
options.logLevel"debug" | "error" | "info" | "warn" | AuthErrorLogLevelResolverLog level or resolver❌

Properties​

PropertyTypeDescription
messagestringError message
errorCodeErrorCodeBlueprint Auth or Kraken error code
causeunknownOriginal cause, if present
source"blueprint-auth"Package that created the error

Usage​

import { AuthError, BlueprintAuthErrorCode } from "@krakentech/blueprint-auth";
import { login } from "@/lib/auth/server";

// Throw an AuthError.
throw new AuthError("Invalid credentials", {
code: BlueprintAuthErrorCode.BadRequest,
});

// Catch and handle AuthError.
try {
await login({ context, input: { email, password } });
} catch (error) {
if (error instanceof AuthError) {
console.error("Auth error:", error.errorCode, error.message);

if (error.errorCode === BlueprintAuthErrorCode.TokenAccessInvalid) {
// handle expired token
}
}
}

Error Code Utilities​

For an AuthError instance, first check error instanceof AuthError, then read error.errorCode directly.


Types​

Public type inventory​

Import public types from these entry points.

Entry pointPublic types
@krakentech/blueprint-authApiRouteHandlerContext, ApiRoutes, AppRoutes, AuthCacheAdapter, AuthCacheValue, AuthConfig, AuthContext, AuthErrorLogContext, AuthErrorLogLevelResolver, AuthHandlers, AuthMethod, AuthScope, AuthSource, AuthUserConfig, BlueprintAuthErrorCode, BlueprintGraphQLClient, CookieMap, CookieName, CreateAuthCacheProfilesConfig, ErrorCode, ErrorPolicy, KrakenError, KrakenErrorDetails, KrakenErrorResponse, KrakenErrorType, MappedKrakenErrorCode, MappedKrakenErrorType, MiddlewareContext, RouteHandlerContext, ServerActionContext, ServerComponentContext, ServerSideContext, ServerSidePropsContext, SessionState, StaticPropsContext
@krakentech/blueprint-auth/cache/global-configCreateGlobalConfigCacheAdapterOptions
@krakentech/blueprint-auth/clientCreateClientSideAuthOptions
@krakentech/blueprint-auth/middlewareAuthMiddlewareConfig, CreateAuthCookieUtilsConfig, CreateAuthCookieUtilsParams
@krakentech/blueprint-auth/serverAppRouterLoginParams, AppRouterLogoutParams, AppRouterPrefetchSessionParams, AppRouterRedirectToLoginParams, AuthContext, AuthSource, CacheFunction, CreateAppRouterAuthParams, CreateAuthCookieUtilsConfig, CreateAuthCookieUtilsParams, CreateAuthServerFunctionsConfig, CreateServerSideAuthParams, CreateUpdateOrgTokenHandlerParams, GenerateKrakenOAuthURIConfig, GenerateKrakenOAuthUriParams, GetRequestPathnameParams, GetSessionParams, LoginConfig, LoginParams, LogoutParams, PrefetchSessionParams, RedirectToLoginConfig, RedirectToLoginParams, ValidateGraphQLRequestOptions, getAuth.OrgConfig, getAuth.OrgParams, getAuth.UserConfig, getAuth.UserParams, getAuth.ViewerConfig, getAuth.ViewerParams, getGraphQLClient.Config, getGraphQLClient.OrgParams, getGraphQLClient.UserParams, getGraphQLClient.ViewerParams
@krakentech/blueprint-auth/testingCreateMockAuthTokenIssuerOptions, MockAccessTokenOptions, MockAuthMethod, MockAuthTokenIssuer
@krakentech/blueprint-auth/utilsNo type exports

AuthCacheAdapter​

The shared server cache interface for authentication data:

interface AuthCacheAdapter {
get(key: string, options?: { bypassCache?: boolean }): Promise<AuthCacheValue | undefined>;
set(key: string, value: AuthCacheValue): Promise<void>;
}

See the custom adapter contract for the required read, fresh-read, missing-value, write, and error behavior.

AuthCacheValue​

The JSON-compatible values that an AuthCacheAdapter can store:

type AuthCacheValue =
boolean | number | string | null | AuthCacheValue[] | { [key: string]: AuthCacheValue };

AuthContext​

A namespace for the server-only values returned by getAuth.*.

TypeRequired fieldsMeaning
AuthContext.ViewerauthScope: "user", sessionUser or Unauthenticated
AuthContext.UseraccessToken, authScope: "user", authSource, sessionLocal user credentials
AuthContext.UnauthenticatedauthScope: "user", session: nullNo usable local user credentials
AuthContext.OrgaccessToken, authScope: "organization", authSourceOrganization credentials
AuthContext.BaseNoneOptional clientIp and headers shared by each context

AuthContext.Viewer is a discriminated union. Check session before using an access token:

const auth = await getAuth.viewer();

if (auth.session) {
// auth is AuthContext.User here.
getGraphQLClient.user({ auth });
}

Any context can contain resolved request headers. Treat the whole context as a credential. Keep it on the server and out of Client Components, browser code, logs, and public props.

AuthSource​

Identifies where Blueprint Auth found the verified token:

type AuthSource = "web" | "mobile-web-view" | "override";
ValueMeaning
"web"Web token for email, OAuth, scoped, masquerade, or organization auth
"mobile-web-view"Mobile web view token
"override"A request token override

AuthSource differs from AuthMethod. AuthMethod identifies the verified grant. A request override is not refreshed with other request credentials.

AuthMethod​

Identifies the user method from the verified access token grant:

type AuthMethod = "email" | "oauth" | "scoped" | "masquerade";
JWT gty fieldAuthMethod
EMAIL-AND-PASSWORD"email"
OPENID-CONNECT"oauth"
PRE-SIGNED-TOKEN"scoped"
MASQUERADE"masquerade"

AuthMethod does not identify where Blueprint Auth found the token. Use AuthSource for that information. SessionState.authMethod is null when the request has no verified user.

See Session management for a session lifecycle overview.

Usage​

import { getSession } from "@/lib/auth/server";

export async function SessionSummary({ context }: SessionSummaryProps) {
const session = await getSession({ context });

return (
<>
{session.authMethod === "masquerade" && <MasqueradeBanner />}
{session.authSource === "mobile-web-view" && <UpdateAppLink />}
{session.isAuthenticated ? <LogoutButton /> : <LoginButton />}
</>
);
}

AuthScope​

Represents the scope of authentication for GraphQL operations.

type AuthScope = "user" | "organization";

Values​

ValueDescription
"user"Authenticates operations performed on behalf of a user.
"organization"Authenticates operations performed with organization credentials.

Usage​

The AuthScope type is used in the customization.setCustomHeaders callback and internally by GraphQL client functions.

const authConfig = createAuthConfig({
customization: {
setCustomHeaders(headers, { authScope }) {
if (authScope === "organization") {
headers.set("X-Custom-Org-Header", "value");
}
},
},
});

BlueprintAuthErrorCode​

Blueprint-specific error codes for authentication operations. All error codes follow the pattern BP-AUTH-XXXX.

const BlueprintAuthErrorCode = {
/* General Errors */
Unknown: "BP-AUTH-0000",
BadRequest: "BP-AUTH-0001",
AuthenticationRequired: "BP-AUTH-0002",
ResponseNotFound: "BP-AUTH-0003",
Forbidden: "BP-AUTH-0004",
CookieWrite: "BP-AUTH-0005",
/* Token Errors */
TokenUnknown: "BP-AUTH-0100",
TokenAccessInvalid: "BP-AUTH-0101",
TokenNotRefreshable: "BP-AUTH-0102",
TokenOrganizationUnavailable: "BP-AUTH-0103",
TokenVerificationInvalid: "BP-AUTH-0104",
TokenVerificationUnavailable: "BP-AUTH-0105",
TokenGrantUnsupported: "BP-AUTH-0106",
TokenRefreshUnavailable: "BP-AUTH-0107",
/* API Handler Errors */
ApiHandlerUnknown: "BP-AUTH-0200",
ApiHandlerRequestNotFound: "BP-AUTH-0201",
ApiHandlerInvalidParameters: "BP-AUTH-0202",
ApiHandlerMethodNotAllowed: "BP-AUTH-0203",
/* Server Function Errors */
ServerFunctionUnknown: "BP-AUTH-0300",
ServerFunctionUnsupportedExecutionContext: "BP-AUTH-0301",
/* Operation Errors */
OperationUnknown: "BP-AUTH-0400",
OperationLoginUnknown: "BP-AUTH-0410",
OperationOAuthUnknown: "BP-AUTH-0420",
OperationLogoutUnknown: "BP-AUTH-0430",
OperationLogoutUpstreamUnavailable: "BP-AUTH-0431",
OperationSessionUnknown: "BP-AUTH-0440",
OperationGraphQLUnknown: "BP-AUTH-0450",
/* Cache Errors */
CacheUnknown: "BP-AUTH-0500",
CacheRead: "BP-AUTH-0501",
CacheReadFresh: "BP-AUTH-0502",
CacheWrite: "BP-AUTH-0503",
/* Encryption Errors */
EncryptionUnknown: "BP-AUTH-0600",
/* Validation Errors */
ValidationUnknown: "BP-AUTH-0700",
ValidationApiUrl: "BP-AUTH-0701",
ValidationMissingProperties: "BP-AUTH-0702",
ValidationInvalidProperties: "BP-AUTH-0703",
ValidationRequestBodyTooLarge: "BP-AUTH-0704",
ValidationQueryStringTooLong: "BP-AUTH-0705",
/* Client Errors */
ClientUnknown: "BP-AUTH-0800",
ClientHookUsedOutsideOfProvider: "BP-AUTH-0802",
} as const;

type BlueprintAuthErrorCode = (typeof BlueprintAuthErrorCode)[keyof typeof BlueprintAuthErrorCode];

Error Codes​

CodeConstantCategoryDescription
BP-AUTH-0000UnknownGeneralUnknown error
BP-AUTH-0001BadRequestGeneralBad request
BP-AUTH-0002AuthenticationRequiredGeneralProtected resource requires authentication
BP-AUTH-0003ResponseNotFoundGeneralResponse not found
BP-AUTH-0004ForbiddenGeneralForbidden operation
BP-AUTH-0005CookieWriteGeneralAuth cookie write failed
BP-AUTH-0100TokenUnknownTokenUnknown token error
BP-AUTH-0101TokenAccessInvalidTokenInvalid or expired access token
BP-AUTH-0102TokenNotRefreshableTokenToken cannot be refreshed
BP-AUTH-0103TokenOrganizationUnavailableTokenOrganization authentication is unavailable
BP-AUTH-0104TokenVerificationInvalidTokenToken verification failed
BP-AUTH-0105TokenVerificationUnavailableTokenVerification keys are not available
BP-AUTH-0106TokenGrantUnsupportedTokenAccess token grant is not supported
BP-AUTH-0107TokenRefreshUnavailableTokenAccess token refresh is temporarily unavailable
BP-AUTH-0200ApiHandlerUnknownAPI HandlerUnknown API handler error
BP-AUTH-0201ApiHandlerRequestNotFoundAPI HandlerAPI request not found
BP-AUTH-0202ApiHandlerInvalidParametersAPI HandlerInvalid parameters provided to API handler
BP-AUTH-0203ApiHandlerMethodNotAllowedAPI HandlerHTTP method not allowed
BP-AUTH-0300ServerFunctionUnknownServer FunctionUnknown server function error
BP-AUTH-0301ServerFunctionUnsupportedExecutionContextServer FunctionServer function called in unsupported context
BP-AUTH-0400OperationUnknownOperationUnknown operation error
BP-AUTH-0410OperationLoginUnknownOperationUnknown login operation error
BP-AUTH-0420OperationOAuthUnknownOperationUnknown OAuth operation error
BP-AUTH-0430OperationLogoutUnknownOperationUnknown logout operation error
BP-AUTH-0431OperationLogoutUpstreamUnavailableOperationUpstream OAuth logout request failed
BP-AUTH-0440OperationSessionUnknownOperationUnknown session operation error
BP-AUTH-0450OperationGraphQLUnknownOperationUnknown GraphQL operation error
BP-AUTH-0500CacheUnknownCacheUnknown cache error
BP-AUTH-0501CacheReadCacheCached read failed
BP-AUTH-0502CacheReadFreshCacheFresh read failed
BP-AUTH-0503CacheWriteCacheCache write failed
BP-AUTH-0600EncryptionUnknownEncryptionUnknown encryption error
BP-AUTH-0700ValidationUnknownValidationUnknown validation error
BP-AUTH-0701ValidationApiUrlValidationInvalid API URL
BP-AUTH-0702ValidationMissingPropertiesValidationMissing required properties
BP-AUTH-0703ValidationInvalidPropertiesValidationInvalid property values
BP-AUTH-0704ValidationRequestBodyTooLargeValidationDeclared Content-Length exceeds maxRequestBodySize
BP-AUTH-0705ValidationQueryStringTooLongValidationGraphQL query string exceeds maxQueryLength
BP-AUTH-0800ClientUnknownClientUnknown client-side error
BP-AUTH-0802ClientHookUsedOutsideOfProviderClientReact hook used outside of AuthProvider

Usage​

import { AuthError, BlueprintAuthErrorCode } from "@krakentech/blueprint-auth";
import { login } from "@/lib/auth/server";

try {
await login({ context, input: { email, password } });
} catch (error) {
if (!(error instanceof AuthError)) throw error;

const errorCode = error.errorCode;
if (errorCode === BlueprintAuthErrorCode.TokenAccessInvalid) {
// handle invalid token
} else if (errorCode === BlueprintAuthErrorCode.ValidationMissingProperties) {
// handle validation error
} else {
throw error;
}
}

CookieMap​

Contains the managed cookie names and values that are present on the request.

type CookieMap = Map<CookieName, string>;

Usage​

const { getAuthCookies } = createAuthCookieUtils({ context });
const cookies = await getAuthCookies();

const accessToken = cookies.get("accessToken");
const hasAccessToken = cookies.has("accessToken");

Use verified SessionState data to read identity or authMethod. Do not infer them from cookie presence.

CookieName​

Valid authentication cookie names used throughout the package.

type CookieName =
| "accessToken"
| "MWAuthToken"
| "MWRefreshToken"
| "oAuthIdToken"
| "pkceVerifier"
| "refreshToken";

Usage​

This type is used by createAuthCookieUtils functions to ensure type-safe cookie operations. See the AUTH_COOKIE constant for the actual cookie name values.

const { setAuthCookie } = createAuthCookieUtils({ context });

await setAuthCookie({
name: "accessToken", // type-safe: must be a valid CookieName
value: token,
expires: new Date(Date.now() + 3600000),
});

ErrorCode​

Union type of all possible error codes from Blueprint Auth and the Kraken API.

type ErrorCode = BlueprintAuthErrorCode | MappedKrakenErrorCode;

This type combines:

  • BlueprintAuthErrorCode represents auth errors specific to Blueprint, such as BP-AUTH-0001.
  • MappedKrakenErrorCode represents Kraken API errors mapped by @krakentech/blueprint-auth.

ErrorPolicy​

Controls how GraphQL errors in responses are handled by BlueprintGraphQLClient. The error policy also determines the return type of the .request() method through type-level inference.

type ErrorPolicy = "none" | "ignore" | "all";

Values​

ValueReturn type of .request()Behavior
"none"Promise<T>(default) GraphQL errors cause the request to throw.
"ignore"Promise<T>GraphQL errors are ignored; response data is returned even when the response contains errors.
"all"Promise<GraphQLClientResponse<T>>Response includes both data and errors (rawRequest-style), so the caller can handle errors explicitly.

Usage​

import { getAuth, getGraphQLClient } from "@/lib/auth/server";

const auth = await getAuth.user({ context });
if (!auth) throw new Error("Authentication required.");

// Default: errorPolicy is "none", request() returns Promise<T>.
const client = getGraphQLClient.user({ auth });
const { account } = await client.request(AccountQuery, { accountNumber });

// With "all": request() returns Promise<GraphQLClientResponse<T>>.
const allClient = getGraphQLClient.user({ auth, errorPolicy: "all" });
const { data, errors } = await allClient.request(AccountQuery, {
accountNumber,
});

SessionState​

Represents the current user session state. See getSession and useSession for full documentation.

type SessionState = {
authMethod: AuthMethod | null;
authSource: AuthSource | null;
isAuthenticated: boolean;
sub: string | null;
};

Identity and authMethod come from verified access token fields. See Session management for a session lifecycle overview.

SetCustomHeadersContext​

Context passed as the second argument to customization.setCustomHeaders.

interface SetCustomHeadersContext {
authScope: AuthScope;
clientIp: string | undefined;
}

authScope is the AuthScope of the request to Kraken.

For clientIp, Blueprint Auth prefers krakenConfig.xClientIpOverride, then the first address in x-forwarded-for. The value is undefined when no client IP is available.

Usage​

Use clientIp to send the client IP to a service that reads a different header from the one Kraken reads.

import { signJwt } from "@krakentech/blueprint-auth/utils";

const authConfig = createAuthConfig({
customization: {
async setCustomHeaders(headers, { clientIp }) {
const secret = process.env.DOWNSTREAM_IP_SECRET;
if (!clientIp || !secret) return;

headers.set("x-downstream-client-ip", await signJwt({ ip: clientIp }, secret));
},
},
});

Constants​

createAuthCacheProfiles​

Creates the auth profile for Next.js Cache Components. Pass the same server-only auth config that runtime auth uses.

Profilestalerevalidateexpire
auth300 seconds3600 - accessTokenRefreshThresholdSeconds seconds3600 seconds

The default refresh threshold is 60 seconds. The default revalidate value is therefore 3540 seconds.

next.config.ts
import { createAuthCacheProfiles } from "@krakentech/blueprint-auth";
import type { NextConfig } from "next";
import { authConfig } from "./src/lib/auth/config";

const nextConfig: NextConfig = {
cacheComponents: true,
cacheLife: { ...createAuthCacheProfiles(authConfig) },
};

export default nextConfig;

Use this profile only for cache timing. Check access at the request boundary because a stale entry can remain after an access token expires or permissions change.

See the Cache Components guide for request boundaries and server-only handling.

ConstantValueDescription
AUTH_COOKIE.accessToken"accessToken"Web access token cookie
AUTH_COOKIE.MWAuthToken"MWAuthToken"Mobile web view access token cookie
AUTH_COOKIE.MWRefreshToken"MWRefreshToken"Mobile web view refresh token cookie
AUTH_COOKIE.oAuthIdToken"oAuthIdToken"OAuth identity token cookie
AUTH_COOKIE.pkceVerifier"pkceVerifier"OAuth PKCE verifier cookie
AUTH_COOKIE.refreshToken"refreshToken"Web refresh token cookie

HTTP Headers​

ConstantValueDescription
krakenAuthTokenOverrideHeader"x-kraken-auth-token-override"Header for token override in scoped requests
xClientIpHeader"x-kraken-client-ip"Header containing the client IP address
xClientIpAuthorizationHeader"x-kraken-client-ip-authorization"Header with signed client IP for rate-limiting prevention
xErrorPolicyHeader"x-error-policy"Internal transport header for error policy ("none", "ignore", "all"). Set automatically by the client returned from useGraphQLClient based on the configured error policy.
When to use xErrorPolicyHeader directly

In normal application code, the client from useGraphQLClient handles this header for you automatically. Server-side requests do not go through the handler, so this header is not relevant there. The xErrorPolicyHeader constant is exported for tests and advanced use cases where you need to make requests through the GraphQL handler without using the hook.

Kraken error codes​

krakenErrorTypeToCodeMap maps authentication error names to Kraken error codes. Import it from @krakentech/blueprint-auth.

KeyValue
AUTH_HEADER_NOT_PROVIDED"KT-CT-1112"
EXPIRED_JWT_SIGNATURE"KT-CT-1124"
EXPIRED_REFRESH_TOKEN"KT-CT-1134"
FAILED_AUTHENTICATION"KT-CT-1142"
INCORRECT_CREDENTIALS"KT-CT-1138"
INTERNAL_ERROR"KT-CT-7899"
INVALID_AUTH_HEADER"KT-CT-1143"
INVALID_REFRESH_TOKEN"KT-CT-1135"
ISSUER_VERIFICATION_FAILED"KT-CT-1127"
SIGNATURE_VERIFICATION_FAILED"KT-CT-1126"
TOKEN_EXPIRED"KT-CT-1120"
TOO_MANY_REQUESTS"KT-CT-1199"
UNAUTHORIZED"KT-CT-1111"
UNAUTHORIZED_REFRESH_TOKEN"KT-CT-1130"

URL Parameters​

ConstantValueDescription
sessionQueryKey["session"]Query key for session queries
ignoredQueryParams["nextPage", "error"]Query parameters to remove from redirect destinations
nextPageParam"nextPage"URL parameter for the destination after an auth operation