Generated banner for Onelake Catalog CLI
Generated logo for Onelake Catalog CLI

Onelake Catalog CLI

MicrosoftOfficialPublished by Microsoft

  • Skill
  • Workflow
  • Automation and integrations
  • MIT
  • No issues found

From the author

Governs and curates the Microsoft Fabric OneLake catalog through Fabric Admin, Core and Power BI REST APIs. Use for tenant or data-owner governance audits and guarded remediation of domains, workspace assignment, capacity, labels, tag definitions, workspace tags, certification, refresh and item identity, and for owners curating an item's description, name, tags and table and column descriptions. Item discovery belongs to search-consumption-cli.
— the description by Microsoft

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

The onelake-catalog-cli skill provides a structured interface for managing the Microsoft Fabric OneLake catalog. It operates through distinct modes for governance auditing and metadata curation, ensuring that actions are performed with appropriate permissions and safety gates. The skill supports tenant-wide admin audits, data-owner governance checks, and item-level metadata curation, including descriptions, tags, and table/column metadata. It enforces strict write-gating and requires explicit owner approval for all changes to ensure data integrity and security.

What it does

  • Audits tenant-wide or workspace-specific governance posture.
  • Curates item metadata including descriptions, display names, and tags.
  • Manages table and column descriptions for items with OneLake Tables.
  • Performs guarded remediation for domains, workspace assignments, and capacities.
  • Provides dry-run capabilities for governance and remediation tasks.
  • Enforces strict write-gates requiring explicit user approval for all changes.

When to use it

  • When you need to audit governance posture across a Fabric tenant or specific workspaces.
  • When an item owner needs to improve discoverability through metadata curation.
  • When a data owner needs to remediate workspace domain, capacity, or tag assignments.
  • When a tenant admin needs to perform bulk governance updates or policy enforcement.

Advantages

  • Provides a unified, mode-based workflow for both auditing and remediation.
  • Enforces safety by requiring explicit approval for all write operations.
  • Supports granular, least-privileged access for data owners.
  • Includes built-in logic for handling long-running operations and API rate limits.
  • Ensures governance findings are actionable and prioritized.

Usage examples

“Propose a better description for the semantic model Sales Model in the Finance workspace.”
The agent will read the current item metadata, draft a suggested description based on content, and present it for owner approval before applying the change.
“Audit our tenant's OneLake catalog governance posture and prioritize the findings.”
The agent will perform a tenant-wide audit, applying the necessary scope filters, and report findings categorized by pillar with recommended actions.
“Which workspaces I administer are not assigned to a domain?”
The agent will identify and list all workspaces within the caller's scope that lack a domain assignment.
“Show a dry run for assigning these workspaces to the Finance domain, including current assignments.”
The agent will perform a read-only check to display the current domain assignments and the proposed changes for the specified workspaces.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/microsoft/onelake-catalog-cli/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip onelake-catalog-cli.zip -d .agents/skills

Documentation by Microsoft

Telemetry — MANDATORY. Every api.fabric.microsoft.com call must carry x-ms-fabric-skill: onelake-catalog-cli (az rest: --headers "x-ms-fabric-skill=onelake-catalog-cli"), including every LRO poll, fabric_lro and retry. Snippets omit it — add it anyway.

