Skip to main content
Data Governance

Fabric SQL Audit Logs Predicate Filtering: Cutting Compliance Noise

Audit logging gets switched on to answer an auditor or satisfy a group policy — and then nobody reviews it, storage climbs, and the control becomes an artefact produced once a year. How predicate filtering drops known activity at capture time, and what the rules actually require.

Amit Kumar Singh - Technology Consulting Partner at MyData Insights

Technology Consulting Partner · MyData Insights

14+ years in industrial data · Former Accenture & EY · India, GCC, SEA

17 August 2026 · 12 min read

The bottom line

Fabric SQL audit logs capture database events as encrypted .XEL files in OneLake — and once switched on, most estates drown in service-account noise and stop reviewing them. Predicate filtering drops known, expected activity at capture time, but it is irreversible: an excluded event is never written. Exclude machine identities by principal, never writes, permission changes, failed logins or reads of classified tables. The regulators — UK GDPR, Saudi PDPL, UAE — do not require auditing every SELECT; they require demonstrable control and detection of misuse. The control that works is a five-to-fifty-row daily exceptions table in front of a named reviewer.

Switched on for a good reason, then never reviewed

Audit logging usually gets switched on for one of two reasons: an external auditor asked how you would prove who read the margin table, or a group security policy landed from a European or Japanese parent and someone in IT ticked the box that made the question go away. Both are reasonable.

What happens next is the problem. Nobody reviews it. Storage climbs, the query that reads the log takes minutes to return, and the control becomes an artefact you produce once a year for the auditor.

Predicate filtering in Microsoft Fabric addresses the part of this that is genuinely a technology problem: it drops known, expected activity at capture time rather than making you filter it out afterwards. It does not decide what matters — that judgement stays yours.

What Fabric SQL audit logs capture, and where they land

SQL audit logs in Microsoft Fabric record database-level events — authentication attempts, data access and modification, schema changes, permission and role changes — for Fabric Data Warehouse, the SQL analytics endpoint and SQL database in Fabric. Fabric writes them as encrypted .XEL files to an Audit folder in the item's OneLake storage.

Three things matter before you design anything around this. It is off by default in Fabric Data Warehouse — a user with the Audit queries permission enables it, and when they do, all actions are enabled and retained for nine years. It is not the same log as the Fabric activity log, which tells you who opened a report or shared a workspace. And events are grouped, not itemised: Fabric maps friendly portal names onto SQL Server audit action groups — BATCH_COMPLETED_GROUP, SCHEMA_OBJECT_ACCESS_GROUP, DATABASE_OBJECT_CHANGE_GROUP, DATABASE_ROLE_MEMBER_CHANGE_GROUP, FAILED_DATABASE_AUTHENTICATION_GROUP and others. Access is separately controlled — Workspace Admins hold Audit queries, and a GRANT lets someone query the log with T-SQL without changing the configuration.

How the predicate expression actually works

Predicate filtering is an optional expression Fabric evaluates before an audit event is written. Microsoft is explicit about the consequence: filtering happens before the event is written, so excluded events are not available later for retrospective investigation. That single fact governs every design decision — filtering is irreversible.

The syntax is the predicate-expression clause from CREATE SERVER AUDIT, without the WHERE keyword. The rules that matter in practice: the field can be any column returned by sys.fn_get_audit_file except file_name, audit_file_offset and event_time — so server_principal_name, database_principal_name, object_name, schema_name, statement and succeeded; action_id and class_type are strings in the output but can only be compared to numeric values inside a predicate; the maximum length is 3,000 characters; and the predicate only evaluates events an enabled action group already generates, so to filter SELECTs on the statement field, BATCH_COMPLETED_GROUP must be enabled first.

Two practitioner notes. The published grammar combines factors with AND, OR and NOT and does not show parentheses, so keep predicates flat and test compound rules rather than trusting operator precedence. And you configure it in the portal or via the REST API as predicateExpression — on updates, omitting the property leaves the existing predicate unchanged, while an empty string removes it.

A worked filtering strategy for an industrial estate

A typical mid-market manufacturer has one or two warehouses serving plant, quality and supply-chain reporting, plus a SQL database in Fabric behind an operational app. The filtering decision comes down to five categories.

CategoryDecisionMechanism
Scheduled refresh and service-principal readsExcludePredicate on server_principal_name
All writes and schema changesKeep, alwaysNever filter DATABASE_OBJECT_CHANGE_GROUP, SCHEMA_OBJECT_CHANGE_GROUP
Permission, role and audit-config changesKeep, alwaysDATABASE_OBJECT_PERMISSION_CHANGE_GROUP, DATABASE_ROLE_MEMBER_CHANGE_GROUP
Failed loginsKeep, alwaysFAILED_DATABASE_AUTHENTICATION_GROUP
Human reads of classified tablesKeep, alwaysItem separation, not predicate logic

The sequence: run unfiltered for one week first, then group the log by principal — in the estates I have worked in, the top three or four principals account for the overwhelming majority of rows, and every one is a machine identity you already know. Exclude by identity, not by statement text (for example, NOT server_principal_name = 'svc-fabric-refresh@yourcompany.com'). Protect classified data with item design, not predicate cleverness. And review the predicate on a schedule, because a new service account added next quarter will otherwise be captured as noise or, worse, a new human reader will be filtered by an over-broad rule.

The cost and reviewability argument

Storage is the smaller half — for SQL database in Fabric, Microsoft states that writing audit logs to OneLake does not currently incur additional charges and counts within the capacity's OneLake storage limits. The larger half is review cost: a weekly exception review an IT or security lead can complete in 15–20 minutes gets done; a log that takes minutes to query and returns millions of rows does not.

