Recopila registros de Atlassian Confluence

Se admite en los siguientes sistemas operativos:

En este documento, se explica cómo transferir registros de Atlassian Confluence a Google Security Operations. Primero, el analizador intenta extraer campos del mensaje de registro sin procesar con expresiones regulares (patrones de Grok) diseñadas para los registros de Atlassian Confluence. Si falla el análisis de grok o el registro está en formato JSON, el código intenta analizar el mensaje como JSON. Por último, los campos extraídos se asignan al esquema de UDM de Google SecOps y se enriquecen con contexto adicional.

Antes de comenzar

Asegúrate de cumplir con los siguientes requisitos previos:

  • Una instancia de Google SecOps
  • Cuenta de Atlassian Confluence Cloud con acceso a los registros de auditoría O Confluence Data Center/Server con acceso de administrador
  • Para los métodos basados en AWS: Acceso con privilegios a AWS (S3, IAM, Lambda, EventBridge)
  • Para el método de Bindplane: Host de Windows 2016 o posterior, o de Linux con systemd

Descripción general de las opciones de integración

En esta guía, se proporcionan dos rutas de integración:

  • Opción 1: Confluence Data Center o Server a través de BindPlane y Syslog
  • Opción 2: Registros de auditoría de Confluence Cloud a través de AWS Lambda + S3 (formato JSON)

Elige la opción que mejor se adapte a tu tipo de implementación y a tu infraestructura de Confluence.

Opción 1: Confluence Data Center o Server a través de Bindplane y Syslog

Esta opción configura Confluence Data Center o Server para que envíe registros a través de syslog a un agente de Bindplane, que luego los reenvía a Google SecOps.

Obtén el archivo de autenticación de transferencia de Google SecOps

  1. Accede a la consola de Google SecOps.
  2. Ve a Configuración de SIEM > Agentes de recopilación.
  3. Descarga el archivo de autenticación de transferencia. Guarda el archivo de forma segura en el sistema en el que se instalará BindPlane.

Obtén el ID de cliente de Google SecOps

  1. Accede a la consola de Google SecOps.
  2. Ve a Configuración de SIEM > Perfil.
  3. Copia y guarda el ID de cliente de la sección Detalles de la organización.

Instala el agente de BindPlane

Instala el agente de Bindplane en tu sistema operativo Windows o Linux según las siguientes instrucciones.

Instalación en Windows

  1. Abre el símbolo del sistema o PowerShell como administrador.
  2. Ejecuta el comando siguiente:

    msiexec /i "https://github.com/observIQ/bindplane-agent/releases/latest/download/observiq-otel-collector.msi" /quiet
    

Instalación en Linux

  1. Abre una terminal con privilegios de raíz o sudo.
  2. Ejecuta el comando siguiente:

    sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
    

Recursos de instalación adicionales

Configura el agente de BindPlane para transferir Syslog y enviarlo a Google SecOps

  1. Accede al archivo de configuración:

    1. Ubica el archivo config.yaml. Por lo general, se encuentra en el directorio /etc/bindplane-agent/ en Linux o en el directorio de instalación en Windows.
    2. Abre el archivo con un editor de texto (por ejemplo, nano, vi o Bloc de notas).
  2. Edita el archivo config.yaml de la siguiente manera:

    receivers:
      udplog:
        # Replace the port and IP address as required
        listen_address: "0.0.0.0:514"
    
    exporters:
      chronicle/chronicle_w_labels:
        compression: gzip
        # Adjust the path to the credentials file you downloaded
        creds_file_path: '/path/to/ingestion-authentication-file.json'
        # Replace with your actual customer ID
        customer_id: YOUR_CUSTOMER_ID
        endpoint: malachiteingestion-pa.googleapis.com
        log_type: 'ATLASSIAN_CONFLUENCE'
        raw_log_field: body
        ingestion_labels:
    
    service:
      pipelines:
        logs/confluence:
          receivers:
            - udplog
          exporters:
            - chronicle/chronicle_w_labels
    

Reinicia el agente de Bindplane para aplicar los cambios

  • Para reiniciar el agente de Bindplane en Linux, ejecuta el siguiente comando:

    sudo systemctl restart bindplane-agent
    
  • Para reiniciar el agente de Bindplane en Windows, puedes usar la consola de Servicios o ingresar el siguiente comando:

    net stop BindPlaneAgent && net start BindPlaneAgent
    

