Spaces:
Configuration error
Configuration error
| import streamlit as st | |
| import re | |
| import time | |
| # Page Config for Dark Mode / Professional Look | |
| st.set_page_config(page_title="Zero-Noise | Agentic SOC", layout="wide", initial_sidebar_state="collapsed") | |
| # Premium Custom CSS for Professional Security Interface | |
| st.markdown(""" | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;600&display=swap'); | |
| * { | |
| font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; | |
| } | |
| .main { | |
| background: linear-gradient(135deg, #0a0e1a 0%, #0f1428 100%); | |
| color: #e8eef5; | |
| } | |
| h1, h2, h3 { | |
| font-family: 'Inter', sans-serif; | |
| font-weight: 700; | |
| letter-spacing: -0.5px; | |
| } | |
| h1 { | |
| font-size: 2.5em; | |
| background: linear-gradient(120deg, #60a5fa 0%, #818cf8 100%); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| margin-bottom: 0.5em; | |
| } | |
| h3 { | |
| color: #c7d2e0; | |
| font-size: 1.1em; | |
| font-weight: 600; | |
| } | |
| /* Metrics Styling */ | |
| .stMetric { | |
| background: linear-gradient(135deg, rgba(99, 102, 241, 0.08) 0%, rgba(168, 85, 247, 0.06) 100%); | |
| border: 1px solid rgba(99, 102, 241, 0.3); | |
| padding: 20px; | |
| border-radius: 12px; | |
| backdrop-filter: blur(10px); | |
| box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); | |
| transition: all 0.3s ease; | |
| } | |
| .stMetric:hover { | |
| border-color: rgba(96, 165, 250, 0.5); | |
| box-shadow: 0 8px 24px rgba(96, 165, 250, 0.2); | |
| } | |
| /* Button Styling */ | |
| .stButton > button { | |
| background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); | |
| border: none; | |
| color: white; | |
| font-weight: 600; | |
| border-radius: 10px; | |
| padding: 12px 24px; | |
| font-size: 0.95em; | |
| transition: all 0.3s ease; | |
| box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4); | |
| } | |
| .stButton > button:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 8px 25px rgba(99, 102, 241, 0.6); | |
| } | |
| /* Card Styling */ | |
| .threat-high { | |
| border-left: 4px solid #ff6b6b; | |
| background: linear-gradient(135deg, rgba(255, 107, 107, 0.1) 0%, rgba(255, 107, 107, 0.05) 100%); | |
| } | |
| .threat-medium { | |
| border-left: 4px solid #ffa940; | |
| background: linear-gradient(135deg, rgba(255, 169, 64, 0.1) 0%, rgba(255, 169, 64, 0.05) 100%); | |
| } | |
| .threat-low { | |
| border-left: 4px solid #52c41a; | |
| background: linear-gradient(135deg, rgba(82, 196, 26, 0.1) 0%, rgba(82, 196, 26, 0.05) 100%); | |
| } | |
| .incident-card { | |
| background-color: #111827; | |
| padding: 18px; | |
| border-radius: 10px; | |
| margin-bottom: 16px; | |
| border: 1px solid rgba(75, 85, 99, 0.3); | |
| transition: all 0.3s ease; | |
| backdrop-filter: blur(5px); | |
| } | |
| .incident-card:hover { | |
| border-color: rgba(99, 102, 241, 0.4); | |
| box-shadow: 0 8px 24px rgba(99, 102, 241, 0.1); | |
| } | |
| /* Horizontal Rule */ | |
| hr { | |
| border: none; | |
| height: 1px; | |
| background: linear-gradient(90deg, transparent, rgba(99, 102, 241, 0.3), transparent); | |
| margin: 2em 0; | |
| } | |
| /* Sidebar Panel */ | |
| .sidebar-panel { | |
| background: linear-gradient(135deg, rgba(99, 102, 241, 0.1) 0%, rgba(168, 85, 247, 0.08) 100%); | |
| border: 1px solid rgba(99, 102, 241, 0.2); | |
| border-radius: 10px; | |
| padding: 20px; | |
| backdrop-filter: blur(10px); | |
| } | |
| /* Code/Specs */ | |
| .specs-text { | |
| font-family: 'IBM Plex Mono', monospace; | |
| font-size: 0.9em; | |
| color: #a0aec0; | |
| line-height: 1.6; | |
| } | |
| /* Subheader styling */ | |
| .subheader-custom { | |
| color: #e8eef5; | |
| font-weight: 600; | |
| font-size: 1.15em; | |
| margin: 1.5em 0 1em 0; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| st.title("Zero-Noise: Agentic SOC-in-a-Box") | |
| st.markdown("<p style='color: #a0aec0; font-size: 1em; margin: -1.5em 0 0.5em 0;'>Real-time Threat Intelligence & Analysis Pipeline</p>", unsafe_allow_html=True) | |
| st.markdown("---") | |
| # Status Overview | |
| cols = st.columns(2) | |
| with cols[0]: | |
| st.metric("System Status", "π’ PROTECTED", delta="Active", delta_color="inverse") | |
| with cols[1]: | |
| st.metric("Latency", "38ms", delta="β 4ms", delta_color="inverse") | |
| st.markdown("---") | |
| col_main, col_side = st.columns([3, 1], gap="medium") | |
| with col_side: | |
| st.markdown("<div class='subheader-custom'>π οΈ Operations</div>", unsafe_allow_html=True) | |
| if st.button("π Re-Scan Logs", use_container_width=True, key="rescan"): | |
| st.toast("Reinitializing threat analysis pipeline...") | |
| st.write("") | |
| # Create placeholder for Log Analysis that will update as we scan | |
| log_analysis_placeholder = st.empty() | |
| with col_main: | |
| st.markdown("<div class='subheader-custom'>π¨ Incident Intelligence Feed</div>", unsafe_allow_html=True) | |
| try: | |
| with open('FINAL_REPORT.md', 'r') as f: | |
| content = f.read() | |
| # Split individual incidents | |
| incidents = content.split("---") | |
| total_logs_scanned = 0 | |
| incident_count = 0 | |
| for incident in incidents: | |
| if "###" in incident: | |
| incident_count += 1 | |
| # Scan logs with 0.5 second increments until we hit the next incident | |
| while total_logs_scanned < incident_count * 3: # Each incident represents ~3 logs scanned | |
| total_logs_scanned += 1 | |
| if total_logs_scanned > 32: | |
| total_logs_scanned = 32 | |
| # Update log analysis in sidebar | |
| with log_analysis_placeholder.container(): | |
| st.markdown(f""" | |
| <div class="sidebar-panel"> | |
| <div style="font-weight: 600; color: #60a5fa; margin-bottom: 12px; font-size: 0.95em;">π Log Analysis</div> | |
| <div class="specs-text"> | |
| <div style="display: flex; justify-content: space-between; margin-bottom: 10px;"> | |
| <span>Total Logs:</span> | |
| <span style="color: #60a5fa; font-weight: 600;">{total_logs_scanned}</span> | |
| </div> | |
| <div style="display: flex; justify-content: space-between; margin-bottom: 10px;"> | |
| <span>Anomalies Found:</span> | |
| <span style="color: #ff6b6b; font-weight: 600;">{incident_count}</span> | |
| </div> | |
| <div style="width: 100%; height: 6px; background-color: rgba(75, 85, 99, 0.3); border-radius: 3px; margin: 12px 0; overflow: hidden;"> | |
| <div style="width: {(total_logs_scanned/32)*100}%; height: 100%; background: linear-gradient(90deg, #60a5fa, #818cf8); border-radius: 3px;"></div> | |
| </div> | |
| <div style="font-size: 0.85em; color: #a0aec0; text-align: center;"> | |
| Scanning... {(total_logs_scanned/32)*100:.1f}% | |
| </div> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| time.sleep(0.5) | |
| # Determine threat level from risk score | |
| risk_match = re.search(r"Risk Score: (\d+)", incident) | |
| risk_score = int(risk_match.group(1)) if risk_match else 5 | |
| if risk_score >= 8: | |
| threat_class = "threat-high" | |
| severity = "π΄ CRITICAL" | |
| elif risk_score >= 5: | |
| threat_class = "threat-medium" | |
| severity = "π MEDIUM" | |
| else: | |
| threat_class = "threat-low" | |
| severity = "π’ LOW" | |
| # Parse incident components | |
| title_match = re.search(r"### (.+)", incident) | |
| title = title_match.group(1) if title_match else "Unknown Threat" | |
| attacker_match = re.search(r"\*\*Attacker IP:\*\*\s*(.+?)(?=\n|$)", incident) | |
| attacker = attacker_match.group(1).strip() if attacker_match else "N/A" | |
| summary_match = re.search(r"\*\*Summary:\*\*\s*(.+?)(?=\*\*Recommendation:\*\*|\n\*\*|$)", incident, re.DOTALL) | |
| summary = summary_match.group(1).strip() if summary_match else "" | |
| recommendation_match = re.search(r"\*\*Recommendation:\*\*\s*(.+?)(?=---|\*\*|$)", incident, re.DOTALL) | |
| recommendation = recommendation_match.group(1).strip() if recommendation_match else "" | |
| with st.container(): | |
| st.markdown(f""" | |
| <div class="incident-card {threat_class}"> | |
| <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;"> | |
| <span style="font-weight: 600; color: #e8eef5; font-size: 1.05em;">{title}</span> | |
| <span style="font-size: 0.85em; color: #a0aec0;">{severity}</span> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| st.markdown(f"**Attacker IP:** {attacker}") | |
| st.markdown(f"**Summary:** {summary}") | |
| st.markdown(f"**Recommendation:** {recommendation}") | |
| st.markdown("</div>", unsafe_allow_html=True) | |
| # 2-second delay between incidents | |
| time.sleep(2) | |
| # Finish scanning remaining logs up to 32 | |
| while total_logs_scanned < 32: | |
| total_logs_scanned += 1 | |
| with log_analysis_placeholder.container(): | |
| st.markdown(f""" | |
| <div class="sidebar-panel"> | |
| <div style="font-weight: 600; color: #60a5fa; margin-bottom: 12px; font-size: 0.95em;">π Log Analysis</div> | |
| <div class="specs-text"> | |
| <div style="display: flex; justify-content: space-between; margin-bottom: 10px;"> | |
| <span>Total Logs:</span> | |
| <span style="color: #60a5fa; font-weight: 600;">{total_logs_scanned}</span> | |
| </div> | |
| <div style="display: flex; justify-content: space-between; margin-bottom: 10px;"> | |
| <span>Anomalies Found:</span> | |
| <span style="color: #ff6b6b; font-weight: 600;">{incident_count}</span> | |
| </div> | |
| <div style="width: 100%; height: 6px; background-color: rgba(75, 85, 99, 0.3); border-radius: 3px; margin: 12px 0; overflow: hidden;"> | |
| <div style="width: {(total_logs_scanned/32)*100}%; height: 100%; background: linear-gradient(90deg, #60a5fa, #818cf8); border-radius: 3px;"></div> | |
| </div> | |
| <div style="font-size: 0.85em; color: #a0aec0; text-align: center;"> | |
| Scanning... {(total_logs_scanned/32)*100:.1f}% | |
| </div> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| time.sleep(0.5) | |
| except Exception as e: | |
| st.info("β³ Awaiting live log ingestion...") | |
| st.markdown(""" | |
| <div class="sidebar-panel"> | |
| <div style="font-weight: 600; color: #60a5fa; margin-bottom: 12px; font-size: 0.95em;">Pipeline Configuration</div> | |
| <div class="specs-text"> | |
| <strong>Analysis Stack:</strong><br> | |
| β’ Filter: Deterministic Regex<br> | |
| β’ Parser: Qwen2-7B (Agent 1)<br> | |
| β’ Analyst: Qwen2-7B (Agent 2)<br> | |
| β’ Hardware: AMD MI300X | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) |