Protect your strings in ADX KQL queries using string obfuscation

Obfuscate strings in KQL queries

Learn how to obfuscate strings in KQL queries in Azure Data Explorer. This way, the query log will not display sensitive information when someone is reviewing executed queries.

Tobias Zimmergren
Tobias Zimmergren

Previously, I wrote about understanding Azure Log Analytics query auditing. I since have had several conversations about what goes into an audit log and what can be protected.

The previous post was about Log Analytics. This post is about Azure Data Explorer and how to protect sensitive strings in your queries. It's effortless and something worth knowing.

ADX Query logs

In Azure Data Explorer (ADX), you can pull up a log of the most recent queries to your cluster like this:

.show queries

You will see a list of the queries, including a defined set of metadata around the query:

Recent Azure Data Explorer queries, as listed from the ADX cluster.

You can also show queries from the last few minutes to clean up the log view:

.show queries
| where StartedOn >= ago(5m)

You can then review the most recent logs from the last 5 minutes, as in my example.

Plain text query logs displayed in an Azure Data Explorer cluster.

If your queries contain sensitive information, for example, Personally Identifiable Information (PII), API keys, user accounts, or any information you wouldn't want to disclose in any plain-text logs, you should consider protecting them.

With KQL, you can easily construct your queries to protect sensitive strings; this way, the audit logs will redact that portion of your protected string but still be a valid audit trail that can serve the use cases we talked about previously.

Protected strings in queries would instead show you this result in the query log:

Azure Data Explorer is showing query logs with obfuscated strings.

Let's set the scene. Here are two elementary examples. The first one is querying based on regular unobfuscated strings, and the second example shows how to ensure you protect the input easily.

Without obfuscation:

securityAudits
| where Status  != "Succeeded" 
    and PersonalIdentifier == "no-thanks@zimmergren.net"

With obfuscation:

securityAudits
| where Status  != "Succeeded" 
    and PersonalIdentifier == h"no-thanks@zimmergren.net"

Notably, the only difference is that you append h or H to your string literals to protect them. It's easy as 1-2-3 but can be a game-changer for your security and compliance journey.

Read more:

ComplianceLog Analytics

Tobias Zimmergren Twitter

Hi, I'm Tobias! 👋 I write about Microsoft Azure, security, cybersecurity, compliance, cloud architecture, Microsoft 365, and general tech!

Reactions and mentions


Hi, I'm Tobias 👋

Tobias Zimmergren profile picture

Find out more about me.

Recent comments

Mastodon