CRITICAL NOTES

  1. To find the workspace ID from its name, one call: az rest --method get --resource "https://api.fabric.microsoft.com" --url "https://api.fabric.microsoft.com/v1/workspaces" --query "value[?displayName=='<name>'] | [0].id" -o tsv (follow continuationToken only if it isn't on the first page; details in COMMON-CLI.md § Finding Workspaces and Items in Fabric).

  2. To find an item's ID, one call: the same on .../v1/workspaces/{ws}/items?type=<Type> with --query "value[?displayName=='<name>'] | [0].id".

  3. Write-gated skill — never call a write API before its gate below has passed. For curation that means the owner reviewed every proposed change and explicitly confirmed — not even a "test" write to check whether a change is allowed or what is already applied.

  4. The item list and Get Item both return an item's tags. An item with no tags has no tags field — that absence means untagged.

OneLake Catalog — CLI Skill (mode dispatcher)

One skill for the OneLake catalog. Govern (catalog health, protection and trust: audits and guarded remediation, by permission tier) and curate (an owner improving specific items' discoverability metadata) are modes, each detailed in a reference loaded on demand. This file picks the mode, holds every write gate, and indexes the references.

Mode selection

ModeUse whenLoadWrites
curateAn owner wants specific items easier to find: a description, a clearer display name, tags, or table and column descriptions (items with a OneLake Tables folder) — one item, an explicit list, or one named workspace's weakly-described itemsreferences/curate.md✅ after the owner approves each suggestion
dataowner-auditA non-admin workspace or domain owner wants governance posture for workspaces they administer (widen to accessible on request; Core API)references/dataowner-audit.md❌
dataowner-remediateA data owner who is also a domain / workspace / capacity admin fixes a governance finding — single-workspace domain or capacity assignment, workspace tags, refresh, item identity (Core & Power BI APIs, no tenant admin), including dry runs of thesereferences/dataowner-remediate.md✅ self-service
admin-auditA Fabric tenant admin wants tenant-wide governance posture (/v1/admin/*)references/admin-audit.md; any tenant count starts from admin-audit-scope.md❌
admin-remediateA Fabric tenant admin makes tenant-wide writes — domains, bulk assignment, domain roles, bulk labels, tenant tag definitions, tenant settingsreferences/admin-remediate.md✅

Govern is a 2×2 grid — tier (which API surface the caller can reach) × action (audit vs remediate) — covering the health, protect and trust pillars. Choose the tier by API surface, not job title: the admin-* modes need the Fabric tenant administrator role (Fabric admin / Power Platform admin / M365 global admin); domain, capacity and workspace admins who are not tenant admins live entirely in the dataowner-* modes.

Mode boundary rules
  • A direct curation request goes straight to curate. Read the target item's current state — don't run a governance audit first. Curation needs neither tenant admin nor workspace Admin; each change has its own permission (see curate.md).

  • Governance starts with an audit. Never remediate before establishing the current state; audit → remediate within the same tier unless the caller's rights change.

  • Curate is the only writer of item metadata. Item descriptions and display names, applying or removing an item's tags, and table and column descriptions are written only in curate. Workspace tags stay in dataowner-remediate; tenant tag definitions in admin-remediate.

  • Govern finds, curate fixes. Govern reports description and tag coverage — presence, with scope, denominator and freshness caveats, not proof the text is accurate; curate judges content and proposes. To fix selected gaps, hand off to curate with: a bounded target (an explicit item list with workspace ID, item ID and type, or one named workspace — never the whole tenant: ask the user to pick), the observed gap with its source and time (a candidate to recheck, not current truth), only the fields the user chose ("fix missing descriptions" = description only), and known access limits and owner contacts. A remediation is done only when curate has verified the write.

  • Audit modes never write. If a write is asked for in an audit mode, switch explicitly to the matching remediate mode or to curate — don't improvise a write.

  • A dry run or preflight of a fix loads that fix's remediate mode and stays read-only there — it isn't an audit. Moving one workspace to a domain is dataowner-remediate; bulk assignment is admin-remediate.

  • Finding items when the workspace isn't known belongs to search-consumption-cli. Looking up a workspace or domain by name, or an item by name inside a known workspace, is not discovery: use the lookups in CRITICAL NOTES and don't load search-consumption-cli for it.

⚠️ Known Fabric gap. A domain or workspace admin who is not a tenant admin has no API for their scoped governance posture: /v1/admin/* rejects them and the Core API can't list a domain's workspaces. dataowner-audit covers only workspaces the caller can access — say so up front rather than routing into an admin-* mode that will 401/403.

Terminal write — the step you must not skip

Reading a reference, drafting suggestions or building a dry run is NOT completing a write. Each writing mode ends with the state-changing call(s) below, issued only after the gate for that write passes. If you did not issue it, nothing changed — say so rather than reporting success.

ModeTerminal write
curatePATCH /v1/workspaces/{ws}/items/{id} (description; display name in a separate call), POST .../items/{id}/applyTags or unapplyTags, and for a table POST https://onelake.table.fabric.microsoft.com/common/v1/{ws}/{item}/schemas/{schema}/tables/{table}/additionalMetadata with the complete set from a fresh read — only for suggestions the owner accepted
dataowner-remediatePOST /v1/workspaces/{id}/assignToDomain / unassignFromDomain (synchronous 200), assignToCapacity (202 — poll to a terminal state), POST /v1/workspaces/{id}/applyTags / unapplyTags (workspace tags), item identity, semantic model refresh
admin-remediate/v1/admin/* writes — domains, bulk workspace assignment, domain roles, labels, tenant tag definitions, tenant settings
dataowner-audit, admin-auditnone — read-only

Before reporting a write done, confirm an explicit success (200/201, or a terminal LRO success for a 202) and read the result back.

Write gates — must pass first
WriteModeGate
Any curation writecurateThe owner saw a numbered current → proposed preview of every suggestion and explicitly approved; "apply all" covers only what was shown. Approving an audit or picking a remediation never approves text the owner hasn't seen.
Table and column descriptionscurateA write replaces the table's whole additional metadata: re-read, change only the approved descriptions, send the complete set in the same command, read again. The API has no concurrency check — never claim concurrent edits were preserved. A shortcut table is written on its source — name it and get explicit confirmation.
Delete a domainadminCheck subdomains (parentDomainId) and assigned-workspace counts for the domain and every subdomain; if workspaces would be orphaned, STOP and get explicit confirmation naming them. The API has no cascade-block. See domain-crud.md.
Delete a tag definitionadminReport how many items carry it first — deletion detaches it everywhere with no undo.
Bulk-assign workspaces to a domainadminCheck each target's current domainId and warn before silently overriding an assignment. Dry-run the target list first.
Remove a principal from a domain roleadminConfirm it will not leave the domain ownerless; name the principal being removed.
Bulk sensitivity-label changeadminDry-run: show the affected items and before/after label, get confirmation. No service principal / managed identity — the call will fail.
Write a tenant settingadminRead and show the current value, then the proposed value — tenant-wide blast radius.
Assign / unassign one workspace to a domaindataownerA move is a reassignment — confirm the current domainId and name the domain it leaves. Needs domain contributor and workspace Admin; say which is missing on failure.
Reassign item ownership (item identity, preview)dataownerAssigns to the caller only; needs Write on the item and its children. Confirm the intended identity.
Assign a workspace to a capacitydataownerNeeds workspace Admin plus capacity Contributor/Admin. 202 is not success — poll to a terminal state.
Apply / remove a workspace tag (preview)dataownerNeeds workspace Admin. Name the workspace and the tags, and confirm. Removing an applied tag is not deleting its definition.

Don't promise a write that has no API. Endorsement, DLP policies, an owner changing a sensitivity label, and tenant-admin item deletion have no write route — say so and name who can act (no-write-api-escalation.md). A SQL Database's display name is fixed at creation: never send a rename for it, even when the owner asks for one — say it can't be renamed and offer the description and tags instead.

Shared essentials (all modes)

  • Prerequisites: auth & tokens · REST, pagination, LRO, rate limits · CLI auth recipes · az rest (always pass --resource) · OneLake via curl (Storage-audience token) · OneLake shortcuts.

  • Resolve workspace and item IDs with the one-call lookups in CRITICAL NOTES 1–2.

  • Keep tool calls few. Each call re-sends the whole conversation, so extra calls are slow and costly. Combine related reads in one script, and don't re-open a doc you've already read.

  • Read an item's definition in one command that waits for the long-running operation itself (a semantic model usually returns 202) — never poll it in separate calls. It waits as long as Fabric's Retry-After asks (often 20–30 s), so give the command up to 3 minutes: if your shell tool has a wait or timeout setting, raise it rather than letting the command move to the background. Only for types with a definition: Warehouse, SQL Database, SQL analytics endpoint, ML model/experiment and Datamart have none — read their schema instead. PowerShell 7 (bash: fabric_lro in COMMON-CLI.md):

    $h = @{ Authorization = "Bearer $(az account get-access-token --resource https://api.fabric.microsoft.com --query accessToken -o tsv)"; 'x-ms-fabric-skill' = 'onelake-catalog-cli' }
    $st = @{ n = 0; end = (Get-Date).AddMinutes(3) }
    # Waits the full Retry-After (202 and 429); backs off 2-30 s only when the header is missing or invalid.
    function Wait-RetryAfter($r) { $ra = 0
      if (-not [int]::TryParse("$(@($r.Headers['Retry-After'])[0])", [ref]$ra) -or $ra -lt 1) { $ra = [Math]::Min(30, [Math]::Pow(2, ++$st.n)) }
      if ((Get-Date).AddSeconds($ra) -gt $st.end) { throw "Definition read did not finish within 3 minutes." }
      Start-Sleep -Seconds $ra }
    while (($r = Invoke-WebRequest -Method Post -Uri "https://api.fabric.microsoft.com/v1/workspaces/$WS_ID/items/$ITEM_ID/getDefinition" -Headers $h -SkipHttpErrorCheck).StatusCode -eq 429) { Wait-RetryAfter $r }
    if ($r.StatusCode -ge 400) { throw "getDefinition returned $($r.StatusCode): $($r.Content)" }
    $def = if ($r.StatusCode -eq 202) {
      $op = [string]$r.Headers['Location']; $res = $r; $s = ''
      while ($s -notin 'Succeeded', 'Failed') {
        Wait-RetryAfter $res; $res = Invoke-WebRequest $op -Headers $h -SkipHttpErrorCheck
        if ($res.StatusCode -eq 200) { $s = ($res.Content | ConvertFrom-Json).status } elseif ($res.StatusCode -ne 429) { throw "Polling returned $($res.StatusCode): $($res.Content)" } }
      if ($s -ne 'Succeeded') { throw "Definition read failed: $($res.Content)" }
      while (($res = Invoke-WebRequest "$op/result" -Headers $h -SkipHttpErrorCheck).StatusCode -eq 429) { Wait-RetryAfter $res }
      if ($res.StatusCode -ge 400) { throw "Definition result returned $($res.StatusCode): $($res.Content)" }
      $res.Content | ConvertFrom-Json
    } else { $r.Content | ConvertFrom-Json }
    $dir = New-Item -ItemType Directory -Force -Path (Join-Path ([IO.Path]::GetTempPath()) "def-$ITEM_ID")
    foreach ($p in $def.definition.parts) {
      $t = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($p.payload)); $f = Join-Path $dir ($p.path -replace '[\\/:]', '_'); Set-Content -LiteralPath $f -Value $t
      "== $($p.path) ($($t.Length) chars)"; if ($t.Length -le 4000) { $t } else { $t.Substring(0, 4000); "[first 4000 of $($t.Length) chars; full text in $f]" } }

    A part cut at 4,000 characters is saved in full: read the rest (one call) if what's shown isn't enough.

  • Use the exact Fabric Admin, Core, Power BI, Graph or OneLake API surface the mode documents; a 401 or 403 is never permission to bypass RBAC.

Rules

MUST
  • Load exactly one mode reference for the request and follow it end to end; come back to the index below when another procedure is needed. In curate, also read the suggestion guidance before drafting anything, and the table metadata reference before any table or column work.

  • (curate) Propose exactly what the owner asked for. A specific request gets only that: "add a description" → the item description; "suggest tags" → tags; "describe the table" → the table description only; "describe the columns" → column descriptions only; "describe the item's objects" or "its tables and columns" → both. A general request ("curate this item", "make it more discoverable", "improve its metadata") gets the item's description, name and tags; an item with a OneLake Tables folder also gets its table and column descriptions. If the owner names several items, cover each one, and report each with only the fields it has.

  • (curate) Check the scope before any call. Curate covers one item, an explicit list of items, or one named workspace at a time. For a tenant-wide request ("all my items", "every workspace"), say plainly that it isn't supported and offer one named workspace or an explicit list; for several named workspaces, ask which to start with. Don't list workspaces or items first.

  • (govern) State scope, exclusions, pagination completeness, and freshness caveats with every governance statistic.

PREFER
  • Least-privileged Core or Power BI APIs for data-owner actions instead of requiring tenant-admin rights.

  • Findings as evidence, consequence, recommended action, priority and effort — not an inventory dump.

  • Sequencing ownership and access-scope fixes before bulk assignment or labeling.

AVOID
  • Mutating a tenant from an audit mode, or reporting an asynchronous 202 as completion.

  • Inventing write APIs for endorsement, DLP policy, admin item deletion, or third-party item-identity assignment.

  • (curate) Volunteering anything about table or column descriptions for items without a OneLake Tables folder (semantic models, reports, notebooks, pipelines, dataflows, …). For these items, description, name and tags are the complete list — present them without qualifiers in the preview and whenever you say what the skill can do (e.g. while declining a request, or offering what else you could review next). Don't add a note that table or column descriptions are N/A, don't apply or aren't covered, and don't offer them: the owner didn't ask. Only if they ask, answer that they aren't supported for that item type, then stop and let the owner choose — don't load another skill or draft those descriptions yourself.

  • (curate) Saying "sub-items" — use the owner's words: "tables" and "columns", or "objects" when speaking generally.

References

Each reference is one hop from this index; after loading one, return here when another is needed.

Curate

Govern — shared

Govern — modes

  • Admin audit — tenant-wide read-only governance assessment

  • Admin audit scope — governable denominator (active workspaces of type Workspace), exclusions, and known blind spots

  • Admin audit assessment — end-to-end evaluative workflow, prioritization, and deliverable contract

  • Admin remediate — tenant-wide guarded writes through Admin APIs

  • Data-owner audit — caller-scoped read-only checks through Core APIs, including a workspace's domain assignment

  • Data-owner workspace health — empty and inactive workspaces within the caller's scope

  • Data-owner remediate — least-privileged Core and Power BI writes: moving one workspace to a domain, capacity, workspace tags, refresh, item identity

Govern — admin audit procedures: domain health · workspace health · capacity health · item inventory · item health · protect coverage · trust curation

Govern — admin remediation procedures: domain lifecycle · bulk workspace assignment (tenant admin) · domain roles · tag definitions · item sensitivity labels · domain default labels · trust remediation · no-write escalation

Examples

I'm curating my items for the OneLake catalog. Propose a better description for the semantic model Sales Model in the Finance workspace.
Make the lakehouse LSEGDemo more discoverable — describe its tables and columns too.
Audit our tenant's OneLake catalog governance posture and prioritize the findings.
Which workspaces I administer are not assigned to a domain?
Show a dry run for assigning these workspaces to the Finance domain, including current assignments.
Find unlabeled items tenant-wide and explain which remediations require a tenant admin versus a data owner.

Files

references/admin-remediate/no-write-api-escalation.md

<!-- TOPIC REFERENCE for onelake-catalog-cli (mode: admin-remediate). Loaded on demand from admin-remediate.md. -->

What Has No Write API — and How to Escalate

Part of the onelake-catalog-cli skill (admin-remediate mode). Return to the dispatcher admin-remediate.md. Read this before promising any remediation.

At admin tier you can read almost everything and write almost nothing about item content. This file lists what has no admin write path, how to turn such a finding into a named contact list, and the one preview exception (item identity).


What Has No Write API

Do not invent endpoints for these. If the user asks for them, say plainly that no public REST API exists and give the portal path.

RequestWhy this API mattersStatusDo this instead
Set endorsement (Promoted / Certified / Master data) on an itemEndorsement is the trust signal consumers rely on to tell an authoritative item from an ad-hoc one. Scripting it would let governance certify at scale and keep trust badges current across thousands of items, instead of clicking through each one by hand.No public REST API — not on Fabric core, Fabric admin, or Power BI. PATCH item endpoints expose only displayName and description.Endorse via the item's Settings → Endorsement page in the Fabric portal. You can enable certification via the tenant-settings API (GET/POST …/tenantsettings/CertifyDatasets, see trust-curate.md) — that half is scriptable; only applying the badge to an item is portal-only.
Create or modify Fabric DLP policiesDLP policies are the primary control stopping sensitive data from leaking out of the tenant. API access would let teams codify, version-control, and consistently roll out data-loss protection rather than hand-editing them in a portal where drift and gaps go unnoticed.No public REST API documented.Microsoft Purview portal → Data loss prevention.
Read DLP violations or last-evaluation timeViolation counts and evaluation freshness are core compliance evidence. Without them you cannot automate audit reporting, alert on new violations, or catch items whose DLP evaluation has gone stale and is silently no longer protecting anything.Not exposed by any API used in this skill family.OneLake catalog Govern tab → View more → Protect, secure & comply (DLP selector: evaluated items, violations, last evaluation time), or Microsoft Purview portal → Data loss prevention → Alerts for aggregate alerts.
Set the tenant-wide default sensitivity label policyA tenant-wide default guarantees nothing ships unclassified — the baseline that makes every downstream protection (encryption, DLP, access) enforceable. Scripting it would let governance set and prove that floor across the whole tenant in one action.Not in Fabric REST.Microsoft Purview, or PowerShell Set-LabelPolicy. Domain-level defaults are settable — see domain-default-label.md.
Read or set a domain image / brandingBranding is how users recognize an authoritative domain at a glance, which drives them toward governed data and away from shadow copies. An API would let large orgs standardize domain identity consistently instead of relying on each domain admin to get it right.No API field exists — not readable and not writable. The Domain object exposes only id, displayName, description, parentDomainId, defaultLabelId — verified against the schema and live responses — so there is no field to GET and none to PATCH. This is not a missing write path over a readable value (as with endorsement); the property is absent from the API surface entirely.Admin portal → Domains → select domain → domain settings. Domain admins can set it themselves.
Configure a default domain (auto-assign users' workspaces)Auto-assigning new workspaces to the right domain keeps the catalog organized and governed as the tenant grows, instead of accumulating unclassified workspaces. An API would let this scale and be audited — especially since the setting also grants contributor access, a permission change that ought to be tracked.No API exists to read or set the user/group list. UpdateDomainRequest accepts only displayName, description, defaultLabelId; all candidate endpoints return 404.Admin portal → Domains → domain settings. ⚠️ Note this also implicitly grants domain contributor to those users, so it is a permission change, not just an assignment convenience.
Fabric-native semantic model refreshFresh data is the entire purpose of a semantic model; a stale one silently serves wrong numbers to every report built on it. Admin-triggerable refresh would let governance guarantee freshness SLAs and remediate stalled models without chasing each owner.Not documented — no admin or public REST API. The Power BI refresh API applies to Power BI semantic models, not Fabric-native ones.Escalate — the item owner or a workspace admin must run it (portal Refresh now, a scheduled refresh, or a Data Factory semantic-model-refresh activity). Name them via Route a Finding to Someone Who Can Fix It. For Power BI models, the owner can use the Power BI refresh API (dataowner-remediate.md).
Add or change a workspace role assignment as tenant admin (e.g. fix a single-admin workspace)A workspace with a single admin is a bus-factor risk — if that person leaves, the workspace becomes unmaintainable and its data ungoverned. An admin write path would let the tenant admin remediate this resilience gap directly, which is exactly the kind of finding the audit surfaces.No admin-scoped write route. Live-verified: GET /v1/admin/workspaces/{id}/roleAssignments reads roles fine, but POST to it returns 404 — it is read-only. The write route POST /v1/workspaces/{id}/roleAssignments returned 403 to a tenant admin, because it requires the workspace Admin role, which tenant admin does not confer.Ask an existing workspace admin to add the second admin, or have the tenant admin take over the workspace first via the portal. ⚠️ Taking over is a visible, auditable permission change — never do it silently to "fix" a report.
Set a capacity's admins, or resolve an invisible capacityCapacity admins own cost and performance for everything running on that capacity; an invisible capacity is a governance blind spot with no accountable owner. An API would let governance restore visibility and assign ownership so capacity risk doesn't go unmanaged.No governance write path here, and 36% of workspaces in a verified tenant referenced a capacity absent from both capacity endpoints (direct fetch returned 401).Capacity admins are managed in the Azure portal (Fabric capacity resource) or Power BI admin portal, not via these APIs.
Reassign ownership of items whose creator has leftAn item whose creator has left is orphaned — no one is accountable for maintaining, refreshing, or securing it, yet it stays live in the catalog. Reassignable ownership keeps every item tied to an active, contactable person.creatorPrincipal is not writable — PATCH item endpoints expose only displayName and description. ⚠️ Partly superseded: for item types supporting item identity, ownership is now reassignable — see Reassign Item Ownership below.For unsupported types (~96% of items): take over in the portal, or recreate under an active owner. For semantic models, use Take over in dataset settings.
Delete or edit an item as tenant admin (e.g. clean up stale/unused items found by the audit)Stale and unused items inflate cost, clutter the catalog, and widen the attack surface. An admin write path would let governance act on its own audit findings — the audit is only worthwhile if the admin who runs it can also clean up what it finds.No admin-tier write route exists at all. Live-verified: DELETE /v1/admin/items/{id} and DELETE /v1/admin/workspaces/{ws}/items/{id} both return 404 — the routes are not real. The only delete route is the core DELETE /v1/workspaces/{ws}/items/{id}, which needs workspace Contributor or above. Against a workspace the tenant admin is not a member of, even GET /v1/workspaces/{ws}/items returned 401 Unauthorized.You cannot do this yourself. Route it to the workspace admins or the item creator — see Route a Finding to Someone Who Can Fix It. A tenant admin can add themselves via the portal first, but that is a visible, auditable permission change.
Read one item's permission listPer-item access is what proves least-privilege: an item may be shared far more narrowly — or more widely — than its workspace. Without per-item ACLs you cannot verify an item isn't over-shared, which is the central question of an access audit.GET /v1/admin/items/{id}/users returns 404 — live-verified against a real item ID; no per-item ACL exists at admin tier.Fall back to workspace-level access: GET /v1/admin/workspaces/{id}/users. State plainly that you are reporting workspace access, not item access.

Route a Finding to Someone Who Can Fix It (Escalation Lists)

Several Pillar 1 findings — stale items, unused items, creator-unresolvable items, single-admin workspaces — are found by the tenant admin but fixable only by someone else. The audit surfaces them; the tenant admin has no write path (see the table above).

Do not end there. A finding with no named owner is not actionable. Convert it into a contact list.

The asymmetry to state out loud: at admin tier you can read everything and write almost nothing about item content. Live-verified on a workspace the tenant admin was not a member of: /v1/admin/workspaces/{id}/users and /v1/admin/items?workspaceId= both returned 200, while the core /v1/workspaces/{id}/items returned 401. You will always be able to say who must act, and usually not act yourself.

Who to contact, in priority order
RankContactWhere it comes fromUse when
1Workspace adminsGET /v1/admin/workspaces/{id}/users → entries with workspaceAccessDetails.workspaceRole == "Admin", each carrying principal.userDetails.userPrincipalNameAlways. They can delete, re-permission and reassign inside the workspace.
2Item creatorcreatorPrincipal.userDetails.userPrincipalName on GET /v1/admin/itemsContext on why the item exists. Not an authority — see caveats.
3Domain adminsGET /v1/admin/domains/{id} → adminPrincipalsThe workspace is in a domain and its admins are unresponsive or absent.
4Capacity adminsGET /v1.0/myorg/admin/capacities → adminsCapacity-level findings only.
Building the list
# For each workspace containing findings, get its admins with contactable UPNs
curl -sS -H "Authorization: ******" \
  "https://api.fabric.microsoft.com/v1/admin/workspaces/$WS/users" \
| jq -r '.accessDetails[]
         | select(.workspaceAccessDetails.workspaceRole == "Admin")
         | [.principal.displayName, .principal.type,
            (.principal.userDetails.userPrincipalName // "no-upn")] | @tsv'

For more than a handful of workspaces use the scanner API instead — POST /v1.0/myorg/admin/workspaces/getInfo?getArtifactUsers=True returns users[] with emailAddress and groupUserAccessRight, 100 workspaces per call. Live-verified.

Caveats you must carry into the report
  1. Creator is not owner and not an authority. They may have moved teams or left. Never write "ask the owner" — write "created by X; workspace admins are Y and Z."

  2. creatorPrincipal.type is always "User", including for service principals. An SPN-created item has no human to email; escalate to the workspace admins instead.

  3. Group admins are not a person. A principal.type of Group gives you a group, not an inbox — its membership is not resolvable from these APIs. Report the group name and say membership was not expanded.

  4. Workspace access ≠ item access. There is no per-item ACL at admin tier (404). An item may be shared more narrowly than its workspace.

  5. Deleted workspaces still return users. Scope to state=Active and type=Workspace first, or you will email people about workspaces that no longer exist.

Reporting shape

Group by who must act, not by finding type — one person should receive one list, not six:

[email protected] — workspace "Sales Analytics" (Admin)
  - 12 items not modified in 180+ days  → confirm still needed, else delete
  - 1 item whose creator no longer resolves → reassign or take over
  - Workspace has 1 admin → add a second (tenant admin cannot do this for you)

Then state explicitly which of these the tenant admin could have done and chose not to, versus which are impossible at admin tier. That distinction is the difference between a delegation and an excuse.


Reassign Item Ownership (Item Identity, Preview)

This runs in the data-owner cell, not here. Item-identity assignment requires Write on the item and its children and assigns to the caller — a tenant admin generally cannot run it on someone else's item. The full procedure is dataowner-remediate.md § Reassign Item Ownership (Item Identity, Preview). When you find orphaned ownership as an admin, hand this instruction to the workspace admin / incoming owner and pair it with the escalation list above.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Microsoft
Publisher
Microsoft (Official)
Source
microsoft/skills-for-fabric · skills/onelake-catalog-cli · commit f8fac11
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Also distributed in
microsoft/skills-for-fabric

AutoGineer is not affiliated with or endorsed by Microsoft or Microsoft.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download onelake-catalog-cli.zip