Securing ILAP Analytics — reference example

Modified on Wed, 12 Aug at 1:17 PM

This page describes an example of how the Azure resources created by the ILAP Analytics installation can be protected — network isolation with private endpoints, an optional web application firewall, controlled egress, monitoring, and the Entra ID controls that limit who can sign in and from which devices. A matching, deployable Bicep template ships in the deployment package under Azure.IaC/Reference-Security/. It is written for the IT administrator hardening an ILAP Analytics environment. Because ILAP Analytics may hold sensitive scheduling information, protection matters — but the right design is specific to each organisation.

This is an example only. It is not a finished, production-ready configuration and not a security guarantee. Each company is responsible for how protection is done and will have its own requirements. Review, adapt, and test everything here, and add whatever additional controls your policies require. The Bicep is provided as a starting point, not a turnkey solution.

Follow the playbook, not this page

This page explains what the reference protects and why. The ordered procedure is Azure.IaC/Reference-Security/PLAYBOOK.md in the deployment package — steps 0 to 11, in an order that has been walked end to end on a clean installation. It ships with the templates rather than being published here, so the copy in your download always matches the templates you downloaded. Use it rather than working from prose, and use its Things that fail silently table when something looks configured but does not work; every row in it was observed on a live deployment.

To plan the work and line up the people before you open the archive, see Securing ILAP Analytics — playbook overview: what each step does, and what has to be in place first.

Install first, then secure

Deploy ILAP Analytics in its default (publicly reachable) configuration and verify it with the Checklist after deployment before applying any of the protection below. Locking down the network first makes failures much harder to diagnose; a verified baseline isolates installation problems from lock-down problems.

The App Services lock themselves down earlier than you expect. Creating a private endpoint for a web app sets its publicNetworkAccess to Disabled automatically — so the API, UI and Background Jobs apps become private-only, including their SCM/Kudu endpoints, the moment the network deployment completes. That is well before you run the hardening script. Any deployment method that uploads through Kudu — including az webapp deploy and most CI/CD pipelines — stops working from a public machine at that point, and the failure presents as a timeout that reads like a build problem. Install the applications first, or make sure you have a path into the VNet before you start.

Name the resources before you build them

Most Azure resource names cannot be changed after creation, and the reference security deployment has to be told the names of everything it protects. A consistent scheme is what stops that step becoming a transcription exercise. The package ships one in Azure.IaC/NAMING.md, enforced by Azure.IaC/Modules/naming.bicep, and the parameter files derive names from four tokens rather than asking you to type each one. See Configure bicep parameters.

What the reference protects, and how

Layer Control Why
Network Virtual network + private endpoints for SQL, Storage, Key Vault, and the App Services; public network access disabled afterwards Removes public exposure of the data and the apps — the biggest protection for sensitive data
Ingress Apps reachable only from the VNet (over your corporate network / VPN); optional internal Application Gateway + WAF v2 Only your network can reach the apps; the WAF adds OWASP filtering
Egress App Service VNet integration; optional Azure Firewall restricting outbound to the IDE API, time-phasing, and Entra/Graph Controls where the apps can call out
Monitoring Log Analytics workspace + diagnostics; optional Microsoft Defender for Cloud/SQL Detection and audit
Identity Require user assignment (limit sign-ins); Conditional Access for MFA and managed (known) devices Controls who signs in and from what devices

Reaching the apps when there is no corporate network yet

Private endpoints mean the apps have no public URL, so something must connect you into the VNet. If you already have a corporate network / VPN / ExpressRoute, use it. If you are still building and testing and do not have one, the reference includes an optional Tailscale subnet router (a small VM, deployed only when deployTestAccess = true) that lets developers reach the private resources from any office. An Azure point-to-site VPN Gateway is the Azure-native alternative. Turn the test-access option off for a real corporate deployment.

Full setup steps (approving the subnet route, split DNS for the private-endpoint names) are in PLAYBOOK.md step 7. Three things about it are worth knowing in advance, because each fails without an error:

  • Tailscale needs two different credentials, and both have "key" in the name. tailscaleAdminSshPublicKey is an ordinary SSH public key you generate yourself, for break-glass admin over the serial console when Tailscale is down. tailscaleAuthKey is an enrolment token from the Tailscale admin console. Generate the keypair up front — the moment you need it is the moment you cannot add one.
  • Auth keys are single-use. One carried forward from another environment, or revoked after it enrolled a router as the playbook tells you to, is dead. A spent key looks identical to a good one in a parameter file: the deployment succeeds, the VM runs, the Tailscale service starts, and the router simply never appears in your tailnet. Generate a fresh key per deployment.
  • Split DNS needs the public domains, not the privatelink.* zones — and Key Vault needs two entries, vault.azure.net and vaultcore.azure.net, because its private name sits under a different parent domain. Miss the second and every service resolves privately except Key Vault.

Troubleshooting connectivity

