# M365 Security Scorecard - Code Snippets Reference ## Key Code Sections from app.py ### 1. Security Categories Definition ```python SECURITY_CHECKS = { "identity_access": { "en": "Identity & Access", "fr": "Identite et Acces", "checks": [ {"en": "MFA enabled for all users", "fr": "MFA activee pour tous les utilisateurs"}, {"en": "Conditional Access policies configured", "fr": "Politiques d'acces conditionnel configurees"}, # ... 6 more checks ] }, # ... 5 more categories } ``` ### 2. KQL Hunting Queries ```python KQL_HUNTING_QUERIES = [ { "title": "Detect MFA Bypass Attempts", "query": "SigninLogs | where ConditionalAccessStatus == 'failure' and AuthenticationRequirement == 'multiFactorAuthentication' | summarize Count=count() by UserPrincipalName, IPAddress, ClientAppUsed" }, # ... 4 more queries ] ``` ### 3. Real-Time Score Calculation ```python def calculate_scores(checks_state): """Calculate scores per category""" scores = {} recommendations = [] for category_id, category_data in SECURITY_CHECKS.items(): if category_id in checks_state: checked_items = sum(checks_state[category_id]) total_items = len(category_data["checks"]) score = (checked_items / total_items) * 100 if total_items > 0 else 0 scores[category_id] = score # Generate recommendations... overall_score = sum(scores.values()) / len(scores) if scores else 0 return scores, overall_score, recommendations ``` ### 4. Radar Chart Creation ```python def create_radar_chart(scores, language): """Create radar chart for category scores""" categories_display = [SECURITY_CHECKS[cat_id][language] for cat_id in scores.keys()] values = list(scores.values()) fig = go.Figure(data=go.Scatterpolar( r=values, theta=categories_display, fill='toself', name='Security Score', line=dict(color='#4f46e5'), fillcolor='rgba(79, 70, 229, 0.2)' )) fig.update_layout( polar=dict(radialaxis=dict(visible=True, range=[0, 100])), showlegend=False, height=400 ) return fig ``` ### 5. Gauge Chart Creation ```python def create_gauge_chart(overall_score, language): """Create gauge chart for overall maturity""" fig = go.Figure(go.Indicator( mode="gauge+number+delta", value=overall_score, title={'text': "Overall Security Maturity Score"}, gauge={ 'axis': {'range': [0, 100]}, 'bar': {'color': "darkblue"}, 'steps': [ {'range': [0, 25], 'color': "rgba(255, 0, 0, 0.2)"}, {'range': [25, 50], 'color': "rgba(255, 165, 0, 0.2)"}, {'range': [50, 75], 'color': "rgba(255, 255, 0, 0.2)"}, {'range': [75, 100], 'color': "rgba(0, 255, 0, 0.2)"} ] } )) fig.update_layout(height=400) return fig ``` ### 6. Smart Recommendations Engine ```python def create_recommendations_html(recommendations, language, limit=5): """Create recommendations panel""" if not recommendations: return "

All checks passed! Your M365 security posture is strong.

" html = "

Top 5 Priority Fixes

    " for i, rec in enumerate(recommendations[:limit], 1): check_text = rec["check"][language] category_text = rec["category"][language] html += f"
  1. {category_text}: {check_text}
  2. " html += "
