💡 Voll funktionsfähiges Beispiel auf GitHub verfügbar:
sanitize-office-document-pii-python

Die Daten, die niemand prüft, bevor er auf Senden klickt

Ein vierteljährlicher Vorstandbericht wird an einen externen Prüfer gesendet. Der Text ist makellos; drei Überprüfungszyklen haben das sichergestellt. Die Datei selbst erzählt eine andere Geschichte. Ihre Eigenschaften nennen noch immer den Analysten, der sie erstellt hat, den Manager, der sie überarbeitet hat, die Unternehmens‑Tochtergesellschaft, die die Vorlage besitzt, einen LastPrinted‑Zeitstempel von der Nacht vor der Frist und eine SharePoint‑Genehmiger‑ID aus dem internen Freigabe‑Workflow. Keines davon erscheint auf einer Seite. Alles reist mit der Datei mit.

Die Entfernung von PII ist ein GroupDocs.Metadata‑Workflow für Python via .NET, der diese identitätsbezogenen Eigenschaften aus Word-, Excel‑ und PowerPoint‑Dateien programmgesteuert entfernt. Dieser Artikel vergleicht die drei von der API angebotenen Ansätze: tag‑gesteuerte Entfernung für Identitätsfelder, namensbasierte Musterentfernung für Eigenschaftsfamilien wie Kommentare und Revisionen sowie den Einmalaufruf sanitize(), der alles löscht. Außerdem sehen Sie den Schritt, den die meisten Bereinigungsskripte überspringen – einen Verifizierungsscan, der beweist, dass die Bereinigung tatsächlich gehalten wurde.

Warum Metadaten‑PII eine eigene Pipeline verdient

Werkzeuge zur Inhaltsprüfung prüfen, was Menschen lesen. Sie prüfen nicht, was Dateisysteme speichern, und genau diese Lücke verursacht Compliance‑Vorfälle. Eine DSGVO‑Anfrage umfasst personenbezogene Daten in den Feldern Author und Manager genauso wie Daten im Text. Rechtliche Discovery liest Revisionszähler und Bearbeitungszeit‑Summen, um nachzuvollziehen, wie lange ein Positionspapier verhandelt wurde. Ausschreibungsprüfer können Ihre Organisationsstruktur aus SharePoint‑Workflow‑Eigenschaften ableiten, und die Kommentar‑Felder einer Pressemitteilung bewahren Reviewer‑Namen neben Entwurfs‑Anmerkungen. Jeder dieser Punkte ist ein Befund. Keiner von ihnen ist im Dokumentenkörper sichtbar.

Voraussetzungen

Bevor Sie beginnen, stellen Sie sicher, dass Sie haben:

  • Python 3 mit pip
  • GroupDocs.Metadata für Python via .NET, im Beispiel‑Repository auf Version 26.5 festgelegt
  • Eine Office‑Datei mit echten Eigenschaften zum Üben

Installation

pip install groupdocs-metadata-net==26.5

Das companion repository liefert ein Beispiel‑DOCX und führt jedes untenstehende Snippet als behauptete Pipeline aus.

Methode 1: Tag‑gesteuerte Identitätsentfernung

Die vier sensibelsten Felder, Author, LastSavedBy, Manager und Company, haben in den verschiedenen Office‑Formaten unterschiedliche interne Namen. Das Tag‑System löst das: Anstatt Eigenschaften zu benennen, fragt das Prädikat nach allem, das als Person oder Unternehmen getaggt ist.

# Match identity properties by meaning, not by format-specific name
with Metadata("board-report.docx") as metadata:
    removed = metadata.remove_properties(lambda p:
        Tags.person.creator in list(p.tags)     # Author, LastSavedBy
        or Tags.person.editor in list(p.tags)
        or Tags.person.manager in list(p.tags)
        or Tags.corporate.company in list(p.tags))
    metadata.save("board-report-clean.docx")

print(f"{removed} identity properties removed")

Wichtige Punkte:

  • Formatunabhängigkeit: Das gleiche Lambda bereinigt DOCX, XLSX und PPTX, weil Tags nach Rolle klassifizieren.
  • Zählbares Ergebnis: remove_properties gibt zurück, wie viele Eigenschaften zutrafen, was in Ihr Audit‑Log gehört.
  • Kopiersemantik: Das Speichern unter einem neuen Pfad behält das Original für Ihre Unterlagen.