The pattern that works: filter machine identities at capture, then land a small daily exceptions table in the Gold layer — access to classified objects, permission changes, failed authentications, and human reads outside a defined working window — in front of a named reviewer. Five to fifty rows a day is a control. A million rows a week is an archive nobody opens.

What UK and GCC rules actually require

This is where vendor material tends to overstate the position, so be careful. In the United Kingdom, UK GDPR does not name audit logging as a requirement — Article 5(2) requires accountability and Article 32 appropriate security measures. Saudi Arabia's PDPL requires organisational, administrative and technical measures to protect personal data; the NCA's Essential Cybersecurity Controls go further on event logging, but neither prescribes auditing every SELECT. The UAE's federal data-protection law requires demonstrable control of processing.

None of these instruments tells you to audit every SELECT. They tell you to demonstrate control and detect misuse — which a targeted, reviewed exceptions log does far better than an unfiltered firehose nobody reads.

How this fits the wider governance layer

Microsoft Purview sensitivity labels classify the item so people know what they are handling and protection policies can restrict access — Fabric supports manual, default, mandatory and programmatic labelling with downstream inheritance, though inheritance from data sources has limits worth checking. Workspace and item design is what makes a narrow, defensible predicate possible: classified data in its own item and workspace means the noisy predicate never applies to it.

Retention runs on two clocks. Fabric stores SQL audit logs inside the item's folder in OneLake and scopes them to the item lifecycle — delete the warehouse and the audit files go with it. If you need independent retention (a regulator's floor, a group policy), copy the .XEL files to a separate Lakehouse or Azure Storage account with its own retention.

Where this breaks, and what it does not fix

Filtering is irreversible — an event excluded by predicate is never written, so an over-broad rule is a permanent blind spot. Statement-text filtering is fragile — LIKE matching against the statement field breaks on parameterised queries, comments, whitespace and casing, and cannot distinguish a routine SELECT from a sensitive one, which is why you filter by identity, not text. Auditing is best-effort under load — Microsoft states the feature is optimised for the availability of the database, and under very high activity it might allow transactions to proceed without recording every event.

And the SQL analytics endpoint has real gaps — DML such as INSERT, UPDATE, DELETE and MERGE is not captured there, because Lakehouse data manipulation happens through the Lakehouse runtime. Configuration is per item and drifts, and is not supported in the default workspace or for warehouse snapshots. Above all, a log tells you what happened, not whether it was legitimate: the finance manager reading margin data at 22:00 may be closing the month or preparing to join a competitor — the log cannot tell you which.

What to do first

Four questions to answer this week, before touching a configuration screen:

  • Which tables would cause a problem if a departing employee copied them — and are they in their own item today?
  • If you ran auditing unfiltered for seven days, which principals would generate the top 80% of events, and are they all machine identities you can name?
  • Who reviews the log, how often, and how long does that review take? If the answer is "nobody", filtering is not your first problem
  • What retention are you actually required to hold — a regulator floor, an ICO expectation, a group policy number — and does your Fabric setting match it?

We build governed Microsoft Fabric estates for manufacturers across the UAE, Saudi, the UK and India, with Microsoft Purview, workspace design and audit configuration treated as part of the build rather than a retrofit — because a predicate is only as defensible as the workspace design underneath it.

The question that decides whether filtering is even your problem is the third one: who reviews the log, and how long does it take? If the honest answer is "nobody", the fix is a five-to-fifty-row daily exceptions table in front of a named reviewer — not a cleverer predicate. Book a diagnostic with Amit — no slides, no pitch deck, no obligation to proceed.

Free Assessment

Where does your operation sit on the data maturity curve?

8 questions. 3 minutes. You get a scored breakdown across data infrastructure, analytics readiness, and automation potential — with a specific next step for your industry.

Data GovernanceMicrosoft FabricAuditComplianceSecurity

Your Data · Our Technology · Our Automation

Get practical insights every fortnight

Amit writes about Microsoft Fabric, Power BI, AI in operations, and digital transformation for manufacturing and supply chain leaders. Practitioner perspective - no fluff, no vendor spin.

No spam. Unsubscribe any time. Also on Substack.

FAQ

Common questions

What is predicate filtering in Fabric SQL audit logs?

An optional T-SQL expression Fabric evaluates before writing an audit event, so expected activity — typically service principals and scheduled jobs — never reaches the log. It uses the predicate-expression grammar from CREATE SERVER AUDIT without the WHERE keyword, and only applies to events an enabled audit action group already generates.

Which fields can I filter on?

Any column returned by sys.fn_get_audit_file except file_name, audit_file_offset and event_time — commonly server_principal_name, database_principal_name, object_name, schema_name, statement and succeeded. action_id and class_type can only be compared to numeric values, and the expression is limited to 3,000 characters.

Where are Fabric SQL audit logs stored, and for how long?

As encrypted .XEL files in the item’s Audit folder in OneLake. Fabric Data Warehouse defaults to nine years; SQL database in Fabric retains until you configure a period. Retention is scoped to the item lifecycle, so copy the files elsewhere if you need independent retention.

Does UK GDPR require database audit logging?

Not by name. Article 5(2) requires accountability and Article 32 appropriate security measures — which a targeted, reviewed exceptions log satisfies better than an unfiltered log nobody reads.

Is auditing for SQL database in Fabric generally available?

It was announced in public preview in November 2025. Confirm the feature state in your own tenant before relying on it as a certified control, as preview features can change.

Is this the challenge you're facing?

Book a 30-minute call. We'll look at your specific operation and tell you what's achievable - plainly and without slides.