Log types
By default Cotool indexes denied flows, and flow begin and end tuples that involve a public IP address. Continuation tuples and allowed traffic between private addresses are kept in the raw archive only, so byte totals in
azure_flow_logs cover the indexed flows.
The Azure detections in the detection library read azure_flow_logs: internet access to management and database ports, scans followed by an allowed connection, internal and outbound denied bursts, traffic with threat-listed addresses, outbound connections to restricted countries, and DNS sent to unapproved resolvers. They are written to work with this default filter.
Authentication
Cotool signs in as a user-assigned managed identity in your tenant through a federated identity credential, so no client secret or storage key is created or stored. Cotool’s runtime identity presents a Google-signed token (issuerhttps://accounts.google.com) whose audience is unique to your Cotool organization; the federated credential accepts only Cotool’s subject and that audience, so no other Cotool customer can use your identity.
The identity holds two roles, each scoped as narrowly as Azure allows:
- Storage Queue Data Message Processor on the Cotool queue, to read and delete its messages.
- Storage Blob Data Reader on each log container, to read the flow log blobs.
Step 1: Create the queue, Event Grid subscription, and identity
On the integration page, select Add log source and enter the storage account and container that hold the flow logs. Network Watcher writes VNet flow logs to theinsights-logs-flowlogflowevent container and legacy NSG flow logs to insights-logs-networksecuritygroupflowevent. Add a prefix to limit Cotool to part of a container. VNet flow logs are stored under flowLogResourceID=/<SUBSCRIPTION-ID>_<NETWORK-WATCHER-RESOURCE-GROUP>/<NETWORK-WATCHER>_<FLOW-LOG-NAME>/, so flowLogResourceID=/<SUBSCRIPTION-ID>_ limits a source to one subscription. NSG flow logs are stored under resourceId=/SUBSCRIPTIONS/<SUBSCRIPTION-ID>/. Azure writes these folder names in upper case; copy the prefix from the container in the Azure portal.
The setup section fills the containers and Cotool’s Subject and your Audience into a Terraform configuration and an Azure CLI script. Each creates:
- a Storage queue dedicated to Cotool (
cotool-logs-<suffix>) in the first log storage account, - an Event Grid system topic for each log storage account, or reuses the one it already has (a storage account can have only one),
- an event subscription for each container and prefix that sends
Microsoft.Storage.BlobCreatedevents to the queue, with the queue’s 7-day maximum message lifetime, - a user-assigned managed identity (
cotool-logs-<suffix>) with a federated credential that trusts only Cotool’s subject and your audience, - the two role assignments above,
- Storage Queue Data Message Sender on the queue for each system topic’s system-assigned managed identity, which Event Grid delivers as, so delivery works from every log storage account and with shared-key access disabled.
<suffix> is a short random value generated for each setup, so several sources can live in the same subscription.
Deploy it signed in as someone who can create managed identities, role assignments, Storage queues, and Event Grid subscriptions in the subscription:
- Terraform
- Azure CLI
- Save the configuration in your infrastructure repository, and sign in with
az login. - Run
terraform init, reviewterraform plan, then runterraform apply. It asks for the subscription that holds the storage accounts and a resource group for the managed identity. If a storage account already has an Event Grid system topic, name it inexisting_system_topicsand enable its system-assigned managed identity. terraform outputprintsqueue_url,tenant_id, andclient_idfor the connection form.
The storage accounts must allow access from public networks. Cotool cannot
reach storage accounts that only accept private endpoints.
Step 2: Connect the source
- Connect: enter the storage accounts, containers, and prefixes. Deploy the setup, then paste the queue URL, tenant ID, and client ID.
- Test: Cotool signs in as the managed identity, checks that it can read the queue, and peeks at up to ten messages without removing them. It reads the start of the first blob they announce to check blob access. If the queue is empty, paste a sample flow log record.
- Format: name the source. Cotool previews the sampled flow tuples.
- Select Enable source, or Save paused to enable it later. Enabling needs a passing test.
Reliability
- Network Watcher appends a block to each hourly
PT1H.jsonblob about once a minute, and Event Grid announces every block. Cotool stores how far it has read each blob, so each run reads only the new bytes, and several announcements of the same blob in a run become one read. - Messages are deleted only after their bytes are archived and indexed. If Cotool restarts mid-run, or a run ends before reaching every message it received, the messages become visible again when the run’s time budget ends and are read again.
- Rereading a blob does not create duplicates: flow tuples are keyed by their blob and byte position.
- A blob that is deleted, or a message for a blob outside the allowed containers, is skipped and reported in the source’s recent errors.
- Permission errors leave the messages on the queue, so they are read once access is fixed, until the queue’s 7-day message lifetime expires.