Configura el reenvío de Syslog en Confluence Data Center o Server

  1. Accede a tu servidor de Confluence a través de SSH o RDP.
  2. Ubica el archivo de configuración de Log4j:
    • Para Log4j2: <confluence-install>/confluence/WEB-INF/classes/log4j2.xml
  3. Edita el archivo de configuración para agregar un SyslogAppender:

    <Configuration>
      <Appenders>
        <!-- Existing appenders -->
    
        <Syslog name="SyslogAppender" 
                host="BINDPLANE_AGENT_IP" 
                port="514" 
                protocol="UDP"
                facility="LOCAL0"
                format="RFC5424">
          <PatternLayout pattern="%d{ISO8601} %p [%t] [%c{1}] %m%n"/>
        </Syslog>
      </Appenders>
    
      <Loggers>
        <Root level="info">
          <AppenderRef ref="SyslogAppender"/>
          <!-- Other appender refs -->
        </Root>
    
        <!-- Audit logger -->
        <Logger name="com.atlassian.confluence.event.events.security.AuditEvent" level="info" additivity="false">
          <AppenderRef ref="SyslogAppender"/>
        </Logger>
      </Loggers>
    </Configuration>
    
    • Reemplaza BINDPLANE_AGENT_IP por la dirección IP de tu agente de BindPlane.
  4. Reinicia Confluence para aplicar los cambios:

    sudo systemctl restart confluence
    

