Kristen Min Chan
All work

NXP Semiconductors · Tableau site admin · Python, REST API, GraphQL

Tableau permission audit

I turned a monthly permission audit that was not realistic by hand into under an hour of my time.

Impact

Under 1 hrof my time per monthly audit
Monthlythe audit runs every month
Enterpriseevery project, workbook and data source, across several sites

In productionA colleague runs it every month from the SOP I wrote.

The challenge

As Tableau admins, we audited who could see what, every month. It is how data access stays correct.

The scale made it hard: thousands of permission records across several Tableau sites. Checking them one at a time in the Server UI was not a realistic way to do it.

What I built

  1. Step 1

    Sign in

    REST API

    The script connects to Tableau Server through the REST API, the same way an admin would.

  2. Step 2

    Pull permissions and project lock settings

    REST API

    For every project, workbook and data source: who can do what, and whether the project locks its permissions.

  3. Step 3

    Pull content and lineage

    GraphQL Metadata API

    The Metadata API lists what content exists and what it depends on, so each permission can be read in context.

  4. Step 4

    Page through every result

    Python

    Results come back one page at a time. The script keeps asking until nothing is left, so no record is quietly missed.

  5. Step 5

    Flatten nested JSON into one table

    Python, pandas

    Records arrive nested at different levels. They are flattened into one clean table a dashboard can read.

  6. Step 6

    Self-service dashboard, on demand

    Tableau

    The table feeds a dashboard any admin can open when they need it, instead of waiting for a monthly pull.

  7. Step 7, human in the loop

    Validate each step against the UI

    After every step, I checked the output myself against what the Tableau UI showed, before the next step was built.

What it looked like

Recreated with sample data. No real company data is shown.

Where AI helped

Microsoft Copilot was in almost every step: brainstorming the approach, writing the action plan, listing risks, learning how to paginate in Python, getting GraphQL syntax right, and testing.

Human in the loop: what I kept

Validation. I checked each step’s output against the Tableau UI, and confirmed the whole flow was correct, before moving to the next step.

What happened after

Before I left, I wrote a PRD-style SOP covering every decision, every step, and how to troubleshoot it, so the work did not depend on me.

GraphQL returned more than permissions, so the same approach became the base for another audit: which workbooks and owners depend on each data source.

Credit

Pagination and flattening approach adapted from Ryan McAnelly, “Paginated GraphiQL queries using Python,” Her Data blog. herdata.net