ieeeColors = ({
navy: "#2C3E50",
teal: "#16A085",
orange: "#E67E22",
gray: "#7F8C8D",
red: "#c0392b",
green: "#27ae60",
purple: "#6B2D5B",
blue: "#3498DB"
})
// Policy categories and options
policyOptions = ({
segmentation: [
{
id: "flat_network",
title: "No Segmentation (Flat Network)",
description: "All devices on single network - traditional approach",
security: 2,
usability: 10,
complexity: 1
},
{
id: "vlan_basic",
title: "Basic VLAN Segmentation",
description: "Separate VLANs for device types (IoT, users, servers)",
security: 5,
usability: 8,
complexity: 4
},
{
id: "microsegmentation",
title: "Microsegmentation",
description: "Segment by device function, trust level, and data sensitivity",
security: 9,
usability: 6,
complexity: 7
},
{
id: "zero_trust_segmentation",
title: "Zero-Trust Microsegmentation",
description: "Per-device/per-workload segmentation with dynamic policies",
security: 10,
usability: 5,
complexity: 9
}
],
identity: [
{
id: "no_auth",
title: "No Authentication",
description: "Trust all devices by default - no identity verification",
security: 1,
usability: 10,
complexity: 1
},
{
id: "basic_password",
title: "Basic Password Authentication",
description: "Simple username/password for device access",
security: 3,
usability: 7,
complexity: 2
},
{
id: "certificate_based",
title: "Certificate-Based Authentication",
description: "X.509 certificates for device identity",
security: 7,
usability: 6,
complexity: 6
},
{
id: "continuous_auth",
title: "Continuous Authentication",
description: "Verify identity on every transaction + behavioral analysis",
security: 10,
usability: 5,
complexity: 8
}
],
access: [
{
id: "implicit_trust",
title: "Implicit Trust",
description: "Once authenticated, full network access granted",
security: 2,
usability: 10,
complexity: 1
},
{
id: "role_based",
title: "Role-Based Access Control (RBAC)",
description: "Access based on device/user roles",
security: 6,
usability: 8,
complexity: 5
},
{
id: "attribute_based",
title: "Attribute-Based Access Control (ABAC)",
description: "Dynamic policies using context (location, time, device health)",
security: 8,
usability: 6,
complexity: 7
},
{
id: "least_privilege",
title: "Least Privilege + Just-In-Time",
description: "Minimal access, time-limited, request-based elevation",
security: 10,
usability: 4,
complexity: 9
}
],
verification: [
{
id: "trust_always",
title: "Trust Once, Always",
description: "Verify at initial connection only",
security: 2,
usability: 10,
complexity: 1
},
{
id: "periodic_reauth",
title: "Periodic Re-Authentication",
description: "Re-verify identity every few hours/days",
security: 5,
usability: 7,
complexity: 4
},
{
id: "per_request",
title: "Per-Request Verification",
description: "Verify every sensitive operation",
security: 8,
usability: 5,
complexity: 6
},
{
id: "continuous_trust_scoring",
title: "Continuous Trust Scoring",
description: "Real-time risk assessment, adaptive policy enforcement",
security: 10,
usability: 6,
complexity: 9
}
]
})
// Attack types that policies defend against
attackTypes = [
{ id: "lateral_movement", name: "Lateral Movement Attack", difficulty: "easy" },
{ id: "credential_theft", name: "Credential Theft", difficulty: "easy" },
{ id: "iot_botnet", name: "IoT Botnet Infection", difficulty: "medium" },
{ id: "insider_threat", name: "Insider Threat", difficulty: "medium" },
{ id: "supply_chain", name: "Supply Chain Compromise", difficulty: "hard" },
{ id: "zero_day", name: "Zero-Day Exploit", difficulty: "hard" }
]
// Game scenarios by difficulty
scenarios = ({
easy: [
{
id: 1,
title: "Smart Office Building",
description: "A 100-person office with smart lighting, HVAC sensors, access control badges, and employee laptops. Devices are from trusted vendors but run on shared network.",
networkInfo: {
devices: "150 IoT devices (sensors, actuators)",
users: "100 employees with laptops",
sensitivity: "Low (office automation, no PII)",
budget: "Medium",
compliance: "None required"
},
optimalPolicy: {
segmentation: ["vlan_basic", "microsegmentation"],
identity: ["certificate_based"],
access: ["role_based"],
verification: ["periodic_reauth", "per_request"]
},
attacks: ["lateral_movement", "credential_theft"],
hint: "Basic segmentation prevents compromised IoT device from accessing employee workstations. Certificate-based auth prevents rogue devices."
},
{
id: 2,
title: "Retail Store IoT",
description: "Retail store with 50 smart cameras, POS systems, inventory sensors, and customer WiFi. Payment data flows through network.",
networkInfo: {
devices: "80 devices (cameras, POS, sensors)",
users: "30 staff + guest WiFi",
sensitivity: "High (PCI-DSS payment data)",
budget: "Medium",
compliance: "PCI-DSS required"
},
optimalPolicy: {
segmentation: ["microsegmentation", "zero_trust_segmentation"],
identity: ["certificate_based"],
access: ["attribute_based", "least_privilege"],
verification: ["per_request"]
},
attacks: ["lateral_movement", "credential_theft", "iot_botnet"],
hint: "PCI-DSS requires network segmentation. Isolate payment systems from IoT devices completely."
},
{
id: 3,
title: "Manufacturing Floor",
description: "Factory with 200 industrial IoT sensors, PLCs, SCADA systems, and operator HMIs. Critical operational technology environment.",
networkInfo: {
devices: "250 OT devices (PLCs, sensors, HMIs)",
users: "50 operators and engineers",
sensitivity: "Critical (production downtime = $50k/hour)",
budget: "High",
compliance: "IEC 62443 recommended"
},
optimalPolicy: {
segmentation: ["microsegmentation", "zero_trust_segmentation"],
identity: ["certificate_based"],
access: ["role_based", "attribute_based"],
verification: ["per_request", "continuous_trust_scoring"]
},
attacks: ["lateral_movement", "insider_threat", "supply_chain"],
hint: "OT/IT convergence is risky. Microsegment by production zone. Air-gap critical safety systems."
},
{
id: 4,
title: "Smart Home Network",
description: "Residential network with 30 consumer IoT devices (cameras, smart speakers, thermostats, TVs) and family computers.",
networkInfo: {
devices: "30 consumer IoT devices",
users: "4 family members with laptops/phones",
sensitivity: "Medium (privacy, personal data)",
budget: "Low",
compliance: "None"
},
optimalPolicy: {
segmentation: ["vlan_basic"],
identity: ["basic_password", "certificate_based"],
access: ["role_based"],
verification: ["periodic_reauth"]
},
attacks: ["iot_botnet", "credential_theft"],
hint: "Consumer devices often have weak security. Isolate IoT VLAN from personal computers."
}
],
medium: [
{
id: 5,
title: "Hospital IoT Network",
description: "Hospital with 500 medical IoT devices (patient monitors, infusion pumps, imaging), EHR systems, and clinical staff workstations. HIPAA compliance required.",
networkInfo: {
devices: "500 medical IoT + 200 IT systems",
users: "300 clinical staff + 100 admin",
sensitivity: "Critical (PHI, life-safety devices)",
budget: "Very High",
compliance: "HIPAA required"
},
optimalPolicy: {
segmentation: ["zero_trust_segmentation"],
identity: ["certificate_based", "continuous_auth"],
access: ["least_privilege"],
verification: ["per_request", "continuous_trust_scoring"]
},
attacks: ["lateral_movement", "insider_threat", "credential_theft", "iot_botnet"],
hint: "HIPAA requires strict access controls and audit logs. Life-safety devices need highest protection."
},
{
id: 6,
title: "Smart City Infrastructure",
description: "City-wide IoT for traffic lights, parking sensors, environmental monitors, and surveillance cameras. Publicly accessible infrastructure.",
networkInfo: {
devices: "2000+ distributed sensors and actuators",
users: "50 municipal operators",
sensitivity: "High (public safety, privacy)",
budget: "High",
compliance: "NIST Cybersecurity Framework"
},
optimalPolicy: {
segmentation: ["microsegmentation", "zero_trust_segmentation"],
identity: ["certificate_based"],
access: ["attribute_based", "least_privilege"],
verification: ["per_request", "continuous_trust_scoring"]
},
attacks: ["lateral_movement", "iot_botnet", "supply_chain", "insider_threat"],
hint: "Geographically distributed = larger attack surface. Segment by city zone and function."
},
{
id: 7,
title: "University Campus IoT",
description: "Large university with building automation, research lab equipment, student IoT devices, and open WiFi. Mix of managed and BYOD.",
networkInfo: {
devices: "1000+ IoT + research equipment",
users: "5000 students/staff (BYOD)",
sensitivity: "Medium-High (research data, PII)",
budget: "Medium",
compliance: "FERPA for student data"
},
optimalPolicy: {
segmentation: ["microsegmentation"],
identity: ["certificate_based"],
access: ["attribute_based"],
verification: ["per_request"]
},
attacks: ["lateral_movement", "credential_theft", "insider_threat", "iot_botnet"],
hint: "BYOD and open WiFi complicate trust. Segment research networks strictly from student networks."
},
{
id: 8,
title: "Energy Grid SCADA",
description: "Electric utility with SCADA systems controlling substations, smart meters, and grid sensors. Critical infrastructure.",
networkInfo: {
devices: "500 SCADA devices + 50,000 smart meters",
users: "100 utility operators",
sensitivity: "Critical (national infrastructure)",
budget: "Very High",
compliance: "NERC CIP"
},
optimalPolicy: {
segmentation: ["zero_trust_segmentation"],
identity: ["certificate_based", "continuous_auth"],
access: ["least_privilege"],
verification: ["continuous_trust_scoring"]
},
attacks: ["lateral_movement", "supply_chain", "insider_threat", "zero_day"],
hint: "Critical infrastructure attracts nation-state actors. Air-gap critical systems, monitor all access."
}
],
hard: [
{
id: 9,
title: "Multi-Tenant Cloud IoT Platform",
description: "SaaS platform hosting IoT data for 200 customers. Shared infrastructure, strict isolation required, high-value target.",
networkInfo: {
devices: "10,000+ customer devices across tenants",
users: "500 customer admins + platform operators",
sensitivity: "Critical (multi-tenant data breach risk)",
budget: "Very High",
compliance: "SOC 2 Type II, ISO 27001"
},
optimalPolicy: {
segmentation: ["zero_trust_segmentation"],
identity: ["continuous_auth"],
access: ["least_privilege"],
verification: ["continuous_trust_scoring"]
},
attacks: ["lateral_movement", "insider_threat", "supply_chain", "credential_theft", "zero_day"],
hint: "Multi-tenancy = one breach affects many. Per-tenant microsegmentation, continuous monitoring critical."
},
{
id: 10,
title: "Autonomous Vehicle Fleet",
description: "Fleet of 100 self-driving delivery vehicles with real-time cloud connectivity, OTA updates, and remote monitoring.",
networkInfo: {
devices: "100 vehicles + edge gateways + cloud backend",
users: "20 fleet operators + remote support",
sensitivity: "Critical (safety, liability)",
budget: "Very High",
compliance: "ISO 26262 (functional safety)"
},
optimalPolicy: {
segmentation: ["zero_trust_segmentation"],
identity: ["continuous_auth"],
access: ["least_privilege"],
verification: ["continuous_trust_scoring"]
},
attacks: ["supply_chain", "zero_day", "insider_threat"],
hint: "Vehicles are mobile attack surface. Secure OTA pipeline, verify every command before execution."
},
{
id: 11,
title: "Defense Contractor IoT",
description: "Classified facility with IoT for physical security, environmental monitoring, and research equipment. Nation-state threat actors.",
networkInfo: {
devices: "300 IoT devices (physical security, environmental)",
users: "200 cleared personnel",
sensitivity: "Top Secret (national security)",
budget: "Unlimited",
compliance: "NIST SP 800-53, CMMC Level 5"
},
optimalPolicy: {
segmentation: ["zero_trust_segmentation"],
identity: ["continuous_auth"],
access: ["least_privilege"],
verification: ["continuous_trust_scoring"]
},
attacks: ["supply_chain", "zero_day", "insider_threat", "lateral_movement"],
hint: "Assume adversary has insider access. Hardware root of trust, air-gapped networks, continuous audit."
},
{
id: 12,
title: "Financial Trading Floor IoT",
description: "High-frequency trading firm with IoT for building automation, badge access, and environment control. Zero downtime tolerance.",
networkInfo: {
devices: "200 IoT devices + trading systems",
users: "50 traders + IT staff",
sensitivity: "Critical (financial + intellectual property)",
budget: "Very High",
compliance: "SOX, PCI-DSS, SEC regulations"
},
optimalPolicy: {
segmentation: ["zero_trust_segmentation"],
identity: ["continuous_auth"],
access: ["least_privilege"],
verification: ["continuous_trust_scoring"]
},
attacks: ["insider_threat", "supply_chain", "zero_day", "lateral_movement"],
hint: "Trading algorithms worth millions. Strict air-gap between IoT and trading networks. Monitor for data exfiltration."
}
]
})
// ----------------------------------------------------------------------------
// SECTION 2: GAME STATE MANAGEMENT
// ----------------------------------------------------------------------------
mutable gameState = ({
difficulty: "easy",
currentScenarioIndex: 0,
score: 0,
answered: false,
selectedPolicies: {
segmentation: null,
identity: null,
access: null,
verification: null
},
securityScore: 0,
usabilityScore: 0,
complexityScore: 0,
attackResults: [],
totalScenarios: 0,
gameComplete: false,
showFeedback: false,
scenarioScores: []
})
// Get current scenario
currentScenario = scenarios[gameState.difficulty][gameState.currentScenarioIndex]
// Calculate total scenarios for current difficulty
totalScenarios = scenarios[gameState.difficulty].length
// ----------------------------------------------------------------------------
// SECTION 3: GAME LOGIC FUNCTIONS
// ----------------------------------------------------------------------------
function selectPolicy(category, optionId) {
if (gameState.answered) return;
const newPolicies = { ...gameState.selectedPolicies };
newPolicies[category] = optionId;
mutable gameState = { ...gameState, selectedPolicies: newPolicies };
}
function calculateScores() {
const selected = gameState.selectedPolicies;
let security = 0, usability = 0, complexity = 0;
Object.entries(selected).forEach(([category, optionId]) => {
if (!optionId) return;
const option = policyOptions[category].find(o => o.id === optionId);
if (option) {
security += option.security;
usability += option.usability;
complexity += option.complexity;
}
});
// Normalize to 0-100 scale
return {
security: Math.round((security / 40) * 100),
usability: Math.round((usability / 40) * 100),
complexity: Math.round((complexity / 36) * 100)
};
}
function simulateAttacks() {
const selected = gameState.selectedPolicies;
const scenario = currentScenario;
const scores = calculateScores();
const results = scenario.attacks.map(attackId => {
const attack = attackTypes.find(a => a.id === attackId);
// Attack succeeds if security score below threshold
let threshold = 50; // base
if (attack.difficulty === "medium") threshold = 60;
if (attack.difficulty === "hard") threshold = 75;
// Bonus points for optimal policies
const optimalMatch = Object.entries(selected).filter(([cat, val]) =>
scenario.optimalPolicy[cat]?.includes(val)
).length;
const adjustedScore = scores.security + (optimalMatch * 5);
const blocked = adjustedScore >= threshold;
return {
attackId,
attackName: attack.name,
blocked,
threshold
};
});
return results;
}
function calculateScenarioScore() {
const scores = calculateScores();
const attackResults = simulateAttacks();
const scenario = currentScenario;
// Score components
const attacksBlocked = attackResults.filter(r => r.blocked).length;
const totalAttacks = attackResults.length;
const defenseRate = attacksBlocked / totalAttacks;
// Optimal policy match bonus
const selected = gameState.selectedPolicies;
const optimalMatches = Object.entries(selected).filter(([cat, val]) =>
scenario.optimalPolicy[cat]?.includes(val)
).length;
const optimalBonus = (optimalMatches / 4) * 20;
// Balance penalty (security vs usability tradeoff)
const securityUsabilityBalance = 100 - Math.abs(scores.security - scores.usability);
const balanceBonus = securityUsabilityBalance * 0.2;
// Final score calculation
const baseScore = (defenseRate * 50) + optimalBonus + balanceBonus;
const difficultyMultiplier = gameState.difficulty === "easy" ? 1 : gameState.difficulty === "medium" ? 1.5 : 2;
return Math.round(baseScore * difficultyMultiplier);
}
function submitPolicy() {
if (gameState.answered) return;
// Check if all categories selected
const selected = gameState.selectedPolicies;
if (Object.values(selected).some(v => !v)) {
alert("Please select a policy for all four categories before submitting.");
return;
}
const scores = calculateScores();
const attackResults = simulateAttacks();
const scenarioScore = calculateScenarioScore();
const newScores = [...gameState.scenarioScores, {
scenarioId: currentScenario.id,
score: scenarioScore,
security: scores.security,
usability: scores.usability,
complexity: scores.complexity,
attacksBlocked: attackResults.filter(r => r.blocked).length,
totalAttacks: attackResults.length
}];
mutable gameState = {
...gameState,
answered: true,
showFeedback: true,
score: gameState.score + scenarioScore,
securityScore: scores.security,
usabilityScore: scores.usability,
complexityScore: scores.complexity,
attackResults: attackResults,
totalScenarios: gameState.totalScenarios + 1,
scenarioScores: newScores
};
}
function nextScenario() {
const nextIndex = gameState.currentScenarioIndex + 1;
if (nextIndex >= scenarios[gameState.difficulty].length) {
mutable gameState = { ...gameState, gameComplete: true };
} else {
mutable gameState = {
...gameState,
currentScenarioIndex: nextIndex,
answered: false,
selectedPolicies: {
segmentation: null,
identity: null,
access: null,
verification: null
},
showFeedback: false,
securityScore: 0,
usabilityScore: 0,
complexityScore: 0,
attackResults: []
};
}
}
function changeDifficulty(difficulty) {
mutable gameState = {
difficulty: difficulty,
currentScenarioIndex: 0,
score: 0,
answered: false,
selectedPolicies: {
segmentation: null,
identity: null,
access: null,
verification: null
},
securityScore: 0,
usabilityScore: 0,
complexityScore: 0,
attackResults: [],
totalScenarios: 0,
gameComplete: false,
showFeedback: false,
scenarioScores: []
};
}
function restartGame() {
mutable gameState = {
...gameState,
currentScenarioIndex: 0,
score: 0,
answered: false,
selectedPolicies: {
segmentation: null,
identity: null,
access: null,
verification: null
},
securityScore: 0,
usabilityScore: 0,
complexityScore: 0,
attackResults: [],
totalScenarios: 0,
gameComplete: false,
showFeedback: false,
scenarioScores: []
};
}
// ----------------------------------------------------------------------------
// SECTION 4: UI RENDERING
// ----------------------------------------------------------------------------
viewof ztGame = {
const container = html`<div class="zt-game-container">
<div class="game-header">
<h2>🛡️ Zero-Trust Policy Builder Challenge</h2>
<p>Design secure, usable, and practical zero-trust policies</p>
</div>
<div class="difficulty-selector">
<button class="difficulty-btn easy ${gameState.difficulty === 'easy' ? 'active' : ''}"
onclick=${() => changeDifficulty('easy')}>
🟢 Easy (4 scenarios)
</button>
<button class="difficulty-btn medium ${gameState.difficulty === 'medium' ? 'active' : ''}"
onclick=${() => changeDifficulty('medium')}>
🟡 Medium (4 scenarios)
</button>
<button class="difficulty-btn hard ${gameState.difficulty === 'hard' ? 'active' : ''}"
onclick=${() => changeDifficulty('hard')}>
🔴 Hard (4 scenarios)
</button>
</div>
<div class="progress-bar">
<div class="progress-fill" style="width: ${(gameState.currentScenarioIndex / totalScenarios) * 100}%"></div>
</div>
<div class="game-stats">
<div class="stat-card">
<div class="stat-value">${gameState.score}</div>
<div class="stat-label">Total Score</div>
</div>
<div class="stat-card">
<div class="stat-value">${gameState.currentScenarioIndex + 1}/${totalScenarios}</div>
<div class="stat-label">Scenario</div>
</div>
<div class="stat-card">
<div class="stat-value">${gameState.securityScore}%</div>
<div class="stat-label">Security</div>
</div>
<div class="stat-card">
<div class="stat-value">${gameState.usabilityScore}%</div>
<div class="stat-label">Usability</div>
</div>
<div class="stat-card">
<div class="stat-value">${gameState.complexityScore}%</div>
<div class="stat-label">Complexity</div>
</div>
</div>
<div id="game-content"></div>
</div>`;
const gameContent = container.querySelector("#game-content");
if (gameState.gameComplete) {
renderGameComplete(gameContent);
} else {
renderScenario(gameContent);
}
return container;
}
function renderScenario(container) {
const scenario = currentScenario;
container.innerHTML = `
<div class="scenario-card">
<div class="scenario-header">
<div class="scenario-title">${scenario.title}</div>
<div class="scenario-number">Scenario ${scenario.id}</div>
</div>
<div class="scenario-description">
${scenario.description}
</div>
<div class="network-info">
<h4>📊 Network Profile</h4>
<div class="info-grid">
${Object.entries(scenario.networkInfo).map(([key, value]) => `
<div class="info-item">
<div class="info-label">${formatLabel(key)}:</div>
<div class="info-value">${value}</div>
</div>
`).join('')}
</div>
</div>
<div class="policy-builder">
<div class="policy-builder-title">
🔧 Design Your Zero-Trust Policy
</div>
<div class="policy-sections">
${renderPolicySection("segmentation", "Network Segmentation")}
${renderPolicySection("identity", "Identity & Authentication")}
${renderPolicySection("access", "Access Control")}
${renderPolicySection("verification", "Continuous Verification")}
</div>
</div>
<div class="hint-box">
<strong>💡 Hint:</strong> ${scenario.hint}
</div>
<div class="action-buttons">
<button class="action-btn submit"
onclick="submitPolicy()"
${gameState.answered ? 'disabled' : ''}>
✓ Deploy Policy & Test
</button>
<button class="action-btn next"
onclick="nextScenario()"
${!gameState.answered ? 'disabled' : ''}>
→ Next Scenario
</button>
</div>
<div class="feedback-panel ${gameState.showFeedback ? 'show' : ''} ${getFeedbackClass()}">
${gameState.showFeedback ? renderFeedback() : ''}
</div>
</div>
`;
}
function renderPolicySection(category, title) {
const options = policyOptions[category];
const selected = gameState.selectedPolicies[category];
const optimal = currentScenario.optimalPolicy[category] || [];
return `
<div class="policy-section">
<div class="section-title">${title}</div>
<div class="policy-options">
${options.map(option => {
const isSelected = selected === option.id;
const isOptimal = optimal.includes(option.id);
let optionClass = 'policy-option';
let indicator = '';
if (gameState.answered) {
optionClass += ' disabled';
if (isSelected && isOptimal) {
optionClass += ' correct';
indicator = '<span class="policy-indicator">✓</span>';
} else if (isSelected && !isOptimal) {
optionClass += ' incorrect';
indicator = '<span class="policy-indicator">✗</span>';
} else if (!isSelected && isOptimal) {
optionClass += ' missed';
indicator = '<span class="policy-indicator">⚠️</span>';
}
} else if (isSelected) {
optionClass += ' selected';
}
return `
<label class="${optionClass}">
<input type="radio"
name="${category}"
class="policy-checkbox"
${isSelected ? 'checked' : ''}
${gameState.answered ? 'disabled' : ''}
onchange="selectPolicy('${category}', '${option.id}')">
<div class="policy-text">
<strong>${option.title}</strong><br>
<span style="font-size: 0.85em; color: #666;">${option.description}</span>
</div>
${indicator}
</label>
`;
}).join('')}
</div>
</div>
`;
}
function formatLabel(key) {
return key.charAt(0).toUpperCase() + key.slice(1).replace(/_/g, ' ');
}
function getFeedbackClass() {
if (!gameState.answered) return '';
const lastScore = gameState.scenarioScores[gameState.scenarioScores.length - 1];
if (lastScore.score >= 80) return 'excellent';
if (lastScore.score >= 50) return 'good';
return 'poor';
}
function renderFeedback() {
const scenario = currentScenario;
const lastScore = gameState.scenarioScores[gameState.scenarioScores.length - 1];
const attacksBlocked = gameState.attackResults.filter(r => r.blocked).length;
const totalAttacks = gameState.attackResults.length;
let title = '';
let emoji = '';
if (lastScore.score >= 80) {
title = 'Excellent Zero-Trust Design!';
emoji = '🏆';
} else if (lastScore.score >= 50) {
title = 'Good Effort!';
emoji = '✅';
} else {
title = 'Policy Needs Improvement';
emoji = '📋';
}
return `
<div class="feedback-title">
${emoji} ${title}
</div>
<div class="feedback-score">
Scenario Score: ${lastScore.score} points
</div>
<div class="feedback-metrics">
<div class="metric-box">
<div class="metric-value">${lastScore.security}%</div>
<div class="metric-label">Security Posture</div>
</div>
<div class="metric-box">
<div class="metric-value">${lastScore.usability}%</div>
<div class="metric-label">Usability Impact</div>
</div>
<div class="metric-box">
<div class="metric-value">${lastScore.complexity}%</div>
<div class="metric-label">Implementation Complexity</div>
</div>
</div>
<div class="attack-simulation">
<h5>⚔️ Attack Simulation Results</h5>
${gameState.attackResults.map(attack => `
<div class="attack-result">
<span class="attack-name">${attack.attackName}</span>
<span class="attack-status ${attack.blocked ? 'blocked' : 'succeeded'}">
${attack.blocked ? '🛡️ BLOCKED' : '❌ SUCCEEDED'}
</span>
</div>
`).join('')}
<div style="margin-top: 12px; font-size: 0.9em; color: #2C3E50;">
<strong>Defense Rate:</strong> ${attacksBlocked}/${totalAttacks} attacks blocked (${Math.round(attacksBlocked/totalAttacks*100)}%)
</div>
</div>
<div class="feedback-explanation">
<h5>📚 What Makes a Good Zero-Trust Policy?</h5>
<ul class="feedback-list">
${generateFeedbackPoints(scenario, lastScore).map(point => `<li>${point}</li>`).join('')}
</ul>
</div>
`;
}
function generateFeedbackPoints(scenario, scoreData) {
const points = [];
const selected = gameState.selectedPolicies;
const optimal = scenario.optimalPolicy;
// Security feedback
if (scoreData.security < 60) {
points.push("Security score is low. Consider stronger segmentation and authentication methods.");
} else if (scoreData.security >= 80) {
points.push("Excellent security posture! Your policies provide strong defense-in-depth.");
}
// Usability feedback
if (scoreData.usability < 50) {
points.push("Low usability may lead to shadow IT or policy workarounds. Balance security with practicality.");
}
// Complexity feedback
if (scoreData.complexity > 80) {
points.push("Very high implementation complexity. Consider phased rollout and staff training.");
}
// Category-specific feedback
if (selected.segmentation !== optimal.segmentation?.[0]) {
points.push(`Network segmentation: Consider ${optimal.segmentation.map(s => policyOptions.segmentation.find(o => o.id === s)?.title).join(' or ')} for this scenario.`);
}
if (selected.verification !== optimal.verification?.[0]) {
points.push("Continuous verification is key to zero-trust. Re-verify access frequently to detect compromises.");
}
// Generic zero-trust principles
points.push("Never trust, always verify: Every access request should be authenticated and authorized.");
points.push("Least privilege: Grant minimal access needed for specific tasks, not broad network permissions.");
points.push("Assume breach: Design policies assuming attackers are already inside the network.");
return points.slice(0, 5); // Limit to 5 key points
}
function renderGameComplete(container) {
const totalScore = gameState.score;
const scenariosCompleted = gameState.totalScenarios;
const avgSecurity = Math.round(gameState.scenarioScores.reduce((sum, s) => sum + s.security, 0) / scenariosCompleted);
const avgUsability = Math.round(gameState.scenarioScores.reduce((sum, s) => sum + s.usability, 0) / scenariosCompleted);
const totalAttacksBlocked = gameState.scenarioScores.reduce((sum, s) => sum + s.attacksBlocked, 0);
const totalAttacks = gameState.scenarioScores.reduce((sum, s) => sum + s.totalAttacks, 0);
const defenseRate = Math.round((totalAttacksBlocked / totalAttacks) * 100);
const maxScore = scenariosCompleted * 100; // Rough estimate
const scorePercentage = Math.round((totalScore / maxScore) * 100);
let feedback, emoji;
if (scorePercentage >= 80) {
feedback = "Outstanding! You're a zero-trust security architect!";
emoji = "🏆";
} else if (scorePercentage >= 60) {
feedback = "Great work! You understand zero-trust principles well!";
emoji = "🎉";
} else if (scorePercentage >= 40) {
feedback = "Good effort! Keep practicing to master zero-trust design.";
emoji = "👍";
} else {
feedback = "Keep learning! Zero-trust is complex - review scenarios and try again.";
emoji = "📚";
}
container.innerHTML = `
<div class="game-complete">
<div class="complete-icon">${emoji}</div>
<div class="complete-title">Challenge Complete!</div>
<div class="complete-score">
Final Score: ${totalScore} points
</div>
<div class="complete-feedback">${feedback}</div>
<div class="performance-grid">
<div class="performance-card">
<div class="performance-value">${avgSecurity}%</div>
<div class="performance-label">Average Security Posture</div>
</div>
<div class="performance-card">
<div class="performance-value">${avgUsability}%</div>
<div class="performance-label">Average Usability</div>
</div>
<div class="performance-card">
<div class="performance-value">${defenseRate}%</div>
<div class="performance-label">Attack Defense Rate</div>
</div>
<div class="performance-card">
<div class="performance-value">${scenariosCompleted}</div>
<div class="performance-label">Scenarios Completed</div>
</div>
</div>
<div style="margin: 24px 0; text-align: left; max-width: 800px; margin-left: auto; margin-right: auto;">
<h3>What You've Learned:</h3>
<ul style="line-height: 1.8;">
<li><strong>Never Trust, Always Verify:</strong> Authenticate every access request regardless of network location</li>
<li><strong>Microsegmentation:</strong> Isolate workloads and devices to prevent lateral movement</li>
<li><strong>Least Privilege Access:</strong> Grant minimal permissions needed for specific tasks</li>
<li><strong>Continuous Verification:</strong> Monitor and re-verify trust in real-time</li>
<li><strong>Assume Breach:</strong> Design defenses assuming attackers are already inside</li>
<li><strong>Context-Aware Policies:</strong> Use device health, location, and behavior for access decisions</li>
<li><strong>Security-Usability Balance:</strong> Strong security with practical implementation</li>
</ul>
</div>
<button class="restart-btn" onclick="restartGame()">
🔄 Play Again
</button>
<div style="margin-top: 24px;">
<p style="font-size: 0.9em; color: #666;">
Try different difficulty levels to master zero-trust design for easy, medium, and hard scenarios!
</p>
</div>
</div>
`;
}
// Make functions globally accessible
window.selectPolicy = selectPolicy;