Once public access is disabled, the apps reach SQL, Storage, Key Vault, the IDE / ILAP Data Exchange API, the Timephasing API, and DNS only over the private path — so a missing private DNS record, an unapproved private endpoint, or missing VNet integration will break one or more of those lines (and can also make the app unreachable over SSH). The deployment package ships a troubleshooting guide and diagnostic scripts under Azure.IaC/Reference-Security/ for exactly this:

  • TROUBLESHOOTING.md — a symptom → cause → verify → fix guide covering every communication line, an "if you cannot SSH in" path, and how to recover an app that was locked down before its private path was verified.
  • Scripts/diagnose-connectivity.sh — run inside the API or Background Jobs container over SSH to test every line live.
  • Scripts/diagnose-connectivity.azcli / .ps1 — run from an admin machine; needs no SSH, so it works even when the environment is fully locked down. Start here — it usually pinpoints the missing private endpoint, DNS record, or VNet integration on its own.
  • Scripts/connectivity-queries.kql — Log Analytics queries for reading failures after the fact.

Verify before you lock down. Disabling public network access on an environment whose private path is not yet working strands the apps from their dependencies and from SSH. Confirm connectivity first (the scripts above go green), then run harden-public-access.

Application secrets: what is required now, and where this is going

The IDE / ILAP Data Exchange service token and the time-phasing access token are the two live secrets in an ILAP Analytics installation.

Required today. Both are supplied as parameters and end up as app settings, which means a filled-in parameter file contains working credentials for your tenant. Treat that file as a secret in its own right:

  • Keep it out of source control, and out of shared folders and ticket attachments.
  • Store the tokens somewhere you can retrieve them — you will need them again on any redeployment, and the IDE token cannot be read back after it is created.
  • Track the expiry. You chose an expiry date when you minted the IDE service token. Nothing warns you: on that date the field synchronisation simply stops, and the failure appears as missing ILAP terms rather than as an authentication error. Diary a renewal before it lapses and register the new token in the parameter file.

Planned direction — not the shipped default yet. The intention is to move both tokens into the same Key Vault that already holds the TLS certificate, and to have the apps read them through Key Vault references (@Microsoft.KeyVault(SecretUri=…)). That removes the credentials from the parameter file entirely and gives the secret an expiry date the platform itself can alert on, instead of relying on someone's diary. The templates do not do this today — if you go looking for a Key Vault reference in the current parameter file, there is not one to find.

Two things will need to be right when it happens, and both are worth knowing now because they shape how you build the vault:

  • The apps must route Key Vault traffic through the VNet. A Key Vault reference is resolved over the app's outbound path. Once the vault is private-endpoint-only, an app with vnetRouteAllEnabled set to false cannot reach it — and the symptom is an app that ran fine yesterday and now cannot read its own configuration. Set it to true on each app, and confirm a reference resolves before you disable public access.
  • Name the secrets so they cannot be confused. If one environment holds tokens for more than one component — ILAP Analytics and the Autonomous Component both call the same IDE tenant — the tokens are interchangeable to look at but identify different clients. ide-servicetoken-ia and ide-servicetoken-ac cost nothing and remove the possibility of a component reporting itself as the wrong client.

Access is granted with Azure RBAC on the vault (Key Vault Secrets User for each app's managed identity). Assignments can be scoped to an individual secret rather than the whole vault if you want components isolated from each other's tokens.

Limiting the number of users who can sign in

Entra ID does not cap sign-ins by a number. You enforce it by requiring user assignment on the API enterprise application and assigning only a specific group — the "number" is the group membership you manage. This is a one-line change (appRoleAssignmentRequired = true on the service principal) plus assigning your allowed group; see the README and Application Registrations / User Permissions.

Allowing only known devices (and requiring MFA)

Restricting access to known/managed devices is done with Conditional Access — an Entra ID control, not part of the Bicep. Create a policy scoped to the ILAP Analytics apps that requires multi-factor authentication and a compliant device (managed by Intune) or a Hybrid Entra joined device, optionally only from your trusted network locations. Always exclude two break-glass accounts so a misconfigured policy cannot lock everyone out, and roll it out in report-only mode first.

Conditional Access and device compliance require Entra ID P1 (P2 for risk-based policies) and Intune (or Hybrid Entra join). Confirm your licensing before relying on these controls.

Beyond your stated requirements, the reference also recommends: MFA (pairs with the device policy), locking down the data plane (SQL/Storage/Key Vault), keeping egress to the IDE API / time-phasing / Entra working, Key Vault hardening (RBAC, soft-delete, purge protection), monitoring/auditing (Log Analytics, SQL auditing, Defender), and break-glass accounts. Cost-heavy options (Application Gateway, Azure Firewall, Bastion, Defender, DDoS) are left as toggles you enable per environment.

Next steps

Use the template and detailed steps under Azure.IaC/Reference-Security/ (see its README.md). For the original high-level checklist, see Securing ILAP Analytics; for the overall install flow and permissions, see the Installation Overview.

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article