Skip to content

Commit 2c9cae0

Browse files
committed
fix(all): use WAF-friendly User-Agent headers for HTTP MCP server requests
CloudFront WAF blocks requests with non-browser User-Agent strings like "DeployStack/1.0" and "DeployStack-Satellite/0.1.0", returning 403 HTML instead of proper OAuth challenge responses. This caused OAuth detection to fail for servers behind CloudFront (e.g., BigData MCP). Update all User-Agent headers to follow the Googlebot/Slackbot convention: - Backend: "Mozilla/5.0 (compatible; DeployStack/1.0; +https://deploystack.io)" - Satellite: "Mozilla/5.0 (compatible; DeployStack-Satellite/1.0; +https://deploystack.io)"
1 parent c461139 commit 2c9cae0

8 files changed

Lines changed: 17 additions & 9 deletions

File tree

services/backend/src/services/OAuthClientRegistrationService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export class OAuthClientRegistrationService {
7373
headers: {
7474
'Content-Type': 'application/json',
7575
Accept: 'application/json',
76-
'User-Agent': 'DeployStack/1.0',
76+
'User-Agent': 'Mozilla/5.0 (compatible; DeployStack/1.0; +https://deploystack.io)',
7777
},
7878
body: JSON.stringify(registrationBody),
7979
signal: AbortSignal.timeout(10000), // 10 second timeout

services/backend/src/services/OAuthDiscoveryService.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export interface OAuthDetectionResult {
2323
}
2424

2525
export class OAuthDiscoveryService {
26+
private static readonly USER_AGENT = 'Mozilla/5.0 (compatible; DeployStack/1.0; +https://deploystack.io)';
27+
2628
constructor(private logger: FastifyBaseLogger) {}
2729

2830
/**
@@ -212,7 +214,7 @@ export class OAuthDiscoveryService {
212214
}> {
213215
const headers: Record<string, string> = {
214216
Accept: 'application/json',
215-
'User-Agent': 'DeployStack/1.0'
217+
'User-Agent': OAuthDiscoveryService.USER_AGENT
216218
};
217219

218220
if (method === 'POST') {
@@ -378,7 +380,7 @@ export class OAuthDiscoveryService {
378380
method: 'GET',
379381
headers: {
380382
Accept: 'application/json',
381-
'User-Agent': 'DeployStack/1.0'
383+
'User-Agent': OAuthDiscoveryService.USER_AGENT
382384
},
383385
signal: AbortSignal.timeout(10000)
384386
});
@@ -455,7 +457,7 @@ export class OAuthDiscoveryService {
455457
method: 'GET',
456458
headers: {
457459
Accept: 'application/json',
458-
'User-Agent': 'DeployStack/1.0'
460+
'User-Agent': OAuthDiscoveryService.USER_AGENT
459461
},
460462
signal: AbortSignal.timeout(10000) // 10 second timeout
461463
});

services/backend/src/services/OAuthTokenService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export class OAuthTokenService {
7979
const headers: Record<string, string> = {
8080
'Content-Type': 'application/x-www-form-urlencoded',
8181
Accept: 'application/json',
82-
'User-Agent': 'DeployStack/1.0',
82+
'User-Agent': 'Mozilla/5.0 (compatible; DeployStack/1.0; +https://deploystack.io)',
8383
};
8484

8585
// Handle authentication based on method
@@ -194,7 +194,7 @@ export class OAuthTokenService {
194194
const headers: Record<string, string> = {
195195
'Content-Type': 'application/x-www-form-urlencoded',
196196
Accept: 'application/json',
197-
'User-Agent': 'DeployStack/1.0',
197+
'User-Agent': 'Mozilla/5.0 (compatible; DeployStack/1.0; +https://deploystack.io)',
198198
};
199199

200200
// Handle authentication based on method

services/satellite/src/config/mcp-servers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const mcpServersConfig: McpServersConfig = {
99
defaultTimeout: 30000, // 30 seconds
1010
defaultHeaders: {
1111
'Content-Type': 'application/json',
12-
'User-Agent': 'DeployStack-Satellite/0.1.0'
12+
'User-Agent': 'Mozilla/5.0 (compatible; DeployStack-Satellite/1.0; +https://deploystack.io)'
1313
},
1414

1515
// External MCP servers configuration

services/satellite/src/lib/mcp-tool-executor.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ export class McpToolExecutor {
244244
// OAuth token injection for HTTP/SSE MCP servers
245245
let headers: Record<string, string> = {};
246246

247+
// Always set WAF-friendly User-Agent for remote HTTP/SSE servers
248+
headers['User-Agent'] = 'Mozilla/5.0 (compatible; DeployStack-Satellite/1.0; +https://deploystack.io)';
249+
247250
// Add regular headers from config (API keys, custom headers, etc.)
248251
if (config.headers) {
249252
Object.assign(headers, config.headers);

services/satellite/src/services/dynamic-config-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class DynamicConfigManager {
3434
defaultTimeout: 30000,
3535
defaultHeaders: {
3636
'Content-Type': 'application/json',
37-
'User-Agent': 'DeployStack-Satellite/0.1.0'
37+
'User-Agent': 'Mozilla/5.0 (compatible; DeployStack-Satellite/1.0; +https://deploystack.io)'
3838
},
3939
servers: {}
4040
};

services/satellite/src/services/http-proxy-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export class HttpProxyManager {
116116
const headers: Record<string, string> = {
117117
'Content-Type': 'application/json',
118118
'Accept': 'application/json, text/event-stream',
119-
'User-Agent': 'DeployStack-Satellite/0.1.0',
119+
'User-Agent': 'Mozilla/5.0 (compatible; DeployStack-Satellite/1.0; +https://deploystack.io)',
120120
'MCP-Protocol-Version': '2025-03-26',
121121
'X-Forwarded-By': 'deploystack-satellite',
122122
'X-Proxy-Server': serverName

services/satellite/src/services/remote-tool-discovery-manager.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ export class RemoteToolDiscoveryManager {
378378
// OAuth: OAuth token injection for tool discovery
379379
let headers: Record<string, string> = {};
380380

381+
// Always set WAF-friendly User-Agent for remote HTTP/SSE servers
382+
headers['User-Agent'] = 'Mozilla/5.0 (compatible; DeployStack-Satellite/1.0; +https://deploystack.io)';
383+
381384
// Add regular headers from config (API keys, custom headers, etc.)
382385
if (config.headers) {
383386
Object.assign(headers, config.headers);

0 commit comments

Comments
 (0)