{
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.13.0"
    },
    "blog_metadata": {
      "topic": "Why Microsoft Purview Label Inheritance Is a Bigger Deal Than It Looks",
      "slug": "why-microsoft-purview-label-inheritance-is-a-bigger-deal-tha",
      "generated_by": "LinkedIn Post Generator + Azure OpenAI",
      "generated_at": "2026-08-10T19:15:40.070Z"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Why Microsoft Purview Label Inheritance Is a Bigger Deal Than It Looks\n",
        "\n",
        "This notebook turns the blog post into a hands-on validation walkthrough using Python simulations. It focuses on the operational value of label inheritance: reducing protection drift, improving consistency at file creation, and showing how inheritance complements DLP and retention rather than replacing them."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "%pip install pandas matplotlib seaborn"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "from dataclasses import dataclass, asdict\n",
        "from typing import List, Dict\n",
        "import pandas as pd\n",
        "import matplotlib.pyplot as plt\n",
        "import seaborn as sns\n",
        "\n",
        "sns.set_theme(style='whitegrid')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Model container-level inheritance\n",
        "\n",
        "This example shows how a site-level sensitivity label can shape default file labeling and collaboration controls. The point is that inheritance is not just classification metadata; it also reinforces the collaboration posture around sharing and device access."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "from dataclasses import dataclass\n",
        "\n",
        "@dataclass\n",
        "class SiteLabelPolicy:\n",
        "    site_label: str\n",
        "    default_file_label: str\n",
        "    external_sharing: str\n",
        "    unmanaged_device_access: str\n",
        "\n",
        "policy = SiteLabelPolicy(\n",
        "    site_label='Confidential',\n",
        "    default_file_label='Confidential',\n",
        "    external_sharing='Existing guests only',\n",
        "    unmanaged_device_access='Web only',\n",
        ")\n",
        "\n",
        "print(f\"Site label: {policy.site_label}\")\n",
        "print(f\"Default file label: {policy.default_file_label}\")\n",
        "print(f\"Sharing: {policy.external_sharing}\")\n",
        "print(f\"Device rule: {policy.unmanaged_device_access}\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Simulate a site policy before files are created\n",
        "\n",
        "This Python version mirrors the PowerShell example from the post. It demonstrates the idea that a site-level decision can define the expected protection state for future uploads before users create or upload content."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "site_policy = {\n",
        "    'SiteUrl': 'https://contoso.sharepoint.com/sites/finance',\n",
        "    'SiteLabel': 'Confidential',\n",
        "    'DefaultFileLabel': 'Confidential',\n",
        "    'ExternalSharing': 'ExistingGuestsOnly',\n",
        "    'UnmanagedDeviceAccess': 'AllowLimitedWebOnly'\n",
        "}\n",
        "\n",
        "for k, v in site_policy.items():\n",
        "    print(f'{k}: {v}')\n",
        "\n",
        "print(f\"\\nNew uploads to {site_policy['SiteUrl']} start with label: {site_policy['DefaultFileLabel']}\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Compare protection at creation versus reactive remediation\n",
        "\n",
        "This example illustrates the core operating-model shift described in the post. Files protected at creation have a smaller exposure window than files discovered later by scanners or review teams."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "files = [\n",
        "    {'name': 'budget.xlsx', 'created_with_label': True},\n",
        "    {'name': 'notes.docx', 'created_with_label': True},\n",
        "    {'name': 'legacy.csv', 'created_with_label': False},\n",
        "]\n",
        "\n",
        "inherited = [f['name'] for f in files if f['created_with_label']]\n",
        "reactive = [f['name'] for f in files if not f['created_with_label']]\n",
        "\n",
        "print('Protected at creation:', inherited)\n",
        "print('Needs later discovery/remediation:', reactive)\n",
        "print('Why it matters: inheritance reduces the unlabeled gap window.')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Show how labels affect collaboration posture\n",
        "\n",
        "The blog argues that inheritance is bigger than a label picker improvement because container labels can influence sharing and device restrictions. This example maps a label to a simple collaboration impact statement."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def get_collaboration_impact(label: str) -> str:\n",
        "    mapping = {\n",
        "        'Public': 'Anonymous sharing may be allowed',\n",
        "        'General': 'Internal collaboration with broad access',\n",
        "        'Confidential': 'Guest sharing restricted and device controls tightened'\n",
        "    }\n",
        "    return mapping.get(label, 'Custom review required')\n",
        "\n",
        "result = get_collaboration_impact('Confidential')\n",
        "print(f'Container impact: {result}')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Prevent accidental downgrades below the inherited default\n",
        "\n",
        "This example validates a simple control pattern: if a site default is Confidential, a user should not be able to manually downgrade a file to a lower label such as Public. This is a useful way to explain why inheritance can reduce drift."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "site_default = 'Confidential'\n",
        "requested_label = 'Public'\n",
        "\n",
        "rank = {'Public': 1, 'General': 2, 'Confidential': 3, 'Highly Confidential': 4}\n",
        "\n",
        "if rank[requested_label] < rank[site_default]:\n",
        "    print(f\"Blocked: cannot downgrade below inherited site default '{site_default}'\")\n",
        "else:\n",
        "    print(f\"Allowed: '{requested_label}' meets or exceeds '{site_default}'\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Build a lightweight rollout dashboard\n",
        "\n",
        "The post recommends measuring operational outcomes instead of just checking whether policies exist. This example creates a small dashboard-style dataset and prints the key takeaway."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "metrics = {\n",
        "    'SitesLabeled': 120,\n",
        "    'LibrariesReceivingDefaultLabel': 120,\n",
        "    'NewFilesProtectedAtCreationPct': 94,\n",
        "    'FilesNeedingReactiveRelabelPct': 6\n",
        "}\n",
        "\n",
        "metrics_df = pd.DataFrame([metrics])\n",
        "display(metrics_df)\n",
        "print('Key takeaway: inheritance shifts protection left and reduces cleanup workload.')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Visualize the operational value of inheritance\n",
        "\n",
        "A chart makes the blog's argument easier to validate with stakeholders. Here we compare the percentage of files protected at creation with the percentage needing reactive relabeling."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "plot_df = pd.DataFrame({\n",
        "    'Metric': ['Protected at creation', 'Needs reactive relabeling'],\n",
        "    'Percent': [94, 6]\n",
        "})\n",
        "\n",
        "plt.figure(figsize=(8, 4))\n",
        "ax = sns.barplot(data=plot_df, x='Metric', y='Percent', palette=['#2E86DE', '#E74C3C'])\n",
        "ax.set_title('Operational Impact of Label Inheritance')\n",
        "ax.set_ylabel('Percent')\n",
        "ax.set_xlabel('')\n",
        "for container in ax.containers:\n",
        "    ax.bar_label(container, fmt='%.0f%%')\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Simulate a small file population with and without inheritance\n",
        "\n",
        "This hands-on simulation expands the blog's idea into a simple dataset. It shows how inheritance can reduce the number of unlabeled artifacts created during normal collaboration."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "without_inheritance = pd.DataFrame([\n",
        "    {'file': 'board_deck.pptx', 'labeled_at_creation': True},\n",
        "    {'file': 'speaker_notes.docx', 'labeled_at_creation': False},\n",
        "    {'file': 'board_deck.pdf', 'labeled_at_creation': False},\n",
        "    {'file': 'extract.xlsx', 'labeled_at_creation': False},\n",
        "    {'file': 'summary.docx', 'labeled_at_creation': False},\n",
        "])\n",
        "\n",
        "with_inheritance = pd.DataFrame([\n",
        "    {'file': 'board_deck.pptx', 'labeled_at_creation': True},\n",
        "    {'file': 'speaker_notes.docx', 'labeled_at_creation': True},\n",
        "    {'file': 'board_deck.pdf', 'labeled_at_creation': True},\n",
        "    {'file': 'extract.xlsx', 'labeled_at_creation': True},\n",
        "    {'file': 'summary.docx', 'labeled_at_creation': True},\n",
        "])\n",
        "\n",
        "summary = pd.DataFrame([\n",
        "    {\n",
        "        'Scenario': 'Without inheritance',\n",
        "        'ProtectedAtCreationPct': without_inheritance['labeled_at_creation'].mean() * 100,\n",
        "        'UnlabeledAtCreationPct': (1 - without_inheritance['labeled_at_creation'].mean()) * 100\n",
        "    },\n",
        "    {\n",
        "        'Scenario': 'With inheritance',\n",
        "        'ProtectedAtCreationPct': with_inheritance['labeled_at_creation'].mean() * 100,\n",
        "        'UnlabeledAtCreationPct': (1 - with_inheritance['labeled_at_creation'].mean()) * 100\n",
        "    }\n",
        "])\n",
        "\n",
        "display(summary)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Visualize the shift-left effect\n",
        "\n",
        "This chart compares the two scenarios side by side. It reinforces the blog's central claim that inheritance reduces cleanup by moving protection earlier in the workflow."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "melted = summary.melt(id_vars='Scenario', var_name='Measure', value_name='Percent')\n",
        "\n",
        "plt.figure(figsize=(9, 4))\n",
        "ax = sns.barplot(data=melted, x='Scenario', y='Percent', hue='Measure', palette='Set2')\n",
        "ax.set_title('Protect at Creation vs Scan and Remediate Later')\n",
        "ax.set_ylabel('Percent')\n",
        "ax.set_xlabel('')\n",
        "for container in ax.containers:\n",
        "    ax.bar_label(container, fmt='%.0f%%')\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Validate the governance stack conceptually\n",
        "\n",
        "The blog separates four layers: sensitivity labels, inheritance, DLP, and retention. This example creates a simple table to show their distinct roles so teams do not confuse inheritance with lifecycle or enforcement."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "governance_stack = pd.DataFrame([\n",
        "    {'Control': 'Sensitivity labels', 'Primary role': 'Define classification context'},\n",
        "    {'Control': 'Inheritance', 'Primary role': 'Carry context into related collaboration events'},\n",
        "    {'Control': 'DLP', 'Primary role': 'Detect and enforce policy on sensitive data movement'},\n",
        "    {'Control': 'Retention', 'Primary role': 'Control lifecycle, deletion, and preservation'}\n",
        "])\n",
        "\n",
        "display(governance_stack)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Test a rollout prioritization list\n",
        "\n",
        "The post recommends starting with boring, high-confidence workflows where unlabeled artifacts cause immediate pain. This example turns that recommendation into a simple prioritization table."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "priorities = pd.DataFrame([\n",
        "    {'Workflow': 'Executive or board materials', 'Exposure_if_unlabeled': 'High', 'Recommended_start': True},\n",
        "    {'Workflow': 'Finance and forecast content', 'Exposure_if_unlabeled': 'High', 'Recommended_start': True},\n",
        "    {'Workflow': 'HR investigation documents', 'Exposure_if_unlabeled': 'High', 'Recommended_start': True},\n",
        "    {'Workflow': 'Active legal matter workspaces', 'Exposure_if_unlabeled': 'High', 'Recommended_start': True},\n",
        "    {'Workflow': 'Engineering design libraries', 'Exposure_if_unlabeled': 'Medium', 'Recommended_start': True},\n",
        "    {'Workflow': 'General collaboration sites', 'Exposure_if_unlabeled': 'Low', 'Recommended_start': False}\n",
        "])\n",
        "\n",
        "display(priorities.sort_values(by=['Recommended_start', 'Exposure_if_unlabeled'], ascending=[False, True]))"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Summary\n",
        "\n",
        "Purview label inheritance matters because it reduces the gap between classification intent and day-to-day collaboration reality. It helps protect related files at creation time, lowers dependence on repeated user decisions, and reduces cleanup effort when used alongside DLP and retention.\n",
        "\n",
        "## Next Steps\n",
        "\n",
        "- Replace the sample datasets with your own site, library, and file metrics.\n",
        "- Add workload-specific tests for SharePoint, OneDrive, Office files, and PDFs.\n",
        "- Compare pre-rollout and post-rollout relabeling effort in your environment.\n",
        "- Validate where inheritance helps most: finance, HR, legal, or executive collaboration.\n",
        "- Use findings to refine label taxonomy before expanding automation further."
      ]
    }
  ]
}