Collect 1Password logs

Supported in:

This document explains how to ingest 1Password logs to Google Security Operations using Bindplane. The parser transforms raw JSON formatted log data into a structured format compliant with the Google SecOps Unified Data Model (UDM). It specifically focuses on normalizing and enriching events related to user sign-in attempts, extracting details about the user, their location, client information, and the outcome of the attempt.

Before you begin

Ensure that you have the following prerequisites:

  • Google SecOps instance
  • Windows 2016 or later or Linux host with systemd
  • If running behind a proxy, firewall ports are open
  • Privileged access to 1Password

Get Google SecOps ingestion authentication file

  1. Sign in to the Google SecOps console.
  2. Go to SIEM Settings > Collection Agents.
  3. Download the Ingestion Authentication File. Save the file securely on the system where Bindplane will be installed.

Get Google SecOps customer ID

  1. Sign in to the Google SecOps console.
  2. Go to SIEM Settings > Profile.
  3. Copy and save the Customer ID from the Organization Details section.

Install the Bindplane agent

Windows installation

  1. Open the Command Prompt or PowerShell as an administrator.
  2. Run the following command:

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

Linux installation

  1. Open a terminal with root or sudo privileges.
  2. Run the following command:

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

Additional installation resources

For additional installation options, consult the installation guide.

Configure the Bindplane agent to ingest Syslog and send to Google SecOps

  1. Access the configuration file:
    • Locate the config.yaml file. Typically, it's in the /etc/bindplane-agent/ directory on Linux or in the installation directory on Windows.
    • Open the file using a text editor (for example, nano, vi, or Notepad).
  2. Edit the config.yaml file as follows:

    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 in Step 1
            creds: '/path/to/ingestion-authentication-file.json'
            # Replace with your actual customer ID from Step 2
            customer_id: <customer_id>
            endpoint: malachiteingestion-pa.googleapis.com
            # Add optional ingestion labels for better organization
            ingestion_labels:
                log_type: 'ONEPASSWORD'
                raw_log_field: body
    
    service:
        pipelines:
            logs/source0__chronicle_w_labels-0:
                receivers:
                    - udplog
                exporters:
                    - chronicle/chronicle_w_labels
    
  3. Replace the port and IP address as required in your infrastructure.

  4. Replace <customer_id> with the actual customer ID.

  5. Update /path/to/ingestion-authentication-file.json to the path where the authentication file was saved in the Get Google SecOps ingestion authentication file section.

Restart Bindplane agent to apply the changes

  • To restart the Bindplane agent in Linux, run the following command:

    sudo systemctl restart bindplane-agent
    
  • To restart the Bindplane agent in Windows, you can either use the Services console or enter the following command:

    net stop BindPlaneAgent && net start BindPlaneAgent
    

Get the 1Password API token

  1. Sign in to the 1Password web UI.
  2. Go to Integrations.
  3. Click Directory at the top of the page.
  4. Enter a name for the token and set the token expiration.
  5. In Events Reporting, click Other.
  6. Select the corresponding Event Types.
  7. Click Issue Token to generate the access token key.
  8. Click Save in 1Password and select which vault to save your token to.
  9. Click View Integration Details to view the token.

