Skip to content

Add data collection access logging app - #456

Open
kvo3 wants to merge 1 commit into
masterfrom
kristenliu/dc-access-logging-app
Open

Add data collection access logging app#456
kvo3 wants to merge 1 commit into
masterfrom
kristenliu/dc-access-logging-app

Conversation

@kvo3

@kvo3 kvo3 commented Jul 29, 2026

Copy link
Copy Markdown

Adds a new Workbench devcontainer app for auditing data collection access grants. The app is a Flask web application that queries BigQuery monitoring tables (workbench-bq-log-sink) to provide visibility into who has access to a data collection, how they got it (directly or via group membership), and when.

Views

  • Forensic: Data Collection (landing page) — Full history of access grants for a data collection. Shows GROUP, MEMBER, and INDIVIDUAL grants with role,
    timestamp, and actor. Group rows are expandable to show who was in the group at the time of the grant. Supports hiding revoked access and toggling between
    user-facing and internal group names.
  • Group Membership Audit — Full grant/revoke history for a Workbench group, with a "current members only" filter.

Features

  • Configurable org and environment via env vars, config.yaml, or auto-detected from wb workspace describe
  • Org override field on all views for cross-org lookups without restarting the app
  • Search values persist across tab navigation
  • Client-side table filtering (AND/OR keyword search), column sorting, column-level filters, and resizable columns

Infrastructure

  • Dockerized with docker-compose.yaml and .devcontainer.json for Workbench devcontainer deployment
  • Python 3.11 slim base image, Gunicorn with 2 workers / 4 threads
  • .gitignore added to exclude .venv/, pycache/, and .env files

BENCH-8927

Flask app for auditing data collection access grants via BigQuery
monitoring tables. Includes forensic views for DC access history and
group membership audit with filtering, sorting, and org override.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kvo3
kvo3 requested review from a team as code owners July 29, 2026 21:25
@kvo3
kvo3 requested review from NavidZ and emmarogge July 29, 2026 21:34
@kvo3 kvo3 closed this Jul 29, 2026
@kvo3 kvo3 reopened this Jul 30, 2026
@kvo3
kvo3 requested review from june-hua and pantherman594 July 30, 2026 14:45

@emmarogge emmarogge left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@kvo3
kvo3 requested a review from yonghaoy August 5, 2026 17:06
@yonghaoy

yonghaoy commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Hey @kvo3 that is a custom app, customers are allowed to bring whatever app into workbench, as long as the app is not a built-in default 1st party app, no review is required.

However, for the purpose of the app, building a app just for DC audit is a bit overkill? It cost time and money to run that app, why not just query from BQ directly?

For AoU, I just provide a snippet of python code and let them to run that code in Jupyter

@NavidZ

NavidZ commented Aug 5, 2026

Copy link
Copy Markdown

@yonghaoy you are correct. Basically at the end this app (or that script you provided to folks) is a bunch of sql queries that folks can run.
This app just gives it a UI and run those queries behind the scene and render it in the UI in a nice way. instead of you giving folks python code to run in a jupyter they would run this app directly (if they choose to) with ideally a nicer UI. of course they can continue using their own direct access on the BQ and this doesn't prevent them from doing that direct path if they want to. This app targets more like a no-code way of exploring those audit logs.

@pantherman594 pantherman594 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, left some small comments but none are blockers

capture_output=True, text=True, timeout=10,
)
for line in out.stdout.splitlines():
for key in ("Organization:", "Google project:"):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future it might be easier to use --format json and read the output as json

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to include this file?

result = {}
try:
out = subprocess.run(
["wb", "workspace", "describe"],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this work? I don't see wb installed

return jsonify({"error": str(e)}), 500


@app.route("/health")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this redundant?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants