mcp-from-openapi 0.0.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,289 @@
1
+ import type { ParameterMapper, SecurityParameterInfo } from './types';
2
+ /**
3
+ * Context for resolving security parameters
4
+ * Frameworks should implement this interface based on their auth system
5
+ */
6
+ export interface SecurityContext {
7
+ /**
8
+ * JWT/Bearer token
9
+ */
10
+ jwt?: string;
11
+ /**
12
+ * Basic auth credentials (base64 encoded "username:password")
13
+ */
14
+ basic?: string;
15
+ /**
16
+ * Digest auth credentials
17
+ * Object with username, password, realm, nonce, etc.
18
+ */
19
+ digest?: DigestAuthCredentials;
20
+ /**
21
+ * API key (single key for backward compatibility)
22
+ */
23
+ apiKey?: string;
24
+ /**
25
+ * Multiple API keys by name
26
+ * Use this when API requires different keys for different purposes
27
+ * @example { 'X-API-Key': 'key1', 'X-Client-Id': 'client123' }
28
+ */
29
+ apiKeys?: Record<string, string>;
30
+ /**
31
+ * OAuth2 access token
32
+ */
33
+ oauth2Token?: string;
34
+ /**
35
+ * Client certificate for mutual TLS (mTLS)
36
+ */
37
+ clientCertificate?: ClientCertificate;
38
+ /**
39
+ * Private key for signature-based auth (HMAC, AWS Signature V4, etc.)
40
+ */
41
+ privateKey?: string;
42
+ /**
43
+ * Public key (if needed for verification)
44
+ */
45
+ publicKey?: string;
46
+ /**
47
+ * HMAC secret for HMAC-based authentication
48
+ */
49
+ hmacSecret?: string;
50
+ /**
51
+ * AWS credentials for AWS Signature V4
52
+ */
53
+ awsCredentials?: AWSCredentials;
54
+ /**
55
+ * Custom headers for proprietary authentication
56
+ * @example { 'X-Custom-Auth': 'custom-value' }
57
+ */
58
+ customHeaders?: Record<string, string>;
59
+ /**
60
+ * Session cookies
61
+ */
62
+ cookies?: Record<string, string>;
63
+ /**
64
+ * Custom resolver for framework-specific auth
65
+ * @param security - Security parameter info from mapper
66
+ * @returns The auth value to use, or undefined if not available
67
+ */
68
+ customResolver?: (security: SecurityParameterInfo) => string | Promise<string | undefined>;
69
+ /**
70
+ * Signature generator for signature-based auth
71
+ * @param data - Data to sign (typically the request)
72
+ * @param security - Security parameter info
73
+ * @returns The signature or signed value
74
+ */
75
+ signatureGenerator?: (data: SignatureData, security: SecurityParameterInfo) => string | Promise<string>;
76
+ }
77
+ /**
78
+ * Digest authentication credentials
79
+ */
80
+ export interface DigestAuthCredentials {
81
+ username: string;
82
+ password: string;
83
+ realm?: string;
84
+ nonce?: string;
85
+ uri?: string;
86
+ qop?: string;
87
+ nc?: string;
88
+ cnonce?: string;
89
+ response?: string;
90
+ opaque?: string;
91
+ }
92
+ /**
93
+ * Client certificate for mTLS
94
+ */
95
+ export interface ClientCertificate {
96
+ /**
97
+ * Certificate in PEM format
98
+ */
99
+ cert: string;
100
+ /**
101
+ * Private key in PEM format
102
+ */
103
+ key: string;
104
+ /**
105
+ * Passphrase for encrypted key
106
+ */
107
+ passphrase?: string;
108
+ /**
109
+ * CA certificates
110
+ */
111
+ ca?: string | string[];
112
+ }
113
+ /**
114
+ * AWS credentials for Signature V4
115
+ */
116
+ export interface AWSCredentials {
117
+ accessKeyId: string;
118
+ secretAccessKey: string;
119
+ sessionToken?: string;
120
+ region?: string;
121
+ service?: string;
122
+ }
123
+ /**
124
+ * Data to be signed for signature-based auth
125
+ */
126
+ export interface SignatureData {
127
+ method: string;
128
+ url: string;
129
+ headers: Record<string, string>;
130
+ body?: string;
131
+ timestamp?: number;
132
+ }
133
+ /**
134
+ * Resolved security parameters ready to be added to HTTP request
135
+ */
136
+ export interface ResolvedSecurity {
137
+ /**
138
+ * Headers to add to the request
139
+ */
140
+ headers: Record<string, string>;
141
+ /**
142
+ * Query parameters to add to the request
143
+ */
144
+ query: Record<string, string>;
145
+ /**
146
+ * Cookie values to add to the request
147
+ */
148
+ cookies: Record<string, string>;
149
+ /**
150
+ * Client certificate for mTLS (if applicable)
151
+ */
152
+ clientCertificate?: ClientCertificate;
153
+ /**
154
+ * Whether signature-based auth is required
155
+ * If true, you need to call signRequest() before sending
156
+ */
157
+ requiresSignature?: boolean;
158
+ /**
159
+ * Signature metadata (if signature-based auth is used)
160
+ */
161
+ signatureInfo?: {
162
+ scheme: string;
163
+ algorithm?: string;
164
+ };
165
+ }
166
+ /**
167
+ * Security resolver that maps OpenAPI security requirements to actual auth values
168
+ *
169
+ * This helper handles security parameters from any OpenAPI spec, regardless of
170
+ * custom naming (BearerAuth, JWT, Authorization, etc.). It uses the mapper's
171
+ * security metadata to determine the auth type and format.
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * // In FrontMCP
176
+ * const resolver = new SecurityResolver();
177
+ * const resolved = resolver.resolve(tool.mapper, {
178
+ * jwt: context.authInfo.jwt,
179
+ * apiKey: process.env.API_KEY
180
+ * });
181
+ *
182
+ * // Use resolved.headers in HTTP request
183
+ * fetch(url, { headers: { ...resolved.headers, ...otherHeaders } });
184
+ * ```
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * // Custom resolver for framework-specific auth
189
+ * const resolved = resolver.resolve(tool.mapper, {
190
+ * customResolver: (security) => {
191
+ * if (security.type === 'http' && security.httpScheme === 'bearer') {
192
+ * return myFramework.getAuthToken();
193
+ * }
194
+ * return undefined;
195
+ * }
196
+ * });
197
+ * ```
198
+ */
199
+ export declare class SecurityResolver {
200
+ /**
201
+ * Resolve security parameters from mapper entries
202
+ *
203
+ * @param mappers - Parameter mappers from the tool definition
204
+ * @param context - Security context with auth values or custom resolver
205
+ * @returns Resolved headers, query params, and cookies with auth applied
206
+ */
207
+ resolve(mappers: ParameterMapper[], context: SecurityContext): Promise<ResolvedSecurity>;
208
+ /**
209
+ * Check if security scheme requires request signing
210
+ */
211
+ private isSignatureBasedAuth;
212
+ /**
213
+ * Resolve the actual auth value based on security type
214
+ */
215
+ private resolveAuthValue;
216
+ /**
217
+ * Resolve HTTP authentication (bearer, basic, digest, etc.)
218
+ */
219
+ private resolveHttpAuth;
220
+ /**
221
+ * Resolve Bearer token authentication
222
+ */
223
+ private resolveBearerAuth;
224
+ /**
225
+ * Resolve Basic authentication
226
+ */
227
+ private resolveBasicAuth;
228
+ /**
229
+ * Resolve Digest authentication
230
+ */
231
+ private resolveDigestAuth;
232
+ /**
233
+ * Resolve custom HTTP authentication schemes
234
+ */
235
+ private resolveCustomHttpScheme;
236
+ /**
237
+ * Resolve API key authentication
238
+ */
239
+ private resolveApiKey;
240
+ /**
241
+ * Resolve OAuth2/OpenID Connect authentication
242
+ */
243
+ private resolveOAuth2;
244
+ /**
245
+ * Check if any security requirements are missing from context
246
+ *
247
+ * @param mappers - Parameter mappers from the tool definition
248
+ * @param context - Security context with auth values
249
+ * @returns Array of missing security scheme names
250
+ */
251
+ checkMissingSecurity(mappers: ParameterMapper[], context: SecurityContext): Promise<string[]>;
252
+ /**
253
+ * Sign a request for signature-based authentication
254
+ *
255
+ * Use this when resolved.requiresSignature is true.
256
+ * This method will call the signatureGenerator from context to sign the request.
257
+ *
258
+ * @param mappers - Parameter mappers from the tool definition
259
+ * @param signatureData - Request data to sign
260
+ * @param context - Security context with signature generator
261
+ * @returns Headers with signature added
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * const resolved = resolver.resolve(tool.mapper, context);
266
+ * if (resolved.requiresSignature) {
267
+ * const signedHeaders = await resolver.signRequest(
268
+ * tool.mapper,
269
+ * { method: 'GET', url: 'https://api.example.com/data', headers: resolved.headers },
270
+ * context
271
+ * );
272
+ * // Use signedHeaders in request
273
+ * }
274
+ * ```
275
+ */
276
+ signRequest(mappers: ParameterMapper[], signatureData: SignatureData, context: SecurityContext): Promise<Record<string, string>>;
277
+ }
278
+ /**
279
+ * Create a basic security context from common auth sources
280
+ *
281
+ * @example
282
+ * ```typescript
283
+ * const context = createSecurityContext({
284
+ * jwt: process.env.JWT_TOKEN,
285
+ * apiKey: process.env.API_KEY
286
+ * });
287
+ * ```
288
+ */
289
+ export declare function createSecurityContext(auth: Partial<SecurityContext>): SecurityContext;
@@ -0,0 +1,324 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SecurityResolver = void 0;
4
+ exports.createSecurityContext = createSecurityContext;
5
+ /**
6
+ * Security resolver that maps OpenAPI security requirements to actual auth values
7
+ *
8
+ * This helper handles security parameters from any OpenAPI spec, regardless of
9
+ * custom naming (BearerAuth, JWT, Authorization, etc.). It uses the mapper's
10
+ * security metadata to determine the auth type and format.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // In FrontMCP
15
+ * const resolver = new SecurityResolver();
16
+ * const resolved = resolver.resolve(tool.mapper, {
17
+ * jwt: context.authInfo.jwt,
18
+ * apiKey: process.env.API_KEY
19
+ * });
20
+ *
21
+ * // Use resolved.headers in HTTP request
22
+ * fetch(url, { headers: { ...resolved.headers, ...otherHeaders } });
23
+ * ```
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * // Custom resolver for framework-specific auth
28
+ * const resolved = resolver.resolve(tool.mapper, {
29
+ * customResolver: (security) => {
30
+ * if (security.type === 'http' && security.httpScheme === 'bearer') {
31
+ * return myFramework.getAuthToken();
32
+ * }
33
+ * return undefined;
34
+ * }
35
+ * });
36
+ * ```
37
+ */
38
+ class SecurityResolver {
39
+ /**
40
+ * Resolve security parameters from mapper entries
41
+ *
42
+ * @param mappers - Parameter mappers from the tool definition
43
+ * @param context - Security context with auth values or custom resolver
44
+ * @returns Resolved headers, query params, and cookies with auth applied
45
+ */
46
+ async resolve(mappers, context) {
47
+ const resolved = {
48
+ headers: {},
49
+ query: {},
50
+ cookies: {},
51
+ };
52
+ // Add client certificate if available (for mTLS)
53
+ if (context.clientCertificate) {
54
+ resolved.clientCertificate = context.clientCertificate;
55
+ }
56
+ // Check if signature-based auth is needed
57
+ let requiresSignature = false;
58
+ let signatureScheme;
59
+ for (const mapper of mappers) {
60
+ // Skip non-security parameters
61
+ if (!mapper.security) {
62
+ continue;
63
+ }
64
+ // Check for signature-based auth
65
+ if (this.isSignatureBasedAuth(mapper.security)) {
66
+ requiresSignature = true;
67
+ signatureScheme = mapper.security.scheme;
68
+ // Signature will be added later by signRequest()
69
+ continue;
70
+ }
71
+ // Try to resolve the auth value
72
+ const authValue = await this.resolveAuthValue(mapper.security, context);
73
+ if (!authValue) {
74
+ // Auth value not available - skip this security requirement
75
+ // Framework may want to throw an error or log a warning
76
+ continue;
77
+ }
78
+ // Apply to the correct location
79
+ const headerName = mapper.key;
80
+ if (mapper.type === 'header') {
81
+ resolved.headers[headerName] = authValue;
82
+ }
83
+ else if (mapper.type === 'query') {
84
+ resolved.query[headerName] = authValue;
85
+ }
86
+ else if (mapper.type === 'cookie') {
87
+ resolved.cookies[headerName] = authValue;
88
+ }
89
+ }
90
+ // Add context cookies if available
91
+ if (context.cookies) {
92
+ resolved.cookies = { ...resolved.cookies, ...context.cookies };
93
+ }
94
+ // Add signature metadata if needed
95
+ if (requiresSignature) {
96
+ resolved.requiresSignature = true;
97
+ resolved.signatureInfo = {
98
+ scheme: signatureScheme || 'unknown',
99
+ };
100
+ }
101
+ return resolved;
102
+ }
103
+ /**
104
+ * Check if security scheme requires request signing
105
+ */
106
+ isSignatureBasedAuth(security) {
107
+ // Check for schemes that typically require signing
108
+ const signatureSchemes = ['aws4', 'hmac', 'signature', 'hawk', 'custom-signature'];
109
+ return signatureSchemes.some(scheme => security.scheme.toLowerCase().includes(scheme));
110
+ }
111
+ /**
112
+ * Resolve the actual auth value based on security type
113
+ */
114
+ async resolveAuthValue(security, context) {
115
+ // Try custom resolver first
116
+ if (context.customResolver) {
117
+ const customValue = await context.customResolver(security);
118
+ if (customValue !== undefined) {
119
+ return customValue;
120
+ }
121
+ }
122
+ // Handle standard security types
123
+ if (security.type === 'http') {
124
+ return this.resolveHttpAuth(security, context);
125
+ }
126
+ else if (security.type === 'apiKey') {
127
+ return this.resolveApiKey(security, context);
128
+ }
129
+ else if (security.type === 'oauth2' || security.type === 'openIdConnect') {
130
+ return this.resolveOAuth2(security, context);
131
+ }
132
+ return undefined;
133
+ }
134
+ /**
135
+ * Resolve HTTP authentication (bearer, basic, digest, etc.)
136
+ */
137
+ resolveHttpAuth(security, context) {
138
+ const scheme = security.httpScheme?.toLowerCase() || 'bearer';
139
+ switch (scheme) {
140
+ case 'bearer':
141
+ return this.resolveBearerAuth(context);
142
+ case 'basic':
143
+ return this.resolveBasicAuth(context);
144
+ case 'digest':
145
+ return this.resolveDigestAuth(context);
146
+ case 'hoba':
147
+ case 'mutual':
148
+ case 'negotiate':
149
+ case 'vapid':
150
+ case 'scram':
151
+ // These schemes typically require custom implementation
152
+ // Try custom headers or signature generator
153
+ return this.resolveCustomHttpScheme(scheme, security, context);
154
+ default:
155
+ // Unknown scheme - try custom resolver
156
+ return undefined;
157
+ }
158
+ }
159
+ /**
160
+ * Resolve Bearer token authentication
161
+ */
162
+ resolveBearerAuth(context) {
163
+ const token = context.jwt;
164
+ if (!token)
165
+ return undefined;
166
+ return `Bearer ${token}`;
167
+ }
168
+ /**
169
+ * Resolve Basic authentication
170
+ */
171
+ resolveBasicAuth(context) {
172
+ const credentials = context.basic;
173
+ if (!credentials)
174
+ return undefined;
175
+ return `Basic ${credentials}`;
176
+ }
177
+ /**
178
+ * Resolve Digest authentication
179
+ */
180
+ resolveDigestAuth(context) {
181
+ const digest = context.digest;
182
+ if (!digest)
183
+ return undefined;
184
+ // Build digest auth header
185
+ const parts = [
186
+ `username="${digest.username}"`,
187
+ digest.realm ? `realm="${digest.realm}"` : '',
188
+ digest.nonce ? `nonce="${digest.nonce}"` : '',
189
+ digest.uri ? `uri="${digest.uri}"` : '',
190
+ digest.response ? `response="${digest.response}"` : '',
191
+ digest.opaque ? `opaque="${digest.opaque}"` : '',
192
+ digest.qop ? `qop=${digest.qop}` : '',
193
+ digest.nc ? `nc=${digest.nc}` : '',
194
+ digest.cnonce ? `cnonce="${digest.cnonce}"` : '',
195
+ ].filter(Boolean);
196
+ return `Digest ${parts.join(', ')}`;
197
+ }
198
+ /**
199
+ * Resolve custom HTTP authentication schemes
200
+ */
201
+ resolveCustomHttpScheme(scheme, security, context) {
202
+ // Try custom headers first
203
+ const headerKey = security.apiKeyName || `X-${scheme.toUpperCase()}`;
204
+ if (context.customHeaders?.[headerKey]) {
205
+ return context.customHeaders[headerKey];
206
+ }
207
+ // Unknown scheme
208
+ return undefined;
209
+ }
210
+ /**
211
+ * Resolve API key authentication
212
+ */
213
+ resolveApiKey(security, context) {
214
+ // Try named API keys first (for multiple keys)
215
+ if (context.apiKeys && security.apiKeyName) {
216
+ const key = context.apiKeys[security.apiKeyName];
217
+ if (key)
218
+ return key;
219
+ }
220
+ // Try custom headers (for proprietary auth headers like X-Custom-Auth)
221
+ if (context.customHeaders && security.apiKeyName) {
222
+ const header = context.customHeaders[security.apiKeyName];
223
+ if (header)
224
+ return header;
225
+ }
226
+ // Fall back to single apiKey (backward compatibility)
227
+ return context.apiKey;
228
+ }
229
+ /**
230
+ * Resolve OAuth2/OpenID Connect authentication
231
+ */
232
+ resolveOAuth2(security, context) {
233
+ const token = context.oauth2Token;
234
+ if (!token)
235
+ return undefined;
236
+ // OAuth2 tokens are typically formatted as "Bearer {token}"
237
+ return `Bearer ${token}`;
238
+ }
239
+ /**
240
+ * Check if any security requirements are missing from context
241
+ *
242
+ * @param mappers - Parameter mappers from the tool definition
243
+ * @param context - Security context with auth values
244
+ * @returns Array of missing security scheme names
245
+ */
246
+ async checkMissingSecurity(mappers, context) {
247
+ const missing = [];
248
+ for (const mapper of mappers) {
249
+ if (!mapper.security)
250
+ continue;
251
+ const authValue = await this.resolveAuthValue(mapper.security, context);
252
+ if (!authValue) {
253
+ missing.push(mapper.security.scheme);
254
+ }
255
+ }
256
+ return missing;
257
+ }
258
+ /**
259
+ * Sign a request for signature-based authentication
260
+ *
261
+ * Use this when resolved.requiresSignature is true.
262
+ * This method will call the signatureGenerator from context to sign the request.
263
+ *
264
+ * @param mappers - Parameter mappers from the tool definition
265
+ * @param signatureData - Request data to sign
266
+ * @param context - Security context with signature generator
267
+ * @returns Headers with signature added
268
+ *
269
+ * @example
270
+ * ```typescript
271
+ * const resolved = resolver.resolve(tool.mapper, context);
272
+ * if (resolved.requiresSignature) {
273
+ * const signedHeaders = await resolver.signRequest(
274
+ * tool.mapper,
275
+ * { method: 'GET', url: 'https://api.example.com/data', headers: resolved.headers },
276
+ * context
277
+ * );
278
+ * // Use signedHeaders in request
279
+ * }
280
+ * ```
281
+ */
282
+ async signRequest(mappers, signatureData, context) {
283
+ const headers = { ...signatureData.headers };
284
+ if (!context.signatureGenerator) {
285
+ throw new Error('Signature-based auth required but no signatureGenerator provided');
286
+ }
287
+ for (const mapper of mappers) {
288
+ if (!mapper.security || !this.isSignatureBasedAuth(mapper.security)) {
289
+ continue;
290
+ }
291
+ // Call signature generator
292
+ const signature = await context.signatureGenerator(signatureData, mapper.security);
293
+ // Add signature to appropriate location
294
+ if (mapper.type === 'header') {
295
+ headers[mapper.key] = signature;
296
+ }
297
+ // Note: Query/cookie signatures would be handled differently
298
+ }
299
+ return headers;
300
+ }
301
+ }
302
+ exports.SecurityResolver = SecurityResolver;
303
+ /**
304
+ * Create a basic security context from common auth sources
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * const context = createSecurityContext({
309
+ * jwt: process.env.JWT_TOKEN,
310
+ * apiKey: process.env.API_KEY
311
+ * });
312
+ * ```
313
+ */
314
+ function createSecurityContext(auth) {
315
+ return {
316
+ ...auth,
317
+ jwt: auth.jwt,
318
+ basic: auth.basic,
319
+ apiKey: auth.apiKey,
320
+ oauth2Token: auth.oauth2Token,
321
+ customResolver: auth.customResolver,
322
+ };
323
+ }
324
+ //# sourceMappingURL=security-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-resolver.js","sourceRoot":"","sources":["../../src/security-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ParameterMapper, SecurityParameterInfo } from './types';\n\n/**\n * Context for resolving security parameters\n * Frameworks should implement this interface based on their auth system\n */\nexport interface SecurityContext {\n /**\n * JWT/Bearer token\n */\n jwt?: string;\n\n /**\n * Basic auth credentials (base64 encoded \"username:password\")\n */\n basic?: string;\n\n /**\n * Digest auth credentials\n * Object with username, password, realm, nonce, etc.\n */\n digest?: DigestAuthCredentials;\n\n /**\n * API key (single key for backward compatibility)\n */\n apiKey?: string;\n\n /**\n * Multiple API keys by name\n * Use this when API requires different keys for different purposes\n * @example { 'X-API-Key': 'key1', 'X-Client-Id': 'client123' }\n */\n apiKeys?: Record<string, string>;\n\n /**\n * OAuth2 access token\n */\n oauth2Token?: string;\n\n /**\n * Client certificate for mutual TLS (mTLS)\n */\n clientCertificate?: ClientCertificate;\n\n /**\n * Private key for signature-based auth (HMAC, AWS Signature V4, etc.)\n */\n privateKey?: string;\n\n /**\n * Public key (if needed for verification)\n */\n publicKey?: string;\n\n /**\n * HMAC secret for HMAC-based authentication\n */\n hmacSecret?: string;\n\n /**\n * AWS credentials for AWS Signature V4\n */\n awsCredentials?: AWSCredentials;\n\n /**\n * Custom headers for proprietary authentication\n * @example { 'X-Custom-Auth': 'custom-value' }\n */\n customHeaders?: Record<string, string>;\n\n /**\n * Session cookies\n */\n cookies?: Record<string, string>;\n\n /**\n * Custom resolver for framework-specific auth\n * @param security - Security parameter info from mapper\n * @returns The auth value to use, or undefined if not available\n */\n customResolver?: (security: SecurityParameterInfo) => string | Promise<string | undefined>;\n\n /**\n * Signature generator for signature-based auth\n * @param data - Data to sign (typically the request)\n * @param security - Security parameter info\n * @returns The signature or signed value\n */\n signatureGenerator?: (data: SignatureData, security: SecurityParameterInfo) => string | Promise<string>;\n}\n\n/**\n * Digest authentication credentials\n */\nexport interface DigestAuthCredentials {\n username: string;\n password: string;\n realm?: string;\n nonce?: string;\n uri?: string;\n qop?: string;\n nc?: string;\n cnonce?: string;\n response?: string;\n opaque?: string;\n}\n\n/**\n * Client certificate for mTLS\n */\nexport interface ClientCertificate {\n /**\n * Certificate in PEM format\n */\n cert: string;\n\n /**\n * Private key in PEM format\n */\n key: string;\n\n /**\n * Passphrase for encrypted key\n */\n passphrase?: string;\n\n /**\n * CA certificates\n */\n ca?: string | string[];\n}\n\n/**\n * AWS credentials for Signature V4\n */\nexport interface AWSCredentials {\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken?: string;\n region?: string;\n service?: string;\n}\n\n/**\n * Data to be signed for signature-based auth\n */\nexport interface SignatureData {\n method: string;\n url: string;\n headers: Record<string, string>;\n body?: string;\n timestamp?: number;\n}\n\n/**\n * Resolved security parameters ready to be added to HTTP request\n */\nexport interface ResolvedSecurity {\n /**\n * Headers to add to the request\n */\n headers: Record<string, string>;\n\n /**\n * Query parameters to add to the request\n */\n query: Record<string, string>;\n\n /**\n * Cookie values to add to the request\n */\n cookies: Record<string, string>;\n\n /**\n * Client certificate for mTLS (if applicable)\n */\n clientCertificate?: ClientCertificate;\n\n /**\n * Whether signature-based auth is required\n * If true, you need to call signRequest() before sending\n */\n requiresSignature?: boolean;\n\n /**\n * Signature metadata (if signature-based auth is used)\n */\n signatureInfo?: {\n scheme: string;\n algorithm?: string;\n };\n}\n\n/**\n * Security resolver that maps OpenAPI security requirements to actual auth values\n *\n * This helper handles security parameters from any OpenAPI spec, regardless of\n * custom naming (BearerAuth, JWT, Authorization, etc.). It uses the mapper's\n * security metadata to determine the auth type and format.\n *\n * @example\n * ```typescript\n * // In FrontMCP\n * const resolver = new SecurityResolver();\n * const resolved = resolver.resolve(tool.mapper, {\n * jwt: context.authInfo.jwt,\n * apiKey: process.env.API_KEY\n * });\n *\n * // Use resolved.headers in HTTP request\n * fetch(url, { headers: { ...resolved.headers, ...otherHeaders } });\n * ```\n *\n * @example\n * ```typescript\n * // Custom resolver for framework-specific auth\n * const resolved = resolver.resolve(tool.mapper, {\n * customResolver: (security) => {\n * if (security.type === 'http' && security.httpScheme === 'bearer') {\n * return myFramework.getAuthToken();\n * }\n * return undefined;\n * }\n * });\n * ```\n */\nexport class SecurityResolver {\n /**\n * Resolve security parameters from mapper entries\n *\n * @param mappers - Parameter mappers from the tool definition\n * @param context - Security context with auth values or custom resolver\n * @returns Resolved headers, query params, and cookies with auth applied\n */\n async resolve(mappers: ParameterMapper[], context: SecurityContext): Promise<ResolvedSecurity> {\n const resolved: ResolvedSecurity = {\n headers: {},\n query: {},\n cookies: {},\n };\n\n // Add client certificate if available (for mTLS)\n if (context.clientCertificate) {\n resolved.clientCertificate = context.clientCertificate;\n }\n\n // Check if signature-based auth is needed\n let requiresSignature = false;\n let signatureScheme: string | undefined;\n\n for (const mapper of mappers) {\n // Skip non-security parameters\n if (!mapper.security) {\n continue;\n }\n\n // Check for signature-based auth\n if (this.isSignatureBasedAuth(mapper.security)) {\n requiresSignature = true;\n signatureScheme = mapper.security.scheme;\n // Signature will be added later by signRequest()\n continue;\n }\n\n // Try to resolve the auth value\n const authValue = await this.resolveAuthValue(mapper.security, context);\n if (!authValue) {\n // Auth value not available - skip this security requirement\n // Framework may want to throw an error or log a warning\n continue;\n }\n\n // Apply to the correct location\n const headerName = mapper.key;\n\n if (mapper.type === 'header') {\n resolved.headers[headerName] = authValue;\n } else if (mapper.type === 'query') {\n resolved.query[headerName] = authValue;\n } else if (mapper.type === 'cookie') {\n resolved.cookies[headerName] = authValue;\n }\n }\n\n // Add context cookies if available\n if (context.cookies) {\n resolved.cookies = { ...resolved.cookies, ...context.cookies };\n }\n\n // Add signature metadata if needed\n if (requiresSignature) {\n resolved.requiresSignature = true;\n resolved.signatureInfo = {\n scheme: signatureScheme || 'unknown',\n };\n }\n\n return resolved;\n }\n\n /**\n * Check if security scheme requires request signing\n */\n private isSignatureBasedAuth(security: SecurityParameterInfo): boolean {\n // Check for schemes that typically require signing\n const signatureSchemes = ['aws4', 'hmac', 'signature', 'hawk', 'custom-signature'];\n return signatureSchemes.some(scheme =>\n security.scheme.toLowerCase().includes(scheme)\n );\n }\n\n /**\n * Resolve the actual auth value based on security type\n */\n private async resolveAuthValue(\n security: SecurityParameterInfo,\n context: SecurityContext\n ): Promise<string | undefined> {\n // Try custom resolver first\n if (context.customResolver) {\n const customValue = await context.customResolver(security);\n if (customValue !== undefined) {\n return customValue;\n }\n }\n\n // Handle standard security types\n if (security.type === 'http') {\n return this.resolveHttpAuth(security, context);\n } else if (security.type === 'apiKey') {\n return this.resolveApiKey(security, context);\n } else if (security.type === 'oauth2' || security.type === 'openIdConnect') {\n return this.resolveOAuth2(security, context);\n }\n\n return undefined;\n }\n\n /**\n * Resolve HTTP authentication (bearer, basic, digest, etc.)\n */\n private resolveHttpAuth(\n security: SecurityParameterInfo,\n context: SecurityContext\n ): string | undefined {\n const scheme = security.httpScheme?.toLowerCase() || 'bearer';\n\n switch (scheme) {\n case 'bearer':\n return this.resolveBearerAuth(context);\n\n case 'basic':\n return this.resolveBasicAuth(context);\n\n case 'digest':\n return this.resolveDigestAuth(context);\n\n case 'hoba':\n case 'mutual':\n case 'negotiate':\n case 'vapid':\n case 'scram':\n // These schemes typically require custom implementation\n // Try custom headers or signature generator\n return this.resolveCustomHttpScheme(scheme, security, context);\n\n default:\n // Unknown scheme - try custom resolver\n return undefined;\n }\n }\n\n /**\n * Resolve Bearer token authentication\n */\n private resolveBearerAuth(context: SecurityContext): string | undefined {\n const token = context.jwt;\n if (!token) return undefined;\n return `Bearer ${token}`;\n }\n\n /**\n * Resolve Basic authentication\n */\n private resolveBasicAuth(context: SecurityContext): string | undefined {\n const credentials = context.basic;\n if (!credentials) return undefined;\n return `Basic ${credentials}`;\n }\n\n /**\n * Resolve Digest authentication\n */\n private resolveDigestAuth(context: SecurityContext): string | undefined {\n const digest = context.digest;\n if (!digest) return undefined;\n\n // Build digest auth header\n const parts: string[] = [\n `username=\"${digest.username}\"`,\n digest.realm ? `realm=\"${digest.realm}\"` : '',\n digest.nonce ? `nonce=\"${digest.nonce}\"` : '',\n digest.uri ? `uri=\"${digest.uri}\"` : '',\n digest.response ? `response=\"${digest.response}\"` : '',\n digest.opaque ? `opaque=\"${digest.opaque}\"` : '',\n digest.qop ? `qop=${digest.qop}` : '',\n digest.nc ? `nc=${digest.nc}` : '',\n digest.cnonce ? `cnonce=\"${digest.cnonce}\"` : '',\n ].filter(Boolean);\n\n return `Digest ${parts.join(', ')}`;\n }\n\n /**\n * Resolve custom HTTP authentication schemes\n */\n private resolveCustomHttpScheme(\n scheme: string,\n security: SecurityParameterInfo,\n context: SecurityContext\n ): string | undefined {\n // Try custom headers first\n const headerKey = security.apiKeyName || `X-${scheme.toUpperCase()}`;\n if (context.customHeaders?.[headerKey]) {\n return context.customHeaders[headerKey];\n }\n\n // Unknown scheme\n return undefined;\n }\n\n /**\n * Resolve API key authentication\n */\n private resolveApiKey(\n security: SecurityParameterInfo,\n context: SecurityContext\n ): string | undefined {\n // Try named API keys first (for multiple keys)\n if (context.apiKeys && security.apiKeyName) {\n const key = context.apiKeys[security.apiKeyName];\n if (key) return key;\n }\n\n // Try custom headers (for proprietary auth headers like X-Custom-Auth)\n if (context.customHeaders && security.apiKeyName) {\n const header = context.customHeaders[security.apiKeyName];\n if (header) return header;\n }\n\n // Fall back to single apiKey (backward compatibility)\n return context.apiKey;\n }\n\n /**\n * Resolve OAuth2/OpenID Connect authentication\n */\n private resolveOAuth2(\n security: SecurityParameterInfo,\n context: SecurityContext\n ): string | undefined {\n const token = context.oauth2Token;\n if (!token) return undefined;\n\n // OAuth2 tokens are typically formatted as \"Bearer {token}\"\n return `Bearer ${token}`;\n }\n\n /**\n * Check if any security requirements are missing from context\n *\n * @param mappers - Parameter mappers from the tool definition\n * @param context - Security context with auth values\n * @returns Array of missing security scheme names\n */\n async checkMissingSecurity(\n mappers: ParameterMapper[],\n context: SecurityContext\n ): Promise<string[]> {\n const missing: string[] = [];\n\n for (const mapper of mappers) {\n if (!mapper.security) continue;\n\n const authValue = await this.resolveAuthValue(mapper.security, context);\n if (!authValue) {\n missing.push(mapper.security.scheme);\n }\n }\n\n return missing;\n }\n\n /**\n * Sign a request for signature-based authentication\n *\n * Use this when resolved.requiresSignature is true.\n * This method will call the signatureGenerator from context to sign the request.\n *\n * @param mappers - Parameter mappers from the tool definition\n * @param signatureData - Request data to sign\n * @param context - Security context with signature generator\n * @returns Headers with signature added\n *\n * @example\n * ```typescript\n * const resolved = resolver.resolve(tool.mapper, context);\n * if (resolved.requiresSignature) {\n * const signedHeaders = await resolver.signRequest(\n * tool.mapper,\n * { method: 'GET', url: 'https://api.example.com/data', headers: resolved.headers },\n * context\n * );\n * // Use signedHeaders in request\n * }\n * ```\n */\n async signRequest(\n mappers: ParameterMapper[],\n signatureData: SignatureData,\n context: SecurityContext\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = { ...signatureData.headers };\n\n if (!context.signatureGenerator) {\n throw new Error('Signature-based auth required but no signatureGenerator provided');\n }\n\n for (const mapper of mappers) {\n if (!mapper.security || !this.isSignatureBasedAuth(mapper.security)) {\n continue;\n }\n\n // Call signature generator\n const signature = await context.signatureGenerator(signatureData, mapper.security);\n\n // Add signature to appropriate location\n if (mapper.type === 'header') {\n headers[mapper.key] = signature;\n }\n // Note: Query/cookie signatures would be handled differently\n }\n\n return headers;\n }\n}\n\n/**\n * Create a basic security context from common auth sources\n *\n * @example\n * ```typescript\n * const context = createSecurityContext({\n * jwt: process.env.JWT_TOKEN,\n * apiKey: process.env.API_KEY\n * });\n * ```\n */\nexport function createSecurityContext(\n auth: Partial<SecurityContext>\n): SecurityContext {\n return {\n ...auth,\n jwt: auth.jwt,\n basic: auth.basic,\n apiKey: auth.apiKey,\n oauth2Token: auth.oauth2Token,\n customResolver: auth.customResolver,\n };\n}\n"]}