💡 Tipp: Dieser Durchlauf bewahrt Title, Subject und andere beschreibende Felder, sodass die Datei für Suche und DMS‑Indexierung freundlich bleibt.

Methode 2: Namens‑Muster‑Entfernung für Eigenschaftsfamilien

Tags decken klassifizierte Konzepte ab. Ganze Familien von leaky‑Feldern liegen außerhalb dieser Klassifizierung: Kommentar‑Eigenschaften, Revisionszähler, SharePoint‑Workflow‑Stempel. Für diese wird der Eigenschaftsname selbst gematcht.

# Comment fields often live in custom properties the tag system
# does not classify, so match them by name substring
with Metadata("board-report.docx") as metadata:
    removed = metadata.remove_properties(lambda p:
        p.name is not None and (
            "Comment" in p.name
            or "Reviewer" in p.name
            or "Reviewed" in p.name))
    metadata.save("board-report-no-comments.docx")

Die gleiche Form behandelt die anderen beiden Familien; nur die Teilstring‑Liste ändert sich:

Familie Zu matchende Teilstrings
Revisionsverlauf Revision, TrackedChange, LastPrinted, TotalEditingTime, EditTime
Server / Workflow Server, Workflow, Approver, ContentType, Template

Dies tauscht Präzision gegen Reichweite: "Comment" fängt auch Comments und CommentCount ab, was normalerweise das Ziel eines Bereinigungsdurchlaufs ist. Breite Teilstrings können auch harmlose Vorlagenfelder treffen, daher sollten Sie die zurückgegebene Anzahl gegen Erwartungen prüfen.

💡 Tipp: Führen Sie jede Familie als eigenen Durchlauf aus, wenn Ihr Audit‑Log pro‑Kategorie‑Zählungen benötigt; fassen Sie die Teilstrings zu einem Prädikat zusammen, wenn das nicht nötig ist.

Methode 3: Der Einmalaufruf für vollständige Bereinigung

Wenn die Datei das Unternehmen verlässt und nichts aus der Metadaten‑Schicht überleben soll, verzichten Sie auf Prädikate.

# One call, every detected metadata package
with Metadata("board-report.docx") as metadata:
    removed = metadata.sanitize()
    metadata.save("board-report-final.docx")

print(f"sanitize() removed {removed} properties")

sanitize() löscht jedes von der Bibliothek erkannte Paket: Dokument‑Info‑Identitätsfelder, Kommentare, Revisionshistorie, Autoren von nachverfolgten Änderungen und benutzerdefinierte OOXML‑Teile. Das Verhalten ist auf der Seite Clean metadata dokumentiert. Seine Stärke ist zugleich sein Nachteil. Title und Subject verschwinden zusammen mit den PII, weshalb es am Export‑Tor und nicht mitten im Kollaborations‑Workflow eingesetzt werden sollte.

Brauche ich alle vier gezielten Durchläufe?

Nein. Jeder Durchlauf existiert, weil ein anderes Team das Risiko trägt. Identitätsfelder beunruhigen Datenschutzbeauftragte, Kommentarspuren das Rechts‑Team, Revisionszähler die Verhandler und Server‑Felder die Sicherheit. Führen Sie die Durchläufe aus, die zu Ihren Prüfern passen, in beliebiger Reihenfolge, da jeder seine eigene Ausgabekopie schreibt. Wenn niemand überlebende Felder benötigt, springen Sie direkt zu sanitize() und verifizieren.

Vergleich der drei Ansätze

Methode Am besten für Wesentliche Vorteile Einschränkungen
Tag‑gesteuerte Entfernung Arbeitskopien, Multi‑Format‑Pipelines Formatunabhängig, bewahrt beschreibende Felder Deckt nur tag‑klassifizierte Konzepte ab
Namens‑Muster‑Entfernung Kommentare, Revisionen, Server‑Felder Erreicht benutzerdefinierte Eigenschaften, die Tags übersehen Teilstrings müssen pro Umgebung abgestimmt werden
Vollständiges sanitize() Endexport außerhalb des Unternehmens Kann keine vergessene Eigenschaft übersehen Löscht auch harmlose Felder

