Abnormal Security: expand CCF Threat Log & Audit Log schemas for MLA parity (v3.2.0)#14712
Open
anoopabsec wants to merge 1 commit into
Open
Abnormal Security: expand CCF Threat Log & Audit Log schemas for MLA parity (v3.2.0)#14712anoopabsec wants to merge 1 commit into
anoopabsec wants to merge 1 commit into
Conversation
…as for MLA parity (v3.2.0) Adds the columns the legacy (Azure Functions/MLA) connector produces that the CCF Push connector's table schemas were missing, so a workspace migrating from MLA to CCF has full field coverage. - ThreatLog: +4 columns (message-engagement forwarded/replied counts, abx_body metadata + abx_metadata datetime timestamps), populated via DCR transforms. - AuditLog: +112 columns (per-field audit details_* + metadata timestamps); the audit timestamps are populated via transforms, the details_* fields are declared for schema parity and remain available in abx_body_abx_body_details_s. - DCR transforms updated for the populatable columns; input stream names unchanged. Additive, non-breaking. - Version 3.1.0 -> 3.2.0; package regenerated with createSolutionV4. Validated: az deployment group validate Succeeded. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Expands Abnormal Security’s CCF Push connector table schemas (Threat Log and Audit Log) and updates DCR transforms/versioning to improve field parity with the legacy (MLA) connector while keeping changes additive.
Changes:
- Bumped solution/package versions to 3.2.0 and updated Release Notes.
- Added 4 new Threat Log columns (message engagement counts + metadata timestamps) and populated them via DCR transforms.
- Added ~112 new Audit Log “details_*” parity columns plus metadata timestamps, and populated the audit timestamps via DCR transforms.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| Solutions/AbnormalSecurity/ReleaseNotes.md | Added 3.2.0 release entry describing schema expansion and transform behavior. |
| Solutions/AbnormalSecurity/Package/mainTemplate.json | Bumped versions, expanded table schemas, and updated DCR transforms for new timestamp/count fields. |
| Solutions/AbnormalSecurity/Data/Solution_AbnormalSecurity.json | Bumped solution version to 3.2.0 for packaging metadata. |
| Solutions/AbnormalSecurity/Data Connectors/AbnormalSecurity_CCF/AbnormalSecurity_table_ThreatLog.json | Added 4 Threat Log columns for parity. |
| Solutions/AbnormalSecurity/Data Connectors/AbnormalSecurity_CCF/AbnormalSecurity_table_AuditLog.json | Added many Audit Log parity columns (details_* + timestamps). |
| Solutions/AbnormalSecurity/Data Connectors/AbnormalSecurity_CCF/AbnormalSecurity_DCR.json | Added transforms to populate new Threat Log fields and Audit/Threat metadata timestamps. |
Comment on lines
+279
to
+287
| }, | ||
| { | ||
| "name": "abx_body_abx_body_message_engagement_forwarded_count_d", | ||
| "type": "real" | ||
| }, | ||
| { | ||
| "name": "abx_body_abx_body_message_engagement_replied_count_d", | ||
| "type": "real" | ||
| }, |
| "clv2ws1" | ||
| ], | ||
| "transformKql": "source | extend TimeGenerated = todatetime(Time)\n| extend abx_metadata_event_type_s = tostring(abx_metadata.event_type)\n| extend abx_metadata_timestamp_s = tostring(abx_metadata.timestamp)\n| extend abx_metadata_trace_id_g = tostring(abx_metadata.trace_id)\n| extend abx_body_abx_body_abx_message_id_d = toreal(abx_body.abx_body.abx_message_id)\n| extend abx_body_abx_body_abx_message_id_str_s = tostring(abx_body.abx_body.abx_message_id_str)\n| extend abx_body_abx_body_abx_portal_url_s = tostring(abx_body.abx_body.abx_portal_url)\n| extend abx_body_abx_body_threat_id_g = tostring(abx_body.abx_body.threat_id)\n| extend abx_body_abx_body_subject_s = tostring(abx_body.abx_body.subject)\n| extend abx_body_abx_body_from_name_s = tostring(abx_body.abx_body.from_name)\n| extend abx_body_abx_body_from_address_s = tostring(abx_body.abx_body.from_address)\n| extend abx_body_abx_body_to_addresses_s = tostring(abx_body.abx_body.to_addresses)\n| extend abx_body_abx_body_recipient_address_s = tostring(abx_body.abx_body.recipient_address)\n| extend abx_body_abx_body_received_time_t = todatetime(abx_body.abx_body.received_time)\n| extend abx_body_abx_body_sent_time_t = todatetime(abx_body.abx_body.sent_time)\n| extend abx_body_abx_body_internet_message_id_s = tostring(abx_body.abx_body.internet_message_id)\n| extend abx_body_abx_body_auto_remediated_b = tobool(abx_body.abx_body.auto_remediated)\n| extend abx_body_abx_body_post_remediated_b = tobool(abx_body.abx_body.post_remediated)\n| extend abx_body_abx_body_remediation_status_s = tostring(abx_body.abx_body.remediation_status)\n| extend abx_body_abx_body_remediation_timestamp_t = todatetime(abx_body.abx_body.remediation_timestamp)\n| extend abx_body_abx_body_attack_type_s = tostring(abx_body.abx_body.attack_type)\n| extend abx_body_abx_body_attack_strategy_s = tostring(abx_body.abx_body.attack_strategy)\n| extend abx_body_abx_body_attack_vector_s = tostring(abx_body.abx_body.attack_vector)\n| extend abx_body_abx_body_attack_score_d = toreal(abx_body.abx_body.attack_score)\n| extend abx_body_abx_body_attacked_party_s = tostring(abx_body.abx_body.attacked_party)\n| extend abx_body_abx_body_return_path_s = tostring(abx_body.abx_body.return_path)\n| extend abx_body_abx_body_reply_to_emails_s = tostring(abx_body.abx_body.reply_to_emails)\n| extend abx_body_abx_body_cc_emails_s = tostring(abx_body.abx_body.cc_emails)\n| extend abx_body_abx_body_bcc_emails_s = tostring(abx_body.abx_body.bcc_emails)\n| extend abx_body_abx_body_sender_ip_address_s = tostring(abx_body.abx_body.sender_ip_address)\n| extend abx_body_abx_body_sender_domain_s = tostring(abx_body.abx_body.sender_domain)\n| extend abx_body_abx_body_sender_auth_results_spf_s = tostring(abx_body.abx_body.sender_auth_results.spf)\n| extend abx_body_abx_body_sender_auth_results_dkim_s = tostring(abx_body.abx_body.sender_auth_results.dkim)\n| extend abx_body_abx_body_sender_auth_results_dmarc_s = tostring(abx_body.abx_body.sender_auth_results.dmarc)\n| extend abx_body_abx_body_impersonated_party_s = tostring(abx_body.abx_body.impersonated_party)\n| extend abx_body_abx_body_attachment_names_s = tostring(abx_body.abx_body.attachment_names)\n| extend abx_body_abx_body_attachment_count_d = toreal(abx_body.abx_body.attachment_count)\n| extend abx_body_abx_body_attachment_analysis_s = tostring(abx_body.abx_body.attachment_analysis)\n| extend abx_body_abx_body_urls_s = tostring(abx_body.abx_body.urls)\n| extend abx_body_abx_body_url_count_d = toreal(abx_body.abx_body.url_count)\n| extend abx_body_abx_body_summary_insights_s = tostring(abx_body.abx_body.summary_insights)\n| extend abx_body_abx_body_is_read_b = tobool(abx_body.abx_body.is_read)\n| extend abx_body_abx_body_folder_locations_s = tostring(abx_body.abx_body.folder_locations)\n| extend abx_body_abx_body_message_sources_s = tostring(abx_body.abx_body.message_sources)\n| extend abx_body_abx_body_message_engagement_s = tostring(abx_body.abx_body.message_engagement)\n| extend abx_body_abx_body_source_s = tostring(abx_body.abx_body.source)\n| extend abx_body_abx_body_tenant_s = tostring(abx_body.abx_body.tenant)\n| extend abx_body_abx_metadata_event_type_s = tostring(abx_body.abx_metadata.event_type)\n| extend abx_body_abx_metadata_timestamp_s = tostring(abx_body.abx_metadata.timestamp)\n| extend abx_body_abx_metadata_trace_id_g = tostring(abx_body.abx_metadata.trace_id)\n| extend abx_body = tostring(abx_body)\n| extend abx_metadata = tostring(abx_metadata)", | ||
| "transformKql": "source | extend TimeGenerated = todatetime(Time)\n| extend abx_body_abx_body_message_engagement_forwarded_count_d = toreal(abx_body.abx_body.message_engagement.forwarded_count)\n| extend abx_body_abx_body_message_engagement_replied_count_d = toreal(abx_body.abx_body.message_engagement.replied_count)\n| extend abx_body_abx_metadata_timestamp_t = todatetime(abx_body.abx_metadata.timestamp)\n| extend abx_metadata_timestamp_t = todatetime(abx_metadata.timestamp)\n| extend abx_metadata_event_type_s = tostring(abx_metadata.event_type)\n| extend abx_metadata_timestamp_s = tostring(abx_metadata.timestamp)\n| extend abx_metadata_trace_id_g = tostring(abx_metadata.trace_id)\n| extend abx_body_abx_body_abx_message_id_d = toreal(abx_body.abx_body.abx_message_id)\n| extend abx_body_abx_body_abx_message_id_str_s = tostring(abx_body.abx_body.abx_message_id_str)\n| extend abx_body_abx_body_abx_portal_url_s = tostring(abx_body.abx_body.abx_portal_url)\n| extend abx_body_abx_body_threat_id_g = tostring(abx_body.abx_body.threat_id)\n| extend abx_body_abx_body_subject_s = tostring(abx_body.abx_body.subject)\n| extend abx_body_abx_body_from_name_s = tostring(abx_body.abx_body.from_name)\n| extend abx_body_abx_body_from_address_s = tostring(abx_body.abx_body.from_address)\n| extend abx_body_abx_body_to_addresses_s = tostring(abx_body.abx_body.to_addresses)\n| extend abx_body_abx_body_recipient_address_s = tostring(abx_body.abx_body.recipient_address)\n| extend abx_body_abx_body_received_time_t = todatetime(abx_body.abx_body.received_time)\n| extend abx_body_abx_body_sent_time_t = todatetime(abx_body.abx_body.sent_time)\n| extend abx_body_abx_body_internet_message_id_s = tostring(abx_body.abx_body.internet_message_id)\n| extend abx_body_abx_body_auto_remediated_b = tobool(abx_body.abx_body.auto_remediated)\n| extend abx_body_abx_body_post_remediated_b = tobool(abx_body.abx_body.post_remediated)\n| extend abx_body_abx_body_remediation_status_s = tostring(abx_body.abx_body.remediation_status)\n| extend abx_body_abx_body_remediation_timestamp_t = todatetime(abx_body.abx_body.remediation_timestamp)\n| extend abx_body_abx_body_attack_type_s = tostring(abx_body.abx_body.attack_type)\n| extend abx_body_abx_body_attack_strategy_s = tostring(abx_body.abx_body.attack_strategy)\n| extend abx_body_abx_body_attack_vector_s = tostring(abx_body.abx_body.attack_vector)\n| extend abx_body_abx_body_attack_score_d = toreal(abx_body.abx_body.attack_score)\n| extend abx_body_abx_body_attacked_party_s = tostring(abx_body.abx_body.attacked_party)\n| extend abx_body_abx_body_return_path_s = tostring(abx_body.abx_body.return_path)\n| extend abx_body_abx_body_reply_to_emails_s = tostring(abx_body.abx_body.reply_to_emails)\n| extend abx_body_abx_body_cc_emails_s = tostring(abx_body.abx_body.cc_emails)\n| extend abx_body_abx_body_bcc_emails_s = tostring(abx_body.abx_body.bcc_emails)\n| extend abx_body_abx_body_sender_ip_address_s = tostring(abx_body.abx_body.sender_ip_address)\n| extend abx_body_abx_body_sender_domain_s = tostring(abx_body.abx_body.sender_domain)\n| extend abx_body_abx_body_sender_auth_results_spf_s = tostring(abx_body.abx_body.sender_auth_results.spf)\n| extend abx_body_abx_body_sender_auth_results_dkim_s = tostring(abx_body.abx_body.sender_auth_results.dkim)\n| extend abx_body_abx_body_sender_auth_results_dmarc_s = tostring(abx_body.abx_body.sender_auth_results.dmarc)\n| extend abx_body_abx_body_impersonated_party_s = tostring(abx_body.abx_body.impersonated_party)\n| extend abx_body_abx_body_attachment_names_s = tostring(abx_body.abx_body.attachment_names)\n| extend abx_body_abx_body_attachment_count_d = toreal(abx_body.abx_body.attachment_count)\n| extend abx_body_abx_body_attachment_analysis_s = tostring(abx_body.abx_body.attachment_analysis)\n| extend abx_body_abx_body_urls_s = tostring(abx_body.abx_body.urls)\n| extend abx_body_abx_body_url_count_d = toreal(abx_body.abx_body.url_count)\n| extend abx_body_abx_body_summary_insights_s = tostring(abx_body.abx_body.summary_insights)\n| extend abx_body_abx_body_is_read_b = tobool(abx_body.abx_body.is_read)\n| extend abx_body_abx_body_folder_locations_s = tostring(abx_body.abx_body.folder_locations)\n| extend abx_body_abx_body_message_sources_s = tostring(abx_body.abx_body.message_sources)\n| extend abx_body_abx_body_message_engagement_s = tostring(abx_body.abx_body.message_engagement)\n| extend abx_body_abx_body_source_s = tostring(abx_body.abx_body.source)\n| extend abx_body_abx_body_tenant_s = tostring(abx_body.abx_body.tenant)\n| extend abx_body_abx_metadata_event_type_s = tostring(abx_body.abx_metadata.event_type)\n| extend abx_body_abx_metadata_timestamp_s = tostring(abx_body.abx_metadata.timestamp)\n| extend abx_body_abx_metadata_trace_id_g = tostring(abx_body.abx_metadata.trace_id)\n| extend abx_body = tostring(abx_body)\n| extend abx_metadata = tostring(abx_metadata)", |
Comment on lines
+199
to
+202
| { | ||
| "name": "abx_body_abx_body_details_entity_id_g", | ||
| "type": "guid" | ||
| }, |
Comment on lines
+227
to
+230
| { | ||
| "name": "abx_body_abx_body_details_instanceId_g", | ||
| "type": "guid" | ||
| }, |
Comment on lines
+239
to
+242
| { | ||
| "name": "abx_body_abx_body_details_levelId_g", | ||
| "type": "guid" | ||
| }, |
Comment on lines
+399
to
+402
| { | ||
| "name": "abx_body_abx_body_details_rule_uuid_g", | ||
| "type": "guid" | ||
| }, |
Contributor
|
Hi @anoopabsec Kindly review the Copilot comments above and mark them as resolved if they have been addressed. and attach a screenshot of the CCF Connector in a connected state for reference. Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Expands the CCF Push connector's Threat Log and Audit Log custom-table schemas to cover the fields the legacy (Azure Functions / MLA) connector produces, so a customer migrating from MLA to CCF has full field parity. Additive and non-breaking.
Changes (v3.1.0 → v3.2.0)
AbnormalSecurity_table_ThreatLog.json: +4 columns —message_engagementforwarded/replied counts andabx_body_abx_metadata/abx_metadatadatetime timestamps.AbnormalSecurity_table_AuditLog.json: +112 columns — per-field auditdetails_*and metadata timestamps.AbnormalSecurity_DCR.json: transform lines added to populate the columns with unambiguous source paths (Threat Log's 4 + the audit timestamps). The auditdetails_*fields are declared for schema parity and remain fully available inabx_body_abx_body_details_s(JSON).createSolutionV4.Test Plan
az deployment group validateSucceeded on the regeneratedmainTemplate.json.guid→string) with no data loss.Deploy Plan
Content Hub update → re-deploy connector. Existing installations gain the new columns on update; no breaking change.
🤖 Generated with Claude Code