Activity logs for organizations in Workbench

How to find and interpret user activity logs for organizations

Prior reading: Manage organizations

Purpose: This document explains what activity logs are and how you can use them to gain insight about your organizations.



What are activity logs and why are they useful?

Verily Workbench activity logs are time-stamped logs that can associate a user ID, org ID, operation taken (e.g., create, clone, delete, update access), and Workbench object (e.g., workspace, data collection, storage resource, VM, Dataproc cluster).

These logs are also useful to organization admins who want to better understand how active the users who belong to their organization are in Workbench. With these logs, admins can write SQL queries to pull results that answer queries such as the following:

  • How many users are in this org?
  • How many workspaces have users in this org created?
  • How many cloud apps (i.e., notebooks) have users in this org created?

How can I access the activity logs?

Activity logs are accessible at the data collection and organization level.

For organizations, organization admins will see a link to these logs, stored in BigQuery, from the Organizations tab:

Organizations page showing details in General
  tab, with Activity logs link highlighted.

Click the Activity Logs link to open these logs in the BigQuery UI. The logs are stored in BigQuery tables that are partitioned by organization ID:

`workbench-bq-log-sink.workbench_monitoring_org_logs_prod.wsm_workspace_activity_logs_*`

Using BigQuery, organization admins can review the schema and directly query the tables via SQL, save query results or open them in Google Sheets, and more. The tables provide information about all the organizations for which you are an admin.

Understanding table naming with org_id suffix

Each table in the activity logs dataset is partitioned by organization ID using a table suffix. The table naming pattern is <table_name>_<org_id>. For example, if your organization ID is abc123, the workspace activity logs table would be named wsm_workspace_activity_logs_abc123.

To query across all organizations you have access to, use the wildcard _* suffix:

FROM `workbench-bq-log-sink.workbench_monitoring_org_logs_prod.wsm_workspace_activity_logs_*`

To query a specific organization, replace _* with _<your_org_id>:

FROM `workbench-bq-log-sink.workbench_monitoring_org_logs_prod.wsm_workspace_activity_logs_<your_org_id>`

You can find your organization's user-facing ID in the URL when viewing your organization: https://workbench.verily.com/organizations/{your-organization-user-facing-id}

Querying a specific organization's table is more efficient than using the wildcard, especially if you manage multiple large organizations.

Schema of the activity logs tables

workbench-bq-log-sink.workbench_monitoring_org_logs_prod.wsm_workspace_activity_logs_* tables:

Field name Type Definition
workspace_id STRING Universally unique identifier (UUID) for workspace
workspace_user_facing_id STRING Human readable, user-facing ID for workspace
change_date TIMESTAMP Timestamp of change event
actor_email STRING The actor email
user_id STRING UUID of the user
change_subject_id STRING UUID of the Workbench resources (e.g. VM, GCS bucket, workspace itself) that was changed.
change_subject_type STRING Type of the changed resources
source_workspace_id STRING UUID of the workspace from which this workspace is cloned. NULL if this is not a duplication.
org_id STRING UUID of the organization
org_user_facing_id STRING Human readable, user-facing ID for Organization
pod_id UUID UUID of the pod
pod_user_facing_id STRING Human readable, user-facing ID for Pod
is_data_collection BOOLEAN Whether this is a data collection

workbench-bq-log-sink.workbench_monitoring_org_logs_prod.wsm_workspaces_* tables:

Field name Type Definition
workspace_id STRING Universally unique identifier (UUID) for workspace
workspace_user_facing_id STRING Human readable, user-facing ID for workspace
workspace_display_name STRING User-friendly display name
description STRING Workspace description
created_date TIMESTAMP The timestamp when workspace is created
created_by_email STRING Email of workspace creator
org_id STRING UUID for the Organization
org_user_facing_id STRING Human readable, user-facing ID for Organization
pod_id UUID UUID of the pod
pod_user_facing_id STRING Human readable, user-facing ID for Pod
cloud_platform STRING GCP/AWS
properties STRING JSON string of metadata on the workspace
workspace_metadata_policy STRING JSON string list of completed metadata policies
gcp_project_id STRING GCP project ID if this is a GCP workspace
gcp_project_number STRING GCP project number if this is a GCP workspace
is_data_collection BOOLEAN Whether this is a data collection

workbench-bq-log-sink.workbench_monitoring_org_logs_prod.wsm_resources_* tables:

