Skip to main content
A verifier is the provider-specific token check you implement and pass to requireBearerAuth or optionalBearerAuth. The middleware calls it on each request to validate the bearer token before any tool runs.

Example

verifyAccessToken validates the token however your provider requires, returns an AuthInfo for a valid token, and throws InvalidTokenError otherwise. Pass it to the middleware as verifier: { verifyAccessToken }.
import { type AuthInfo, InvalidTokenError } from "skybridge/server";

async function verifyAccessToken(token: string): Promise<AuthInfo> {
  try {
    const payload = await validateToken(token); // JWT verification, introspection, etc.
    return {
      token,
      clientId: payload.client_id,
      scopes: payload.scope.split(" "),
      expiresAt: payload.exp,
      extra: { sub: payload.sub },
    };
  } catch (err) {
    throw new InvalidTokenError(
      err instanceof Error ? err.message : "Token validation failed",
    );
  }
}
How you validate the token depends on your provider. Check its docs.

verifyAccessToken

verifyAccessToken(token: string): Promise<AuthInfo>;
The verifier’s only required method.
  • Resolve with an AuthInfo for a valid token. The middleware puts it on extra.authInfo for tool handlers.
  • Throw InvalidTokenError for a malformed, badly signed, or expired token. The middleware returns a 401 with the right WWW-Authenticate header.
Do not check scopes here: the middleware enforces requiredScopes against authInfo.scopes and returns a 403 on a missing scope.

AuthInfo

What verifyAccessToken resolves with for a valid token.
type AuthInfo = {
  token: string;
  clientId: string;
  scopes: string[];
  expiresAt: number;
  extra?: Record<string, unknown>;
};
FieldPurpose
tokenThe raw bearer token.
clientIdThe OAuth client_id, often the azp or client_id claim.
scopesThe scopes granted, checked against requiredScopes and per-tool securitySchemes.
expiresAtExpiry in unix seconds. Required: tokens with no expiration are rejected.
extraAnything else you want available to handlers, for example sub or email.

requireBearerAuth

Require a token on every request

optionalBearerAuth

Accept a token when present, allow anonymous otherwise

Authenticate Users

Add sign-in to your app end to end