Feinsteuerung des Zugriffs auf Feld- und Dokumentebene
In einem gemeinsam genutzten Elasticsearch-Index liegen häufig Dokumente, die nicht jede Nutzerrolle vollständig sehen darf. Ein Produktdokument enthält neben öffentlichen Feldern wie Name und Beschreibung oft auch interne Daten wie Einkaufspreise, Lieferantenkonditionen oder Margenkalkulationen, die ausschließlich für bestimmte Abteilungen bestimmt sind. Getrennte Indizes für jede Sichtbarkeitsstufe zu pflegen ist aufwendig und fehleranfällig, sobald sich Rollen oder Datenmodelle ändern. Die Security-API von Elasticsearch bietet dafür zwei ergänzende Mechanismen direkt auf Rollenebene: Field-Level Security blendet einzelne Felder für bestimmte Rollen aus der Antwort aus, während Document-Level Security ganze Dokumente über einen Query-Filter unsichtbar macht, bevor sie überhaupt in die Trefferliste gelangen. Wie beide Mechanismen konfiguriert werden, wie sie sich kombinieren lassen und welche Fallstricke bei Aggregationen und Performance lauern, zeigt dieser Artikel an einem praxisnahen Beispiel mit rollenabhängigen Einkaufspreisen.
Inhaltsverzeichnis
- 1. Das Grundproblem: ein Index, viele Sichtbarkeitsstufen
- 2. Field-Level Security: Felder pro Rolle gezielt ausblenden
- 3. Document-Level Security: Zugriffsfilter über eine Query
- 4. Praxisbeispiel: Einkaufspreise nur für die Einkaufsrolle sichtbar
- 5. FLS und DLS kombinieren: eine Rolle, zwei Mechanismen
- 6. Auswirkungen auf Aggregationen, Scoring und Highlighting
- 7. Performance: Query-Rewriting-Kosten und Caching von Rollen-Queries
- 8. Fallstricke beim Debugging: Nested Felder, Runtime Fields, verschachtelte Rollen
- 9. Einführungsstrategie und Audit über die Security-API
- 10. Zusammenfassung
- 11. FAQ
1. Das Grundproblem: ein Index, viele Sichtbarkeitsstufen
Ein zentraler Produktindex, der von Einkauf, Vertrieb und Kundenservice gemeinsam genutzt wird, spart Pflegeaufwand und garantiert konsistente Daten über alle Abteilungen hinweg. Genau das wird jedoch zum Problem, sobald einzelne Felder oder ganze Dokumente nur für bestimmte Rollen sichtbar sein dürfen, etwa der Einkaufspreis, interne Lieferantenkonditionen oder Bestellungen einer bestimmten Vertriebsregion. Ein zweiter, komplett separater Index nur für sensible Felder erzeugt doppelte Pflege, Synchronisationsaufwand und zusätzliche Joins auf Anwendungsseite, was bei jeder Schemaänderung erneut zu Inkonsistenzen führen kann.
Elasticsearch löst dieses Problem direkt in der Security-API auf Rollenebene, ohne dass die Anwendung selbst Felder herausfiltern oder Ergebnislisten nachträglich bereinigen muss. Zwei Mechanismen stehen dafür bereit: Field-Level Security wirkt auf der Ebene einzelner Feldnamen innerhalb eines Dokuments, Document-Level Security wirkt auf der Ebene ganzer Dokumente über einen automatisch angehängten Query-Filter. Beide werden zentral in der Rollendefinition gepflegt und greifen bei jeder Suchanfrage automatisch, unabhängig davon, über welchen Client oder welche Anwendung die Anfrage kommt.
2. Field-Level Security: Felder pro Rolle gezielt ausblenden
Field-Level Security wird über das Objekt field_security in der Rollendefinition konfiguriert und besteht aus zwei Listen: grant legt fest, welche Felder für diese Rolle grundsätzlich sichtbar sind, meist als Wildcard-Ausdruck wie * für alle Felder, während except aus dieser Menge gezielt einzelne Felder wieder herausnimmt. Diese Kombination erlaubt es, mit wenigen Zeilen eine Blacklist statt einer aufwendigen Whitelist zu pflegen, was bei Indizes mit vielen Feldern deutlich wartungsärmer ist als jedes erlaubte Feld einzeln aufzuzählen.
Ausgeblendete Felder erscheinen weder in _source noch lassen sie sich für diese Rolle durchsuchen, sortieren oder in Aggregationen verwenden. Sie tauchen auch nicht im Highlighting auf, selbst wenn der Suchbegriff zufällig im ausgeblendeten Feld vorkäme. Metafelder wie _id, _index oder _score bleiben davon unberührt, da Field-Level Security ausschließlich auf benutzerdefinierte Felder des Mappings wirkt.
PUT /_security/role/vertrieb_rolle
{
"indices": [
{
"names": ["produkte"],
"privileges": ["read"],
"field_security": {
"grant": ["*"],
"except": ["einkaufspreis", "lieferant.*", "margen_kalkulation"]
}
}
]
}
3. Document-Level Security: Zugriffsfilter über eine Query
Document-Level Security funktioniert grundsätzlich anders: Statt einzelne Felder auszublenden, hinterlegt man in der Rolle ein query-Objekt, das Elasticsearch bei jeder Suchanfrage dieser Rolle automatisch als zusätzlichen Filter anhängt. Technisch geschieht das wie eine implizite bool-Query mit einer filter-Klausel, die vor allen anderen Query-Bestandteilen ausgewertet wird. Dokumente, die diese Query nicht erfüllen, tauchen für die betroffene Rolle in keiner Suchanfrage auf, weder in Treffern noch in Aggregationen noch im Trefferzähler hits.total.
Besonders praktisch wird Document-Level Security durch Template-Ausdrücke, die auf Metadaten des angemeldeten Nutzers zugreifen können, etwa {{_user.metadata.region}}. So lässt sich eine einzige Rollendefinition für viele Nutzer wiederverwenden, während jeder Nutzer über seine individuellen Metadaten trotzdem nur die für ihn passenden Dokumente sieht, ohne dass für jede Region oder jede Abteilung eine eigene Rolle angelegt werden muss.
PUT /_security/role/kundenservice_region
{
"indices": [
{
"names": ["bestellungen"],
"privileges": ["read"],
"query": {
"template": {
"source": {
"term": { "region": "{{_user.metadata.region}}" }
}
}
}
}
]
}
4. Praxisbeispiel: Einkaufspreise nur für die Einkaufsrolle sichtbar
Im praktischen Szenario existieren zwei Rollen für denselben Produktindex. Die Rolle einkauf_rolle erhält vollen Feldzugriff ohne Einschränkung, während vertrieb_rolle über field_security gezielt den Einkaufspreis und die Lieferantenfelder ausblendet. Beide Rollen greifen auf exakt dieselben physischen Dokumente zu, es existiert kein zweiter Index und keine Kopie der Daten, wodurch Preisänderungen sofort für beide Rollen konsistent sichtbar beziehungsweise unsichtbar sind.
Ist einem Nutzer sowohl Einkauf als auch Vertrieb zugewiesen, kombiniert Elasticsearch die Field-Level-Security-Grants additiv als Vereinigungsmenge, sodass der Nutzer am Ende alle Felder sieht, die mindestens eine seiner Rollen erlaubt. Diese additive Logik ist beim Rollendesign wichtig: Eine zu breit gefasste Zusatzrolle kann versehentlich Felder freigeben, die eigentlich über eine andere, restriktivere Rolle geschützt werden sollten.
PUT /_security/role/einkauf_rolle
{
"indices": [
{ "names": ["produkte"], "privileges": ["read"] }
]
}
// Suchanfrage der vertrieb_rolle liefert kein "einkaufspreis"-Feld:
GET /produkte/_search
{ "query": { "match": { "name": "Werkzeugkoffer" } } }
// Antwort enthält nur öffentliche Felder in _source
5. FLS und DLS kombinieren: eine Rolle, zwei Mechanismen
Field-Level Security und Document-Level Security schließen sich nicht gegenseitig aus, im Gegenteil: In der Praxis werden sie häufig gemeinsam in derselben Rollendefinition verwendet. Elasticsearch wertet dabei zuerst die Document-Level-Security-Query aus und reduziert die Trefferliste auf die für die Rolle sichtbaren Dokumente, anschließend wendet es Field-Level Security auf die verbliebenen Treffer an und blendet die konfigurierten Felder aus. Diese Reihenfolge stellt sicher, dass beide Mechanismen unabhängig voneinander gepflegt werden können, ohne dass sich ihre Wirkung gegenseitig beeinflusst.
Ein Kundenservice-Mitarbeiter könnte so über Document-Level Security ausschließlich Bestellungen der eigenen Region sehen und gleichzeitig über Field-Level Security keinen Zugriff auf hinterlegte Zahlungsdaten erhalten. Beide Regeln stehen in derselben Rolle, werden aber unabhängig gepflegt, sodass eine Änderung an der Regionsfilterung keinen Einfluss auf die Feldsichtbarkeit hat und umgekehrt.
6. Auswirkungen auf Aggregationen, Scoring und Highlighting
Weil Document-Level Security als impliziter Filter vor jeder Anfrage greift, berücksichtigen auch Aggregationen automatisch nur die für die jeweilige Rolle sichtbaren Dokumente. Eine Summenaggregation über Bestellwerte liefert für die Kundenservice-Rolle also automatisch nur die Summe der eigenen Region, ohne dass die Anwendung selbst zusätzliche Filter in die Aggregationsanfrage einbauen muss. Das verhindert ein häufiges Datenleck, bei dem Einzeldokumente korrekt gefiltert werden, aggregierte Kennzahlen aber versehentlich über die gesamte Datenmenge berechnet werden.
Bei Field-Level Security gilt: Eine Aggregation oder Sortierung auf einem ausgeblendeten Feld schlägt für die betroffene Rolle fehl, da das Feld für sie schlicht nicht existiert. Highlighting funktioniert ebenfalls nur auf sichtbaren Feldern, ein Treffer im ausgeblendeten Feld wird weder hervorgehoben noch fließt er in den Score ein, sodass ausgeblendete Felder auch die Relevanzsortierung nicht beeinflussen.
7. Performance: Query-Rewriting-Kosten und Caching von Rollen-Queries
Document-Level Security baut die hinterlegte Query bei jeder Suchanfrage in die tatsächlich ausgeführte Query ein, was Elasticsearch über einen speziellen Bitset-Cache für Rollen-Queries beschleunigt. Wiederkehrende, identisch formulierte Rollen-Queries werden als Bitset zwischengespeichert und müssen nicht bei jeder Anfrage neu ausgewertet werden. Bei sehr vielen individuell unterschiedlichen Rollen, etwa einer eigenen Query pro einzelnem Nutzer statt pro Abteilung, wächst dieser Cache jedoch schnell und die Trefferquote im Cache sinkt, was zusätzliche CPU-Last erzeugt.
Field-Level Security verursacht dagegen praktisch keinen messbaren Overhead zur Laufzeit, da die Filterung erst beim Zusammenstellen der Antwort stattfindet und nicht in den eigentlichen Suchalgorithmus eingreift. Empfehlenswert ist deshalb, Rollen möglichst grob nach Funktionsgruppen statt pro einzelnem Nutzer zu modellieren, sowohl aus Gründen der Wartbarkeit als auch, damit der Rollen-Query-Cache seine Wirkung behält.
8. Fallstricke beim Debugging: Nested Felder, Runtime Fields, verschachtelte Rollen
Document-Level-Security-Queries auf nested-Feldern müssen als korrekte nested-Query formuliert werden, sonst greift der Filter nicht wie erwartet und liefert entweder zu viele oder gar keine Treffer, weil eine einfache term-Query gegen ein nested-Feld strukturell ins Leere läuft. Ebenso kollidieren Runtime Fields gelegentlich mit Field-Level Security: Ein Skript, das intern auf ein für die Rolle eigentlich gesperrtes Feld zugreift, kann inkonsistente Ergebnisse liefern, da der Zugriffsschutz je nach Elasticsearch-Version nicht konsequent bis in jedes Runtime-Skript durchgereicht wird.
Sind einem Nutzer mehrere Rollen zugewiesen, kombiniert Elasticsearch die Document-Level-Security-Queries per logischem Oder, was zu einer unerwartet breiten Sichtbarkeit führen kann, wenn eine der Rollen großzügiger konfiguriert ist als beabsichtigt. Zum gezielten Testen einer Rollenkonfiguration eignen sich die Endpunkte _security/user/_has_privileges sowie das Ausführen von Testanfragen mit einem eigens dafür angelegten Testnutzer, bevor eine Rolle produktiv Anwendung findet.
9. Einführungsstrategie und Audit über die Security-API
Bei der Einführung empfiehlt sich ein schrittweises Vorgehen: Zunächst wenige grobe Rollen entlang der Hauptabteilungen definieren, diese mit Testnutzern und realistischen Suchanfragen verifizieren und erst danach feiner nach einzelnen Feldern oder Regionen ausdifferenzieren. Jede neue Rolle sollte vor dem produktiven Einsatz gegen konkrete Beispieldokumente getestet werden, um sicherzustellen, dass weder zu viel noch zu wenig sichtbar ist.
Für die laufende Kontrolle bietet Elasticsearch Audit-Logging, das protokolliert, welche Rolle welche Anfrage gestellt und welche Zugriffsentscheidung dabei gegriffen hat. Eine regelmäßige Überprüfung der Rollenzuordnungen, insbesondere nach organisatorischen Änderungen wie Abteilungswechseln, schließt eine typische Sicherheitslücke, bei der ehemals korrekt vergebene Rollen über die Zeit zu weit gefasst bleiben.
| Aspekt | Field-Level Security | Document-Level Security | Praxisrelevanz |
|---|---|---|---|
| Wirkungsebene | Einzelne Felder in Treffern | Ganze Dokumente vor der Trefferliste | FLS für sensible Attribute, DLS für Mandantentrennung |
| Konfiguration | grant/except in field_security | query-Objekt in der Rolle | Beide Teile derselben Rollendefinition |
| Performance-Kosten | Praktisch vernachlässigbar | Query-Rewriting mit Bitset-Cache | DLS bei sehr vielen Rollen beobachten |
| Aggregationen | Feld existiert für Rolle nicht | Automatisch nur sichtbare Dokumente | DLS verhindert Datenlecks über Kennzahlen |
| Kombination mehrerer Rollen | Grants werden additiv vereinigt | Queries werden per Oder verknüpft | Rollenkombinationen sorgfältig planen |
Mironsoft
Suchindex-Setup, Relevanz-Tuning und Magento-Suche
Magento-Suche, die die falschen Produkte zuerst zeigt?
Wir richten Elasticsearch oder OpenSearch für Magento sauber ein, tunen Relevanz und Facetten auf das tatsächliche Sortiment und optimieren Indexierungsprozesse für große Kataloge.
Relevanz-Tuning
Suchergebnisse und Facetten auf die tatsächlichen Kundenbedürfnisse abstimmen.
Such-Migration
Umstieg von Solr oder MySQL-Suche auf Elasticsearch/OpenSearch sauber begleiten.
Index-Performance
Indexierungsprozesse für große Kataloge zuverlässig und performant gestalten.
10. Zusammenfassung
Field-Level und Document-Level Security: Das Wichtigste auf einen Blick
Grundprinzip
Field-Level Security blendet einzelne Felder für eine Rolle aus, Document-Level Security filtert über eine Query ganze Dokumente, bevor sie in die Trefferliste gelangen.
Konfiguration
Beide Mechanismen werden zentral in der Rollendefinition der Security-API gepflegt und greifen automatisch bei jeder Suchanfrage, unabhängig vom Client.
Kombination
Eine Rolle kann field_security und query gleichzeitig nutzen, wobei Elasticsearch zuerst Dokumente filtert und dann Felder ausblendet.
Empfehlung
Rollen grob nach Funktionsgruppen modellieren statt pro Nutzer, um Wartbarkeit und den Rollen-Query-Cache nicht zu belasten.