Azure AI-102 study materials
Azure AI-102 study resources

Northwind internal assistant: private networking, keyless auth, and chargeback

Azure AI-102 ยท Put your knowledge to work in context.

All case studies

Northwind internal assistant: private networking, keyless auth, and chargeback

Northwind's internal assistant serves 1,200 staff and answers about 18,000 questions per day from a 600,000-chunk index. The solution pairs an Azure AI Foundry resource hosting a GPT-4o deployment with Azure AI Search, and source documents live in Blob Storage. Security has three requirements: the search service must not be reachable from the public internet, no service keys may be stored in application configuration, and the development environment must not be able to read production data. After the team disabled public network access on the search service and created its private endpoint, two things broke: the blob indexer started failing with a connection error, and developers working from home could no longer run the app locally. The platform team also wants per-department cost reporting for internal chargeback.

1. Explain why the blob indexer broke after the search service's public network access was disabled, and describe what must be configured for indexing to work again.

Read the worked answer

Why it broke. The private endpoint on Azure AI Search protects inbound traffic to the search service. The indexer is a different direction: the search service makes an outbound connection to Blob Storage, and that traffic leaves from the search service's own network, not from your virtual network. Disabling public network access on Search does not change that outbound path; what actually broke is the storage account firewall or the DNS/link configuration that previously let the indexer reach the account.

What to configure.

  1. Create a shared private link from the search service to the storage account (Search โ†’ Networking โ†’ Shared private links, or via the indexer's data source connection). This is the supported way to let an indexer reach a storage account that is firewalled off.
  2. Approve the private endpoint connection on the storage account side; it stays in a pending state until approved.
  3. Confirm private DNS: the storage account's privatelink.blob.core.windows.net zone must resolve to the private IP from wherever the indexer egresses, otherwise the shared private link resolves but name resolution falls back to the public endpoint and is refused.
  4. Give the indexer's identity Storage Blob Data Reader on the account (see the auth question) - firewall and identity failures produce similar-looking indexer errors, so check both.

Judgement point. Do not "fix" this by re-enabling public access on storage or by adding the search service's outbound IPs to the firewall; those are brittle and are the exact thing the security requirement forbids. Test with a one-document indexer run before re-running the full index, and surface the indexer execution history/error detail rather than guessing.

2. The requirement says no keys in configuration, and developers must still be able to run locally. Recommend the authentication design and name the role assignments you would make.

Read the worked answer

Design. Remove shared-key auth entirely rather than merely refusing to store keys.

  • Disable local (key-based) authentication on both the Azure AI Foundry/Azure OpenAI resource and the search service. Once disabled, a leaked key is worthless and any code path that still depends on keys fails loudly in dev instead of silently in prod.
  • The application uses a managed identity in Azure and DefaultAzureCredential in code, so the same code path works locally with the developer's own Entra ID sign-in (az login) and in Azure with the managed identity. No secret ever enters configuration.
  • Role assignments (least privilege, per environment): app identity gets Cognitive Services OpenAI User on the Foundry resource and Search Index Data Reader on the index; the indexer identity gets Storage Blob Data Reader and, if it writes to the index, Search Index Data Contributor; humans who administer the index get Search Service Contributor, not data-plane reader.
  • Separate identities per environment; the dev identity must have no assignment on the production resources at all. This satisfies the "dev cannot read production data" requirement at the authorization layer, not the network layer alone.

Judgement point. Developers working from home failed because the private endpoint removed the public data path. The correct answer is not to open production to the internet: it is a separate non-production Foundry + Search pair for local work, or a point-to-site/ExpressRoute path into the production VNet for the small set of people who genuinely need it. Choose the separate-environment option unless there is a documented need to debug against production data.

3. Finance wants monthly cost per department for the assistant. Describe how you would produce that number and what Azure cost data alone cannot give you.

Read the worked answer

What the invoice can and cannot tell you. Azure Cost Management reports spend per resource and per tag. A single shared Foundry deployment and a single search service serve all departments, so tagging gives you the total bill, split by service, and nothing more. Cost data has no idea which caller sent which request.

Approach.

  1. Tag resources with env, owner, and costCenter for the fixed/platform portion (search tier, private endpoints, storage, container hosting). That portion is allocated by a stated rule - for example by seat count or by share of requests - and documented so it can be defended.
  2. Meter the variable portion at the application layer. Log every request with the department claim from the user's token and the token counts returned by the model (prompt tokens, completion tokens, cached tokens). Aggregate in Log Analytics and price it with the published per-1K-token rates.
  3. Reconcile monthly: metered variable cost plus allocated fixed cost should approximate the invoice within a small margin. If it drifts, either traffic is bypassing the metered path or pricing changed.

Judgement point. Do not try to infer per-department usage from Azure metrics; they are aggregated per resource. Also resist the urge to split into one Foundry resource per department purely for reporting - that multiplies quota management and private-endpoint work. Split only if a department has a genuine data-isolation or quota-guarantee requirement.

Capacity note. At ~18,000 requests/day (~540k/month) the peak tokens-per-minute matters more than the monthly total: check the deployment's TPM quota and request an increase before considering provisioned throughput, which only pays off at sustained high utilization and is wasted if usage is spiky.