La integración de Miro con Splunk permite a los clientes Enterprise exportar dos tipos de datos de registro a Splunk para un monitoreo avanzado de seguridad, informes de cumplimiento y análisis operativo en toda la organización. Esta integración admite:
- Registros de auditoría: capturan actividad a nivel de usuario y sistema en toda tu organización, como acceso de usuarios, compartición de tableros, cambios de permisos, instalaciones de aplicaciones, inicios de sesión y acciones administrativas.
-
Registros de contenido (complemento Enterprise Guard): captura de actividades detalladas a nivel de contenido dentro de los tableros de Miro, como la creación, edición y eliminación de objetos del tablero (widgets, notas adhesivas, imágenes, texto, marcos), así como también la actividad de comentarios.
Prácticas recomendadas
- Usa índices separados para registros de auditoría y registros de contenido.
- Planifica los períodos de retención según las necesidades de cumplimiento.
- Revisa ambos tipos de registros juntos para un monitoreo exhaustivo de la actividad.
Requisitos previos
- Suscripción del plan Enterprise.
- Se requiere el complemento de Enterprise Guard para habilitar los registros de contenido.
- Acceso de admin a ambos:
- Consola de admin de Miro (para habilitar SIEM y generar tokens)
- Instancia de Splunk (para configurar entradas de datos)
Generación de tokens de acceso en Miro
Tanto los tokens de registro de auditoría como los de registro de contenido se pueden generar desde la misma ubicación en Miro:
- Ve a Integraciones de Enterprise → Aplicaciones e Integraciones en tu Consola de Administración.
- Para registros de auditoría: Habilitar el interruptor SIEM.
Para registros de contenido: Habilitar la opción eDiscovery.
Alternativamente, genera tokens registrando una aplicación personalizada de Miro con los alcances: auditlogs:read, contentlogs:export.
⚠️ Los registros de auditoría y los registros de contenido usan tokens separados. Selecciona el token correcto para cada tipo de entrada.
También necesitarás tu ID de organización; esto se puede copiar de la URL de tu consola de admin:https://miro.com/app/org/{organization_id}/...
Instalar y configurar la aplicación de Splunk para Miro
- Instala la aplicación de Miro para Splunk de Splunkbase.
- En tu instancia de Splunk, ve a Aplicación de Miro → Entradas.
- Haz clic en Crear nueva entrada.
- Selecciona el tipo de entrada deseada: Registros de auditoría o Registros de contenido (para clientes de Enterprise Guard).
- Proporciona la siguiente información:
- Token — selecciona el token adecuado según el tipo de entrada.
- ID de la organización.
- Intervalo de tiempo — determina con qué frecuencia Splunk extrae nuevos eventos.
- Índice — especifica cuál índice usar para almacenar datos de registros. Para los registros de contenido, se recomienda un índice separado debido al mayor volumen y sensibilidad de los datos.
Una vez configurado, Splunk comenzará a recopilar eventos de registro de Miro.
Resolución de problemas
- Asegúrate de que los tokens se generen correctamente y se asignen al tipo de entrada adecuado.
- Verifica que la ID de la organización coincida con tu consola de admin.
- Verifica que los índices estén correctamente creados y que los permisos estén asignados en Splunk.
Cómo buscar registros en Splunk
Después de configurar las entradas de datos, puedes buscar y analizar los registros en Splunk usando los índices que asignaste para los Registros de auditoría y los Registros de contenido.
-
Registros de auditoría:
índice="your_audit_index" fuente="miro_audit_logs"
-
Registros de contenido:
índice="tu_índice_de_contenido" fuente="miro_content_logs"
Reemplaza your_audit_index y your_content_index con los índices que especificaste durante la configuración de entrada. Puedes usar las funciones estándar de búsqueda, filtrado y visualización de Splunk en ambos tipos de log.
Visualización de datos en Splunk
La aplicación de Splunk para Miro incluye paneles prediseñados para los registros de auditoría que te ayudan a monitorear la actividad de usuarios y del sistema. Después de configurar los registros de contenido, puedes crear paneles personalizados para visualizar los cambios de contenido a nivel de tablero usando las herramientas de visualización estándar de Splunk.
Usa filtros, gráficos y gráficas basadas en el tiempo para analizar tendencias como:
- Eliminaciones o cambios de contenido del tablero a lo largo del tiempo
- Detección de picos para modificaciones masivas de contenido
- Actividad de usuarios en tableros sensibles
Los paneles predefinidos en la aplicación Splunk están diseñados actualmente para los registros de auditoría. Los registros de contenido pueden ser analizados a través de consultas de búsqueda personalizadas y paneles según las necesidades de tu organización.
<dashboard theme="light" version="1.1">
<label>Actividad de usuario en Miro</label>
<description>Descripción general de los eventos de usuario en tu cuenta de Miro.</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>Más temprano</earliest>
<latest>$time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>Rango de tiempo</label>
<default>
<earliest>-30 d@d</earliest>
<latest>ahora</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>Organización</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| tabla context.organization.name | eliminar duplicados context.organization.name</query>
</search>
<choice value="*">Toda</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>Equipo</label>
<choice value="*">Todas</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>nombre.del.equipo</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| tabla context.team.name | dedup context.team.name</query>
</search>
</input>
</fieldset>
<row>
<panel>
<single>
<title>Eventos totales</title>
<search base="basesearch">
<query>| estadísticas cuenta</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Eventos por fecha</title>
<search base="basesearch">
<query>| timechart count as Eventos</query>
</search>
<option name="charting.axisTitleX.visibility">plegado</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">área</option>
<option name="charting.chart.nullValueMode">espacios</option>
<option name="charting.chart.stackMode">apilado</option>
<option name="charting.drilldown">ninguno</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">estándar</option>
<option name="charting.legend.placement">ninguno</option>
<option name="refresh.display">barra de progreso</option>
</chart>
</panel>
<panel>
<chart>
<title>Eventos por equipo</title>
<search base="basesearch">
<query>| renombrar context.team.name como Equipo | estadísticas contar como "Eventos" por Equipo | ordenar por "Eventos" descendente</query>
</search>
<option name="charting.chart">tarta</option>
<option name="charting.chart.sliceCollapsingThreshold">0,03</option>
<option name="charting.drilldown">todos</option>
<option name="refresh.display">barra de progreso</option>
<drilldown>
<set token="form.team">$click.value$</set>
</drilldown>
</chart>
</panel>
</row>
<row>
<panel>
<single>
<title>Eventos en el tablero</title>
<search base="basesearch">
<query>| búsqueda evento = tablero_* | estadísticas cuenta</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
<panel>
<single>único
<title>Tableros creados</title>
<search base="basesearch">
<query>| buscar evento = tablero_creado | stats count</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
<panel>
<single>
<title>Tableros abiertos</title>
<search base="basesearch">
<query>| buscar evento = tablero_abierto | estadísticas contar</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Tableros abiertos o creados</title>
<search base="basesearch">
<query>| búsqueda evento = tablero_creado O evento = tablero_abierto | gráfico_tiempo recuento como "Tableros creados" por evento</query>
</search>
<option name="charting.axisTitleX.visibility">colapsado</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.chart">columna</option>
<option name="charting.chart.stackMode">apilado</option>
<option name="charting.drilldown">ninguna</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.placement">derecha</option>
<option name="refresh.display">barra de progreso</option>
</chart>
</panel>
</row>
</dashboard>
<dashboard theme="light" version="1.1">
<label>Actividad de Seguridad de Miro</label>
<description>Descripción general de los eventos de seguridad en tu cuenta de Miro.</description>
<search id="basesearch">
<query>source=miro_audit_logs | fields * | search context.organization.name = "$form.organization$"</query>
<earliest>$time.más temprano$</earliest>
<latest>$time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>Rango de tiempo</label>
<default>
<earliest>-30d@d</earliest>
<latest>ahora</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>Organización</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| tabla context.organization.name | deduplicar context.organization.name</query>
</search>
<choice value="*">Todo</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>Equipo</label>
<choice value="*">Elección</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>nombre.del.equipo.contextual</fieldForLabel>
<fieldForValue>contexto.equipo.nombre</fieldForValue>
<search base="basesearch">Buscar
<query>| tabla context.team.name | eliminar duplicados context.team.name</query>
</search>
</input>
</fieldset>
<row>
<panel>
<single>
<title>Inicios de sesión exitosos</title>
<search base="basesearch">
<query>| búsqueda evento = sign_in_succeeded | estadísticas contar</query>
</search>
<option name="drilldown">ninguna</option>
</single>
</panel>
<panel>
<single>
<title>Inicios de sesión fallidos</title>
<search base="basesearch">
<query>| búsqueda evento = inicio_de_sesión_fallido | stats count</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Inicios de sesión por método de autenticación</title>
<search base="basesearch">
<query>| search event = sign_in_* | timechart count as Eventos por details.authType</query>
</search>
<option name="charting.axisTitleX.visibility">colapsado</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">columna</option>
<option name="charting.chart.nullValueMode">espacios</option>
<option name="charting.chart.stackMode">apilado</option>
<option name="charting.drilldown">ninguno</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">estándar</option>
<option name="charting.legend.placement">derecha</option>
<option name="refresh.display">barra de progreso</option>
</chart>
</panel>
</row>
<row>
<panel>
<table>
<title>Eventos para compartir</title>
<search base="basesearch">
<query>| buscar evento = *public_link* O evento = *compartir* | renombrar context.team.name como Equipo createdBy.name como Usuario object.name como Tablero details.role como Detalles event como Evento | tabla id _time Evento Equipo Usuario Tablero Detalles</query>
</search>
<option name="count">10</option>
<option name="drilldown">celda</option>
<option name="refresh.display">barra de progreso</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<title>Eventos de archivos</title>
<search base="basesearch">
<query>| búsqueda evento = tablero_exportado O evento = archivo_* | renombrar contexto.equipo.nombre como Equipo creadoPor.nombre como Usuario objeto.nombre como Tablero detalles.tipo como Tipo detalles.objeto como Objeto evento como Evento | tabla id _time Evento Equipo Usuario Tablero Tipo Objeto</query>
</search>
<option name="count">10</option>
<option name="drilldown">celda</option>
<option name="refresh.display">barra de progreso</option>
</table>
</panel>
</row>
</dashboard>
Figura 18: Editar panel
Actividad del Usuario
La primera visualización es Actividad de usuario, donde puedes encontrar un resumen de los eventos de tu usuario en Miro. Estos son:
- La cantidad de eventos a lo largo del tiempo, por equipo y total.
-
Eventos del tablero: tableros creados, tableros abiertos y total.
Figura 19: Actividad del usuario
<dashboard theme="light" version="1.1">
<label>Actividad del usuario de Miro</label>
<description>Descripción general de los eventos de usuario en tu cuenta de Miro.</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>Rango de tiempo</label>
<default>
<earliest>-30d@d</earliest>
<latest>ahora</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>Organización</label>
<fieldForLabel>context.organization.nombre</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| tabla context.organization.name | deduplicar context.organization.name</query>
</search>
<choice value="*">Toda</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>Equipo</label>
<choice value="*">Todo</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>contexto.equipo.nombre</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| tabla context.team.name | deduplica context.team.name</query>
</search>
</input>
</fieldset>
<row>
<panel>
<single>
<title>Eventos totales</title>
<search base="basesearch">
<query>| stats cuenta</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Eventos por fecha</title>
<search base="basesearch">
<query>| gráfico de tiempo cuenta como Eventos</query>
</search>
<option name="charting.axisTitleX.visibility">colapsado</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">área</option>
<option name="charting.chart.nullValueMode">huecos</option>
<option name="charting.chart.stackMode">apilado</option>
<option name="charting.drilldown">ninguna</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">estándar</option>
<option name="charting.legend.placement">ninguno</option>
<option name="refresh.display">barra de progreso</option>
</chart>
</panel>
<panel>
<chart>
<title>Eventos por equipo</title>
<search base="basesearch">
<query>| renombrar context.team.name como Team | stats count as "Eventos" by Team | sort - "Eventos"</query>
</search>
<option name="charting.chart">gráfico circular</option>
<option name="charting.chart.sliceCollapsingThreshold">0,03</option>
<option name="charting.drilldown">todas</option>
<option name="refresh.display">barra de progreso</option>
<drilldown>
<set token="form.team">$click.value$</set>
</drilldown>
</chart>
</panel>
</row>
<row>Fila
<panel>
<single>
<title>Eventos del tablero</title>
<search base="basesearch">Buscar por palabra clave
<query>| search event = tablero_* | stats count</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
<panel>
<single>
<title>Tableros creados</title>
<search base="basesearch">
<query>| buscar evento = tablero_creado | stats count</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
<panel>
<single>único
<title>Tableros abiertos</title>
<search base="basesearch">
<query>| búsqueda evento = tablero_abierto | estadísticas cuenta</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
</row>
<row>Fila
<panel>
<chart>
<title>Tableros abiertos o creados</title>
<search base="basesearch">
<query>| buscar evento = tablero_creado OR evento = tablero_abierto | timechart count as "Tableros creados" por evento</query>
</search>
<option name="charting.axisTitleX.visibility">colapsado</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.chart">columna</option>
<option name="charting.chart.stackMode">apilado</option>
<option name="charting.drilldown">ninguno</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.placement">derecha</option>
<option name="refresh.display">barra de progreso</option>
</chart>
</panel>
</row>
</dashboard>
Actividad de seguridad
La segunda visualización es Actividad de seguridad, donde puedes encontrar un resumen de tus eventos de usuario en Miro. Estos son:
- Actividad de inicio de sesión: la cantidad de inicios de sesión exitosos y fallidos.
-
Eventos de uso compartido: lista de eventos de usuarios al compartir tableros.
Figura 20: Actividad de seguridad
<dashboard theme="light" version="1.1">
<label>Actividad de Seguridad en Miro</label>
<description>Descripción general de los eventos de seguridad en tu cuenta de Miro.</description>
<search id="basesearch">Buscar
<query>source=miro_audit_logs | fields * | search context.organization.name = "$form.organization$"</query>
<earliest>$time.más_antiguo$</earliest>
<latest>Última versión</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>Rango de tiempo</label>
<default>
<earliest>-30d@d</earliest>
<latest>ahora</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>Organización</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| tabla context.organization.name | eliminar duplicados context.organization.name</query>
</search>
<choice value="*">Todo</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>Equipo</label>
<choice value="*">Todo</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>contexto.equipo.nombre</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">Buscar
<query>| deduplica context.team.name | en contexto la tabla context.team.name</query>
</search>
</input>
</fieldset>
<row>
<panel>
<single>
<title>Inicios de sesión exitosos</title>
<search base="basesearch">
<query>| search event = sign_in_succeeded | stats count</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
<panel>
<single>
<title>Inicios de sesión fallidos</title>
<search base="basesearch">
<query>| search event = sign_in_failed | stats count</query>
</search>
<option name="drilldown">ninguno</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>Inicios de sesión por método de autenticación</title>
<search base="basesearch">Buscar por base
<query>| búsqueda evento = iniciar_sesión_* | gráfica de tiempo cuenta como Eventos por detalles.authType</query>
</search>
<option name="charting.axisTitleX.visibility">colapsado</option>
<option name="charting.axisTitleY.visibility">visible</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">columna</option>
<option name="charting.chart.nullValueMode">espacios</option>
<option name="charting.chart.stackMode">apilado</option>
<option name="charting.drilldown">ninguno</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">estándar</option>
<option name="charting.legend.placement">derecha</option>
<option name="refresh.display">barra de progreso</option>
</chart>
</panel>
</row>
<row>
<panel>
<table>
<title>Eventos de uso compartido</title>
<search base="basesearch">
<query>| búsqueda evento = *public_link* O evento = *sharing* | renombrar context.team.name como Equipo createdBy.name como Usuario object.name como Tablero details.role como Detalles event como Evento | tabla id _tiempo Evento Equipo Usuario Tablero Detalles</query>
</search>
<option name="count">10</option>
<option name="drilldown">celda</option>
<option name="refresh.display">barra de progreso</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<title>Eventos de archivo</title>
<search base="basesearch">
<query>| search event = tablero_exported OR event = archivo_* | rename context.team.name as Equipo createdBy.name as Usuario object.name as Tablero details.type as Tipo details.object as Objeto event as Evento | table id _time Evento Equipo Usuario Tablero Tipo Objeto</query>
</search>
<option name="count">10</option>
<option name="drilldown">celda</option>
<option name="refresh.display">barra de progreso</option>
</table>
</panel>
</row>
</dashboard>