Field name Type Definition
workspace_id STRING Universally unique identifier (UUID) for workspace
workspace_user_facing_id STRING Human readable, user-facing ID for workspace
resource_id STRING Universally unique identifier (UUID) for resource
resource_user_facing_id STRING Human readable, user-facing ID for resource
resource_display_name STRING User-friendly display name
description STRING Resource description
created_date TIMESTAMP The timestamp when this resource is created
created_by_email STRING Email of resource creator
resource_type STRING Type of resources
exact_resource_type STRING TYPE of resource, used when needing to distinguish CONTROLLED and REFERENCED resources
resource_lineage STRING Where this resource is from, e.g., the data collection ID where it's imported from
state STRING Lifecycle state of the resource
org_id STRING UUID for the Organization
org_user_facing_id STRING Human readable, user-facing ID for Organization
pod_id UUID UUID of the pod
pod_user_facing_id STRING Human readable, user-facing ID for Pod
is_data_collection BOOLEAN Whether this resource is in a data collection

workbench-bq-log-sink.workbench_monitoring_org_logs_prod.sam_workspace_users_* tables:

Field name Type Definition
user_email STRING Email of the user
org_id STRING UUID for the Organization
workspace_id STRING Universally unique identifier (UUID) for workspace
role STRING Role of the user at the workspace - one of: owner, reader, writer

workbench-bq-log-sink.workbench_monitoring_org_logs_prod.um_users_* tables:

Field name Type Definition
user_id UUID Universally unique identifier (UUID) of the user
email STRING User email
org_id UUID UUID of the organization
org_user_facing_id STRING Human readable, user-facing ID for Organization
active_state STRING The current user state (ENABLED, DISABLED, ARCHIVED, INVITED)
tos_state STRING Whether the user has accepted Terms of Service (TOS_REQUIRED, TOS_OK)
created_date TIMESTAMP When the user account on Workbench is created
created_by_email STRING Email of user who created the user's account.
last_updated_date TIMESTAMP Last time the user's status, profile or other metadata is updated.
last_updated_by_email STRING Email of user who last updated the user

workbench-bq-log-sink.workbench_monitoring_org_logs_prod.um_pods_* tables:

Field name Type Definition
pod_id UUID UUID of the pod
pod_user_facing_id STRING Human readable, user-facing ID for Pod
description STRING Description for the POD
org_id UUID UUID of the organization
org_user_facing_id STRING Human readable, user-facing ID for Organization
org_display_name STRING Organization display name
environment_type STRING The cloud environment this POD supports (AWS, GCP)
billing_account_id STRING Cloud billing account ID (GCP only)
created_date TIMESTAMP When the user account on Workbench is created
created_by_email STRING Email of user who created the user's account.
last_updated_date TIMESTAMP Last time the user's status, profile or other metadata is updated.
last_updated_by_email STRING Email of user who last updated the user

workbench-bq-log-sink.workbench_monitoring_org_logs_prod.um_user_pod_roles_* tables:

Field name Type Definition
user_email STRING User email
policy_group STRING Google Group for the pod role.
role STRING User's role on the POD
pod_id UUID UUID of the pod
pod_user_facing_id STRING Human readable, user-facing ID for Pod
description STRING Description for the POD
org_id STRING UUID of the organization
org_user_facing_id STRING Human readable, user-facing ID for Organization
environment_type STRING The cloud environment this POD supports (AWS, GCP)
created_date TIMESTAMP When the pod was created
created_by_email STRING Email of pod creator
last_updated_date STRING Last time the pod was updated.
last_updated_by_email STRING Email of user who last updated the pod

workbench-bq-log-sink.workbench_monitoring_org_logs_prod.cloud_audit_logs_* tables:

Field name Type Definition
insert_id STRING Unique identifier for each audit log entry (used for deduplication)
timestamp TIMESTAMP Timestamp when the event occurred
org_id STRING UUID of the organization
org_user_facing_id STRING Human-readable, user-facing ID for organization
workspace_id STRING UUID of the workspace
workspace_user_facing_id STRING Human-readable, user-facing ID for workspace
gcp_project_id STRING GCP project ID associated with the workspace
gcp_project_number STRING GCP project number associated with the workspace
user_email STRING The end-user's email address
audit_log STRING The full audit log payload as JSON

Querying the activity logs tables

BigQuery UI

You can query the activity logs table directly from the BigQuery panel in the Google Cloud console, by clicking the Activity logs link from a data collection that you own.

Running queries from a Workbench app

You can also query the table from within a Workbench app, using the bigquery library, e.g., by running something like the following:

import pandas as pd
from google.cloud import bigquery

BQ_dataset = 'workbench-bq-log-sink.workbench_monitoring_org_logs_prod'

job_query_config = bigquery.QueryJobConfig(default_dataset=BQ_dataset)
client = bigquery.Client(default_query_job_config=job_query_config)

Next, define a query on the table:

query = """
SELECT DISTINCT(workspace_user_facing_id), workspace_id, pod_user_facing_id, is_data_collection
FROM `wsm_workspace_activity_logs_*`
ORDER BY change_date DESC
"""