Die Ansätze lassen sich natürlich kombinieren: gezielte Durchläufe, solange das Dokument aktiv ist, sanitize() beim Versand.

Verifizieren, bevor Sie vertrauen

Ein Entfernen‑Aufruf, der eine Anzahl zurückgibt, ist kein Beweis dafür, dass die Datei sauber ist. Das Repository beendet jeden Lauf, indem es die bereinigte Ausgabe erneut öffnet und mit find_properties scannt, wobei ein Prädikat verwendet wird, das die Tag‑Regeln und Namens‑Regeln aller oben genannten Durchläufe kombiniert.

def is_pii(p):
    if p.name is None:
        return False
    return (
        Tags.person.creator in list(p.tags)
        or Tags.person.editor in list(p.tags)
        or Tags.person.manager in list(p.tags)
        or Tags.corporate.company in list(p.tags)
        or any(n in p.name for n in (
            "Comment", "Reviewer", "Revision", "TrackedChange",
            "Classification", "Department", "Server", "Workflow")))

with Metadata("board-report-final.docx") as metadata:
    for p in metadata.find_properties(is_pii):
        value = (str(p.interpreted_value) if p.interpreted_value is not None
                 else (str(p.value) if p.value is not None else ""))
        if value and value not in ("0", "0.0"):
            print(f"LEAK {p.name}={value}")

Die vollständige Version im Repository sortiert Überlebende in zwei Buckets, und die Unterscheidung ist wichtig. Metadaten‑Lecks müssen null sein. Inhalte‑seitige Überbleibsel, Word‑Kommentar‑Ballons und nachverfolgte Änderungen in word/document.xml, sind Body‑Inhalte, die eine Metadaten‑API nicht erreichen kann; deren Entfernung erfordert eine Inhalts‑Bearbeitungs‑Bibliothek wie Aspose.Words. Ein ehrlicher Bericht nennt beide Buckets, anstatt den Sieg bereits beim ersten zu erklären. Beim ersten Durchlauf dieses Scans auf einer „sauberen“ Datei wurde ein Department‑Feld markiert, das eine Unternehmensvorlage stillschweigend seit Monaten wieder hinzufügte.

Best Practices und Tipps

  • Kopien bereinigen, niemals Originale: Jedes Snippet hier schreibt in einen neuen Pfad und bewahrt das Original für Ihre Unterlagen und Aufbewahrungsregeln.
  • Zählungen protokollieren: Die Rückgabewerte von remove_properties und sanitize() bilden Ihr Audit‑Trail. Speichern Sie sie pro Datei, pro Durchlauf.
  • Verifizierung in CI einbinden: Ein Leak‑Check, der den Build fehlschlagen lässt, fängt Vorlagen‑Regressionen am Tag ihres Auftretens ab, nicht am Tag, an dem ein Kunde es bemerkt.
  • Grenze zwischen Metadaten und Inhalt beachten: Meldet nie eine Datei als sauber, solange body‑level‑Kommentare verbleiben; stellen Sie sie als separaten Befund dar.
  • Lizenzierung: Der Evaluierungsmodus reproduziert alles in diesem Artikel; verwenden Sie in der Produktion eine Lizenz, damit keine Evaluierungs‑Markierungen ausgehende Dateien berühren.

Fazit

Drei Ansätze, eine Entscheidungsregel. Nutzen Sie Tags, wenn das Konzept klassifiziert ist und die Datei weiterhin nutzbar bleiben muss. Nutzen Sie Namen, wenn die Familie in benutzerdefinierten Eigenschaften lebt. Rufen Sie sanitize() auf, wenn die Datei die Vertrauensgrenze überschreitet, und verifizieren Sie mit einem Rücklese‑Scan, welchen Weg Sie auch gewählt haben.

Bereit, tiefer einzusteigen? Hier sind einige nächste Schritte:

Zusätzliche Ressourcen

Haben Sie Fragen oder möchten Ihre Implementierung teilen? Kontaktieren Sie uns im support forum.