FAQ
Frequently asked questions
Clear answers on integration, licensing, where data lives, how to include objects in a scan, and how to tune detectors in your output Lakehouse.
Getting started
How hard is it to integrate OneLake Guard with our Fabric?
Low effort. Deploy the container from Azure Marketplace, set the service principal credentials and API_AUTH_KEY, then grant Fabric roles.
- Viewer (or higher) on every workspace you want scanned
- Contributor on the output workspace / Lakehouse (writes ops.* and deploys the report)
There is no allowlist of workspaces to maintain: scan scope = whatever the service principal can see. No Spark notebooks are required for analysis. Step-by-step: How to.
What identity does it use?
Service principal only — managed identity is not used. Configure client ID / secret (or certificate) for Fabric and OneLake access in the container settings.
Do users need to learn a new UI?
No. Results land in your output Lakehouse and open in the deployed Direct Lake Power BI report inside Fabric. Day-to-day review stays in the Fabric / Power BI experience you already use.
What Fabric / Entra permissions are needed beyond Viewer and Contributor?
Workspace roles are the main day-to-day control: Viewer (or higher) on monitored workspaces, Contributor on the output workspace / Lakehouse (plus Read on the Lakehouse SQL analytics endpoint for the report connection).
For auto-deploy of the semantic model, report, and the shareable SQL connection, a tenant admin typically needs Fabric settings that allow service principals to create workspaces, connections, and deployment pipelines (and Fabric public APIs) for that app registration.
Do not grant unnecessary tenant-wide admin — only add the SP where monitoring and output should happen. Details: How to.
When does the default scan run, and how do I change the schedule?
Default schedule is 0 2 * * * (daily at 02:00 in the container timezone) via SCAN_CRON_SCHEDULE.
Timezone: optional TIME_ZONE. If empty / unset, the container uses the OS / VM local timezone. Set these as container environment variables at Marketplace / Bicep deploy (they are not edited in ops.config).
For an extra run outside the cron, use POST /run — see Control API.
Public vs Private (VNet) install — how do I reach the Control API?
Chosen at Marketplace / Bicep install time (networkType):
- Public — set a dnsNameLabel. API base: http://{dnsNameLabel}.{region}.azurecontainer.io:8080
- Private — place ACI in an existing subnet delegated to Microsoft.ContainerInstance/containerGroups (ideally dedicated /28+). Call the API on the private IP from the VNet / peered network.
Auth is the same in both modes: X-API-Key / Bearer API_AUTH_KEY (except GET /livez).
License & data
Does one license limit workspaces, Lakehouses, Warehouses, or tables?
No. The $49 / container / month software fee does not meter by workspace, Lakehouse, Warehouse, or table count. One container can scan an unlimited number of those objects — limited only by what the service principal can access and by your Azure compute during the scan.
Details: Pricing.
Do data leave our tenant / customer infrastructure?
No product data plane outside your Fabric / Azure. OneLake Guard reads Delta metadata (and light-scans Parquet when needed) in your OneLake, then writes results to the Lakehouse you choose. The semantic model and report stay in your workspace. Nothing is shipped to a vendor SaaS database for monitoring.
Do we need a new vendor, or can we pay via our existing Azure subscription?
You install from Azure Marketplace and pay on the Azure subscription you already use. No separate vendor procurement for the software offer — Marketplace billing lands on your Azure invoice together with the container infra you run.
Does the $49 price include Azure container cost?
No. $49 is the Marketplace software license. ACI / compute / networking are billed by Azure separately. You can stop the container outside scan windows to cut most of that infra spend — see the operations section below.
Does one container cover the whole tenant / multiple capacities automatically?
No magic tenant-wide coverage. One container uses one service principal. Scan scope = every Fabric workspace that identity can list (Viewer+). Capacities, regions, and workspaces outside that SP’s access are not scanned.
To cover more of the estate with a single blast radius, grant the same SP Viewer on additional workspaces. If you need separation, install multiple Marketplace instances (each $49 / container / month), each with its own service principal and its own output Lakehouse (and report). Typical patterns:
- Dev / Test / Prod — separate SP + output Lakehouse per environment so results and access stay isolated
- Regions or business units — for large customers, one instance per region or domain, each scanning only the workspaces that SP can see
That way scan scope, credentials, and ops results never mix across environments or regions unless you deliberately share an SP.
Control API
Is there an API? Can I trigger a scan outside the default schedule?
Yes. The container exposes a Control API (default port 8080). The scheduler still runs on its cron, and you can start an extra on-demand scan anytime with POST /run (returns 202 and a run_id).
Auth: header X-API-Key: <API_AUTH_KEY> or Authorization: Bearer <API_AUTH_KEY> (same secret you set at deploy). Only GET /livez is unauthenticated.
Replace BASE with your ACI URL, e.g. http://<dnsLabel>.<region>.azurecontainer.io:8080.
Trigger an on-demand scan:
curl -sS -X POST "$BASE/run" \ -H "X-API-Key: $API_AUTH_KEY"
Example response: {"status":"accepted","message":"Scan started","run_id":"20261103T143000Z"}. If a scan is already running you get 409.
Check that run:
curl -sS "$BASE/run/20261103T143000Z" \ -H "X-API-Key: $API_AUTH_KEY"
Can I check service health and which Fabric workspaces are accessible?
Yes. Use liveness for “is the process up?”, authenticated health for Fabric connectivity / run status, and workspaces for what the service principal can currently resolve.
Liveness (no auth — for probes):
curl -sS "$BASE/livez"
Health (Fabric reachable + last/current run; needs API key):
curl -sS "$BASE/health" \ -H "X-API-Key: $API_AUTH_KEY"
Returns 200 when healthy, 503 with a detail payload when not (e.g. cannot reach Fabric).
Workspaces the service principal can access (scan targets):
curl -sS "$BASE/workspaces" \ -H "X-API-Key: $API_AUTH_KEY"
Response lists workspace name / id from service_principal_accessible discovery — that is the effective scan scope.
Optional: list runtime config via API:
curl -sS "$BASE/config" \ -H "X-API-Key: $API_AUTH_KEY"
How should we secure the Control API / API key?
Treat API_AUTH_KEY like a password: store it in Marketplace / Key Vault / pipeline secrets, rotate when people leave, and do not commit it to git.
Prefer Private (VNet) ACI if the API must not be on the public internet. In Public mode, still require the key on every call except /livez (which only confirms the process is up — it does not expose Fabric data).
Restrict who can reach port 8080 (NSG / private endpoint patterns / jump host). Do not share the key in browser bookmarks or chat.
Scanning & configuration
How do I add a Warehouse or Lakehouse to the scanned objects?
Grant the service principal at least Viewer on the Fabric workspace that contains that Lakehouse or Warehouse. On the next scan, OneLake Guard discovers Delta tables under items the identity can list.
- Only Delta tables are scanned
- Shortcuts and non-Delta formats are skipped
- Tables in the output schema (default ops) are excluded from analysis
There is no separate “register this Lakehouse” UI — access control is the inclusion list.
Can I turn off a detector type I do not care about (e.g. small files)?
Yes. After the first run, open the output Lakehouse table ops.config (schema name follows OUTPUT_SCHEMA). Set the matching *_enabled parameter to false.
Examples:
- small_file_bloat_enabled
- storage_bloat_enabled
- stale_table_enabled
- schema_drift_enabled
Values in ops.config win at runtime after first start. The Help page in the deployed report also lists detectors and related parameters.
Can I change detector sensitivity (file size, stale days, Z-scores, …)?
Yes — in ops.config in the output Lakehouse. Edit the parameter row; the next scan picks it up. Useful examples:
- small_file_bytes, small_file_ratio_alert, small_file_min_file_count
- stale_table_days — days without commits before STALE_TABLE
- volume_zscore_threshold, null_rate_zscore_threshold, mean_zscore_threshold, distinct_zscore_threshold
- vacuum_retention_days, storage_bloat_min_bytes
- commit_storm_min_commits, large_rewrite_min_rows
Each row in ops.config has a description column — use it as the field guide. Defaults originally ship from detection_thresholds; DB values override after seed.
Can I reassign an alert from INFO / WARNING / CRITICAL to another severity?
Yes. In ops.config, change the matching *_severity parameter to INFO, WARNING, or CRITICAL.
Examples: schema_drift_severity_type_change, stale_table_severity, small_file_bloat_severity.
Schema drift also has separate severities for add / drop / type change (schema_drift_severity_add, _drop, _type_change).
What objects are not scanned?
Shortcuts, non-Delta tables, and tables under the configured output schema (default ops). Everything else Delta that the service principal can discover is in scope.
If I change ops.config, can I get back to the defaults?
Yes. Edit freely — there is no lock-in. To restore packaged defaults:
- Clear the contents of the ops.config table in the output Lakehouse (or delete/recreate that table if you prefer).
- Restart the OneLake Guard container.
On startup the engine re-seeds ops.config from the default threshold catalog. You can then tune values again as needed.
What happens if some tables fail during a scan?
Failures are handled per table. OneLake Guard continues with the rest of the estate; it does not abort the whole run on a single bad path.
Check tables_failed (and related counts) on the run: Log page in the report, ops.fact_scan_runs, or GET /run/{run_id}. Fix access, Delta health, or transient OneLake errors, then re-run (cron or POST /run).
Why are volume / null / mean / distinct alerts quiet at the beginning (cold start)?
Z-score style detectors need history. By default min_history_days is 30 — until enough daily history exists, those statistical alerts stay quiet to avoid false positives on a brand-new estate.
Schema drift, new/deleted tables, small-file / storage / vacuum style checks can still fire earlier because they do not depend on the same cold-start window. You can tune min_history_days and related baselines in ops.config after you understand the trade-off.
Can I build a custom Power BI report on top of OneLake Guard?
Yes. The output workspace includes a semantic model over the ops.* tables. You can either customize the shipped report or create a new report connected to that model.
Recommendation: build a new report with a different name (or copy the shipped report under a new name) instead of heavily editing the default OneLake Guard report in place.
When you install / upgrade the Marketplace app to a newer version, the product redeploys the semantic model and the standard report to the current template. Custom edits on that default report would be overwritten. Keeping your customizations in a separately named report avoids losing them on upgrade.
Where can I read what each detector does and which config parameters exist?
Open the deployed Power BI report and go to the Help page.
- Anomaly types — every detector with how detection works, how it shows up, why it matters, and what you can do
- Config parameters — the full list of runtime settings that live in ops.config (parameter, value, description), matching what you can edit in the Lakehouse
Use Help as the in-product field guide before changing thresholds or severities in ops.config.
I open the Detail page in the report and see no data — how do I show a detail?
The Detail page is driven by a selected anomaly. Opening it from the left nav alone (with no selection) often shows an empty view — that is expected.
To load detail:
- Go to the Overview page.
- In the anomalies table, select / right-click the row you care about.
- Use Drill through (or the report’s drill-through action) to Detail.
That passes the anomaly context into Detail (schema diff, storage, column metrics, commits, and so on). Filters on Overview (severity, anomaly type, workspace, table, …) also narrow which rows you can drill from.
Someone edited the default semantic model or report — how do I restore the originals?
The stock OneLake Guard Model and OneLake Guard report are redeployed from the container template whenever the recorded app version in ops.schema_version does not match the running container.
To force a restore to the packaged definitions:
- In the output Lakehouse, open ops.schema_version and clear (or change) the app_version value so it no longer equals the current OneLake Guard version.
- Restart the OneLake Guard container (or start it if it was stopped).
On startup the product detects a version change, runs any needed migrations, and redeploys the standard semantic model and report — overwriting in-place edits on those default items.
Your ops.* monitoring data stays. Separately named custom reports are left alone. Prefer putting custom work on a copy with another name so you rarely need this reset.
Alerts & operations
Can we raise alerts on anomaly types (e.g. Critical only)?
Not as a built-in product feature today (no Teams/Slack alert workflow inside OneLake Guard yet).
You already own the data and the semantic model in your workspace. After a scan, you can build a Fabric pipeline (or notebook / Data Activator pattern) that reads ops.fact_anomalies (filter e.g. severity = 'CRITICAL' for the latest run), then sends email or runs any other pipeline action.
That keeps alerting under your control, on your Fabric capacity, without a separate vendor alert bus.
If we uninstall the app, do data, semantic model, and report remain?
Yes for the Lakehouse data — and typically for the report artifacts in your workspace. Results were written into your output Lakehouse. Uninstalling / removing the Marketplace container stops future scans; it does not delete the customer workspace items that already exist (Lakehouse tables, semantic model, report) unless you remove those items yourself.
How can we save on pricing / Azure infra cost?
The Marketplace license is flat. The Azure container only needs to run while a scan (and any Control API work) runs. Outside the daily scan window you can stop / deallocate the container and keep the license.
Automate start/stop with Azure (Logic Apps, Automation Account, scheduled CLI/Bicep, etc.): start before the scan cron, stop after the run finishes. That commonly saves on the order of ~90% of ACI cost versus leaving the container up 24/7 — see Pricing.
Does analysis require Spark notebooks or Fabric CU for the scan engine?
The Guard engine itself does not run as Fabric Spark notebooks for analysis — it reads _delta_log (and optional light scans) from the container. Writing results and using Direct Lake / Power BI still uses normal Fabric capacity as any Lakehouse + report would.
What happens on a Marketplace upgrade / new app version?
On start, OneLake Guard compares the container app version with ops.schema_version in the output Lakehouse.
- Same version — skips migrations and PBI redeploy (aside from light cleanup).
- New / first version — applies pending schema migrations, then creates/updates the OneLake Guard Model and the standard OneLake Guard report (and the shareable SQL connection for Direct Lake).
Your ops.* history stays in the Lakehouse. Custom edits on the default report/model can be overwritten on that redeploy — keep customizations in a separately named report (see the custom report question above).
Support
Where do we go for support or product questions?
For further questions, contact me directly:
Also useful:
For self-serve diagnosis first: GET /health, GET /workspaces, and the Log / Help pages in the deployed report.
Still stuck?
Contact me on LinkedIn or milos.gregor@anomalyguard.com.