Then, run the query and view a dataframe of the results:

df = client.query(query).result().to_dataframe()
df

Querying on a specific data collection

If you're an owner of multiple data collections, the logs are aggregated in one table. So if you are interested in the usage of a particular data collection, you can first get the user-facing ID of that data collection, and then refine your query to retrieve data for just that data collection. You can find the user-facing ID in the path of the data collection URL like this: https://workbench.verily.com/data-collections/{your-data-collection-user-facing-id}

Example queries

"How many users are in my org?"

SELECT COUNT(user_id)
FROM `workbench-bq-log-sink.workbench_monitoring_org_logs_prod.um_users_*`

To query a specific organization, replace _* with your organization ID:

SELECT COUNT(user_id)
FROM `workbench-bq-log-sink.workbench_monitoring_org_logs_prod.um_users_<your_org_id>`
WHERE org_id = '<your_org_id>'

"How many pods are in my org?"

SELECT COUNT(pod_id)
FROM `workbench-bq-log-sink.workbench_monitoring_org_logs_prod.um_user_pod_roles_*`

"How many workspaces are in my org?"

SELECT COUNT(workspace_id)
FROM `workbench-bq-log-sink.workbench_monitoring_org_logs_prod.wsm_workspaces_*`

"How many cloud apps (i.e., notebooks) have users in this org created?"

SELECT COUNT(resource_id)
FROM `workbench-bq-log-sink.workbench_monitoring_org_logs_prod.wsm_resources_*`
WHERE resource_type IN ('AWS_EC2_INSTANCE', 'AWS_SAGEMAKER_NOTEBOOK', 'AI_NOTEBOOK_INSTANCE', 'DATAPROC_CLUSTER', 'GCE_INSTANCE')

"What are the most recent cloud audit log events for my organization?"

SELECT timestamp, workspace_id, user_email, org_id
FROM `workbench-bq-log-sink.workbench_monitoring_org_logs_prod.cloud_audit_logs_*`
ORDER BY timestamp DESC
LIMIT 50

"What workspaces have the most audit log activity?"

SELECT workspace_id, org_id, COUNT(*) as event_count
FROM `workbench-bq-log-sink.workbench_monitoring_org_logs_prod.cloud_audit_logs_*`
GROUP BY workspace_id, org_id
ORDER BY event_count DESC
LIMIT 10

Querying comprehensive cloud audit logs

For detailed GCP-level audit logs across your organization, use the workbench_cloud_audit_logs_prod dataset:

"What are the most recent comprehensive cloud audit logs for my organization?"

SELECT timestamp, workspace_id, user_email, org_id
FROM `workbench-bq-log-sink.workbench_cloud_audit_logs_prod.cloud_audit_logs_*`
ORDER BY timestamp DESC
LIMIT 50

"What are the audit logs for a specific workspace?"

SELECT timestamp, user_email, audit_log
FROM `workbench-bq-log-sink.workbench_cloud_audit_logs_prod.cloud_audit_logs_*`
WHERE workspace_id = 'your-workspace-id'
ORDER BY timestamp DESC
LIMIT 100

"What BigQuery queries were performed?"

SELECT
  timestamp,
  user_email,
  JSON_VALUE(audit_log, '$.methodName') AS method_name,
  JSON_VALUE(audit_log, '$.status.code') AS status_code,
  JSON_VALUE(audit_log, '$.status.message') AS status_message,
  JSON_VALUE(audit_log, '$.servicedata_v1_bigquery.jobInsertRequest.resource.jobConfiguration.query.query') AS query_text
FROM `workbench-bq-log-sink.workbench_cloud_audit_logs_prod.cloud_audit_logs_*`
WHERE JSON_VALUE(audit_log, '$.serviceName') = 'bigquery.googleapis.com' and JSON_VALUE(audit_log, '$.methodName') ='jobservice.insert'
ORDER BY timestamp DESC
LIMIT 100

"What Google Cloud Storage (GCS) operations were performed?"

SELECT
  timestamp,
  user_email,
  JSON_VALUE(audit_log, '$.methodName') AS method_name,
  JSON_VALUE(audit_log, '$.resourceName') AS resource_name,
  JSON_VALUE(audit_log, '$.status.code') AS status_code,
  JSON_VALUE(audit_log, '$.status.message') AS status_message
FROM `workbench-bq-log-sink.workbench_cloud_audit_logs_prod.cloud_audit_logs_*`
WHERE JSON_VALUE(audit_log, '$.serviceName') = 'storage.googleapis.com'
ORDER BY timestamp DESC
LIMIT 100

Last Modified: 3 November 2025