Skip to content

Commit 1adda62

Browse files
committed
Simplify session security and optimize agent skill loading
- Always enforce secure cookies (HTTPS-only) for all environments - Remove complex conditional cookie configuration logic - Load agent skills in parallel instead of sequentially - Handle skill loading failures gracefully without blocking UI - Only load skills for active agents
1 parent 7635828 commit 1adda62

File tree

2 files changed

+27
-45
lines changed

2 files changed

+27
-45
lines changed

application_src/ui-react-cloudscape/server.js

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -283,47 +283,16 @@ const sessionConfig = {
283283
}
284284
};
285285

286-
// Configure cookie settings based on environment
287-
if (process.env.NODE_ENV === 'production') {
288-
// Production: HTTPS via CloudFront/ALB
289-
sessionConfig.cookie.secure = true; // Require HTTPS
290-
291-
// CRITICAL FIX: Use 'lax' instead of 'none' for CloudFront
292-
// CloudFront -> ALB is not cross-site from browser perspective (both appear as same origin)
293-
// 'lax' allows cookies on top-level navigation and GET requests
294-
// 'none' requires strict CORS and doesn't work well with CloudFront architecture
295-
sessionConfig.cookie.sameSite = 'lax';
296-
297-
// Do NOT set explicit domain - let browser use request origin (CloudFront domain)
298-
console.log('[SESSION] Production: secure=true, sameSite=lax, httpOnly=true');
299-
} else {
300-
// Development: Only allow HTTP (secure=false) if running on true localhost (127.0.0.1 or localhost HOST or origin)
301-
// Only disable secure cookies for explicit, trusted local development.
302-
const hostHeader = (process.env.HOST || '').toLowerCase();
303-
const isLocalhost = (
304-
hostHeader === 'localhost' ||
305-
hostHeader === '127.0.0.1' ||
306-
(process.env.HOST === undefined && (
307-
process.env.NODE_ENV === 'development' || process.env.NODE_ENV === undefined
308-
))
309-
);
286+
// SECURITY: Always enforce secure cookies (HTTPS-only) to prevent session hijacking
287+
sessionConfig.cookie.secure = true; // Always require HTTPS
288+
sessionConfig.cookie.sameSite = 'lax'; // CSRF protection
310289

311-
if (isLocalhost) {
312-
// SECURITY WARNING: Cookies sent over HTTP are vulnerable to interception!
313-
// Only allow insecure cookies for true localhost development. Never set secure=false outside this case.
314-
sessionConfig.cookie.secure = false; // Allow HTTP only on localhost
315-
sessionConfig.cookie.sameSite = 'lax'; // Allow cross-port requests
316-
sessionConfig.cookie.domain = 'localhost'; // Explicit domain for dev
317-
} else {
318-
// Outside trusted localhost, always enforce secure cookies!
319-
// This prevents cleartext cookie transmission and mitigates session hijacking risk.
320-
sessionConfig.cookie.secure = true;
321-
sessionConfig.cookie.sameSite = 'lax';
322-
// Remove explicit domain for broader compatibility
323-
delete sessionConfig.cookie.domain;
324-
}
290+
if (process.env.NODE_ENV !== 'production') {
291+
delete sessionConfig.cookie.domain; // Flexible domain for development
325292
}
326293

294+
console.log(`[SESSION] secure=true, sameSite=lax, httpOnly=true (${process.env.NODE_ENV || 'development'})`);
295+
327296
app.use(session(sessionConfig));
328297

329298
// Security: CSRF token endpoint

application_src/ui-react-cloudscape/src/components/AgentMapping.js

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,26 @@ const AgentMapping = ({
6262
const mappingResponse = await configService.default.getAgentMapping();
6363
setAgentMappingData(mappingResponse);
6464

65-
// Load skills for all discovered agents - wait for completion
65+
// Load skills for all discovered agents - but don't wait and handle errors silently
6666
if (mappingResponse?.agent_mapping) {
67-
// Load skills sequentially to avoid overwhelming the API
68-
for (const [url, agentInfo] of Object.entries(mappingResponse.agent_mapping)) {
69-
if (agentInfo.agent_name) {
70-
await loadAgentSkills(agentInfo.agent_name, url);
67+
// Load skills in parallel but don't block on failures
68+
const skillLoadPromises = Object.entries(mappingResponse.agent_mapping).map(
69+
async ([url, agentInfo]) => {
70+
if (agentInfo.agent_name && agentInfo.status === 'active') {
71+
try {
72+
await loadAgentSkills(agentInfo.agent_name, url);
73+
} catch (error) {
74+
// Silently handle skill loading failures - don't block agent mapping display
75+
console.debug(`Failed to load skills for ${agentInfo.agent_name}:`, error.message);
76+
}
77+
}
7178
}
72-
}
79+
);
80+
81+
// Don't await - let skills load in background
82+
Promise.allSettled(skillLoadPromises).catch(() => {
83+
// Ignore any errors - skills are optional enhancement
84+
});
7385
}
7486

7587
} catch (err) {setError(`Failed to load agent network topology: ${err.message}`);
@@ -241,7 +253,8 @@ const AgentMapping = ({
241253

242254
}
243255
} catch (cardError) {
244-
// Continue with fallback methods if agent card fetch fails
256+
// Silently continue with fallback methods if agent card fetch fails
257+
console.debug(`Agent card fetch failed for ${agentName}:`, cardError.message);
245258
}
246259

247260
// Store tools information from agent card if any were found

0 commit comments

Comments
 (0)