inspector/core/auth/storage.ts
Bob Dickinson 5de4e911e3
feat(web,core): enterprise-managed authorization (EMA) (#1509) (#1512)
Adds enterprise-managed authorization (EMA): browser-side IdP login + RFC 8693 token-exchange and JWT-bearer resource-token mint, per-server EMA opt-in in Server Settings, IdP config in Client Settings, and IdP clientSecret keychain storage. Includes the v2/main merge and review follow-ups (400 on malformed client config; normalizeIdpIssuer import consolidation).
2026-06-24 22:15:12 -04:00

169 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type {
OAuthClientInformation,
OAuthTokens,
OAuthMetadata,
} from "@modelcontextprotocol/sdk/shared/auth.js";
/**
* Abstract storage interface for OAuth state
* Supports both browser (sessionStorage) and Node.js (Zustand) environments
*/
export interface SaveTokensOptions {
/** Marks resource tokens minted via EMA (legs 2–3) for sign-out cleanup. */
enterpriseManaged?: boolean;
}
export interface OAuthStorage {
/**
* Get client information (preregistered or dynamically registered)
*/
getClientInformation(
serverUrl: string,
isPreregistered?: boolean,
): Promise<OAuthClientInformation | undefined>;
/**
* Save client information (dynamically registered)
*/
saveClientInformation(
serverUrl: string,
clientInformation: OAuthClientInformation,
): Promise<void>;
/**
* Save preregistered client information (static client from config)
*/
savePreregisteredClientInformation(
serverUrl: string,
clientInformation: OAuthClientInformation,
): Promise<void>;
/**
* Clear client information
*/
clearClientInformation(serverUrl: string, isPreregistered?: boolean): void;
/**
* Get OAuth tokens
*/
getTokens(serverUrl: string): Promise<OAuthTokens | undefined>;
/**
* Save OAuth tokens
*/
saveTokens(
serverUrl: string,
tokens: OAuthTokens,
options?: SaveTokensOptions,
): Promise<void>;
/**
* Clear OAuth tokens
*/
clearTokens(serverUrl: string): void;
/**
* Get code verifier (for PKCE)
*/
getCodeVerifier(serverUrl: string): string | undefined;
/**
* Save code verifier (for PKCE)
*/
saveCodeVerifier(serverUrl: string, codeVerifier: string): Promise<void>;
/**
* Clear code verifier
*/
clearCodeVerifier(serverUrl: string): void;
/**
* Get scope
*/
getScope(serverUrl: string): string | undefined;
/**
* Save scope
*/
saveScope(serverUrl: string, scope: string | undefined): Promise<void>;
/**
* Clear scope
*/
clearScope(serverUrl: string): void;
/**
* Get server metadata (for guided mode)
*/
getServerMetadata(serverUrl: string): OAuthMetadata | null;
/**
* Save server metadata (for guided mode)
*/
saveServerMetadata(serverUrl: string, metadata: OAuthMetadata): Promise<void>;
/**
* Clear server metadata
*/
clearServerMetadata(serverUrl: string): void;
/**
* Clear all OAuth data for a server
*/
clear(serverUrl: string): void;
/**
* Get cached IdP OIDC session for EMA (keyed by issuer).
*/
getIdpSession(issuer: string): Promise<IdpSessionState | undefined>;
/**
* Save IdP OIDC session fields for EMA.
*/
saveIdpSession(
issuer: string,
session: Partial<IdpSessionState>,
): Promise<void>;
/**
* Clear cached IdP session for an issuer.
*/
clearIdpSession(issuer: string): void;
/**
* Remove per-server OAuth state for MCP servers whose tokens were minted via EMA.
*/
clearEnterpriseManagedResourceServers(): void;
}
/**
* Cached IdP OIDC session for EMA leg 1.
*/
export interface IdpSessionState {
idToken?: string;
refreshToken?: string;
/** Epoch ms when the ID Token expires (when known). */
idTokenExpiresAt?: number;
}
/**
* Generate server-specific storage key
*/
export function getServerSpecificKey(
baseKey: string,
serverUrl: string,
): string {
return `[${serverUrl}] ${baseKey}`;
}
/**
* Base storage keys for OAuth data
*/
export const OAUTH_STORAGE_KEYS = {
CODE_VERIFIER: "mcp_code_verifier",
TOKENS: "mcp_tokens",
CLIENT_INFORMATION: "mcp_client_information",
PREREGISTERED_CLIENT_INFORMATION: "mcp_preregistered_client_information",
SERVER_METADATA: "mcp_server_metadata",
SCOPE: "mcp_scope",
} as const;