Configure a Linux host to run the following

  • Run the following command:

      import datetime
      import requests
      import os
      import socket
      import json
    
    # For more information, check out the support page: https://support.1password.com/events-reporting
    
      api_token = os.environ.get('EVENTS_API_TOKEN')
      url = "https://events.1password.com"
      if not api_token:
          print("Please set the EVENTS_API_TOKEN environment variable.")
          exit(1)
      start_time = datetime.datetime.now() - datetime.timedelta(hours=24)
    
    # Define the bindplane agent details
    
      syslog_server_ip = <ip-address> # Replace with your Bindplane IP
      syslog_server_port = <port-number> # Replace with your Bindplane port
      headers = {
          "Content-Type": "application/json",
          "Authorization": f"Bearer {api_token}"
      payload = {
          "limit": 20,
          "start_time": start_time.astimezone().replace(microsecond=0).isoformat()
    
    # Alternatively, use the cursor returned from previous responses to get any new events
      # payload = { "cursor": cursor }
      try:
          r = requests.post(f"{url}/api/v1/signinattempts", headers=headers, json=payload)
          r.raise_for_status()  # Raise an exception if the request fails
          if r.status_code == requests.codes.ok:
    
    # Send the response to the bindplane server
              syslog_message = f"{json.dumps(r.json())}"
              with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
                  sock.connect((syslog_server_ip, syslog_server_port))
                  sock.sendall(f"{syslog_message}\n".encode())
          else:
              print(f"Error getting sign-in attempts: status code {r.status_code}")
      except requests.exceptions.RequestException as e:
          print(f"Request error: {e}")
      except Exception as e:
          print(f"Error during syslog logging: {e}")
    

UDM mapping table

Log field UDM mapping Logic
category security_result.category_details The value is taken from the category field in the raw log.
client.app_name principal.application The value is taken from the client.app_name field in the raw log.
client.app_version metadata.product_version The value is taken from the client.app_version field in the raw log.
client.ip_address principal.ip The value is taken from the client.ip_address field in the raw log.
client.os_name principal.platform The value is taken from the client.os_name field in the raw log and mapped to the corresponding UDM platform value (LINUX, WINDOWS, MAC).
client.os_version principal.platform_version The value is taken from the client.os_version field in the raw log.
client.platform_name principal.resource.attribute.labels.key: platform_name, principal.resource.attribute.labels.value: Chrome The value is taken from the client.platform_name field in the raw log.
client.platform_version principal.asset.platform_software.platform_version The value is taken from the client.platform_version field in the raw log.
country principal.location.country_or_region The value is taken from the country field in the raw log if location.country is not present.
item_uuid security_result.about.resource.attribute.labels.key: item_uuid, security_result.about.resource.attribute.labels.value: nx4f2lhmafhhfkvgid6ff2fyh4 The value is taken from the item_uuid field in the raw log.
location.city principal.location.city The value is taken from the location.city field in the raw log.
location.country principal.location.country_or_region The value is taken from the location.country field in the raw log.
location.latitude principal.location.region_latitude The value is taken from the location.latitude field in the raw log.
location.longitude principal.location.region_longitude The value is taken from the location.longitude field in the raw log.
location.region principal.location.name The value is taken from the location.region field in the raw log.
session.ip principal.ip The value is taken from the session.ip field in the raw log.
session_uuid network.session_id The value is taken from the session_uuid field in the raw log.
target_user.email target.user.email_addresses The value is taken from the target_user.email field in the raw log.
target_user.uuid target.user.userid The value is taken from the target_user.uuid field in the raw log.
timestamp metadata.event_timestamp.seconds, metadata.event_timestamp.nanos The value is taken from the timestamp field in the raw log and converted to seconds and nanoseconds.
type additional.fields.key: type, additional.fields.value.string_value: mfa_ok The value is taken from the type field in the raw log.
user.email principal.user.email_addresses The value is taken from the user.email field in the raw log.
user.name principal.user.user_display_name The value is taken from the user.name field in the raw log.
used_version additional.fields.key: used_version, additional.fields.value.string_value: 1 The value is taken from the used_version field in the raw log.
uuid principal.resource.attribute.labels.key: uuid, principal.resource.attribute.labels.value: EPNGUJLHFVHCXMJL5LJQGXTENA The value is taken from the uuid field in the raw log.
vault_uuid security_result.about.resource.attribute.labels.key: vault_uuid, security_result.about.resource.attribute.labels.value: lddjidoxtrxteclqhubbo3pkyq The value is taken from the vault_uuid field in the raw log.
N/A extensions.auth An empty object is created for this field.
N/A metadata.event_type The value is set to USER_LOGIN if category is success or firewall_reported_success, STATUS_UPDATE if no user information is present, and USER_UNCATEGORIZED otherwise.
N/A metadata.log_type The value is set to ONEPASSWORD.
N/A metadata.product_name The value is set to ONEPASSWORD.
N/A metadata.vendor_name The value is set to ONEPASSWORD.
N/A security_result.action The value is set to ALLOW if category is success or firewall_reported_success, BLOCK if category is credentials_failed, mfa_failed, modern_version_failed, or firewall_failed, and is left empty otherwise.

Changes

2024-07-08

Enhancement:

  • Mapped item.actor_details.uuid to principal.user.userid.
  • Mapped item.actor_details.name to principal.user.user_display_name.
  • Mapped item.actor_details.email to principal.email.
  • Mapped item.actor_uuid to security_result.about.resource.attribute.labels.
  • Mapped item.object_type to additional.fields.
  • Mapped item.object_uuid to security_result.about.resource.attribute.labels.
  • Mapped item.aux_info to additional.fields.
  • Mapped item.aux_uuid to security_result.about.resource.attribute.labels.
  • Mapped item.session.uuid to network.session_id.
  • Mapped item.session.device_uuid to target.resource.product_object_id.
  • Mapped item.session.ip to principal.ip.

2023-06-07

Enhancement:

  • Remapped target_user.name to target.user.user_display_name.
  • Remapped target_user.email to target.user.email_addresses.
  • Remapped target_user.uuid to target.user.userid.
  • If user fields aren't present, changed metadata.event_type to STATUS_UPDATE.

2023-05-05

Enhancement:

  • Added gsub function to correct format and parse the unparsed logs.

2023-04-27

Enhancement:

  • Provided parsing support for multiple fields in items array by using loop.

2023-02-15

Enhancement:

  • Unmapped user.uuid and uuid.
  • Modified mapping of target_user.email from target.user.userid to principal.user.email_addresses.
  • Modified mapping of target_user.uuid from target.user.product_object_id to principal.user.userid.

2023-02-06

Enhancement:

  • Mapped metadata.vendor_name and metadata.product_name.

2023-01-15

Enhancement:

  • Mapped uuid to principal.userid.
  • If user.uuid and uuid are present then map uuid to additional.fields.
  • Mapped location.region to principal.location.name.
  • Mapped metadata.product_version to client.app_version.
  • Mapped principal.asset.platform_software.platform_version to client.platform_version.
  • Mapped type,action,used_version, to additional.fields.
  • Mapped client.platform_name to principal.resource.attribute.labels.
  • Mapped vault_uuid to security_result.about.resource.attribute.labels.
  • Mapped country to principal.location.country_or_region.
  • If category is equal to success, then map security_result.action to ALLOW.
  • Mapped category to security_result.category_details.
  • Remapped target_user.email to target.user.userid.
  • Remapped target_user.uuid to target.user.product_object_id.
  • Remapped item_uuid to about.resource.attribute.labels.

2022-10-07

  • Newly created parser.

Need more help? Get answers from Community members and Google SecOps professionals.