A web application for querying and viewing Azure Firewall logs from Log Analytics. Users sign in with their Entra ID accounts and see only the virtual networks and workspaces they have access to in Azure, enforced through RBAC and the On-Behalf-Of (OBO) authentication flow.
Navigate to your deployed app URL (e.g., https://fwlog-webapp.azurewebsites.net). You will be redirected to sign in with your Microsoft Entra ID account. After signing in, the app loads the virtual networks and Log Analytics workspaces you have access to based on your Azure RBAC roles.
- Select a Log Analytics workspace from the dropdown — only workspaces you have Reader access to will appear.
- Select virtual networks to filter by — click the VNet chips to toggle them on. When selected, only logs with source or destination IPs in those VNet address ranges are returned.
- Optionally filter by source IP, destination IP, or time range.
- Click Query Logs.
- Filter results using the Action, Log Type, Protocol, Port, and IP search controls that appear above the results table.
- Switch to Summary view to see results grouped by a field (Action, Source IP, Destination, Port, Protocol, or Log Type) with Allow/Deny counts.
- Export to CSV using the export button.
- View the KQL query by expanding "Show KQL Query" below the results.
Click Sign out in the top-right corner of the header.
There are two deployment scenarios:
- I already have an Azure Firewall and Log Analytics workspace — follow Web App Deployment only.
- I want a complete POC environment — follow POC Infrastructure first, then Web App Deployment.
- Azure CLI installed and signed in (
az login) - An Azure subscription with permissions to create resources
- Permissions to create Entra ID app registrations (or have an admin do it)
This must be done before deploying the web app.
- Go to Microsoft Entra ID → App registrations → New registration.
- Name:
Firewall Log Reader(or your preferred name). - Supported account types: Accounts in this organizational directory only.
- Redirect URI: Web —
https://<your-app-name>.azurewebsites.net/.auth/login/aad/callback(update after deployment if you don't know the URL yet). - Click Register.
- Note the Application (client) ID and Directory (tenant) ID.
- Go to Certificates & secrets → New client secret.
- Add a description and choose an expiry.
- Click Add and copy the secret value immediately (it won't be shown again).
- Go to Expose an API.
- Click Set next to Application ID URI — accept the default (
api://<client-id>). - Click Add a scope:
- Scope name:
user_impersonation - Who can consent: Admins and users
- Admin consent display name:
Access Azure resources on behalf of user - Admin consent description:
Allows the app to access Azure resources on behalf of the signed-in user - State: Enabled
- Scope name:
- Go to API permissions → Add a permission.
- Select APIs my organization uses → search for Azure Service Management.
- Select Delegated permissions → check user_impersonation.
- Click Add permissions.
- Click Grant admin consent for <your tenant>.
- Go to Authentication.
- Under Implicit grant and hybrid flows, check both Access tokens and ID tokens.
- Click Save.
- A resource group in Azure (create one if needed:
az group create --name rg-firewall-log-reader --location australiaeast) - A Log Analytics workspace that receives Azure Firewall logs (
AZFWNetworkRuleandAZFWApplicationRuletables) - The Entra ID app registration from Step 1
.\infra\deploy-webapp.ps1 `
-ResourceGroupName "rg-firewall-log-reader" `
-EntraClientId "<your-client-id>" `
-EntraClientSecret (Read-Host -AsSecureString "Enter client secret") `
-LogAnalyticsWorkspaceName "<your-workspace-name>" `
-Prefix "fwlog"The script will:
- Look up the Log Analytics workspace details.
- Deploy the App Service (Linux, Python 3.11, B1 tier) with a system-assigned managed identity.
- Assign Log Analytics Reader to the managed identity on the workspace.
- Configure Easy Auth with your Entra ID app registration and OBO flow.
- Zip deploy the web application code.
- Update the Redirect URI in the Entra ID app registration if you didn't set it beforehand:
- Go to Authentication → Web → add
https://<prefix>-webapp.azurewebsites.net/.auth/login/aad/callback
- Go to Authentication → Web → add
- Browse to the app URL shown in the deployment output.
| Who | Role | Scope | Purpose |
|---|---|---|---|
| App managed identity | Log Analytics Reader | Log Analytics workspace | Query firewall logs |
| Each user | Reader | Subscriptions / resource groups containing VNets they should see | List VNets and their address spaces in the UI |
| Each user | Reader | Subscriptions / resource groups containing workspaces they should see | List Log Analytics workspaces in the UI |
Note: The managed identity role assignment on the workspace is handled automatically by the deployment script. User RBAC roles must be assigned separately by an Azure administrator.
If you don't have an existing Azure Firewall and want to set up a complete test environment:
# Deploy hub-spoke network with Azure Firewall Basic (~15-20 minutes)
.\infra\deploy.ps1 -AdminPassword (Read-Host -AsSecureString "Enter VM admin password")This creates:
- Hub VNet (10.0.0.0/16) with Azure Firewall Basic
- Spoke 1 VNet (10.1.0.0/16) with a test VM
- Spoke 2 VNet (10.2.0.0/16) with a test VM
- Log Analytics workspace with firewall diagnostic logs enabled
- Firewall policy with spoke-to-spoke and outbound web rules
After infrastructure deployment, generate firewall log entries by running the test script on the spoke VMs:
.\tests\run_tests.ps1 -ResourceGroupName "rg-firewall-log-reader"Logs appear in Log Analytics within 5–15 minutes.
cd webapp
pip install -r requirements.txt
python app.pyRequires Azure credentials via az login. The app runs on http://localhost:5000. In local mode:
- VNets and workspaces are loaded using your Azure CLI credentials (no OBO flow).
- Log Analytics queries use your Azure CLI credentials.
- Easy Auth headers are not present, so the "Signed in as" display and sign-out button are hidden.
┌─────────────────────────────────────────────────────────┐
│ Azure App Service │
│ ┌──────────────┐ ┌──────────┐ ┌───────────────────┐ │
│ │ Easy Auth │→ │ Flask │→ │ Log Analytics SDK │ │
│ │ (Entra ID) │ │ app.py │ │ (Managed Identity)│ │
│ └──────────────┘ └──────────┘ └───────────────────┘ │
│ │ │ │
│ │ │ OBO flow (MSAL) │
│ ▼ ▼ │
│ User ID token ARM API calls │
│ (user's permissions) │
└─────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
Entra ID Azure ARM API Log Analytics
(authentication) (list VNets & (query firewall
workspaces) logs)
Authentication flow:
- User signs in via Entra ID Easy Auth.
- Easy Auth provides an ID token in request headers.
- The app exchanges the ID token for an ARM access token via the OBO flow (MSAL).
- ARM API calls (listing VNets and workspaces) use the user's token — users only see resources they have RBAC access to.
- Log Analytics queries use the managed identity — the managed identity needs Log Analytics Reader on the workspace.
Key design decisions:
- User-scoped resource visibility: VNets and workspaces are listed using the user's own Azure permissions via OBO, so no static configuration file is needed.
- Managed identity for queries: Log Analytics queries use the App Service managed identity. This allows centralised query access while user RBAC controls which VNets/workspaces are visible in the UI.
- KQL filtering: When users select VNets, the app builds KQL queries using
ipv4_is_in_range()to filter firewall logs by the selected VNet address spaces.
Security controls:
- Input validation: All user-supplied parameters (IP addresses, CIDR ranges, workspace IDs, time ranges) are validated server-side before being used in KQL queries. This prevents KQL injection attacks.
- Workspace authorisation: Before querying Log Analytics, the server uses the user's OBO token to verify they have ARM read access to the requested workspace. This prevents users from querying workspaces they don't have access to, even though the managed identity has broader access.
- Health endpoint: A
/healthendpoint is exposed (excluded from authentication) for App Service health monitoring.
The app exposes a /health endpoint that returns {"status": "healthy"}. This endpoint is excluded from Entra ID authentication and is used by App Service for health monitoring. You can test it at https://<your-app-name>.azurewebsites.net/health.
The signed-in user needs Reader role on the subscriptions or resource groups containing the resources. Check Azure RBAC assignments for the user.
- Verify the Entra ID app registration has the Azure Service Management > user_impersonation delegated permission with admin consent granted.
- Verify the app registration has an exposed API scope (
user_impersonation) under Expose an API. - Verify ID tokens and Access tokens are enabled under Authentication > Implicit grant.
- Try signing out and back in to get a fresh token.
The server validates that you have ARM read access to the workspace before running the query. Ensure you have Reader (or higher) role on the resource group or subscription containing the Log Analytics workspace.
The App Service managed identity needs Log Analytics Reader on the target workspace. The deployment script assigns this automatically, but verify with:
az role assignment list --assignee <managed-identity-principal-id> --scope <workspace-resource-id> --output tableCheck the app logs:
az webapp log tail --resource-group <rg-name> --name <app-name>Common causes: missing Python dependencies, startup command errors, or the managed identity credential failing at import time (check AZURE_CLIENT_ID is set correctly).