Opción B: Configura rsyslog para que reenvíe los archivos de registro locales

  1. Configura Confluence para que escriba registros en archivos (comportamiento predeterminado).
  2. Instala rsyslog si no está presente:

    sudo apt-get install rsyslog  # Debian/Ubuntu
    sudo yum install rsyslog      # RHEL/CentOS
    
  3. Crea el archivo de configuración de rsyslog /etc/rsyslog.d/confluence.conf:

    # Forward Confluence logs to BindPlane
    $ModLoad imfile
    
    # Application logs
    $InputFileName /opt/atlassian/confluence/logs/atlassian-confluence.log
    $InputFileTag confluence-app:
    $InputFileStateFile stat-confluence-app
    $InputFileSeverity info
    $InputFileFacility local0
    $InputRunFileMonitor
    
    # Audit logs (JSON format in DC/Server)
    $InputFileName /var/atlassian/application-data/confluence/log/audit/*.json
    $InputFileTag confluence-audit:
    $InputFileStateFile stat-confluence-audit
    $InputFileSeverity info
    $InputFileFacility local1
    $InputRunFileMonitor
    
    # Forward to BindPlane agent
    *.* @@BINDPLANE_AGENT_IP:514
    
    • Reemplaza BINDPLANE_AGENT_IP por la dirección IP de tu agente de Bindplane.
    • Ajusta las rutas de acceso de los archivos de registro según tu instalación de Confluence:
      • Por lo general, los registros de la aplicación son <confluence-install>/logs/ o <local-home>/logs/.
      • Registros de auditoría: <confluence-home>/log/audit/*.json
  4. Reinicia rsyslog:

    sudo systemctl restart rsyslog
    

Opción 2: Registros de auditoría de Confluence Cloud a través de AWS Lambda y S3

Recopila credenciales de la API de Confluence Cloud

  1. Accede a tu cuenta de Atlassian.
  2. Ve a https://id.atlassian.com/manage-profile/security/api-tokens.
  3. Haz clic en Crear token de API.
  4. Ingresa una etiqueta para el token (por ejemplo, Google Security Operations Integration).
  5. Haz clic en Crear.
  6. Copia y guarda el token de API de forma segura.
  7. Anota la URL de tu sitio de Confluence Cloud (por ejemplo, https://yoursite.atlassian.net).
  8. Anota la dirección de correo electrónico de tu cuenta de Atlassian (que se usa para la autenticación).

Configura el bucket de AWS S3 y el IAM para Google SecOps

  1. Crea un bucket de Amazon S3 siguiendo esta guía del usuario: Crea un bucket
  2. Guarda el Nombre y la Región del bucket para futuras referencias (por ejemplo, confluence-audit-logs).
  3. Crea un usuario siguiendo esta guía del usuario: Cómo crear un usuario de IAM.
  4. Selecciona el usuario creado.
  5. Selecciona la pestaña Credenciales de seguridad.
  6. Haz clic en Crear clave de acceso en la sección Claves de acceso.
  7. Selecciona Servicio de terceros como Caso de uso.
  8. Haz clic en Siguiente.
  9. Opcional: Agrega una etiqueta de descripción.
  10. Haz clic en Crear clave de acceso.
  11. Haz clic en Descargar archivo CSV para guardar la clave de acceso y la clave de acceso secreta para consultarlas en el futuro.
  12. Haz clic en Listo.
  13. Selecciona la pestaña Permisos.
  14. Haz clic en Agregar permisos en la sección Políticas de permisos.
  15. Selecciona Agregar permisos.
  16. Selecciona Adjuntar políticas directamente.
  17. Busca la política AmazonS3FullAccess.
  18. Selecciona la política.
  19. Haz clic en Siguiente.
  20. Haz clic en Agregar permisos.

Configura la política y el rol de IAM para las cargas de S3

  1. En la consola de AWS, ve a IAM > Policies > Create policy > pestaña JSON.
  2. Ingresa la siguiente política:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowPutObjects",
          "Effect": "Allow",
          "Action": "s3:PutObject",
          "Resource": "arn:aws:s3:::confluence-audit-logs/*"
        },
        {
          "Sid": "AllowGetStateObject",
          "Effect": "Allow",
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::confluence-audit-logs/confluence-audit/state.json"
        }
      ]
    }
    
    • Reemplaza confluence-audit-logs si ingresaste un nombre de bucket diferente.
  3. Haz clic en Siguiente > Crear política.

  4. Asigna a la política el nombre ConfluenceAuditToS3Policy.

  5. Ve a IAM > Roles > Crear rol > Servicio de AWS > Lambda.

  6. Adjunta la política recién creada ConfluenceAuditToS3Policy.

  7. Nombra el rol ConfluenceAuditLambdaRole y haz clic en Crear rol.

Crea la función Lambda

  1. En la consola de AWS, ve a Lambda > Functions.
  2. Haz clic en Crear función > Autor desde cero.
  3. Proporciona los siguientes detalles de configuración:

    Configuración Valor
    Nombre ConfluenceAuditToS3
    Tiempo de ejecución Python 3.13
    Arquitectura x86_64
    Rol de ejecución ConfluenceAuditLambdaRole
  4. Después de crear la función, abre la pestaña Code, borra el código auxiliar y, luego, ingresa el siguiente código:

    import json
    import os
    import boto3
    from datetime import datetime, timezone, timedelta
    from urllib import request, parse, error
    from base64 import b64encode
    
    # Environment variables
    S3_BUCKET = os.environ['S3_BUCKET']
    S3_PREFIX = os.environ.get('S3_PREFIX', 'confluence-audit/')
    STATE_KEY = os.environ.get('STATE_KEY', 'confluence-audit/state.json')
    CONFLUENCE_URL = os.environ['CONFLUENCE_URL']  # e.g., https://yoursite.atlassian.net
    CONFLUENCE_EMAIL = os.environ['CONFLUENCE_EMAIL']
    CONFLUENCE_API_TOKEN = os.environ['CONFLUENCE_API_TOKEN']
    MAX_RECORDS = int(os.environ.get('MAX_RECORDS', '1000'))
    
    s3_client = boto3.client('s3')
    
    def lambda_handler(event, context):
        """Fetch Confluence Cloud audit logs and write to S3."""
    
        # Read last execution state
        start_date = get_last_execution_time()
        end_date = datetime.now(timezone.utc)
    
        print(f"Fetching audit logs from {start_date} to {end_date}")
    
        # Fetch audit records
        records = fetch_audit_logs(start_date, end_date)
    
        if not records:
            print("No new audit records found.")
            save_state(end_date)
            return {'statusCode': 200, 'body': 'No new records'}
    
        # Write to S3
        timestamp = end_date.strftime('%Y%m%d_%H%M%S')
        object_key = f"{S3_PREFIX}audit_{timestamp}.json"
    
        s3_client.put_object(
            Bucket=S3_BUCKET,
            Key=object_key,
            Body='\n'.join(json.dumps(record) for record in records),
            ContentType='application/json'
        )
    
        print(f"Wrote {len(records)} records to s3://{S3_BUCKET}/{object_key}")
    
        # Update state
        save_state(end_date)
    
        return {
            'statusCode': 200,
            'body': f"Processed {len(records)} records"
        }
    
    def get_last_execution_time():
        """Retrieve the last execution timestamp from S3 state file."""
        try:
            response = s3_client.get_object(Bucket=S3_BUCKET, Key=STATE_KEY)
            state = json.loads(response['Body'].read())
            return datetime.fromisoformat(state['last_execution'])
        except s3_client.exceptions.NoSuchKey:
            # First run: fetch logs from last 24 hours
            return datetime.now(timezone.utc) - timedelta(hours=24)
        except Exception as e:
            print(f"Error reading state: {e}")
            return datetime.now(timezone.utc) - timedelta(hours=24)
    
    def save_state(execution_time):
        """Save the execution timestamp to S3 state file."""
        state = {'last_execution': execution_time.isoformat()}
        s3_client.put_object(
            Bucket=S3_BUCKET,
            Key=STATE_KEY,
            Body=json.dumps(state),
            ContentType='application/json'
        )
    
    def fetch_audit_logs(start_date, end_date):
        """Fetch audit logs from Confluence Cloud REST API."""
        records = []
        start_param = int(start_date.timestamp() * 1000)  # milliseconds
        end_param = int(end_date.timestamp() * 1000)
    
        # Build authentication header
        auth_string = f"{CONFLUENCE_EMAIL}:{CONFLUENCE_API_TOKEN}"
        auth_bytes = auth_string.encode('ascii')
        auth_b64 = b64encode(auth_bytes).decode('ascii')
    
        headers = {
            'Authorization': f'Basic {auth_b64}',
            'Accept': 'application/json'
        }
    
        # Confluence Cloud Audit API endpoint
        url = f"{CONFLUENCE_URL}/wiki/rest/api/audit?startDate={start_param}&endDate={end_param}&limit=1000"
    
        try:
            req = request.Request(url, headers=headers)
            with request.urlopen(req) as response:
                data = json.loads(response.read())
                records = data.get('results', [])
                print(f"Retrieved {len(records)} audit records")
        except error.HTTPError as e:
            print(f"HTTP Error: {e.code} - {e.reason}")
            print(e.read().decode())
        except Exception as e:
            print(f"Error fetching audit logs: {e}")
    
        return records[:MAX_RECORDS]
    
  5. Ve a Configuration > Environment variables.

  6. Haz clic en Editar > Agregar nueva variable de entorno.

  7. Ingresa las siguientes variables de entorno y reemplaza los valores por los tuyos.

    Clave Valor de ejemplo
    S3_BUCKET confluence-audit-logs
    S3_PREFIX confluence-audit/
    STATE_KEY confluence-audit/state.json
    CONFLUENCE_URL https://yoursite.atlassian.net
    CONFLUENCE_EMAIL your-email@example.com
    CONFLUENCE_API_TOKEN your-api-token-here
    MAX_RECORDS 1000
  8. Selecciona la pestaña Configuración.

  9. En el panel Configuración general, haz clic en Editar.

  10. Cambia Tiempo de espera a 5 minutos (300 segundos) y haz clic en Guardar.

Crea una programación de EventBridge

  1. Ve a Amazon EventBridge > Scheduler > Create schedule.
  2. Proporciona los siguientes detalles de configuración:
    • Programación recurrente: Frecuencia (1 hour).
    • Destino: Tu función Lambda ConfluenceAuditToS3.
    • Nombre: ConfluenceAuditToS3-1h.
  3. Haz clic en Crear programación.

Opcional: Crea un usuario y claves de IAM de solo lectura para Google SecOps

  1. Ve a Consola de AWS > IAM > Usuarios.
  2. Haz clic en Agregar usuarios.
  3. Proporciona los siguientes detalles de configuración:
    • Usuario: Ingresa secops-confluence-reader.
    • Tipo de acceso: Selecciona Clave de acceso: Acceso programático.
  4. Haz clic en Siguiente.
  5. Haz clic en Adjuntar políticas directamente > Crear política.
  6. En el editor de JSON, ingresa la siguiente política:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["s3:GetObject"],
          "Resource": "arn:aws:s3:::confluence-audit-logs/*"
        },
        {
          "Effect": "Allow",
          "Action": ["s3:ListBucket"],
          "Resource": "arn:aws:s3:::confluence-audit-logs"
        }
      ]
    }
    
  7. Configura el nombre como secops-reader-policy.

  8. Ve a Crear política > busca o selecciona > Siguiente > Agregar permisos.

  9. Ve a Credenciales de seguridad > Claves de acceso > Crear clave de acceso.

  10. Descarga el archivo CSV (estos valores se ingresan en el feed).

Configura un feed en Google SecOps para transferir registros de Confluence

  1. Ve a Configuración de SIEM > Feeds.
  2. Haz clic en Agregar feed nuevo.
  3. En el campo Nombre del feed, ingresa un nombre para el feed (por ejemplo, Confluence Cloud Audit Logs).
  4. Selecciona Amazon S3 V2 como el Tipo de fuente.
  5. Selecciona Atlassian Confluence como el Tipo de registro.
  6. Haz clic en Siguiente.
  7. Especifica valores para los siguientes parámetros de entrada:
    • URI de S3: s3://confluence-audit-logs/confluence-audit/
    • Opciones de borrado de la fuente: Selecciona la opción de borrado según tu preferencia.
    • Antigüedad máxima del archivo: Incluye los archivos modificados en la cantidad de días especificada. El valor predeterminado es de 180 días.
    • ID de clave de acceso: Clave de acceso del usuario con acceso al bucket de S3.
    • Clave de acceso secreta: Clave secreta del usuario con acceso al bucket de S3.
    • Espacio de nombres del recurso: Es el espacio de nombres del recurso.
    • Etiquetas de transmisión: Es la etiqueta que se aplica a los eventos de este feed.
  8. Haz clic en Siguiente.
  9. Revisa la nueva configuración del feed en la pantalla Finalizar y, luego, haz clic en Enviar.

Tabla de asignación de UDM

Campo de registro Asignación de UDM Lógica
agente read_only_udm.network.http.user_agent Valor tomado del campo "agente".
app_protocol read_only_udm.network.application_protocol Se deriva del campo "app_protocol". Si "app_protocol" contiene "HTTPS", "HTTP", "SSH" o "RDP", se usa el protocolo correspondiente. De lo contrario, el valor predeterminado es "UNKNOWN_APPLICATION_PROTOCOL".
app_protocol read_only_udm.network.application_protocol_version Es el valor que se toma del campo "app_protocol".
auditType.action read_only_udm.security_result.action Se deriva del campo "auditType.action". Si "auditType.action" contiene "successful", el valor se establece en "ALLOW". Si contiene "restricted", el valor se establece en "BLOCK".
auditType.action read_only_udm.security_result.summary Valor que se toma del campo "auditType.action" cuando "auditType" no está vacío y "auditType_area" es "SECURITY".
auditType.actionI18nKey read_only_udm.metadata.product_event_type Valor que se toma del campo "auditType.actionI18nKey" cuando "auditType" no está vacío.
auditType.area read_only_udm.security_result.detection_fields.value El valor se toma del campo "auditType.area" y se asigna al campo "value" de un campo de detección con el campo "key" establecido en "auditType area". Esta asignación se realiza cuando "auditType" no está vacío.
auditType.category read_only_udm.security_result.category_details Valor que se toma del campo "auditType.category" cuando "auditType" no está vacío.
auditType.categoryI18nKey read_only_udm.security_result.detection_fields.value Valor tomado del campo "auditType.categoryI18nKey" y asignado al campo "value" de un campo de detección con el campo "key" establecido en "auditType categoryI18nKey". Esta asignación se realiza cuando "auditType" no está vacío.
auditType.level read_only_udm.security_result.detection_fields.value Valor tomado del campo "auditType.level" y asignado al campo "value" de un campo de detección con el campo "key" establecido en "auditType level". Esta asignación se realiza cuando "auditType" no está vacío.
author.displayName read_only_udm.principal.user.user_display_name Valor tomado del campo "author.displayName".
author.externalCollaborator read_only_udm.security_result.about.resource.attribute.labels.value El valor se toma del campo "author.externalCollaborator" y se asigna al campo "value" de una etiqueta con el campo "key" establecido en "externalCollaborator".
author.id read_only_udm.principal.user.userid Valor que se toma del campo "author.id" cuando "author.type" es "user" y "principal_user_present" es "false".
author.isExternalCollaborator read_only_udm.security_result.about.resource.attribute.labels.value El valor se toma del campo "author.isExternalCollaborator" y se asigna al campo "value" de una etiqueta con el campo "key" establecido en "isExternalCollaborator".
author.name read_only_udm.principal.user.user_display_name El valor se toma del campo "author.name" cuando "author.type" es "user" y "principal_user_present" es "false".
bytes_in read_only_udm.network.received_bytes Valor tomado del campo "bytes_in" si contiene dígitos. De lo contrario, el valor predeterminado es 0.
category read_only_udm.security_result.category_details Valor tomado del campo "categoría".
changedValues read_only_udm.principal.resource.attribute.labels Itera por cada elemento de "changedValues" y crea etiquetas con claves como "changedValue[index][key]" y valores de los valores correspondientes en el array "changedValues".
creationDate read_only_udm.metadata.event_timestamp Valor tomado del campo "creationDate", analizado como marca de tiempo UNIX o UNIX_MS.
extraAttributes read_only_udm.principal.resource.attribute.labels Itera por cada elemento de "extraAttributes" y crea etiquetas con claves basadas en los campos "name" y "nameI18nKey", y los valores del campo "value" correspondiente.
http_verb read_only_udm.network.http.method Es el valor que se toma del campo "http_verb".
ip read_only_udm.target.ip Valor tomado del campo "ip".
principal_host read_only_udm.principal.hostname Valor tomado del campo "principal_host".
referral_url read_only_udm.network.http.referral_url Valor tomado del campo "referral_url".
remoteAddress read_only_udm.principal.ip Valor tomado del campo "remoteAddress", analizado como una dirección IP.
response_code read_only_udm.network.http.response_code Es el valor que se toma del campo "response_code".
session_duration read_only_udm.additional.fields.value.string_value Valor tomado del campo "session_duration" y asignado al campo "string_value" de una etiqueta con el campo "key" establecido en "Duración de la sesión".
source read_only_udm.principal.ip Valor tomado del campo "source" y analizado como una dirección IP.
src_ip read_only_udm.principal.ip Valor que se toma del campo "src_ip" si "remoteAddress" está vacío.
resumen read_only_udm.security_result.summary Valor tomado del campo "summary".
sysAdmin read_only_udm.security_result.about.resource.attribute.labels.value El valor se toma del campo "sysAdmin" y se asigna al campo "value" de una etiqueta con el campo "key" establecido en "sysAdmin".
superAdmin read_only_udm.security_result.about.resource.attribute.labels.value Valor tomado del campo "superAdmin" y asignado al campo "value" de una etiqueta con el campo "key" establecido en "superAdmin".
target_url read_only_udm.target.url Valor tomado del campo "target_url".
timestamp read_only_udm.metadata.event_timestamp Valor tomado del campo "timestamp", analizado como una cadena de fecha y hora.
user_id read_only_udm.principal.user.userid Valor tomado del campo "user_id".
read_only_udm.metadata.event_type El valor de este campo se determina mediante una serie de verificaciones y, de forma predeterminada, se establece en "GENERIC_EVENT". Se establece en valores específicos, como "NETWORK_HTTP", "USER_UNCATEGORIZED" o "STATUS_UPDATE", según la presencia y el contenido de otros campos, como "principal_host", "user_id", "has_principal" y "author.type".
read_only_udm.metadata.vendor_name Se debe establecer en "ATLASSIAN".
read_only_udm.metadata.product_name Se establece en "CONFLUENCE".
read_only_udm.metadata.log_type Se debe establecer en "ATLASSIAN_CONFLUENCE".
read_only_udm.principal.user.user_display_name El valor de este campo puede provenir de "author.displayName" o "affectedObject.name", según el contexto.
read_only_udm.target.process.pid El valor de este campo puede provenir de "principal_host" o "pid", según el contexto.
read_only_udm.principal.resource.attribute.labels Este campo se propaga con varias etiquetas derivadas de campos como "affectedObjects", "changedValues" y "extraAttributes". Las claves y los valores de estas etiquetas se generan de forma dinámica según el contenido específico de estos campos.

¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.