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
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
- Step 1
Sign in
REST API
The script connects to Tableau Server through the REST API, the same way an admin would.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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
Permission audit, sample month
| Project | Content | Type | Group or user | Capability | Project setting |
|---|---|---|---|---|---|
| Project Alpha | Weekly Sales | Workbook | Group: Analysts | View | Locked |
| Project Beta | Pipeline Detail | Workbook | User: sample.user | Download full data | Customized |
| Project Beta | Orders Source | Data source | Group: Data Owners | Connect | Customized |
| Project Gamma | Ops Overview | Workbook | Group: All Users | View | Locked |
| Project Delta | Finance Draft | Workbook | Group: All Users | Edit | Customized |
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