CloudKeyVaultEvents: Azure Key Vault Logs, Schema and KQL Hunting
CloudKeyVaultEvents is a table I recently discovered in Microsoft Defender Advanced Hunting. Despite being available in multiple tenants, I could find very little public documentation describing the table, its schema, or how the events are populated. While trying to find more information on Google no results were found. The AI function of Google Search even suggested that CloudKeyVaultEvents is likely a typo :). With no further information available it made an interesting candidate for some hands on research. I tested the table across multiple tenants, generated Key Vault activity, compared the resulting events, and investigated which Azure Key Vault operations were exposed.
This post documents the results, including the observed schema, ingestion requirements, available Key Vault operations, and several KQL hunting approaches.

How are CloudKeyVaultEvents ingested?
Since there is no official documentation available for the CloudKeyVaultEvents table at the time this blog was drafted I had one hypothesis how these logs would be ingested into the table. The assumption was that the logs are part of the Microsoft Defender for Key Vault plan.
The performed simulation (see section Generating KeyVault Activities) with both Microsoft Defender for Key Vault enabled and disabled. Once the plan was disabled no logs would be ingested into the CloudKeyVaultEvents table. The cost $0.25/Vault/Month for 30 days of logs is good value for the money. Once the Microsoft Defender for Key Vault plan is enabled the logs automatically flow towards the CloudKeyVaultEvents table. In the performed experiments there was no need to set dedicated Azure Monitor policies to recieve the data.
The information in Defender For Cloud is listed in the portal:
Pricing: $0.25/Vault/Month
- Identifies illegitimate attempts to access or exploit Azure Key Vault accounts
- Generates detailed, context-based, security alerts easily integrated with any SIEM
- Alerts include guidelines to help investigate and mitigate identified threats
- Regulatory compliance and industry best practices
The
CloudKeyVaultEventsis not the only table in the Cloud Infrastructure logs. You can also exploreCloudAuditEvents,CloudDnsEvents,CloudPolicyEnforcementEvents,CloudProcessEventsandCloudStorageAggregatedEvents
CloudKeyVaultEvents Advanced Hunting Schema
On the Microsoft Learn pages no reference to the CloudKeyVaultEvents table is found, in Advanced Hunting a schema reference can be retrieved as shown in the table below.
| ColumnName | Type | Description |
|---|---|---|
| AccountApplicationId | String | The application ID associated with the Key Vault access |
| AccountObjectId | String | The unique identifier of the object making the Key Vault access |
| AccountTenantId | String | The unique identifier of the Azure tenant |
| AccountType | String | The account type used (e.g., app, user) |
| AccountUpn | String | The user principal name of the accessing user |
| ActivityName | String | The name of the Key Vault activity performed |
| AdditionalFields | Object | Additional information about the entity or event |
| AzureResourceId | String | The Azure Resource ID of the Key Vault |
| DataSource | String | The source of the key vault logs |
| HttpStatusCode | Int32 | HTTP status code returned by the Key Vault operation |
| IPAddress | String | The IP address from which the Key Vault was accessed |
| Location | String | The location of the Key Vault (region) |
| ReportId | String | Guid to identify the record in the specific table |
| RequestUri | String | The URI of the Key Vault request |
| ResultSignature | String | The result signature of the Key Vault operation |
| SourceSystem | String | - |
| SubscriptionId | String | Unique identifier assigned to the Azure subscription |
| TenantId | String | - |
| TimeGenerated | DateTime | - |
| Timestamp | DateTime | Date and time when the record was generated |
| Type | String | - |
| UserAgentHeader | String | The user agent string from the HTTP request |
| VaultName | String | Name of the Key Vault |
Schema obtained from: XDRInternals.
Alternative approach:
CloudKeyVaultEvents
| getschema Generating Azure Key Vault Activity for Testing
In my test environment some logs flowed to this table, but these were not sufficient to draw conlusions. To generate a representative set of Key Vault events, I created a test environment and used three scripts to deploy the required resources, simulate Key Vault operations, and clean up the environment afterward.
- Deploy KeyVaults
- Simulate KeyVault Operations
- Clean-up deployed resources
The goal of the simulation was not to reproduce malicious activity, but to generate a broad set of legitimate Key Vault operations so that the resulting CloudKeyVaultEvents records could be compared and classified.
The full script to generate the logs is available on GitHub: Key Vault activity simulation scripts.
PS C:\KeyVault> Start-AzAutomationRunbook -ResourceGroupName KeyVaults -AutomationAccountName kvaudit-kvlab-aa -Name Invoke-KeyVaultActivitySimulation -Parameters @{ DurationMinutes = 60 }
ResourceGroupName : KeyVaults
AutomationAccountName : kvaudit-kvlab-aa
JobId : 6f341806-69a9-410e-bebd-c2969511afff
CreationTime : 28/09/2026 21:48:32 +02:00
Status : New
StatusDetails : None
StartTime :
EndTime :
Exception :
LastModifiedTime : 28/09/2026 21:48:32 +02:00
LastStatusModifiedTime : 28/09/2026 21:48:32 +02:00
JobParameters : {[DurationMinutes, 60]}
RunbookName : Invoke-KeyVaultActivitySimulation
HybridWorker :
StartedBy :Investigating the logs
The simulation generated several hundred events across the five test vaults. More importantly, the activity represented a broad range of Key Vault operations across vaults, keys, secrets, and certificates as listed below.
["KeyUnwrap","SecretGet","KeyGet","KeyImport","CertificateGet","CertificateListVersions","KeyList","CertificateIssuerSet",
"CertificateGetDeleted","CertificateList","CertificateContactsGet","VaultGet","SecretList","KeyWrap","CertificateIssuerGet","SecretGetDeleted",
"SecretDelete","SecretSet","CertificateIssuersList","KeyVerify","KeyRecover","CertificatePolicyUpdate","KeyListDeleted","CertificatePolicyGet",
"CertificateImport","KeyCreate","KeyRotationPolicySet","KeyRotate","KeyGetDeleted","KeyDecrypt","KeySign","KeyUpdate","CertificateCreate",
"CertificateContactsSet","KeyDelete","SecretListDeleted","KeyRestore","KeyBackup","SecretUpdate","KeyEncrypt","KeyListVersions",
"CertificateListDeleted","SecretListVersions","CertificatePendingGet","CertificateRecover","SecretRecover","CertificatePendingMerge",
"CertificateEnroll","VaultPut","SecretPurge","Authentication","VaultPatch","CertificateDelete","KeyPurge","SecretRestore","CertificateContactsDelete",
"CertificateUpdate","KeyNearExpiryEventGridNotification","CertificateNearExpiryEventGridNotification","SecretNearExpiryEventGridNotification",
"CertificateExpiredEventGridNotification","KeyExpiredEventGridNotification","SecretBackup","CertificateRestore","CertificatePendingDelete",
"AccessPolicyMerge","CertificatePendingUpdate","KeyRotationPolicyGet","AccessPolicyRemove","CertificateBackup","SecretExpiredEventGridNotification",
"CertificatePurge"]
The first useful step is to establish which Key Vaults are generating events and how much activity each vault produces. The following query summarizes event volume and the distinct operations observed per vault:
CloudKeyVaultEvents
| where TimeGenerated > ago(30d)
| summarize TotalLogs = count(), UniqueActions = dcount(ActivityName), ActivitySet = make_set(ActivityName) by AzureResourceIdTo validate if all your KeyVaults are in scope of the CloudKeyVaultEvents logs you can run two queries in Advanced Hunting.
- List the unnique count of KeyVaults sending data to the
CloudKeyVaultEventstable:CloudKeyVaultEvents | distinct AzureResourceId | count - Run an Azure Resource Graph query to identify the total number of KeyVaults in your Azure environment:
arg("").Resources | where type == "microsoft.keyvault/vaults" | count
Azure Resource Graph queries can directly be executed into Advanced Hunting. Examples can be found on GitHub.
CloudKeyVaultEvents Operations
Azure Key Vault logging and its activities is documented on the Microsoft Learn pages and shown in the tables below.
Vault
| operationName | REST API command |
|---|---|
| Authentication | Authenticate via Microsoft Entra endpoint |
| VaultGet | Get information about a key vault |
| VaultPut | Create or update a key vault |
| VaultDelete | Delete a key vault |
| VaultPatch | Update a key vault |
| VaultRecover | Recover deleted vault |
| VaultAccessPolicyChangedEventGridNotification | Vault access policy changed event published. It is logged regardless if an Event Grid subscription exists. |
Keys
| operationName | REST API command |
|---|---|
| KeyCreate | Create a key |
| KeyGet | Get information about a key |
| KeyImport | Import a key into a vault |
| KeyDelete | Delete a key |
| KeySign | Sign with a key |
| KeyVerify | Verify with a key |
| KeyWrap | Wrap a key |
| KeyUnwrap | Unwrap a key |
| KeyEncrypt | Encrypt with a key |
| KeyDecrypt | Decrypt with a key |
| KeyUpdate | Update a key |
| KeyList | List the keys in a vault |
| KeyListVersions | List the versions of a key |
| KeyPurge | Purge a key |
| KeyBackup | Backup a key |
| KeyRestore | Restore a key |
| KeyRecover | Recover a key |
| KeyGetDeleted | Get deleted key |
| KeyListDeleted | List the deleted keys in a vault |
| KeyNearExpiryEventGridNotification | Key near expiry event published. It is logged regardless if an Event Grid subscription exists. |
| KeyExpiredEventGridNotification | Key expired event published. It is logged regardless if an Event Grid subscription exists. |
| KeyRotate | Rotate key |
| KeyRotateIfDue | Scheduled automated key rotation operation based on defined rotation policy |
| KeyRotationPolicyGet | Get Key Rotation Policy |
| KeyRotationPolicySet | Update Key Rotation Policy |
Secrets
| operationName | REST API command |
|---|---|
| SecretSet | Create a secret |
| SecretGet | Get a secret |
| SecretUpdate | Update a secret |
| SecretDelete | Delete a secret |
| SecretList | List secrets in a vault |
| SecretListVersions | List versions of a secret |
| SecretPurge | Purge a secret |
| SecretBackup | Backup a secret |
| SecretRestore | Restore a secret |
| SecretRecover | Recover a secret |
| SecretGetDeleted | Get deleted secret |
| SecretListDeleted | List the deleted secrets in a vault |
| SecretNearExpiryEventGridNotification | Secret near expiry event published. It is logged regardless if an Event Grid subscription exists. |
| SecretExpiredEventGridNotification | Secret expired event published. It is logged regardless if an Event Grid subscription exists. |
Certificates
| operationName | REST API command |
|---|---|
| CertificateGet | Get information about a certificate |
| CertificateCreate | Create a certificate |
| CertificateImport | Import a certificate into a vault |
| CertificateUpdate | Update a certificate |
| CertificateList | List the certificates in a vault |
| CertificateListVersions | List the versions of a certificate |
| CertificateDelete | Delete a certificate |
| CertificatePurge | Purge a certificate |
| CertificateBackup | Backup a certificate |
| CertificateRestore | Restore a certificate |
| CertificateRecover | Recover a certificate |
| CertificateGetDeleted | Get deleted certificate |
| CertificateListDeleted | List the deleted certificates in a vault |
| CertificatePolicyGet | Get certificate policy |
| CertificatePolicyUpdate | Update certificate policy |
| CertificatePolicySet | Create certificate policy |
| CertificateContactsGet | Get certificate contacts |
| CertificateContactsSet | Set certificate contacts |
| CertificateContactsDelete | Delete certificate contacts |
| CertificateIssuerGet | Get certificate issuer |
| CertificateIssuerSet | Set certificate issuer |
| CertificateIssuerUpdate | Update certificate issuer |
| CertificateIssuerDelete | Delete certificate issuer |
| CertificateIssuersList | List the certificate issuers |
| CertificateEnroll | Enroll a certificate |
| CertificateRenew | Renew a certificate |
| CertificatePendingGet | Retrieve pending certificate |
| CertificatePendingMerge | The merger of the certificate is pending |
| CertificatePendingUpdate | The update of the certificate is pending |
| CertificatePendingDelete | Delete pending certificate |
| CertificateNearExpiryEventGridNotification | Certificate near expiry event published. It is logged regardless if an Event Grid subscription exists. |
| CertificateExpiredEventGridNotification | Certificate expired event published. It is logged regardless if an Event Grid subscription exists. |
Security Value
Azure Key Vault is a target because it can contain secrets, cryptographic keys, certificates, and other material used to authenticate to applications and infrastructure. An attacker who compromises an identity with Key Vault permissions may therefore use Key Vault activity as a stepping stone to application takeover, privilege escalation, or lateral movement. Key Vaults audit events provide useful evidence for both detection and incident response: they show which identity accessed a vault, what operation it performed, when it happened, and the client context associated with the request.
Some useful investigation scenarios include:
- Unexpected secret or key access. Review
SecretGet,KeyGet,KeyDecrypt,KeyUnwrap, and similar data-plane operations, especially when the identity, source IP, user agent, or time is unusual for that vault. - Suspicious enumeration. A burst of list operations such as
SecretList,KeyList, orCertificateListcan be worth investigating when it is followed by reads or comes from an unfamiliar identity or location. - Destructive or persistence-related changes. Investigate deletes, purges, restores, access-policy changes, and changes to keys, secrets, or certificate policies. These may indicate cleanup, tampering, or an attempt to maintain or regain access.
- Failed or anomalous requests. Use the HTTP status code alongside the operation and identity to distinguish successful access from denied or unsuccessful attempts. A sequence of failures followed by a success can provide useful investigative context.
- Risky identity activity. Correlate a vault event with the corresponding user or service-principal sign-in to see whether the authentication was risky, originated from an unusual location, or otherwise stands out from that identity’s normal activity.
The CloudKeyVaultEvents table contains several fields that support these investigations:
ActivityNameidentifies the operation (the available column name can depend on the schema exposed in your environment).IPAddress,CountryCode,City,ISP,IsAnonymousProxy, andUserAgentdescribe the request’s network and client context.AzureResourceIdidentifies the affected vault, whileAccountType,AccountId, andAccountObjectIdhelp identify the actor.HttpStatusCodeindicates the request outcome.UniqueTokenIdentifier, when present inAdditionalFields, can be used to correlate the event with a user or service-principal sign-in.
Detection and Hunting with CloudKeyVaultEvents
CloudKeyVaultEvents can also be used to detect suspicious activities in your Azure environment.
Query 1: Risky sign-in followed by Key Vault activity
let SearchPeriod = 7d;
EntraIdSignInEvents
| where TimeGenerated > ago(SearchPeriod)
| where RiskLevelDuringSignIn in (10, 50, 100)
| project SignInTime = TimeGenerated, IPAddress, UserAgent, AccountUpn, UniqueTokenId, ErrorCode
| join kind=inner (CloudKeyVaultEvents
| where AccountType == "user"
| extend UniqueTokenIdentifier = tostring(AdditionalFields.UniqueTokenIdentifier)
| project TimeGenerated, UniqueTokenIdentifier, AzureResourceId, ActivityName)
on $left.UniqueTokenId == $right.UniqueTokenIdentifierQuery 2: Suspicious Key Vault Enumuration or Reads
This query provides the basis for detecting enumuration or credential access of Key Vaults. Depending on the activities in your tenant a filter is required based on the TotalEnumerationActivities and TotalReadActivities executed by the User/Application.
A more detailed query is available on GitHub: Suspicious Key Vault Enumeration or Reads
let EnumerationActivities = dynamic([
"SecretList",
"SecretListVersions",
"SecretListDeleted",
"KeyList",
"KeyListVersions",
"KeyListDeleted",
"CertificateList",
"CertificateListVersions",
"CertificateListDeleted"
]);
let ReadActivities = dynamic([
"SecretGet",
"KeyGet",
"CertificateGet"
]);
CloudKeyVaultEvents
| where ActivityName in~ (EnumerationActivities) or ActivityName in~ (ReadActivities)
| summarize Total = count(), UniqueKeyVaults = dcount(AzureResourceId), TotalEnumerationActivities = countif(ActivityName in~ (EnumerationActivities)), TotalReadActivities = countif(ActivityName in~ (ReadActivities)) by AccountObjectId, AccountType Incident Response and Forensic Enrichment
During an investigation, the Key Vault event is can be tied back to the authentication event that produced it. The token identifier provides a useful point for connecting user and service-principal sign-ins with subsequent Key Vault activity.
Enriching Service Principal Activity
CloudKeyVaultEvents
| where AccountType == "app"
| extend UniqueTokenIdentifier = tostring(AdditionalFields.UniqueTokenIdentifier)
| join kind=leftouter EntraIdSpnSignInEvents on $left.UniqueTokenIdentifier == $right.UniqueTokenIdEnriching User Activity
CloudKeyVaultEvents
| where AccountType == "user"
| extend UniqueTokenIdentifier = tostring(AdditionalFields.UniqueTokenIdentifier)
| join kind=leftouter EntraIdSignInEvents on $left.UniqueTokenIdentifier == $right.UniqueTokenIdConclusion
CloudKeyVaultEvents provides useful visibility into Azure Key Vault activity from Microsoft Defender Advanced Hunting. The table exposes operations across vaults, keys, secrets, and certificates, together with identity and network context that can be useful for detection engineering, threat hunting and incident response.
Because the table is not currently documented in the same way as many established Advanced Hunting tables, validate the schema and ingestion behavior in your own environment before deploying detections based on these examples.
Questions? Feel free to reach out to me on any of my socials.