Miros Splunk-Integration ermöglicht es Enterprise-Kunden, zwei Arten von Protokolldaten in Splunk zu exportieren, um erweiterte Sicherheitsüberwachung, Compliance-Berichterstattung und Betriebsanalysen im gesamten Unternehmen durchzuführen. Diese Integration unterstützt:
- Audit-Protokolle: Erfasse Nutzer- und Systemaktivitäten in deiner gesamten Organisation, wie z. B. den Nutzerzugang, das Teilen von Boards, Änderungen von Berechtigungen, App-Installationen, Logins und administrative Aktionen.
-
Inhaltsprotokolle (Enterprise-Guard-Add-on): Erfasse detaillierte Aktivitäten auf Inhaltsebene innerhalb von Miro-Boards, wie die Erstellung, Bearbeitung und Löschung von Board-Objekten (Widgets, Haftnotizen, Bilder, Text, Rahmen) sowie Kommentaraktivitäten.
Best Practices
- Verwenden Sie separate Indizes für Audit-Protokolle und Inhaltsprotokolle.
- Aufbewahrungsfristen basierend auf Compliance-Anforderungen planen.
- Überprüfe beide Protokolltypen zusammen für eine umfassende Aktivitätsüberwachung.
Voraussetzungen
- Enterprise-Preisplan-Abo.
- Add-on „Enterprise Guard“ ist erforderlich, um Inhaltsprotokolle zu aktivieren.
- Admin-Zugriff auf beide:
- Miro Adminkonsole (um SIEM zu aktivieren und Tokens zu generieren)
- Splunk-Instanz (zum Konfigurieren von Dateneingaben)
Zugriffstoken in Miro generieren
Sowohl Audit-Protokoll- als auch Inhaltsprotokoll-Token können an derselben Stelle in Miro generiert werden:
- Navigiere in deinem Admin-Console zu Enterprise-Integrationen → Apps & Integrationen.
- Für Audit-Protokolle: Aktiviere den SIEM-Umschalter.
Für Inhaltsprotokolle: Aktiviere den eDiscovery-Umschalter.
Alternativ kannst du Tokens generieren, indem du eine benutzerdefinierte Miro-App mit den Geltungsbereichen auditlogs:read, contentlogs:export registrierst.
⚠️ Audit-Protokolle und Inhaltsprotokolle verwenden separate Tokens. Wähle das richtige Token für jeden Eingabetyp aus.
Du benötigst auch deine Organisations-ID – diese kann aus der URL deiner Adminkonsole kopiert werden:https://miro.com/app/org/{organization_id}/...
Installation und Konfiguration der Splunk-App für Miro
- Installiere die Miro Splunk App von Splunkbase.
- In deiner Splunk-Instanz gehe zu Miro-App → Inputs.
- Klicke auf Neue Eingabe erstellen.
- Wähle den gewünschten Eingabetyp aus: Audit-Protokolle oder Content-Protokolle (für Enterprise Guard-Kunden).
- Bitte gib die folgenden Informationen an:
- Token – Wähle das passende Token basierend auf dem Eingabetyp aus.
- Unternehmens-ID.
- Zeitintervall – bestimmt, wie oft Splunk neue Ereignisse abruft.
- Index – gib an, welchen Index du zum Speichern von Protokolldaten verwenden möchtest. Für Inhaltsprotokolle wird ein separates Index aufgrund des höheren Volumens und der Datensensibilität empfohlen.
Sobald konfiguriert, beginnt Splunk mit der Erfassung von Protokollereignissen von Miro.
Fehlerbehebung
- Stelle sicher, dass Tokens korrekt generiert und dem richtigen Eingabetyp zugeordnet werden.
- Bestätigen Sie, dass die Unternehmens-ID mit Ihrer Admin-Konsole übereinstimmt.
- Überprüfen Sie, ob die Indexe korrekt erstellt und die Berechtigungen in Splunk zugewiesen sind.
So suchst du Protokolle in Splunk
Nachdem du die Dateneingaben konfiguriert hast, kannst du in Splunk nach Protokollen suchen und diese analysieren, indem du die von dir zugewiesenen Indizes für Audit-Protokolle und Inhaltsprotokolle verwendest.
-
Audit-Protokolle:
index="your_audit_index" source="miro_audit_logs"
-
Inhaltsprotokolle:
index="your_content_index" source="miro_content_logs"
Ersetze your_audit_index
und your_content_index
durch die Indizes, die du während der Eingaberichtung angegeben hast. Du kannst die Standard-Splunk-Such-, Filter- und Visualisierungsfunktionen für beide Protokolltypen verwenden.
Datenvisualisierung in Splunk
Die Splunk-App für Miro enthält vorgefertigte Dashboards für Audit-Protokolle, die dir helfen, Nutzer- und Systemaktivitäten zu überwachen. Nachdem du die Content-Logs eingerichtet hast, kannst du mithilfe der Standard-Visualisierungstools von Splunk eigene Dashboards erstellen, um Änderungen am Board-Inhalt zu visualisieren.
Verwende Filter, Diagramme und zeitbasierte Grafiken, um Trends wie die folgenden zu analysieren:
- Löschungen oder Änderungen von Board-Inhalten im Laufe der Zeit
- Spitzenerkennung für die Masseninhaltsänderungen
- Nutzeraktivität auf sensiblen Boards
✏️ Die sofort einsatzbereiten Dashboards in der Splunk-App sind derzeit für Audit-Protokolle konzipiert. Content-Protokolle können je nach den Anforderungen Ihrer Organisation durch benutzerdefinierte Suchanfragen und Dashboards analysiert werden.
<dashboard theme="light" version="1.1">
<label>Miro-Nutzeraktivität</label>
<description>Übersicht über Nutzereignisse in deinem Miro-Konto.</description>
<search id="basesearch">
<query>source=miro_audit_logs | fields * | eval context.team.name = if(isnull('context.team'), 'context.team.name', "None") | search context.organization.name = "$form.organization$" context.team.name = "$form.team$"</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>Zeitraum</label>
<default>
<earliest>-30d@d</earliest>
<latest>jetzt</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>Organisation</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| table context.organization.name | dedup context.organization.name</query>
</search>
<choice value="*">Alle</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>Team</label>
<choice value="*">Alle</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>context.team.name</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| table context.team.name | dedup context.team.name</query>
</search>
</input>Eingabe
</fieldset>
<row>
<panel>
<single>Einzeln
<title>Alle Ereignisse</title>
<search base="basesearch">
<query>| stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Veranstaltungen nach Datum</title>
<search base="basesearch">
<query>| timechart count as Events</query>
</search>
<option name="charting.axisTitleX.visibility">collapsed</option>
<option name="charting.axisTitleY.visibility">sichtbar</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">area</option>
<option name="charting.chart.nullValueMode">gaps</option>
<option name="charting.chart.stackMode">stacked</option>
<option name="charting.drilldown">none</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">standard</option>
<option name="charting.legend.placement">none</option>
<option name="refresh.display">progressbar</option>
</chart>
</panel>
<panel>
<chart>
<title>Events nach Team</title>
<search base="basesearch">
<query>| rename context.team.name as Team | stats count as "Events" by Team | sort - "Events"</query>
</search>
<option name="charting.chart">pie</option>
<option name="charting.chart.sliceCollapsingThreshold">0.03</option>
<option name="charting.drilldown">all</option>
<option name="refresh.display">progressbar</option>
<drilldown>
<set token="form.team">$click.value$</set>
</drilldown>
</chart>
</panel>
</row>
<row>
<panel>
<single>Einzel
<title>Board-Ereignisse</title>
<search base="basesearch">
<query>| search event = board_* | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
<panel>
<single>
<title>Erstellte Boards</title>
<search base="basesearch">
<query>| search event = board_created | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
<panel>
<single>
<title>Boards geöffnet</title>
<search base="basesearch">
<query>| search event = board_opened | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
</row>
<row>
<panel>Feld
<chart>
<title>Geöffnete oder erstellte Boards</title>
<search base="basesearch">
<query>| search event = board_created OR event = board_opened | timechart count as "Boards created" by event</query>
</search>
<option name="charting.axisTitleX.visibility">collapsed</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.chart">column</option>
<option name="charting.chart.stackMode">stacked</option>
<option name="charting.drilldown">none</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.placement">right</option>
<option name="refresh.display">progressbar</option>
</chart>
</panel>
</row>
</dashboard>
<dashboard theme="light" version="1.1">
<label>Sicherheit bei Miro</label>
<description>Übersicht über Sicherheitsereignisse in deinem Miro-Konto.</description>
<search id="basesearch">
<query>source=miro_audit_logs | fields * | search context.organization.name = "$form.organization$"</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>Zeitraum</label>
<default>
<earliest>-30d@d</earliest>
<latest>jetzt</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>Organisation</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| table context.organization.name | dedup context.organization.name</query>
</search>
<choice value="*">Alle</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>Team</label>
<choice value="*">Alle</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>context.team.name</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| table context.team.name | dedup context.team.name</query>
</search>
</input>
</fieldset>
<row>
<panel>
<single>Einzeln
<title>Erfolgreiche Anmeldungen</title>
<search base="basesearch">
<query>| search event = sign_in_succeeded | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
<panel>
<single>Einzel
<title>Fehlgeschlagene Anmeldungen</title>
<search base="basesearch">
<query>| search event = sign_in_failed | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Anmeldungen nach Authentifizierungsmethode</title>
<search base="basesearch">
<query>| search event = sign_in_* | timechart count as Events by details.authType</query>
</search>
<option name="charting.axisTitleX.visibility">collapsed</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">column</option>
<option name="charting.chart.nullValueMode">gaps</option>
<option name="charting.chart.stackMode">stacked</option>
<option name="charting.drilldown">none</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">standard</option>
<option name="charting.legend.placement">right</option>
<option name="refresh.display">progressbar</option>
</chart>
</panel>
</row>
<row>
<panel>
<table>
<title>Sharing events</title>
<search base="basesearch">
<query>| search event = *public_link* OR event = *sharing* | rename context.team.name as Team createdBy.name as User object.name as Board details.role as Details event as Event | table id _time Event Team User Board Details</query>
</search>
<option name="count">10</option>
<option name="drilldown">cell</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<title>Datei-Ereignisse</title>
<search base="basesearch">
<query>| search event = board_exported OR event = file_* | rename context.team.name as Team createdBy.name as User object.name as Board details.type as Type details.object as Object event as Event | table id _time Event Team User Board Type Object</query>
</search>
<option name="count">10</option>
<option name="drilldown">cell</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
</dashboard>
Abbildung 18: Dashboard bearbeiten
Nutzeraktivität
Die erste Visualisierung ist Nutzeraktivität, in der du einen Überblick über die Ereignisse deiner Nutzer in Miro findest. Dies sind:
- Die Anzahl der Ereignisse im Laufe der Zeit, nach Team und insgesamt.
-
Board-Ereignisse: erstellte Boards, geöffnete Boards und insgesamt.
Abbildung 19: Aktivität des Nutzers
<dashboard theme="light" version="1.1">
<label>Miro-Nutzeraktivität</label>
<description>Übersicht über die Ereignisse der Nutzer in deinem Miro-Konto.</description>
<search id="basesearch">
<query>source=miro_audit_logs | fields * | eval context.team.name = if(isnull('context.team'), 'context.team.name', "None") | search context.organization.name = "$form.organization$" context.team.name = "$form.team$"</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>Zeitraum</label>
<default>
<earliest>-30d@d</earliest>
<latest>jetzt</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>Organisation</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| table context.organization.name | dedup context.organization.name</query>
</search>
<choice value="*">Alle</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>Team</label>
<choice value="*">Alle</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>context.team.name</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| table context.team.name | dedup context.team.name</query>
</search>
</input>
</fieldset>
<row>
<panel>
<single>
<title>Gesamte Ereignisse</title>
<search base="basesearch">
<query>| stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Veranstaltungen nach Datum</title>
<search base="basesearch">
<query>| timechart count as Events</query>
</search>
<option name="charting.axisTitleX.visibility">collapsed</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">area</option>
<option name="charting.chart.nullValueMode">gaps</option>
<option name="charting.chart.stackMode">stacked</option>
<option name="charting.drilldown">none</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">standard</option>
<option name="charting.legend.placement">none</option>
<option name="refresh.display">progressbar</option>
</chart>
</panel>
<panel>
<chart>
<title>Events nach Team</title>
<search base="basesearch">
<query>| rename context.team.name as Team | stats count as "Events" by Team | sort - "Events"</query>
</search>
<option name="charting.chart">pie</option>
<option name="charting.chart.sliceCollapsingThreshold">0.03</option>
<option name="charting.drilldown">all</option>
<option name="refresh.display">progressbar</option>
<drilldown>
<set token="form.team">$click.value$</set>
</drilldown>
</chart>
</panel>
</row>
<row>
<panel>
<single>Einzel
<title>Board-Ereignisse</title>
<search base="basesearch">
<query>| search event = board_* | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
<panel>
<single>Einzel
<title>Erstellte Boards</title>
<search base="basesearch">
<query>| search event = board_created | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
<panel>
<single>Einzel
<title>Boards geöffnet</title>
<search base="basesearch">
<query>| search event = board_opened | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Geöffnete oder erstellte Boards</title>
<search base="basesearch">
<query>| search event = board_created OR event = board_opened | timechart count as "Boards created" by event</query>
</search>
<option name="charting.axisTitleX.visibility">collapsed</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.chart">column</option>
<option name="charting.chart.stackMode">stacked</option>
<option name="charting.drilldown">none</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.placement">right</option>
<option name="refresh.display">progressbar</option>
</chart>
</panel>
</row>
</dashboard>
Sicherheitsaktivität
Die zweite Visualisierung ist „Security Activity“, in der du einen Überblick über deine Nutzerereignisse in Miro findest. Dies sind:
- Login-Aktivität: die Anzahl der erfolgreichen und fehlgeschlagenen Anmeldungen.
-
Freigabeereignisse: Liste der Nutzererignisse beim Freigeben von Boards.
Abbildung 20: Sicherheitsaktivität
<dashboard theme="light" version="1.1">
<label>Miro Security Activity</label>
<description>Übersicht über die Sicherheitsereignisse in deinem Miro-Konto.</description>
<search id="basesearch">
<query>source=miro_audit_logs | fields * | search context.organization.name = "$form.organization$"</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>Zeitbereich</label>
<default>
<earliest>-30d@d</earliest>
<latest>jetzt</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>Organisation</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| table context.organization.name | dedup context.organization.name</query>
</search>
<choice value="*">Alle</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>Team</label>
<choice value="*">Alle</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>context.team.name</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| table context.team.name | dedup context.team.name</query>
</search>
</input>Eingabe
</fieldset>
<row>
<panel>
<single>Einzel
<title>Erfolgreiche Anmeldungen</title>
<search base="basesearch">
<query>| search event = sign_in_succeeded | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
<panel>
<single>
<title>Fehlgeschlagene Anmeldungen</title>
<search base="basesearch">
<query>| search event = sign_in_failed | stats count</query>
</search>
<option name="drilldown">none</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Anmeldungen nach Authentifizierungsmethode</title>
<search base="basesearch">
<query>| search event = sign_in_* | timechart count as Events by details.authType</query>
</search>
<option name="charting.axisTitleX.visibility">collapsed</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">column</option>
<option name="charting.chart.nullValueMode">gaps</option>
<option name="charting.chart.stackMode">stacked</option>
<option name="charting.drilldown">none</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">standard</option>
<option name="charting.legend.placement">right</option>
<option name="refresh.display">progressbar</option>
</chart>
</panel>
</row>
<row>
<panel>
<table>
<title>Sharing events</title>
<search base="basesearch">
<query>| search event = *public_link* OR event = *sharing* | rename context.team.name as Team createdBy.name as User object.name as Board details.role as Details event as Event | table id _time Event Team User Board Details</query>
</search>
<option name="count">10</option>
<option name="drilldown">cell</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<title>Datei-Ereignisse</title>
<search base="basesearch">
<query>| search event = board_exported OR event = file_* | rename context.team.name as Team createdBy.name as User object.name as Board details.type as Type details.object as Object event as Event | table id _time Event Team User Board Type Object</query>
</search>
<option name="count">10</option>
<option name="drilldown">cell</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
</dashboard>