" return html ``` ### 7. Markdown Report Export ```python def generate_markdown_report(checks_state, scores, overall_score, language): """Generate markdown report for export""" timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") lang_code = "FR" if language == "fr" else "EN" report = f"# M365 Security Scorecard Report\n\n" report += f"**Report Generated:** {timestamp}\n" report += f"**Language:** {lang_code}\n" report += f"**Overall Security Score:** {overall_score:.1f}%\n\n" # Add detailed assessment... return report ``` ### 8. Gradio Interface Setup ```python with gr.Blocks(title="M365 Security Scorecard", theme=gr.themes.Soft(primary_hue="blue", secondary_hue="indigo")) as demo: gr.Markdown("# M365 Security Scorecard - Microsoft 365 Security Assessment") with gr.Row(): language_radio = gr.Radio( choices=["EN - English", "FR - Francais"], value="EN - English", label="Language / Langue", interactive=True ) # Create tabs for each category with gr.Tabs(): check_components = {} for category_id, category_data in SECURITY_CHECKS.items(): with gr.Tab(label=category_data["en"]): # Create checkboxes for each check for i, check in enumerate(category_data["checks"]): check_key = f"{category_id}_{i}" check_components[check_key] = gr.Checkbox( label=f"{check['en']} / {check['fr']}", value=False ) ``` ### 9. Real-Time Update Handler ```python def update_display(language, *check_args): """Update all displays based on checks""" # Convert check_args to dictionary structure checks_state = {} arg_index = 0 for category_id in SECURITY_CHECKS.keys(): num_checks = len(SECURITY_CHECKS[category_id]["checks"]) checks_state[category_id] = list(check_args[arg_index:arg_index + num_checks]) arg_index += num_checks # Calculate scores scores, overall_score, recommendations = calculate_scores(checks_state) # Create visualizations radar = create_radar_chart(scores, language) gauge = create_gauge_chart(overall_score, language) # Create recommendations recommendations_html = create_recommendations_html(recommendations, language) # Create KQL section kql_html = create_kql_queries_html(language) # Create markdown report markdown_report = generate_markdown_report(checks_state, scores, overall_score, language) return radar, gauge, recommendations_html, kql_html, markdown_report ``` ### 10. Event Binding ```python # Change event to update results in real-time language_radio.change( fn=lambda *args: update_display("EN" if args[0] == "EN - English" else "FR", *args[1:]), inputs=[language_radio] + list(check_components.values()), outputs=[radar_chart, gauge_chart, recommendations_html, kql_html, markdown_output] ) for component in check_components.values(): component.change( fn=lambda *args: update_display("EN" if args[0] == "EN - English" else "FR", *args[1:]), inputs=[language_radio] + list(check_components.values()), outputs=[radar_chart, gauge_chart, recommendations_html, kql_html, markdown_output] ) ``` ## HTML Generation Functions ### KQL Queries Display ```python def create_kql_queries_html(language): """Create KQL hunting queries section""" html = "

M365 Threat Hunting - KQL Queries

" for i, query_data in enumerate(KQL_HUNTING_QUERIES, 1): html += f"

{i}. {query_data['title']}

" html += f"
{query_data['query']}
" return html ``` ### Resources Display ```python def create_resources_html(language): """Create resources section with backlinks""" resources = [ {"title": "Top 10 Tools for M365 Security Analysis", "url": "..."}, # ... 10 more resources ] html = "

Resources & Learning Materials

" return html ``` ## Gradio 4.44.0 Compatibility Notes ### Correct Patterns Used 1. **Tab Usage**: Using `gr.Tab` instead of deprecated `gr.TabItem` 2. **No Scale Parameter**: Avoiding `scale=` parameter on components 3. **No gr.update()**: Direct function returns instead of gr.update() 4. **f-strings**: No backslashes in f-strings 5. **Event Binding**: Using .change() and .click() properly ### Avoided Patterns - No `scale=` on components - No `gr.update()` calls - No `gr.TabItem()` usage - No backslashes in f-strings - No deprecated component API ## Configuration Examples ### YAML Frontmatter (README.md) ```yaml --- title: M365 Security Scorecard emoji: 🛡️ colorFrom: blue colorTo: indigo sdk: gradio sdk_version: 4.44.0 python_version: "3.10" app_file: app.py pinned: false license: apache-2.0 tags: - cybersecurity - microsoft-365 - m365-security --- ``` ### Theme Configuration ```python theme=gr.themes.Soft(primary_hue="blue", secondary_hue="indigo") ``` ## Dependencies ```python import gradio as gr import plotly.graph_objects as go from datetime import datetime import json ``` All dependencies are standard and production-ready. --- For complete code, see `/home/deeptechadmin/hf/spaces/m365-scorecard/app.py`